[jlm] 02/11: Imported Upstream version 2.2+repack

Martin Quinson mquinson at alioth.debian.org
Wed Sep 4 19:27:07 UTC 2013


This is an automated email from the git hooks/post-receive script.

mquinson pushed a commit to branch debian-debian
in repository jlm.

commit d3957890f282a5a8a7c6b33085486f1ca4d2a2ba
Author: Martin Quinson <martin.quinson at loria.fr>
Date:   Wed Sep 4 14:53:25 2013 +0200

    Imported Upstream version 2.2+repack
---
 COPYING                                            |    8 +-
 ChangeLog                                          |   44 +
 README.md                                          |    8 +-
 TODO                                               |    3 -
 build.xml                                          |  112 +-
 img/focus_check.svg                                |    2 +-
 img/focus_intro.svg                                |    2 +-
 img/focus_not.svg                                  |    2 +-
 img/focus_working.svg                              |    2 +-
 img/lang_scala.png                                 |  Bin 0 -> 1175 bytes
 lib/doc/MainWindow.fr.html                         |    6 +-
 lib/doc/MainWindow.html                            |    4 +-
 lib/jb2jlm.pl                                      |  109 -
 lib/jb2plm.pl                                      |  109 +
 lib/l10n-engine/en.po                              | 1364 ++-
 lib/l10n-engine/fr.po                              | 1671 ++--
 lib/l10n-engine/jlm.pot                            | 1138 ---
 lib/l10n-engine/plm.pot                            | 1571 +++
 lib/l10n/README                                    |    2 +-
 lib/l10n/fr.po                                     | 9702 +++++++++---------
 lib/l10n/jlm.pot                                   |10557 --------------------
 lib/l10n/plm.pot                                   |10346 +++++++++++++++++++
 lib/resources/jlm.configuration.properties         |   33 -
 lib/resources/plm.configuration.properties         |   23 +
 po4a.conf                                          |  176 +-
 site/jlm.jnlp                                      |   56 -
 site/plm.jnlp                                      |   56 +
 src/jlm/core/ExoTest.java                          |  138 -
 src/jlm/core/GameListener.java                     |   22 -
 src/jlm/core/GameStateListener.java                |    9 -
 src/jlm/core/HumanLangChangesListener.java         |    9 -
 src/jlm/core/InMemoryCompiler.java                 |  657 --
 src/jlm/core/JLMCompilerException.java             |   76 -
 src/jlm/core/JLMException.java                     |   14 -
 src/jlm/core/ProgLangChangesListener.java          |    9 -
 src/jlm/core/StatusStateListener.java              |    8 -
 src/jlm/core/model/Course.java                     |  281 -
 src/jlm/core/model/CourseAppEngine.java            |   79 -
 src/jlm/core/model/DemoRunner.java                 |   65 -
 src/jlm/core/model/Game.java                       |  942 --
 src/jlm/core/model/HelpAppEngine.java              |   77 -
 src/jlm/core/model/HelpServer.java                 |   41 -
 src/jlm/core/model/LessonLoadingException.java     |   13 -
 src/jlm/core/model/LessonRunner.java               |  143 -
 src/jlm/core/model/LogWriter.java                  |   18 -
 src/jlm/core/model/Logger.java                     |  124 -
 src/jlm/core/model/ProgrammingLanguage.java        |   47 -
 src/jlm/core/model/ServerAnswer.java               |    8 -
 src/jlm/core/model/ServerExerciseData.java         |   73 -
 src/jlm/core/model/ServerUserData.java             |  142 -
 src/jlm/core/model/UserAbortException.java         |   15 -
 .../model/lesson/AccessibleExercisesListener.java  |    5 -
 .../core/model/lesson/BrokenLessonException.java   |   11 -
 src/jlm/core/model/lesson/ExecutionProgress.java   |   42 -
 src/jlm/core/model/lesson/Exercise.java            |  289 -
 src/jlm/core/model/lesson/ExerciseTemplated.java   |  420 -
 .../model/lesson/ExerciseTemplatingEntity.java     |   56 -
 src/jlm/core/model/lesson/ISourceFileListener.java |    9 -
 src/jlm/core/model/lesson/Lecture.java             |  133 -
 src/jlm/core/model/lesson/Lesson.java              |  171 -
 .../core/model/lesson/NoSuchEntityException.java   |   11 -
 src/jlm/core/model/lesson/SourceFile.java          |  129 -
 .../core/model/lesson/SourceFileRevertable.java    |   48 -
 src/jlm/core/model/lesson/package-info.java        |    7 -
 src/jlm/core/model/package-info.java               |    6 -
 src/jlm/core/model/session/FileSessionKit.java     |  211 -
 src/jlm/core/model/session/ISessionKit.java        |   41 -
 src/jlm/core/model/session/SessionDB.java          |  150 -
 src/jlm/core/model/session/ZipSessionKit.java      |  387 -
 src/jlm/core/model/session/package-info.java       |    8 -
 src/jlm/core/model/tracking/HeartBeatSpy.java      |   37 -
 src/jlm/core/model/tracking/IdenticaSpy.java       |   66 -
 src/jlm/core/model/tracking/LocalFileSpy.java      |   65 -
 .../core/model/tracking/ProgressSpyListener.java   |   15 -
 src/jlm/core/model/tracking/ServerSpy.java         |  119 -
 .../core/model/tracking/ServerSpyAppEngine.java    |   59 -
 src/jlm/core/model/tracking/TwitterSpy.java        |   51 -
 src/jlm/core/model/tracking/package-info.java      |    7 -
 src/jlm/core/package-info.java                     |   18 -
 src/jlm/core/ui/AboutJLMDialog.java                |   88 -
 src/jlm/core/ui/AboutLessonDialog.java             |   30 -
 src/jlm/core/ui/AboutWorldDialog.java              |   48 -
 src/jlm/core/ui/AbstractAboutDialog.java           |   48 -
 src/jlm/core/ui/ChooseCourseDialog.java            |  203 -
 src/jlm/core/ui/ChooseLectureDialog.java           |   92 -
 src/jlm/core/ui/CreateCourseDialog.java            |  158 -
 src/jlm/core/ui/EntityCellRenderer.java            |   44 -
 src/jlm/core/ui/EntityComboListAdapter.java        |   77 -
 src/jlm/core/ui/ExerciseFailedDialog.java          |   62 -
 src/jlm/core/ui/ExerciseView.java                  |  380 -
 src/jlm/core/ui/FeedbackDialog.java                |  179 -
 src/jlm/core/ui/IEditorPanel.java                  |    5 -
 src/jlm/core/ui/JavaEditorPanel.java               |   78 -
 src/jlm/core/ui/JavaLearningMachine.java           |   26 -
 src/jlm/core/ui/JlmHtmlEditorKit.java              |  291 -
 src/jlm/core/ui/LessonChooser.java                 |  256 -
 src/jlm/core/ui/LoggerPanel.java                   |  100 -
 src/jlm/core/ui/MainFrame.java                     |  723 --
 src/jlm/core/ui/MissionEditorTabs.java             |  209 -
 src/jlm/core/ui/OSXAdapter.java                    |  246 -
 src/jlm/core/ui/ResourcesCache.java                |  129 -
 src/jlm/core/ui/ResultsPanel.java                  |   70 -
 .../core/ui/SourceFileDocumentSynchronizer.java    |  105 -
 src/jlm/core/ui/StatusBar.java                     |  185 -
 src/jlm/core/ui/StudentDetailsDialog.java          |   48 -
 src/jlm/core/ui/TeacherConsoleDialog.java          |  136 -
 src/jlm/core/ui/TipsDialog.java                    |   28 -
 src/jlm/core/ui/WorldCellRenderer.java             |   46 -
 src/jlm/core/ui/WorldComboListAdapter.java         |   82 -
 src/jlm/core/ui/WorldView.java                     |   61 -
 src/jlm/core/ui/XMPPDialog.java                    |  129 -
 src/jlm/core/ui/action/AbstractGameAction.java     |   60 -
 src/jlm/core/ui/action/CleanUpSession.java         |   23 -
 src/jlm/core/ui/action/CreateCourse.java           |   34 -
 src/jlm/core/ui/action/DeleteCourse.java           |   54 -
 src/jlm/core/ui/action/ExportSession.java          |   43 -
 src/jlm/core/ui/action/HelpMe.java                 |   41 -
 src/jlm/core/ui/action/ImportSession.java          |   38 -
 src/jlm/core/ui/action/OneStep.java                |   22 -
 src/jlm/core/ui/action/PlayDemo.java               |   30 -
 src/jlm/core/ui/action/QuitGame.java               |   31 -
 src/jlm/core/ui/action/RefreshCourse.java          |   51 -
 src/jlm/core/ui/action/Reset.java                  |   32 -
 src/jlm/core/ui/action/RevertExercise.java         |   49 -
 src/jlm/core/ui/action/SetLanguage.java            |   24 -
 src/jlm/core/ui/action/SetProgLanguage.java        |   23 -
 src/jlm/core/ui/action/StartExecution.java         |   35 -
 src/jlm/core/ui/action/StepExecution.java          |   33 -
 src/jlm/core/ui/action/StopExecution.java          |   30 -
 src/jlm/core/ui/action/SwitchExo.java              |   32 -
 src/jlm/core/ui/action/package-info.java           |    5 -
 src/jlm/core/ui/package-info.java                  |    5 -
 src/jlm/core/utils/ColorMapper.java                |   48 -
 src/jlm/core/utils/FileUtils.java                  |  135 -
 src/jlm/core/utils/InvalidColorNameException.java  |   11 -
 src/jlm/universe/BrokenWorldFileException.java     |    9 -
 src/jlm/universe/Direction.java                    |  112 -
 src/jlm/universe/Entity.java                       |  326 -
 src/jlm/universe/EntityControlPanel.java           |   22 -
 src/jlm/universe/GridWorld.java                    |   94 -
 src/jlm/universe/GridWorldCell.java                |   42 -
 src/jlm/universe/IEntityStackListener.java         |    7 -
 src/jlm/universe/IWorldView.java                   |   15 -
 src/jlm/universe/World.java                        |  328 -
 src/jlm/universe/bat/BatEntity.java                |  100 -
 src/jlm/universe/bat/BatExercise.java              |   64 -
 src/jlm/universe/bat/BatTest.java                  |  206 -
 src/jlm/universe/bat/BatWorld.java                 |   96 -
 src/jlm/universe/bat/BatWorldView.java             |   70 -
 src/jlm/universe/bat/package-info.java             |    4 -
 src/jlm/universe/bugglequest/AbstractBuggle.java   |  446 -
 src/jlm/universe/bugglequest/Baggle.java           |   69 -
 src/jlm/universe/bugglequest/Buggle.java           |   33 -
 src/jlm/universe/bugglequest/BuggleWorld.fr.html   |   74 -
 src/jlm/universe/bugglequest/BuggleWorld.html      |   72 -
 src/jlm/universe/bugglequest/BuggleWorld.java      |  493 -
 src/jlm/universe/bugglequest/BuggleWorldCell.java  |  254 -
 src/jlm/universe/bugglequest/SimpleBuggle.java     |  126 -
 .../exception/AlreadyHaveBaggleException.java      |   13 -
 .../exception/BuggleInOuterSpaceException.java     |   14 -
 .../bugglequest/exception/BuggleWallException.java |   14 -
 .../exception/NoBaggleUnderBuggleException.java    |   14 -
 .../bugglequest/exception/package-info.java        |    5 -
 .../bugglequest/mapeditor/EditionListener.java     |   23 -
 src/jlm/universe/bugglequest/mapeditor/Editor.java |  125 -
 .../universe/bugglequest/mapeditor/MainFrame.java  |  262 -
 .../bugglequest/mapeditor/MapEditorApp.java        |   21 -
 .../universe/bugglequest/mapeditor/MapView.java    |  143 -
 .../bugglequest/mapeditor/PropertiesEditor.java    |  389 -
 .../bugglequest/mapeditor/package-info.java        |    5 -
 src/jlm/universe/bugglequest/package-info.java     |    5 -
 .../universe/bugglequest/ui/BuggleButtonPanel.java |  240 -
 .../bugglequest/ui/BuggleColorCellRenderer.java    |   48 -
 .../universe/bugglequest/ui/BuggleWorldView.java   |  318 -
 src/jlm/universe/bugglequest/ui/package-info.java  |    5 -
 src/jlm/universe/lightbot/LightBotEditorPanel.java |  138 -
 src/jlm/universe/lightbot/LightBotEntity.java      |  220 -
 src/jlm/universe/lightbot/LightBotExercise.java    |   83 -
 src/jlm/universe/lightbot/LightBotInstruction.java |   98 -
 src/jlm/universe/lightbot/LightBotSourceFile.java  |   78 -
 src/jlm/universe/lightbot/LightBotWorld.fr.html    |   32 -
 src/jlm/universe/lightbot/LightBotWorld.html       |   19 -
 src/jlm/universe/lightbot/LightBotWorld.java       |  204 -
 src/jlm/universe/lightbot/LightBotWorldCell.java   |  113 -
 src/jlm/universe/lightbot/LightBotWorldView2D.java |  137 -
 .../lightbot/LightBotWorldViewIsometric.java       |  312 -
 src/jlm/universe/lightbot/package-info.java        |    6 -
 src/jlm/universe/package-info.java                 |    8 -
 src/jlm/universe/sort/CopyVal.java                 |   25 -
 src/jlm/universe/sort/GetVal.java                  |   28 -
 src/jlm/universe/sort/Operation.java               |   57 -
 src/jlm/universe/sort/SetVal.java                  |   30 -
 src/jlm/universe/sort/SortingButtonPanel.java      |  104 -
 src/jlm/universe/sort/SortingEntity.java           |   62 -
 src/jlm/universe/sort/SortingWorld.fr.html         |   69 -
 src/jlm/universe/sort/SortingWorld.html            |   65 -
 src/jlm/universe/sort/SortingWorld.java            |  348 -
 src/jlm/universe/sort/SortingWorldView.java        |  335 -
 src/jlm/universe/sort/Swap.java                    |   30 -
 src/jlm/universe/sort/package-info.java            |    6 -
 src/jlm/universe/turtles/Direction.java            |    7 -
 src/jlm/universe/turtles/Line.java                 |   66 -
 src/jlm/universe/turtles/Turtle.java               |  392 -
 src/jlm/universe/turtles/TurtleButtonPanel.java    |   28 -
 src/jlm/universe/turtles/TurtleWorld.fr.html       |   77 -
 src/jlm/universe/turtles/TurtleWorld.html          |   74 -
 src/jlm/universe/turtles/TurtleWorld.java          |  196 -
 src/jlm/universe/turtles/TurtleWorldView.java      |   57 -
 src/jlm/universe/turtles/package-info.java         |    6 -
 src/lessons/backtracking/BacktrackingEntity.java   |    4 +-
 src/lessons/backtracking/BacktrackingExercise.java |   12 +-
 src/lessons/backtracking/BacktrackingWorld.java    |   10 +-
 .../backtracking/BacktrackingWorldView.java        |    4 +-
 src/lessons/backtracking/ExKnapsack.java           |    4 +-
 src/lessons/backtracking/KnapsackSolver.java       |    4 -
 src/lessons/backtracking/Main.fr.html              |    8 +-
 src/lessons/backtracking/Main.html                 |   10 +-
 src/lessons/backtracking/Main.java                 |    2 +-
 src/lessons/bat/string1/AltPairs.fr.html           |    2 +-
 src/lessons/bat/string1/AltPairs.html              |    2 +-
 src/lessons/bat/string1/AltPairs.java              |   22 +-
 src/lessons/bat/string1/FrontTimes.fr.html         |    2 +-
 src/lessons/bat/string1/FrontTimes.html            |    2 +-
 src/lessons/bat/string1/FrontTimes.java            |   25 +-
 src/lessons/bat/string1/Last2.fr.html              |    2 +-
 src/lessons/bat/string1/Last2.html                 |    2 +-
 src/lessons/bat/string1/Last2.java                 |   27 +-
 src/lessons/bat/string1/Main.fr.html               |    2 +-
 src/lessons/bat/string1/Main.html                  |    2 +-
 src/lessons/bat/string1/Main.java                  |   11 +-
 src/lessons/bat/string1/StringBits.fr.html         |    2 +-
 src/lessons/bat/string1/StringBits.html            |    2 +-
 src/lessons/bat/string1/StringBits.java            |   22 +-
 src/lessons/bat/string1/StringMatch.fr.html        |    2 +-
 src/lessons/bat/string1/StringMatch.html           |    2 +-
 src/lessons/bat/string1/StringMatch.java           |   24 +-
 src/lessons/bat/string1/StringSplosion.fr.html     |    2 +-
 src/lessons/bat/string1/StringSplosion.html        |    2 +-
 src/lessons/bat/string1/StringSplosion.java        |   22 +-
 src/lessons/bat/string1/StringTimes.fr.html        |    2 +-
 src/lessons/bat/string1/StringTimes.html           |    2 +-
 src/lessons/bat/string1/StringTimes.java           |   22 +-
 src/lessons/bat/string1/StringX.fr.html            |    2 +-
 src/lessons/bat/string1/StringX.html               |    2 +-
 src/lessons/bat/string1/StringX.java               |   23 +-
 src/lessons/bat/string1/StringYak.fr.html          |    2 +-
 src/lessons/bat/string1/StringYak.html             |    2 +-
 src/lessons/bat/string1/StringYak.java             |   28 +-
 src/lessons/bat/string1/short_desc.fr.html         |    2 +-
 src/lessons/bat/string1/short_desc.html            |    2 +-
 src/lessons/chooser/LessonChooser.fr.html          |   25 +-
 src/lessons/chooser/LessonChooser.fr.rtfd/TXT.rtf  |   44 -
 src/lessons/chooser/LessonChooser.html             |   18 +-
 src/lessons/chooser/LessonChooser.java             |    6 +-
 src/lessons/chooser/Main.java                      |    2 +-
 src/lessons/lightbot/Board01TwoSteps.java          |   10 +-
 src/lessons/lightbot/Board02Turn.java              |   10 +-
 src/lessons/lightbot/Board03Jump.java              |   10 +-
 src/lessons/lightbot/Board04Stairs.java            |   10 +-
 src/lessons/lightbot/Board05Higher.java            |   10 +-
 src/lessons/lightbot/Board06Func.java              |   10 +-
 src/lessons/lightbot/Board07Repeat.java            |   10 +-
 src/lessons/lightbot/Board08Rec.java               |   10 +-
 src/lessons/lightbot/Board09Castle.java            |   10 +-
 src/lessons/lightbot/Board10Wall.java              |   10 +-
 src/lessons/lightbot/Board11Sea.java               |   10 +-
 src/lessons/lightbot/Board12Escher.java            |   10 +-
 src/lessons/lightbot/Main.java                     |    2 +-
 src/lessons/maze/Main.java                         |    4 +-
 src/lessons/maze/island/IslandMaze.fr.html         |   59 +-
 src/lessons/maze/island/IslandMaze.html            |  142 +-
 src/lessons/maze/island/IslandMaze.java            |   10 +-
 src/lessons/maze/island/IslandMazeEntity.java      |   19 +-
 src/lessons/maze/island/IslandMazeEntity.py        |    6 +-
 src/lessons/maze/island/IslandMazeEntity.scala     |   66 +
 src/lessons/maze/pledge/PledgeMaze.fr.html         |   32 +-
 src/lessons/maze/pledge/PledgeMaze.java            |   10 +-
 src/lessons/maze/pledge/PledgeMazeEntity.java      |   20 +-
 src/lessons/maze/pledge/PledgeMazeEntity.py        |    6 +-
 src/lessons/maze/pledge/PledgeMazeEntity.scala     |   68 +
 .../maze/randommouse/RandomMouseMaze.fr.html       |   20 +-
 src/lessons/maze/randommouse/RandomMouseMaze.html  |   60 +-
 src/lessons/maze/randommouse/RandomMouseMaze.java  |   10 +-
 .../maze/randommouse/RandomMouseMazeEntity.java    |   14 +-
 .../maze/randommouse/RandomMouseMazeEntity.py      |    4 +-
 .../maze/randommouse/RandomMouseMazeEntity.scala   |   43 +
 .../maze/shortestpath/ShortestPathMaze.fr.html     |   53 +-
 .../maze/shortestpath/ShortestPathMaze.java        |   10 +-
 .../maze/shortestpath/ShortestPathMazeEntity.java  |   38 +-
 .../maze/shortestpath/ShortestPathMazeEntity.scala |  123 +
 .../maze/wallfindfollow/WallFindFollowMaze.fr.html |   20 +-
 .../maze/wallfindfollow/WallFindFollowMaze.java    |   11 +-
 .../wallfindfollow/WallFindFollowMazeEntity.java   |   53 +
 .../wallfindfollow/WallFindFollowMazeEntity.py     |    8 +-
 .../wallfindfollow/WallFindFollowMazeEntity.scala  |   49 +
 .../maze/wallfollower/WallFollowerMaze.fr.html     |   32 +-
 .../maze/wallfollower/WallFollowerMaze.html        |  129 +-
 .../maze/wallfollower/WallFollowerMaze.java        |   10 +-
 .../maze/wallfollower/WallFollowerMazeEntity.java  |   32 +-
 .../maze/wallfollower/WallFollowerMazeEntity.py    |    8 +-
 .../maze/wallfollower/WallFollowerMazeEntity.scala |   49 +
 src/lessons/recursion/Main.java                    |    6 +-
 src/lessons/recursion/circle/Circle.fr.html        |   15 +-
 src/lessons/recursion/circle/Circle.html           |   42 +-
 src/lessons/recursion/circle/Circle.java           |   10 +-
 src/lessons/recursion/circle/CircleEntity.java     |   18 +-
 src/lessons/recursion/circle/CircleEntity.py       |    2 +-
 src/lessons/recursion/circle/CircleEntity.scala    |   22 +
 .../recursion/dragoncurve/DragonCurve1.fr.html     |   12 +-
 .../recursion/dragoncurve/DragonCurve1.html        |   54 +-
 .../recursion/dragoncurve/DragonCurve1.java        |   10 +-
 .../recursion/dragoncurve/DragonCurve1Entity.java  |    2 +-
 .../recursion/dragoncurve/DragonCurve1Entity.scala |   28 +
 .../recursion/dragoncurve/DragonCurve2.fr.html     |   20 +-
 .../recursion/dragoncurve/DragonCurve2.html        |   96 +-
 .../recursion/dragoncurve/DragonCurve2.java        |   10 +-
 .../recursion/dragoncurve/DragonCurve2Entity.java  |    2 +-
 .../recursion/dragoncurve/DragonCurve2Entity.scala |   46 +
 src/lessons/recursion/hanoi/HanoiBoard.fr.html     |   11 +-
 src/lessons/recursion/hanoi/HanoiBoard.html        |   92 +-
 src/lessons/recursion/hanoi/HanoiBoard.java        |    4 +-
 src/lessons/recursion/hanoi/HanoiBoardEntity.scala |   35 +
 src/lessons/recursion/hanoi/Main.java              |    2 +-
 .../recursion/hanoi/universe/HanoiEntity.java      |   11 +-
 .../recursion/hanoi/universe/HanoiMovePanel.java   |    4 +-
 .../recursion/hanoi/universe/HanoiWorld.fr.html    |    9 +-
 .../recursion/hanoi/universe/HanoiWorld.html       |   51 +-
 .../recursion/hanoi/universe/HanoiWorld.java       |   19 +-
 .../recursion/hanoi/universe/HanoiWorldView.java   |    4 +-
 src/lessons/recursion/koch/Koch.fr.html            |   16 +-
 src/lessons/recursion/koch/Koch.html               |   38 +-
 src/lessons/recursion/koch/Koch.java               |   10 +-
 src/lessons/recursion/koch/KochEntity.java         |   14 +-
 src/lessons/recursion/koch/KochEntity.py           |   12 +-
 src/lessons/recursion/koch/KochEntity.scala        |   36 +
 .../polygonfractal/PolygonFractal.fr.html          |    2 +-
 .../recursion/polygonfractal/PolygonFractal.html   |   16 +-
 .../recursion/polygonfractal/PolygonFractal.java   |   10 +-
 .../polygonfractal/PolygonFractalEntity.java       |    8 +-
 .../polygonfractal/PolygonFractalEntity.py         |    6 +-
 .../polygonfractal/PolygonFractalEntity.scala      |   31 +
 .../recursion/sierpinski/Sierpinski.fr.html        |    8 +-
 src/lessons/recursion/sierpinski/Sierpinski.html   |   18 +-
 src/lessons/recursion/sierpinski/Sierpinski.java   |   10 +-
 .../recursion/sierpinski/SierpinskiEntity.java     |    8 +-
 .../recursion/sierpinski/SierpinskiEntity.py       |    6 +-
 .../recursion/sierpinski/SierpinskiEntity.scala    |   26 +
 src/lessons/recursion/spiral/Spiral.fr.html        |   22 +-
 src/lessons/recursion/spiral/Spiral.html           |   58 +-
 src/lessons/recursion/spiral/Spiral.java           |   10 +-
 src/lessons/recursion/spiral/SpiralEntity.java     |    4 +-
 src/lessons/recursion/spiral/SpiralEntity.py       |    2 +-
 src/lessons/recursion/spiral/SpiralEntity.scala    |   23 +
 src/lessons/recursion/spiral/SpiralUse.fr.html     |   31 +-
 src/lessons/recursion/spiral/SpiralUse.html        |   69 +-
 src/lessons/recursion/spiral/SpiralUse.java        |   10 +-
 src/lessons/recursion/spiral/SpiralUseEntity.java  |    4 +-
 src/lessons/recursion/spiral/SpiralUseEntity.py    |    2 +-
 src/lessons/recursion/spiral/SpiralUseEntity.scala |   35 +
 src/lessons/recursion/square/FourSquare.fr.html    |   58 +
 src/lessons/recursion/square/FourSquare.html       |   55 +
 src/lessons/recursion/square/FourSquare.java       |   20 +
 src/lessons/recursion/square/FourSquareEntity.java |   25 +
 src/lessons/recursion/square/FourSquareEntity.py   |   13 +
 .../recursion/square/FourSquareEntity.scala        |   23 +
 src/lessons/recursion/square/Square.fr.html        |   60 -
 src/lessons/recursion/square/Square.html           |   56 -
 src/lessons/recursion/square/Square.java           |   20 -
 src/lessons/recursion/square/SquareEntity.java     |   23 -
 src/lessons/recursion/square/SquareEntity.py       |   13 -
 src/lessons/recursion/star/Star.java               |   10 +-
 src/lessons/recursion/star/StarEntity.java         |   28 +-
 src/lessons/recursion/star/StarEntity.py           |    8 +-
 src/lessons/recursion/star/StarEntity.scala        |   36 +
 src/lessons/recursion/tree/Tree.fr.html            |    2 +-
 src/lessons/recursion/tree/Tree.html               |   30 +-
 src/lessons/recursion/tree/Tree.java               |   10 +-
 src/lessons/recursion/tree/TreeEntity.java         |    8 +-
 src/lessons/recursion/tree/TreeEntity.py           |    6 +-
 src/lessons/recursion/tree/TreeEntity.scala        |   29 +
 src/lessons/sort/Main.java                         |   16 +-
 src/lessons/sort/baseball/BubbleBaseball.fr.html   |    2 +-
 src/lessons/sort/baseball/BubbleBaseball.java      |    4 +-
 .../sort/baseball/BubbleBaseballEntity.scala       |   37 +
 src/lessons/sort/baseball/InsertBaseball.java      |    4 +-
 .../sort/baseball/InsertBaseballEntity.scala       |   43 +
 src/lessons/sort/baseball/Main.fr.html             |    4 +-
 src/lessons/sort/baseball/Main.html                |    4 +-
 src/lessons/sort/baseball/Main.java                |    2 +-
 src/lessons/sort/baseball/NaiveBaseball.fr.html    |    2 +-
 src/lessons/sort/baseball/NaiveBaseball.java       |    4 +-
 .../sort/baseball/NaiveBaseballEntity.scala        |   32 +
 src/lessons/sort/baseball/SelectBaseball.java      |    4 +-
 .../sort/baseball/SelectBaseballEntity.scala       |   76 +
 .../sort/baseball/universe/BaseballEntity.java     |   17 +-
 .../sort/baseball/universe/BaseballMovePanel.java  |    4 +-
 .../sort/baseball/universe/BaseballWorld.fr.html   |   28 +-
 .../sort/baseball/universe/BaseballWorld.html      |   31 +-
 .../sort/baseball/universe/BaseballWorld.java      |   42 +-
 .../sort/baseball/universe/BaseballWorldView.java  |   12 +-
 src/lessons/sort/bubble/AlgBubbleSort1.fr.html     |   28 +-
 src/lessons/sort/bubble/AlgBubbleSort1.html        |   17 +-
 src/lessons/sort/bubble/AlgBubbleSort1.java        |    8 +-
 src/lessons/sort/bubble/AlgBubbleSort1Entity.java  |    2 +-
 src/lessons/sort/bubble/AlgBubbleSort1Entity.scala |   27 +
 src/lessons/sort/bubble/AlgBubbleSort2.java        |    8 +-
 src/lessons/sort/bubble/AlgBubbleSort2Entity.java  |    2 +-
 src/lessons/sort/bubble/AlgBubbleSort2Entity.scala |   21 +
 src/lessons/sort/bubble/AlgBubbleSort3.java        |    8 +-
 src/lessons/sort/bubble/AlgBubbleSort3Entity.java  |    2 +-
 src/lessons/sort/bubble/AlgBubbleSort3Entity.scala |   31 +
 src/lessons/sort/cocktail/AlgCocktailSort1.java    |    8 +-
 .../sort/cocktail/AlgCocktailSort1Entity.java      |    2 +-
 .../sort/cocktail/AlgCocktailSort1Entity.scala     |   33 +
 src/lessons/sort/cocktail/AlgCocktailSort2.java    |    8 +-
 .../sort/cocktail/AlgCocktailSort2Entity.java      |    2 +-
 .../sort/cocktail/AlgCocktailSort2Entity.scala     |   37 +
 src/lessons/sort/cocktail/AlgCocktailSort3.java    |    8 +-
 .../sort/cocktail/AlgCocktailSort3Entity.java      |    2 +-
 .../sort/cocktail/AlgCocktailSort3Entity.scala     |   40 +
 src/lessons/sort/comb/AlgCombSort.fr.html          |   18 +-
 src/lessons/sort/comb/AlgCombSort.html             |   12 +-
 src/lessons/sort/comb/AlgCombSort.java             |    8 +-
 src/lessons/sort/comb/AlgCombSort11.java           |    8 +-
 src/lessons/sort/comb/AlgCombSort11Entity.java     |    2 +-
 src/lessons/sort/comb/AlgCombSort11Entity.scala    |   34 +
 src/lessons/sort/comb/AlgCombSortEntity.java       |    2 +-
 src/lessons/sort/comb/AlgCombSortEntity.scala      |   31 +
 src/lessons/sort/gnome/AlgGnomeSort.java           |    8 +-
 src/lessons/sort/gnome/AlgGnomeSortEntity.java     |    2 +-
 src/lessons/sort/gnome/AlgGnomeSortEntity.scala    |   30 +
 src/lessons/sort/insertion/AlgInsertionSort.java   |    8 +-
 .../sort/insertion/AlgInsertionSortEntity.java     |    2 +-
 .../sort/insertion/AlgInsertionSortEntity.scala    |   28 +
 src/lessons/sort/pancake/BasicPancake.java         |    4 +-
 src/lessons/sort/pancake/BasicPancakeEntity.scala  |   35 +
 src/lessons/sort/pancake/BurnedPancake.java        |    4 +-
 src/lessons/sort/pancake/BurnedPancakeEntity.scala |   42 +
 src/lessons/sort/pancake/GatesPancake.java         |    4 +-
 src/lessons/sort/pancake/GatesPancakeEntity.scala  |  287 +
 src/lessons/sort/pancake/Main.fr.html              |    4 +-
 src/lessons/sort/pancake/Main.html                 |    4 +-
 src/lessons/sort/pancake/Main.java                 |    2 +-
 src/lessons/sort/pancake/img/gates-a.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-b.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-c.svg           |   18 +-
 src/lessons/sort/pancake/img/gates-d.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-e.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-f.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-f1.svg          |   16 +-
 src/lessons/sort/pancake/img/gates-f2.svg          |    2 +-
 src/lessons/sort/pancake/img/gates-g.svg           |    2 +-
 src/lessons/sort/pancake/img/gates-h.svg           |    2 +-
 .../sort/pancake/universe/PancakeEntity.java       |   14 +-
 .../pancake/universe/PancakeFlipButtonPanel.java   |    4 +-
 .../sort/pancake/universe/PancakeWorld.fr.html     |   20 +-
 .../sort/pancake/universe/PancakeWorld.html        |   20 +-
 .../sort/pancake/universe/PancakeWorld.java        |   23 +-
 .../sort/pancake/universe/PancakeWorldView.java    |    4 +-
 src/lessons/sort/selection/AlgSelectionSort.java   |    8 +-
 .../sort/selection/AlgSelectionSortEntity.java     |    2 +-
 .../sort/selection/AlgSelectionSortEntity.scala    |   29 +
 src/lessons/sort/shell/AlgShellSort.fr.html        |   12 +-
 src/lessons/sort/shell/AlgShellSort.html           |    6 +-
 src/lessons/sort/shell/AlgShellSort.java           |    8 +-
 src/lessons/sort/shell/AlgShellSortEntity.java     |    6 +-
 src/lessons/sort/shell/AlgShellSortEntity.scala    |   53 +
 src/lessons/turmites/Main.fr.html                  |    9 +-
 src/lessons/turmites/Main.html                     |   10 +-
 src/lessons/turmites/Main.java                     |    4 +-
 .../turmites/helloturmite/HelloTurmite.fr.html     |   77 +-
 .../turmites/helloturmite/HelloTurmite.html        |  150 +-
 .../turmites/helloturmite/HelloTurmite.java        |    6 +-
 .../turmites/helloturmite/HelloTurmiteEntity.java  |   14 +-
 .../turmites/helloturmite/HelloTurmiteEntity.py    |    6 +-
 .../turmites/helloturmite/HelloTurmiteEntity.scala |   68 +
 src/lessons/turmites/langton/Langton.fr.html       |   23 +-
 src/lessons/turmites/langton/Langton.html          |   87 +-
 src/lessons/turmites/langton/Langton.java          |    4 +-
 src/lessons/turmites/langton/LangtonEntity.java    |    6 +-
 src/lessons/turmites/langton/LangtonEntity.py      |    4 +-
 src/lessons/turmites/langton/LangtonEntity.scala   |   39 +
 .../turmites/langtoncolors/LangtonColors.fr.html   |   20 +-
 .../turmites/langtoncolors/LangtonColors.html      |   75 +-
 .../turmites/langtoncolors/LangtonColors.java      |    6 +-
 .../langtoncolors/LangtonColorsEntity.java         |    6 +-
 .../turmites/langtoncolors/LangtonColorsEntity.py  |    4 +-
 .../langtoncolors/LangtonColorsEntity.scala        |   49 +
 .../turmites/turmitecreator/TurmiteCreator.fr.html |   12 +-
 .../turmites/turmitecreator/TurmiteCreator.html    |  295 +-
 .../turmites/turmitecreator/TurmiteCreator.java    |    4 +-
 .../turmitecreator/TurmiteCreatorEntity.java       |    8 +-
 .../turmitecreator/TurmiteCreatorEntity.py         |    6 +-
 .../turmitecreator/TurmiteCreatorEntity.scala      |  139 +
 src/lessons/turmites/universe/TurmiteWorld.fr.html |   59 +-
 src/lessons/turmites/universe/TurmiteWorld.html    |   64 +-
 src/lessons/turmites/universe/TurmiteWorld.java    |   26 +-
 .../turmites/universe/TurmiteWorldView.java        |    4 +-
 src/lessons/turtleart/CircleSquareEntity.java      |   23 +
 src/lessons/turtleart/CircleSquareEntity.py        |   12 +
 src/lessons/turtleart/CircleSquareEntity.scala     |   23 +
 src/lessons/turtleart/CircleTenEntity.java         |   16 +
 src/lessons/turtleart/CircleTenEntity.py           |    4 +
 src/lessons/turtleart/CircleTenEntity.scala        |   16 +
 src/lessons/turtleart/CircleTwoEntity.java         |   21 +
 src/lessons/turtleart/CircleTwoEntity.py           |    9 +
 src/lessons/turtleart/CircleTwoEntity.scala        |   21 +
 src/lessons/turtleart/CircleYingEntity.java        |   25 +
 src/lessons/turtleart/CircleYingEntity.py          |   12 +
 src/lessons/turtleart/CircleYingEntity.scala       |   25 +
 src/lessons/turtleart/DiskFourEntity.java          |   29 +
 src/lessons/turtleart/DiskFourEntity.py            |   15 +
 src/lessons/turtleart/DiskFourEntity.scala         |   29 +
 src/lessons/turtleart/DiskFourthEntity.java        |   19 +
 src/lessons/turtleart/DiskFourthEntity.py          |    7 +
 src/lessons/turtleart/DiskFourthEntity.scala       |   19 +
 src/lessons/turtleart/DiskTwoEntity.java           |   28 +
 src/lessons/turtleart/DiskTwoEntity.py             |   13 +
 src/lessons/turtleart/DiskTwoEntity.scala          |   28 +
 src/lessons/turtleart/HouseEntity.java             |   32 +
 src/lessons/turtleart/HouseEntity.py               |   19 +
 src/lessons/turtleart/HouseEntity.scala            |   32 +
 src/lessons/turtleart/HouseManyEntity.java         |   62 +
 src/lessons/turtleart/HouseManyEntity.py           |   47 +
 src/lessons/turtleart/HouseManyEntity.scala        |   62 +
 src/lessons/turtleart/HouseThreeEntity.java        |   39 +
 src/lessons/turtleart/HouseThreeEntity.py          |   26 +
 src/lessons/turtleart/HouseThreeEntity.scala       |   39 +
 src/lessons/turtleart/Main.fr.html                 |   32 +
 src/lessons/turtleart/Main.html                    |   21 +
 src/lessons/turtleart/Main.java                    |  135 +
 src/lessons/turtleart/Polygon15Entity.java         |   20 +
 src/lessons/turtleart/Polygon15Entity.py           |    8 +
 src/lessons/turtleart/Polygon15Entity.scala        |   20 +
 src/lessons/turtleart/Polygon360Entity.java        |   19 +
 src/lessons/turtleart/Polygon360Entity.py          |    7 +
 src/lessons/turtleart/Polygon360Entity.scala       |   19 +
 src/lessons/turtleart/Polygon6Entity.java          |   19 +
 src/lessons/turtleart/Polygon6Entity.py            |    7 +
 src/lessons/turtleart/Polygon6Entity.scala         |   19 +
 src/lessons/turtleart/Polygon7Entity.java          |   19 +
 src/lessons/turtleart/Polygon7Entity.py            |    7 +
 src/lessons/turtleart/Polygon7Entity.scala         |   19 +
 src/lessons/turtleart/SmallSquareEntity.java       |   20 +
 src/lessons/turtleart/SmallSquareEntity.py         |    8 +
 src/lessons/turtleart/SmallSquareEntity.scala      |   20 +
 src/lessons/turtleart/SquareEntity.java            |   20 +
 src/lessons/turtleart/SquareEntity.py              |    8 +
 src/lessons/turtleart/SquareEntity.scala           |   20 +
 src/lessons/turtleart/StairsEntity.java            |   21 +
 src/lessons/turtleart/StairsEntity.py              |    9 +
 src/lessons/turtleart/StairsEntity.scala           |   21 +
 src/lessons/turtleart/StarEntity.java              |   25 +
 src/lessons/turtleart/StarEntity.py                |   13 +
 src/lessons/turtleart/StarEntity.scala             |   25 +
 src/lessons/turtleart/TriangleEntity.java          |   20 +
 src/lessons/turtleart/TriangleEntity.py            |    8 +
 src/lessons/turtleart/TriangleEntity.scala         |   20 +
 src/lessons/turtleart/TriangleFlatEntity.java      |   19 +
 src/lessons/turtleart/TriangleFlatEntity.py        |    7 +
 src/lessons/turtleart/TriangleFlatEntity.scala     |   19 +
 src/lessons/turtleart/icon.png                     |  Bin 0 -> 1150 bytes
 src/lessons/turtleart/short_desc.fr.html           |    6 +
 src/lessons/turtleart/short_desc.html              |    5 +
 src/lessons/welcome/Main.fr.html                   |   14 +
 src/lessons/welcome/Main.html                      |   13 +
 src/lessons/welcome/Main.java                      |  245 +-
 .../welcome/array/array123/Array123.fr.html        |    2 +-
 src/lessons/welcome/array/array123/Array123.html   |    2 +-
 src/lessons/welcome/array/array123/Array123.java   |   22 +-
 .../welcome/array/array667/Array667.fr.html        |    2 +-
 src/lessons/welcome/array/array667/Array667.html   |    2 +-
 src/lessons/welcome/array/array667/Array667.java   |   23 +-
 .../welcome/array/arraycount9/ArrayCount9.fr.html  |    2 +-
 .../welcome/array/arraycount9/ArrayCount9.html     |    2 +-
 .../welcome/array/arraycount9/ArrayCount9.java     |   23 +-
 .../welcome/array/arrayfront9/ArrayFront9.fr.html  |    2 +-
 .../welcome/array/arrayfront9/ArrayFront9.html     |    2 +-
 .../welcome/array/arrayfront9/ArrayFront9.java     |   22 +-
 .../welcome/array/averagevalue/AverageValue.java   |   22 +-
 src/lessons/welcome/array/basics/Array.fr.html     |  237 -
 src/lessons/welcome/array/basics/Array.html        |  229 -
 src/lessons/welcome/array/basics/Array.java        |   50 -
 .../{Array-answer0.map => Array1-answer0.map}      |    0
 .../{Array-answer1.map => Array1-answer1.map}      |    0
 .../{Array-answer2.map => Array1-answer2.map}      |    0
 src/lessons/welcome/array/basics/Array1.fr.html    |  298 +
 src/lessons/welcome/array/basics/Array1.html       |  242 +
 src/lessons/welcome/array/basics/Array1.java       |   50 +
 src/lessons/welcome/array/basics/Array1Entity.java |   57 +
 src/lessons/welcome/array/basics/Array1Entity.py   |   37 +
 .../welcome/array/basics/Array1Entity.scala        |   55 +
 src/lessons/welcome/array/basics/Array2.fr.html    |   25 +-
 src/lessons/welcome/array/basics/Array2.html       |   57 +-
 src/lessons/welcome/array/basics/Array2.java       |   10 +-
 src/lessons/welcome/array/basics/Array2Entity.java |   13 +-
 src/lessons/welcome/array/basics/Array2Entity.py   |    4 +-
 .../welcome/array/basics/Array2Entity.scala        |   59 +
 src/lessons/welcome/array/basics/ArrayEntity.java  |   57 -
 src/lessons/welcome/array/basics/ArrayEntity.py    |   37 -
 src/lessons/welcome/array/has271/Has271.fr.html    |    2 +-
 src/lessons/welcome/array/has271/Has271.html       |    2 +-
 src/lessons/welcome/array/has271/Has271.java       |   23 +-
 .../array/indexof/maxvalue/IndexOfMaxValue.java    |   26 +-
 .../welcome/array/indexof/value/IndexOfValue.java  |   22 +-
 src/lessons/welcome/array/maxvalue/MaxValue.java   |   23 +-
 .../welcome/array/notriples/NoTriples.fr.html      |    2 +-
 src/lessons/welcome/array/notriples/NoTriples.html |    2 +-
 src/lessons/welcome/array/notriples/NoTriples.java |   23 +-
 .../array/occurenceofvalue/OccurrenceOfValue.java  |   23 +-
 .../welcome/baggleseeker/BaggleSeeker.fr.html      |   13 -
 src/lessons/welcome/baggleseeker/BaggleSeeker.html |   11 -
 src/lessons/welcome/baggleseeker/BaggleSeeker.java |   29 -
 .../welcome/baggleseeker/BaggleSeekerEntity.java   |   27 -
 src/lessons/welcome/basics/Basics.fr.html          |   93 -
 src/lessons/welcome/basics/Basics.html             |   80 -
 src/lessons/welcome/basics/Basics.java             |   22 -
 src/lessons/welcome/basics/BasicsEntity.java       |   25 -
 src/lessons/welcome/basics/BasicsEntity.js         |   19 -
 src/lessons/welcome/basics/BasicsEntity.py         |   16 -
 .../welcome/basicsdrawg/BasicsDrawG.fr.html        |   66 -
 src/lessons/welcome/basicsdrawg/BasicsDrawG.html   |   53 -
 src/lessons/welcome/basicsdrawg/BasicsDrawG.java   |   22 -
 .../welcome/basicsdrawg/BasicsDrawGEntity.java     |   42 -
 .../welcome/basicsdrawg/BasicsDrawGEntity.py       |   22 -
 src/lessons/welcome/bat/bool1/Close10.fr.html      |   11 +
 src/lessons/welcome/bat/bool1/Close10.html         |    7 +
 src/lessons/welcome/bat/bool1/Close10.java         |   62 +
 src/lessons/welcome/bat/bool1/CountTeen.fr.html    |    4 +
 src/lessons/welcome/{ => bat}/bool1/CountTeen.html |    0
 src/lessons/welcome/bat/bool1/CountTeen.java       |   79 +
 src/lessons/welcome/bat/bool1/Diff21.fr.html       |    6 +
 src/lessons/welcome/bat/bool1/Diff21.html          |    5 +
 src/lessons/welcome/bat/bool1/Diff21.java          |   57 +
 src/lessons/welcome/bat/bool1/HasTeen.fr.html      |    7 +
 src/lessons/welcome/bat/bool1/HasTeen.html         |    6 +
 src/lessons/welcome/bat/bool1/HasTeen.java         |   53 +
 src/lessons/welcome/bat/bool1/IcyHot.fr.html       |    6 +
 src/lessons/welcome/bat/bool1/IcyHot.html          |    5 +
 src/lessons/welcome/bat/bool1/IcyHot.java          |   47 +
 src/lessons/welcome/bat/bool1/In1020.fr.html       |    6 +
 src/lessons/welcome/bat/bool1/In1020.html          |    5 +
 src/lessons/welcome/bat/bool1/In1020.java          |   50 +
 src/lessons/welcome/bat/bool1/In3050.fr.html       |    7 +
 src/lessons/welcome/bat/bool1/In3050.html          |    5 +
 src/lessons/welcome/bat/bool1/In3050.java          |   53 +
 src/lessons/welcome/bat/bool1/LastDigit.fr.html    |    9 +
 src/lessons/welcome/bat/bool1/LastDigit.html       |    9 +
 src/lessons/welcome/bat/bool1/LastDigit.java       |   44 +
 src/lessons/welcome/bat/bool1/LoneTeen.fr.html     |    7 +
 src/lessons/welcome/bat/bool1/LoneTeen.html        |    6 +
 src/lessons/welcome/bat/bool1/LoneTeen.java        |   59 +
 src/lessons/welcome/bat/bool1/Main.fr.html         |   12 +
 src/lessons/welcome/bat/bool1/Main.html            |   11 +
 src/lessons/welcome/bat/bool1/Makes10.fr.html      |    6 +
 src/lessons/welcome/bat/bool1/Makes10.html         |    5 +
 src/lessons/welcome/bat/bool1/Makes10.java         |   49 +
 src/lessons/welcome/bat/bool1/Max1020.fr.html      |   10 +
 src/lessons/welcome/bat/bool1/Max1020.html         |    7 +
 src/lessons/welcome/bat/bool1/Max1020.java         |   65 +
 .../welcome/bat/bool1/MonkeyTrouble.fr.html        |    9 +
 src/lessons/welcome/bat/bool1/MonkeyTrouble.html   |    7 +
 src/lessons/welcome/bat/bool1/MonkeyTrouble.java   |   52 +
 src/lessons/welcome/bat/bool1/NearHundred.fr.html  |   11 +
 src/lessons/welcome/bat/bool1/NearHundred.html     |    7 +
 src/lessons/welcome/bat/bool1/NearHundred.java     |   51 +
 src/lessons/welcome/bat/bool1/ParotTrouble.fr.html |    8 +
 src/lessons/welcome/bat/bool1/ParotTrouble.html    |    8 +
 src/lessons/welcome/bat/bool1/ParotTrouble.java    |   49 +
 src/lessons/welcome/bat/bool1/PosNeg.fr.html       |    7 +
 src/lessons/welcome/bat/bool1/PosNeg.html          |    5 +
 src/lessons/welcome/bat/bool1/PosNeg.java          |   60 +
 src/lessons/welcome/bat/bool1/SleepIn.fr.html      |    9 +
 src/lessons/welcome/bat/bool1/SleepIn.html         |    7 +
 src/lessons/welcome/bat/bool1/SleepIn.java         |   43 +
 src/lessons/welcome/bat/bool1/SumDouble.fr.html    |    6 +
 src/lessons/welcome/bat/bool1/SumDouble.html       |    5 +
 src/lessons/welcome/bat/bool1/SumDouble.java       |   55 +
 src/lessons/welcome/bat/bool2/AlarmClock.fr.html   |   13 +
 src/lessons/welcome/bat/bool2/AlarmClock.html      |   11 +
 src/lessons/welcome/bat/bool2/AlarmClock.java      |   79 +
 src/lessons/welcome/bat/bool2/AnswerCell.fr.html   |    8 +
 src/lessons/welcome/bat/bool2/AnswerCell.html      |    8 +
 src/lessons/welcome/bat/bool2/AnswerCell.java      |   44 +
 src/lessons/welcome/bat/bool2/BlueTicket.fr.html   |   11 +
 src/lessons/welcome/bat/bool2/BlueTicket.html      |   10 +
 src/lessons/welcome/bat/bool2/BlueTicket.java      |   75 +
 .../welcome/bat/bool2/CaughtSpeeding.fr.html       |   12 +
 src/lessons/welcome/bat/bool2/CaughtSpeeding.html  |   11 +
 src/lessons/welcome/bat/bool2/CaughtSpeeding.java  |   65 +
 src/lessons/welcome/bat/bool2/CigarParty.fr.html   |    9 +
 src/lessons/welcome/bat/bool2/CigarParty.html      |    9 +
 src/lessons/welcome/bat/bool2/CigarParty.java      |   49 +
 src/lessons/welcome/bat/bool2/DateFashion.fr.html  |   13 +
 src/lessons/welcome/bat/bool2/DateFashion.html     |   12 +
 src/lessons/welcome/bat/bool2/DateFashion.java     |   65 +
 src/lessons/welcome/bat/bool2/GreenTicket.fr.html  |    9 +
 src/lessons/welcome/bat/bool2/GreenTicket.html     |    9 +
 src/lessons/welcome/bat/bool2/GreenTicket.java     |   65 +
 src/lessons/welcome/bat/bool2/In1To10.fr.html      |    8 +
 src/lessons/welcome/bat/bool2/In1To10.html         |    8 +
 src/lessons/welcome/bat/bool2/In1To10.java         |   50 +
 src/lessons/welcome/bat/bool2/InOrder.fr.html      |    8 +
 src/lessons/welcome/bat/bool2/InOrder.html         |    8 +
 src/lessons/welcome/bat/bool2/InOrder.java         |   50 +
 src/lessons/welcome/bat/bool2/InOrderEqual.fr.html |    9 +
 src/lessons/welcome/bat/bool2/InOrderEqual.html    |    9 +
 src/lessons/welcome/bat/bool2/InOrderEqual.java    |   52 +
 src/lessons/welcome/bat/bool2/LastDigit2.fr.html   |    8 +
 src/lessons/welcome/bat/bool2/LastDigit2.html      |    8 +
 src/lessons/welcome/bat/bool2/LastDigit2.java      |   60 +
 src/lessons/welcome/bat/bool2/LessBy10.fr.html     |    7 +
 src/lessons/welcome/bat/bool2/LessBy10.html        |    5 +
 src/lessons/welcome/bat/bool2/LessBy10.java        |   52 +
 src/lessons/welcome/bat/bool2/Main.fr.html         |    5 +
 src/lessons/welcome/bat/bool2/Main.html            |    4 +
 src/lessons/welcome/bat/bool2/MaxMod5.fr.html      |   10 +
 src/lessons/welcome/bat/bool2/MaxMod5.html         |    9 +
 src/lessons/welcome/bat/bool2/MaxMod5.java         |   83 +
 src/lessons/welcome/bat/bool2/NearTen.fr.html      |    8 +
 src/lessons/welcome/bat/bool2/NearTen.html         |    8 +
 src/lessons/welcome/bat/bool2/NearTen.java         |   52 +
 src/lessons/welcome/bat/bool2/RedTicket.fr.html    |   10 +
 src/lessons/welcome/bat/bool2/RedTicket.html       |    9 +
 src/lessons/welcome/bat/bool2/RedTicket.java       |   70 +
 src/lessons/welcome/bat/bool2/ShareDigit.fr.html   |    9 +
 src/lessons/welcome/bat/bool2/ShareDigit.html      |    9 +
 src/lessons/welcome/bat/bool2/ShareDigit.java      |   48 +
 src/lessons/welcome/bat/bool2/SortaSum.fr.html     |    7 +
 src/lessons/welcome/bat/bool2/SortaSum.html        |    7 +
 src/lessons/welcome/bat/bool2/SortaSum.java        |   59 +
 src/lessons/welcome/bat/bool2/SquirrelPlay.fr.html |   10 +
 src/lessons/welcome/bat/bool2/SquirrelPlay.html    |   10 +
 src/lessons/welcome/bat/bool2/SquirrelPlay.java    |   51 +
 src/lessons/welcome/bat/bool2/TeaParty.fr.html     |   12 +
 src/lessons/welcome/bat/bool2/TeaParty.html        |   11 +
 src/lessons/welcome/bat/bool2/TeaParty.java        |   66 +
 src/lessons/welcome/bat/bool2/TeenSum.fr.html      |    8 +
 src/lessons/welcome/bat/bool2/TeenSum.html         |    8 +
 src/lessons/welcome/bat/bool2/TeenSum.java         |   63 +
 src/lessons/welcome/bat/bool2/TwoAsOne.fr.html     |    7 +
 src/lessons/welcome/bat/bool2/TwoAsOne.html        |    5 +
 src/lessons/welcome/bat/bool2/TwoAsOne.java        |   50 +
 .../welcome/bat/bool2/WithoutDoubles.fr.html       |    8 +
 src/lessons/welcome/bat/bool2/WithoutDoubles.html  |    8 +
 src/lessons/welcome/bat/bool2/WithoutDoubles.java  |   68 +
 src/lessons/welcome/bdr/BDR.fr.html                |  255 +-
 src/lessons/welcome/bdr/BDR.html                   |  434 +-
 src/lessons/welcome/bdr/BDR.java                   |   12 +-
 src/lessons/welcome/bdr/BDR2.fr.html               |  188 +-
 src/lessons/welcome/bdr/BDR2.html                  |  313 +-
 src/lessons/welcome/bdr/BDR2.java                  |   12 +-
 src/lessons/welcome/bdr/BDR2Entity.java            |   91 +-
 src/lessons/welcome/bdr/BDR2Entity.py              |    6 +-
 src/lessons/welcome/bdr/BDR2Entity.scala           |   37 +
 src/lessons/welcome/bdr/BDREntity.java             |   10 +-
 src/lessons/welcome/bdr/BDREntity.py               |   20 +-
 src/lessons/welcome/bdr/BDREntity.scala            |   34 +
 src/lessons/welcome/bool1/Close10.fr.html          |   11 -
 src/lessons/welcome/bool1/Close10.html             |   10 -
 src/lessons/welcome/bool1/Close10.java             |   54 -
 src/lessons/welcome/bool1/CountTeen.fr.html        |    3 -
 src/lessons/welcome/bool1/CountTeen.java           |   67 -
 src/lessons/welcome/bool1/Diff21.fr.html           |    6 -
 src/lessons/welcome/bool1/Diff21.html              |    5 -
 src/lessons/welcome/bool1/Diff21.java              |   51 -
 src/lessons/welcome/bool1/HasTeen.fr.html          |    7 -
 src/lessons/welcome/bool1/HasTeen.html             |    6 -
 src/lessons/welcome/bool1/HasTeen.java             |   49 -
 src/lessons/welcome/bool1/IcyHot.fr.html           |    6 -
 src/lessons/welcome/bool1/IcyHot.html              |    5 -
 src/lessons/welcome/bool1/IcyHot.java              |   44 -
 src/lessons/welcome/bool1/In1020.fr.html           |    6 -
 src/lessons/welcome/bool1/In1020.html              |    5 -
 src/lessons/welcome/bool1/In1020.java              |   47 -
 src/lessons/welcome/bool1/In3050.fr.html           |    7 -
 src/lessons/welcome/bool1/In3050.html              |    5 -
 src/lessons/welcome/bool1/In3050.java              |   50 -
 src/lessons/welcome/bool1/LastDigit.fr.html        |    9 -
 src/lessons/welcome/bool1/LastDigit.html           |    9 -
 src/lessons/welcome/bool1/LastDigit.java           |   41 -
 src/lessons/welcome/bool1/LoneTeen.fr.html         |    7 -
 src/lessons/welcome/bool1/LoneTeen.html            |    6 -
 src/lessons/welcome/bool1/LoneTeen.java            |   54 -
 src/lessons/welcome/bool1/Main.fr.html             |   12 -
 src/lessons/welcome/bool1/Main.html                |   11 -
 src/lessons/welcome/bool1/Makes10.fr.html          |    6 -
 src/lessons/welcome/bool1/Makes10.html             |    5 -
 src/lessons/welcome/bool1/Makes10.java             |   46 -
 src/lessons/welcome/bool1/Max1020.fr.html          |    9 -
 src/lessons/welcome/bool1/Max1020.html             |    8 -
 src/lessons/welcome/bool1/Max1020.java             |   56 -
 src/lessons/welcome/bool1/MonkeyTrouble.fr.html    |    9 -
 src/lessons/welcome/bool1/MonkeyTrouble.html       |    7 -
 src/lessons/welcome/bool1/MonkeyTrouble.java       |   48 -
 src/lessons/welcome/bool1/NearHundred.fr.html      |    6 -
 src/lessons/welcome/bool1/NearHundred.html         |    5 -
 src/lessons/welcome/bool1/NearHundred.java         |   48 -
 src/lessons/welcome/bool1/ParotTrouble.fr.html     |    8 -
 src/lessons/welcome/bool1/ParotTrouble.html        |    8 -
 src/lessons/welcome/bool1/ParotTrouble.java        |   46 -
 src/lessons/welcome/bool1/PosNeg.fr.html           |    7 -
 src/lessons/welcome/bool1/PosNeg.html              |    5 -
 src/lessons/welcome/bool1/PosNeg.java              |   55 -
 src/lessons/welcome/bool1/SleepIn.fr.html          |    9 -
 src/lessons/welcome/bool1/SleepIn.html             |    7 -
 src/lessons/welcome/bool1/SleepIn.java             |   45 -
 src/lessons/welcome/bool1/SumDouble.fr.html        |    6 -
 src/lessons/welcome/bool1/SumDouble.html           |    5 -
 src/lessons/welcome/bool1/SumDouble.java           |   47 -
 src/lessons/welcome/bool2/AlarmClock.fr.html       |   13 -
 src/lessons/welcome/bool2/AlarmClock.html          |   11 -
 src/lessons/welcome/bool2/AlarmClock.java          |   63 -
 src/lessons/welcome/bool2/AnswerCell.fr.html       |    8 -
 src/lessons/welcome/bool2/AnswerCell.html          |    8 -
 src/lessons/welcome/bool2/AnswerCell.java          |   41 -
 src/lessons/welcome/bool2/BlueTicket.fr.html       |   11 -
 src/lessons/welcome/bool2/BlueTicket.html          |   10 -
 src/lessons/welcome/bool2/BlueTicket.java          |   64 -
 src/lessons/welcome/bool2/CaughtSpeeding.fr.html   |   12 -
 src/lessons/welcome/bool2/CaughtSpeeding.html      |   11 -
 src/lessons/welcome/bool2/CaughtSpeeding.java      |   57 -
 src/lessons/welcome/bool2/CigarParty.fr.html       |    9 -
 src/lessons/welcome/bool2/CigarParty.html          |    9 -
 src/lessons/welcome/bool2/CigarParty.java          |   46 -
 src/lessons/welcome/bool2/DateFashion.fr.html      |   13 -
 src/lessons/welcome/bool2/DateFashion.html         |   12 -
 src/lessons/welcome/bool2/DateFashion.java         |   57 -
 src/lessons/welcome/bool2/GreenTicket.fr.html      |    9 -
 src/lessons/welcome/bool2/GreenTicket.html         |    9 -
 src/lessons/welcome/bool2/GreenTicket.java         |   57 -
 src/lessons/welcome/bool2/In1To10.fr.html          |    8 -
 src/lessons/welcome/bool2/In1To10.html             |    8 -
 src/lessons/welcome/bool2/In1To10.java             |   47 -
 src/lessons/welcome/bool2/InOrder.fr.html          |    8 -
 src/lessons/welcome/bool2/InOrder.html             |    8 -
 src/lessons/welcome/bool2/InOrder.java             |   47 -
 src/lessons/welcome/bool2/InOrderEqual.fr.html     |    9 -
 src/lessons/welcome/bool2/InOrderEqual.html        |    9 -
 src/lessons/welcome/bool2/InOrderEqual.java        |   49 -
 src/lessons/welcome/bool2/LastDigit2.fr.html       |    8 -
 src/lessons/welcome/bool2/LastDigit2.html          |    8 -
 src/lessons/welcome/bool2/LastDigit2.java          |   54 -
 src/lessons/welcome/bool2/LessBy10.fr.html         |    7 -
 src/lessons/welcome/bool2/LessBy10.html            |    5 -
 src/lessons/welcome/bool2/LessBy10.java            |   49 -
 src/lessons/welcome/bool2/Main.fr.html             |    5 -
 src/lessons/welcome/bool2/Main.html                |    4 -
 src/lessons/welcome/bool2/MaxMod5.fr.html          |   10 -
 src/lessons/welcome/bool2/MaxMod5.html             |    9 -
 src/lessons/welcome/bool2/MaxMod5.java             |   69 -
 src/lessons/welcome/bool2/NearTen.fr.html          |    8 -
 src/lessons/welcome/bool2/NearTen.html             |    8 -
 src/lessons/welcome/bool2/NearTen.java             |   49 -
 src/lessons/welcome/bool2/RedTicket.fr.html        |   10 -
 src/lessons/welcome/bool2/RedTicket.html           |    9 -
 src/lessons/welcome/bool2/RedTicket.java           |   60 -
 src/lessons/welcome/bool2/ShareDigit.fr.html       |    9 -
 src/lessons/welcome/bool2/ShareDigit.html          |    9 -
 src/lessons/welcome/bool2/ShareDigit.java          |   45 -
 src/lessons/welcome/bool2/SortaSum.fr.html         |    7 -
 src/lessons/welcome/bool2/SortaSum.html            |    7 -
 src/lessons/welcome/bool2/SortaSum.java            |   52 -
 src/lessons/welcome/bool2/SquirrelPlay.fr.html     |   10 -
 src/lessons/welcome/bool2/SquirrelPlay.html        |   10 -
 src/lessons/welcome/bool2/SquirrelPlay.java        |   48 -
 src/lessons/welcome/bool2/TeaParty.fr.html         |   12 -
 src/lessons/welcome/bool2/TeaParty.html            |   11 -
 src/lessons/welcome/bool2/TeaParty.java            |   58 -
 src/lessons/welcome/bool2/TeenSum.fr.html          |    8 -
 src/lessons/welcome/bool2/TeenSum.html             |    8 -
 src/lessons/welcome/bool2/TeenSum.java             |   57 -
 src/lessons/welcome/bool2/TwoAsOne.fr.html         |    7 -
 src/lessons/welcome/bool2/TwoAsOne.html            |    5 -
 src/lessons/welcome/bool2/TwoAsOne.java            |   47 -
 src/lessons/welcome/bool2/WithoutDoubles.fr.html   |    8 -
 src/lessons/welcome/bool2/WithoutDoubles.html      |    8 -
 src/lessons/welcome/bool2/WithoutDoubles.java      |   59 -
 src/lessons/welcome/conditions/Conditions.fr.html  |  235 +-
 src/lessons/welcome/conditions/Conditions.html     |  196 +-
 src/lessons/welcome/conditions/Conditions.java     |   10 +-
 .../welcome/conditions/ConditionsEntity.java       |    2 +-
 .../welcome/conditions/ConditionsEntity.scala      |   14 +
 .../welcome/environment/Environment.fr.html        |   38 +-
 src/lessons/welcome/environment/Environment.html   |   29 +-
 src/lessons/welcome/environment/Environment.java   |   10 +-
 .../welcome/environment/EnvironmentEntity.java     |    2 +-
 .../welcome/environment/EnvironmentEntity.scala    |   11 +
 .../Instructions-answer0.map}                      |    0
 .../welcome/instructions/Instructions.fr.html      |   83 +
 src/lessons/welcome/instructions/Instructions.html |   75 +
 src/lessons/welcome/instructions/Instructions.java |   22 +
 .../InstructionsDrawG-answer0.map}                 |    0
 .../welcome/instructions/InstructionsDrawG.fr.html |   49 +
 .../welcome/instructions/InstructionsDrawG.html    |   40 +
 .../welcome/instructions/InstructionsDrawG.java    |   22 +
 .../instructions/InstructionsDrawGEntity.java      |   42 +
 .../instructions/InstructionsDrawGEntity.py        |   22 +
 .../instructions/InstructionsDrawGEntity.scala     |   38 +
 .../welcome/instructions/InstructionsEntity.java   |   25 +
 .../welcome/instructions/InstructionsEntity.js     |   19 +
 .../welcome/instructions/InstructionsEntity.py     |   16 +
 .../welcome/instructions/InstructionsEntity.scala  |   24 +
 .../welcome/instructions/sub-exercise-folded.png   |  Bin 0 -> 3455 bytes
 .../welcome/instructions/sub-exercise-unfolded.png |  Bin 0 -> 5026 bytes
 .../welcome/loop/dowhileloop/LoopDoWhile.fr.html   |   45 -
 .../welcome/loop/dowhileloop/LoopDoWhile.html      |   41 -
 .../welcome/loop/dowhileloop/LoopDoWhile.java      |   31 -
 .../loop/dowhileloop/LoopDoWhileEntity.java        |   19 -
 .../welcome/loop/dowhileloop/LoopDoWhileEntity.py  |   11 -
 .../welcome/loop/dowhileloop/Poucet.fr.html        |   54 -
 src/lessons/welcome/loop/dowhileloop/Poucet.html   |   40 -
 src/lessons/welcome/loop/dowhileloop/Poucet.java   |   27 -
 .../welcome/loop/dowhileloop/PoucetEntity.java     |   45 -
 .../welcome/loop/dowhileloop/PoucetEntity.py       |   34 -
 src/lessons/welcome/loop/forloop/LoopCourse.html   |   10 -
 src/lessons/welcome/loop/forloop/LoopCourse.java   |   27 -
 .../welcome/loop/forloop/LoopCourseEntity.java     |   50 -
 .../welcome/loop/forloop/LoopCourseEntity.py       |   30 -
 .../welcome/loop/forloop/LoopCourseForest.java     |   27 -
 .../loop/forloop/LoopCourseForestEntity.java       |   72 -
 .../welcome/loop/forloop/LoopCourseForestEntity.py |   48 -
 src/lessons/welcome/loop/forloop/LoopFor.fr.html   |   82 -
 src/lessons/welcome/loop/forloop/LoopFor.html      |   78 -
 src/lessons/welcome/loop/forloop/LoopFor.java      |   31 -
 .../welcome/loop/forloop/LoopForEntity.java        |   32 -
 src/lessons/welcome/loop/forloop/LoopStairs.html   |   13 -
 src/lessons/welcome/loop/forloop/LoopStairs.java   |   25 -
 .../welcome/loop/forloop/LoopStairsEntity.java     |   57 -
 .../welcome/loop/forloop/LoopStairsEntity.py       |   44 -
 .../welcome/loop/whileloop/LoopWhile.fr.html       |   37 -
 src/lessons/welcome/loop/whileloop/LoopWhile.html  |   33 -
 src/lessons/welcome/loop/whileloop/LoopWhile.java  |   28 -
 .../welcome/loop/whileloop/LoopWhileEntity.java    |   25 -
 .../welcome/loop/whileloop/WhileMoria.fr.html      |   20 -
 src/lessons/welcome/loop/whileloop/WhileMoria.html |   17 -
 src/lessons/welcome/loop/whileloop/WhileMoria.java |   26 -
 .../welcome/loop/whileloop/WhileMoriaEntity.java   |   42 -
 .../welcome/loop/whileloop/WhileMoriaEntity.py     |   19 -
 .../LoopDoWhile-answer0.map                        |    0
 .../welcome/loopdowhile/LoopDoWhile.fr.html        |   59 +
 src/lessons/welcome/loopdowhile/LoopDoWhile.html   |   53 +
 src/lessons/welcome/loopdowhile/LoopDoWhile.java   |   31 +
 .../welcome/loopdowhile/LoopDoWhileEntity.java     |   22 +
 .../welcome/loopdowhile/LoopDoWhileEntity.py       |   14 +
 .../welcome/loopdowhile/LoopDoWhileEntity.scala    |   21 +
 .../dowhileloop => loopdowhile}/Poucet-answer0.map |    0
 .../dowhileloop => loopdowhile}/Poucet-answer1.map |    0
 src/lessons/welcome/loopdowhile/Poucet.fr.html     |   57 +
 src/lessons/welcome/loopdowhile/Poucet.html        |   41 +
 src/lessons/welcome/loopdowhile/Poucet.java        |   27 +
 .../{loop/dowhileloop => loopdowhile}/Poucet.map   |    0
 .../{loop/dowhileloop => loopdowhile}/Poucet2.map  |    0
 src/lessons/welcome/loopdowhile/PoucetEntity.java  |   51 +
 src/lessons/welcome/loopdowhile/PoucetEntity.py    |   41 +
 src/lessons/welcome/loopdowhile/PoucetEntity.scala |   43 +
 .../forloop => loopfor}/LoopCourse-answer0.map     |    0
 .../{loop/forloop => loopfor}/LoopCourse.fr.html   |    0
 src/lessons/welcome/loopfor/LoopCourse.html        |   10 +
 src/lessons/welcome/loopfor/LoopCourse.java        |   27 +
 .../{loop/forloop => loopfor}/LoopCourse.map       |    0
 src/lessons/welcome/loopfor/LoopCourseEntity.java  |   50 +
 src/lessons/welcome/loopfor/LoopCourseEntity.py    |   30 +
 src/lessons/welcome/loopfor/LoopCourseEntity.scala |   45 +
 .../LoopCourseForest-answer0.map                   |    0
 .../forloop => loopfor}/LoopCourseForest.fr.html   |    0
 .../forloop => loopfor}/LoopCourseForest.html      |    0
 src/lessons/welcome/loopfor/LoopCourseForest.java  |   27 +
 .../{loop/forloop => loopfor}/LoopCourseForest.map |    0
 .../welcome/loopfor/LoopCourseForestEntity.java    |   74 +
 .../welcome/loopfor/LoopCourseForestEntity.py      |   48 +
 .../welcome/loopfor/LoopCourseForestEntity.scala   |   64 +
 .../{loop/forloop => loopfor}/LoopFor-answer0.map  |    0
 src/lessons/welcome/loopfor/LoopFor.fr.html        |   80 +
 src/lessons/welcome/loopfor/LoopFor.html           |   77 +
 src/lessons/welcome/loopfor/LoopFor.java           |   31 +
 src/lessons/welcome/loopfor/LoopForEntity.java     |   34 +
 .../{loop/forloop => loopfor}/LoopForEntity.py     |    0
 src/lessons/welcome/loopfor/LoopForEntity.scala    |   28 +
 .../forloop => loopfor}/LoopStairs-answer0.map     |    0
 .../{loop/forloop => loopfor}/LoopStairs.fr.html   |    0
 src/lessons/welcome/loopfor/LoopStairs.html        |   13 +
 src/lessons/welcome/loopfor/LoopStairs.java        |   25 +
 .../{loop/forloop => loopfor}/LoopStairs.map       |    0
 src/lessons/welcome/loopfor/LoopStairsEntity.java  |   59 +
 src/lessons/welcome/loopfor/LoopStairsEntity.py    |   44 +
 src/lessons/welcome/loopfor/LoopStairsEntity.scala |   53 +
 .../BaggleSeeker-answer0.map                       |    0
 src/lessons/welcome/loopwhile/BaggleSeeker.fr.html |   13 +
 src/lessons/welcome/loopwhile/BaggleSeeker.html    |   11 +
 src/lessons/welcome/loopwhile/BaggleSeeker.java    |   29 +
 .../welcome/loopwhile/BaggleSeekerEntity.java      |   28 +
 .../BaggleSeekerEntity.py                          |    0
 .../welcome/loopwhile/BaggleSeekerEntity.scala     |   22 +
 .../whileloop => loopwhile}/LoopWhile-answer0.map  |    0
 src/lessons/welcome/loopwhile/LoopWhile.fr.html    |   42 +
 src/lessons/welcome/loopwhile/LoopWhile.html       |   38 +
 src/lessons/welcome/loopwhile/LoopWhile.java       |   28 +
 src/lessons/welcome/loopwhile/LoopWhileEntity.java |   24 +
 .../whileloop => loopwhile}/LoopWhileEntity.py     |    0
 .../welcome/loopwhile/LoopWhileEntity.scala        |   21 +
 .../whileloop => loopwhile}/WhileMoria-answer0.map |    0
 src/lessons/welcome/loopwhile/WhileMoria.fr.html   |   23 +
 src/lessons/welcome/loopwhile/WhileMoria.html      |   19 +
 src/lessons/welcome/loopwhile/WhileMoria.java      |   26 +
 .../{loop/whileloop => loopwhile}/WhileMoria.map   |    0
 .../welcome/loopwhile/WhileMoriaEntity.java        |   43 +
 src/lessons/welcome/loopwhile/WhileMoriaEntity.py  |   19 +
 .../welcome/loopwhile/WhileMoriaEntity.scala       |   37 +
 .../welcome/methods/args/MethodsArgs.fr.html       |  152 +-
 src/lessons/welcome/methods/args/MethodsArgs.html  |  177 +-
 src/lessons/welcome/methods/args/MethodsArgs.java  |   10 +-
 .../welcome/methods/args/MethodsArgsEntity.java    |   10 +-
 .../welcome/methods/args/MethodsArgsEntity.scala   |   33 +
 src/lessons/welcome/methods/basics/Methods.fr.html |  215 +-
 src/lessons/welcome/methods/basics/Methods.html    |  226 +-
 src/lessons/welcome/methods/basics/Methods.java    |   12 +-
 .../MethodsDogHouse-answer0.map                    |    0
 .../welcome/methods/basics/MethodsDogHouse.fr.html |   49 +
 .../welcome/methods/basics/MethodsDogHouse.html    |   41 +
 .../welcome/methods/basics/MethodsDogHouse.java    |   20 +
 .../methods/basics/MethodsDogHouseEntity.java      |   79 +
 .../methods/basics/MethodsDogHouseEntity.py        |   48 +
 .../methods/basics/MethodsDogHouseEntity.scala     |   85 +
 .../welcome/methods/basics/MethodsEntity.java      |   10 +-
 .../welcome/methods/basics/MethodsEntity.py        |    4 +-
 .../welcome/methods/basics/MethodsEntity.scala     |   39 +
 .../methods/doghouse/MethodsDogHouse.fr.html       |   59 -
 .../welcome/methods/doghouse/MethodsDogHouse.html  |   55 -
 .../welcome/methods/doghouse/MethodsDogHouse.java  |   20 -
 .../methods/doghouse/MethodsDogHouseEntity.java    |   68 -
 .../methods/doghouse/MethodsDogHouseEntity.py      |   48 -
 .../methods/flowerpot/FlowerCase-answer0.map       |  287 +
 .../welcome/methods/flowerpot/FlowerCase.fr.html   |    7 +
 .../welcome/methods/flowerpot/FlowerCase.html      |    7 +
 .../welcome/methods/flowerpot/FlowerCase.java      |   25 +
 .../welcome/methods/flowerpot/FlowerCase.map       |  286 +
 .../methods/flowerpot/FlowerCaseEntity.java        |   74 +
 .../welcome/methods/flowerpot/FlowerCaseEntity.py  |   60 +
 .../methods/flowerpot/FlowerCaseEntity.scala       |   74 +
 .../methods/flowerpot/FlowerPot-answer0.map        |   84 +
 .../welcome/methods/flowerpot/FlowerPot.fr.html    |   25 +
 .../welcome/methods/flowerpot/FlowerPot.html       |   23 +
 .../welcome/methods/flowerpot/FlowerPot.java       |   25 +
 .../welcome/methods/flowerpot/FlowerPot.map        |   83 +
 .../welcome/methods/flowerpot/FlowerPotEntity.java |   51 +
 .../welcome/methods/flowerpot/FlowerPotEntity.py   |   38 +
 .../methods/flowerpot/FlowerPotEntity.scala        |   51 +
 .../methods/picture/MethodsPicture-answer0.map     |  100 +-
 .../welcome/methods/picture/MethodsPicture.fr.html |   56 +-
 .../welcome/methods/picture/MethodsPicture.html    |   80 +-
 .../welcome/methods/picture/MethodsPicture.java    |   17 +-
 .../methods/picture/MethodsPictureEntity.java      |   38 +-
 .../methods/picture/MethodsPictureEntity.py        |   29 +-
 .../methods/picture/MethodsPictureEntity.scala     |   61 +
 .../MethodsPictureLarge-answer0.map}               |    0
 .../methods/picture/MethodsPictureLarge.fr.html    |   12 +
 .../methods/picture/MethodsPictureLarge.html       |   11 +
 .../methods/picture/MethodsPictureLarge.java       |   21 +
 .../methods/picture/MethodsPictureLargeEntity.java |   62 +
 .../methods/picture/MethodsPictureLargeEntity.py   |   43 +
 .../picture/MethodsPictureLargeEntity.scala        |   62 +
 .../PatternPicture-answer0.map}                    |    0
 .../welcome/methods/picture/PatternPicture.fr.html |   10 +
 .../welcome/methods/picture/PatternPicture.html    |   10 +
 .../welcome/methods/picture/PatternPicture.java    |   26 +
 .../methods/picture/PatternPictureEntity.java      |   85 +
 .../methods/picture/PatternPictureEntity.py        |   63 +
 .../methods/picture/PatternPictureEntity.scala     |   85 +
 .../methods/picture/PictureMono-answer0.map        |   15 +
 .../welcome/methods/picture/PictureMono.fr.html    |   24 +
 .../welcome/methods/picture/PictureMono.html       |   21 +
 .../welcome/methods/picture/PictureMono.java       |   20 +
 .../methods/picture/PictureMono2-answer0.map       |  111 +
 .../welcome/methods/picture/PictureMono2.fr.html   |   18 +
 .../welcome/methods/picture/PictureMono2.html      |   16 +
 .../welcome/methods/picture/PictureMono2.java      |   21 +
 .../methods/picture/PictureMono2Entity.java        |   59 +
 .../welcome/methods/picture/PictureMono2Entity.py  |   38 +
 .../methods/picture/PictureMono2Entity.scala       |   58 +
 .../methods/picture/PictureMono3-answer0.map       |  975 ++
 .../welcome/methods/picture/PictureMono3.fr.html   |    8 +
 .../welcome/methods/picture/PictureMono3.html      |    8 +
 .../welcome/methods/picture/PictureMono3.java      |   21 +
 .../methods/picture/PictureMono3Entity.java        |   60 +
 .../welcome/methods/picture/PictureMono3Entity.py  |   38 +
 .../methods/picture/PictureMono3Entity.scala       |   60 +
 .../welcome/methods/picture/PictureMonoEntity.java |   39 +
 .../welcome/methods/picture/PictureMonoEntity.py   |   23 +
 .../methods/picture/PictureMonoEntity.scala        |   42 +
 .../methods/picture2/MethodsPicture2-answer0.map   |  111 -
 .../methods/picture2/MethodsPicture2.fr.html       |   27 -
 .../welcome/methods/picture2/MethodsPicture2.html  |   26 -
 .../welcome/methods/picture2/MethodsPicture2.java  |   21 -
 .../methods/picture2/MethodsPicture2Entity.java    |   63 -
 .../methods/picture2/MethodsPicture2Entity.py      |   43 -
 .../methods/picture3/MethodsPicture3.fr.html       |   12 -
 .../welcome/methods/picture3/MethodsPicture3.html  |   11 -
 .../welcome/methods/picture3/MethodsPicture3.java  |   21 -
 .../methods/picture3/MethodsPicture3Entity.java    |   65 -
 .../methods/picture3/MethodsPicture3Entity.py      |   43 -
 .../methods/picture4/MethodsPicture4.fr.html       |   11 -
 .../welcome/methods/picture4/MethodsPicture4.html  |   11 -
 .../welcome/methods/picture4/MethodsPicture4.java  |   26 -
 .../methods/picture4/MethodsPicture4Entity.java    |   88 -
 .../methods/picture4/MethodsPicture4Entity.py      |   63 -
 .../methods/returning/MethodsReturning.fr.html     |   93 +-
 .../methods/returning/MethodsReturning.html        |  150 +-
 .../methods/returning/MethodsReturning.java        |   12 +-
 .../methods/returning/MethodsReturningEntity.java  |   15 +-
 .../methods/returning/MethodsReturningEntity.py    |    4 +-
 .../methods/returning/MethodsReturningEntity.scala |   40 +
 .../{ => methods}/slug/SlugHunting-answer0.map     |    0
 .../{ => methods}/slug/SlugHunting-answer1.map     |    0
 .../welcome/methods/slug/SlugHunting.fr.html       |   24 +
 .../welcome/{ => methods}/slug/SlugHunting.html    |    0
 src/lessons/welcome/methods/slug/SlugHunting.java  |   71 +
 .../welcome/methods/slug/SlugHuntingEntity.java    |   45 +
 .../welcome/methods/slug/SlugHuntingEntity.py      |   30 +
 .../welcome/methods/slug/SlugHuntingEntity.scala   |   44 +
 .../{ => methods}/slug/SlugSnail-answer0.map       |    0
 .../{ => methods}/slug/SlugSnail-answer1.map       |    0
 .../welcome/{ => methods}/slug/SlugSnail.fr.html   |    0
 .../welcome/{ => methods}/slug/SlugSnail.html      |    0
 src/lessons/welcome/methods/slug/SlugSnail.java    |   74 +
 .../welcome/methods/slug/SlugSnailEntity.java      |   47 +
 .../welcome/methods/slug/SlugSnailEntity.py        |   31 +
 .../welcome/methods/slug/SlugSnailEntity.scala     |   45 +
 .../{ => methods}/slug/SlugTracking-answer0.map    |    0
 .../{ => methods}/slug/SlugTracking-answer1.map    |    0
 .../welcome/methods/slug/SlugTracking.fr.html      |   28 +
 src/lessons/welcome/methods/slug/SlugTracking.html |   20 +
 src/lessons/welcome/methods/slug/SlugTracking.java |   71 +
 .../welcome/methods/slug/SlugTrackingEntity.java   |   40 +
 .../welcome/methods/slug/SlugTrackingEntity.py     |   29 +
 .../welcome/methods/slug/SlugTrackingEntity.scala  |   39 +
 src/lessons/welcome/slug/SlugHunting.fr.html       |   24 -
 src/lessons/welcome/slug/SlugHunting.java          |   71 -
 src/lessons/welcome/slug/SlugHuntingEntity.java    |   45 -
 src/lessons/welcome/slug/SlugHuntingEntity.py      |   30 -
 src/lessons/welcome/slug/SlugSnail.java            |   74 -
 src/lessons/welcome/slug/SlugSnailEntity.java      |   47 -
 src/lessons/welcome/slug/SlugSnailEntity.py        |   31 -
 src/lessons/welcome/slug/SlugTracking.fr.html      |   31 -
 src/lessons/welcome/slug/SlugTracking.html         |   22 -
 src/lessons/welcome/slug/SlugTracking.java         |   71 -
 src/lessons/welcome/slug/SlugTrackingEntity.java   |   40 -
 src/lessons/welcome/slug/SlugTrackingEntity.py     |   29 -
 src/lessons/welcome/snake/Snake.fr.html            |   51 -
 src/lessons/welcome/snake/Snake.html               |   47 -
 src/lessons/welcome/snake/Snake.java               |   27 -
 src/lessons/welcome/snake/SnakeEntity.java         |   47 -
 src/lessons/welcome/snake/SnakeEntity.py           |   29 -
 .../welcome/{snake => traversal}/Snake-answer0.map |    0
 src/lessons/welcome/traversal/Snake.fr.html        |   44 +
 src/lessons/welcome/traversal/Snake.html           |   40 +
 src/lessons/welcome/traversal/Snake.java           |   27 +
 src/lessons/welcome/traversal/SnakeEntity.java     |   46 +
 src/lessons/welcome/traversal/SnakeEntity.py       |   29 +
 src/lessons/welcome/traversal/SnakeEntity.scala    |   46 +
 .../traversal/column/TraversalByColumn.fr.html     |   43 +-
 .../traversal/column/TraversalByColumn.html        |  100 +-
 .../traversal/column/TraversalByColumn.java        |   10 +-
 .../traversal/column/TraversalByColumnEntity.java  |   53 +-
 .../traversal/column/TraversalByColumnEntity.py    |   12 +-
 .../traversal/column/TraversalByColumnEntity.scala |   70 +
 .../traversal/diagonal/TraversalDiagonal.java      |   10 +-
 .../diagonal/TraversalDiagonalEntity.java          |   49 +-
 .../traversal/diagonal/TraversalDiagonalEntity.py  |   12 +-
 .../diagonal/TraversalDiagonalEntity.scala         |   75 +
 .../welcome/traversal/line/TraversalByLine.java    |   10 +-
 .../traversal/line/TraversalByLineEntity.java      |   49 +-
 .../traversal/line/TraversalByLineEntity.py        |   12 +-
 .../traversal/line/TraversalByLineEntity.scala     |   71 +
 .../welcome/traversal/zigzag/TraversalZigZag.java  |   10 +-
 .../traversal/zigzag/TraversalZigZagEntity.java    |   49 +-
 .../traversal/zigzag/TraversalZigZagEntity.py      |   12 +-
 .../traversal/zigzag/TraversalZigZagEntity.scala   |   75 +
 src/lessons/welcome/variables/RunFour.fr.html      |    6 +-
 src/lessons/welcome/variables/RunFour.java         |   10 +-
 src/lessons/welcome/variables/RunFourEntity.java   |    9 +-
 src/lessons/welcome/variables/RunFourEntity.scala  |   23 +
 src/lessons/welcome/variables/RunHalf.fr.html      |    6 +-
 src/lessons/welcome/variables/RunHalf.java         |   10 +-
 src/lessons/welcome/variables/RunHalfEntity.java   |   13 +-
 src/lessons/welcome/variables/RunHalfEntity.py     |    3 +
 src/lessons/welcome/variables/RunHalfEntity.scala  |   34 +
 src/lessons/welcome/variables/Variables.fr.html    |  207 +-
 src/lessons/welcome/variables/Variables.html       |  158 +-
 src/lessons/welcome/variables/Variables.java       |   12 +-
 src/lessons/welcome/variables/VariablesEntity.java |    8 +-
 .../welcome/variables/VariablesEntity.scala        |   30 +
 src/plm/core/CompilerJava.java                     |  657 ++
 src/plm/core/CompilerScala.java                    |  173 +
 src/plm/core/ExoTest.java                          |  168 +
 src/plm/core/GameListener.java                     |   22 +
 src/plm/core/GameStateListener.java                |    9 +
 src/plm/core/HumanLangChangesListener.java         |    9 +
 src/plm/core/PLMCompilerException.java             |   76 +
 src/plm/core/PLMException.java                     |   11 +
 src/plm/core/ProgLangChangesListener.java          |    9 +
 src/plm/core/PythonExceptionDecipher.java          |   84 +
 src/plm/core/StatusStateListener.java              |    8 +
 src/plm/core/model/Course.java                     |  281 +
 src/plm/core/model/CourseAppEngine.java            |   79 +
 src/plm/core/model/DemoRunner.java                 |   65 +
 src/plm/core/model/Game.java                       | 1080 ++
 src/plm/core/model/HelpAppEngine.java              |   77 +
 src/plm/core/model/HelpServer.java                 |   41 +
 src/plm/core/model/LessonLoadingException.java     |   13 +
 src/plm/core/model/LessonRunner.java               |  144 +
 src/plm/core/model/LogWriter.java                  |   18 +
 src/plm/core/model/Logger.java                     |  124 +
 src/plm/core/model/ProgrammingLanguage.java        |   47 +
 src/plm/core/model/ServerAnswer.java               |    8 +
 src/plm/core/model/ServerExerciseData.java         |   73 +
 src/plm/core/model/ServerUserData.java             |  142 +
 src/plm/core/model/UserAbortException.java         |   15 +
 .../model/lesson/AccessibleExercisesListener.java  |    5 +
 .../core/model/lesson/BrokenLessonException.java   |   11 +
 src/plm/core/model/lesson/ExecutionProgress.java   |   45 +
 src/plm/core/model/lesson/Exercise.java            |  360 +
 src/plm/core/model/lesson/ExerciseTemplated.java   |  462 +
 .../model/lesson/ExerciseTemplatingEntity.java     |  136 +
 src/plm/core/model/lesson/Lecture.java             |  138 +
 src/plm/core/model/lesson/Lesson.java              |  173 +
 .../core/model/lesson/NoSuchEntityException.java   |   11 +
 src/plm/core/model/lesson/package-info.java        |    7 +
 src/plm/core/model/package-info.java               |    6 +
 src/plm/core/model/session/FileSessionKit.java     |  209 +
 src/plm/core/model/session/ISessionKit.java        |   41 +
 .../core/model/session/ISourceFileListener.java    |    9 +
 src/plm/core/model/session/SessionDB.java          |  150 +
 src/plm/core/model/session/SourceFile.java         |  141 +
 .../core/model/session/SourceFileRevertable.java   |   48 +
 src/plm/core/model/session/ZipSessionKit.java      |  388 +
 src/plm/core/model/session/package-info.java       |    8 +
 src/plm/core/model/tracking/HeartBeatSpy.java      |   37 +
 src/plm/core/model/tracking/LocalFileSpy.java      |   65 +
 .../core/model/tracking/ProgressSpyListener.java   |   15 +
 src/plm/core/model/tracking/ServerSpy.java         |  119 +
 .../core/model/tracking/ServerSpyAppEngine.java    |   59 +
 src/plm/core/model/tracking/TwitterSpy.java        |   59 +
 src/plm/core/model/tracking/package-info.java      |    7 +
 src/plm/core/package-info.java                     |   18 +
 src/plm/core/ui/AboutLessonDialog.java             |   30 +
 src/plm/core/ui/AboutPLMDialog.java                |   88 +
 src/plm/core/ui/AboutWorldDialog.java              |   48 +
 src/plm/core/ui/AbstractAboutDialog.java           |   48 +
 src/plm/core/ui/ChooseCourseDialog.java            |  216 +
 src/plm/core/ui/ChooseLectureDialog.java           |   92 +
 src/plm/core/ui/ChooseLessonDialog.java            |  256 +
 src/plm/core/ui/CreateCourseDialog.java            |  166 +
 src/plm/core/ui/EntityCellRenderer.java            |   44 +
 src/plm/core/ui/EntityComboListAdapter.java        |   77 +
 src/plm/core/ui/ExerciseFailedDialog.java          |   64 +
 src/plm/core/ui/ExerciseView.java                  |  381 +
 src/plm/core/ui/FeedbackDialog.java                |  180 +
 src/plm/core/ui/IEditorPanel.java                  |    5 +
 src/plm/core/ui/JavaEditorPanel.java               |   87 +
 src/plm/core/ui/LoggerPanel.java                   |   99 +
 src/plm/core/ui/MainFrame.java                     |  723 ++
 src/plm/core/ui/MissionEditorTabs.java             |  182 +
 src/plm/core/ui/OSXAdapter.java                    |  246 +
 src/plm/core/ui/PlmHtmlEditorKit.java              |  393 +
 src/plm/core/ui/ProgrammersLearningMachine.java    |   26 +
 src/plm/core/ui/ResourcesCache.java                |  135 +
 src/plm/core/ui/ResultsPanel.java                  |   77 +
 .../core/ui/SourceFileDocumentSynchronizer.java    |  105 +
 src/plm/core/ui/StatusBar.java                     |  185 +
 src/plm/core/ui/StudentDetailsDialog.java          |   54 +
 src/plm/core/ui/TeacherConsoleDialog.java          |  145 +
 src/plm/core/ui/TipsDialog.java                    |   28 +
 src/plm/core/ui/WorldCellRenderer.java             |   46 +
 src/plm/core/ui/WorldComboListAdapter.java         |   82 +
 src/plm/core/ui/WorldView.java                     |   61 +
 src/plm/core/ui/action/AbstractGameAction.java     |   60 +
 src/plm/core/ui/action/CleanUpSession.java         |   23 +
 src/plm/core/ui/action/CreateCourse.java           |   34 +
 src/plm/core/ui/action/DeleteCourse.java           |   54 +
 src/plm/core/ui/action/ExportSession.java          |   43 +
 src/plm/core/ui/action/HelpMe.java                 |   41 +
 src/plm/core/ui/action/ImportSession.java          |   38 +
 src/plm/core/ui/action/OneStep.java                |   22 +
 src/plm/core/ui/action/PlayDemo.java               |   30 +
 src/plm/core/ui/action/QuitGame.java               |   31 +
 src/plm/core/ui/action/RefreshCourse.java          |   53 +
 src/plm/core/ui/action/Reset.java                  |   32 +
 src/plm/core/ui/action/RevertExercise.java         |   52 +
 src/plm/core/ui/action/SetLanguage.java            |   24 +
 src/plm/core/ui/action/SetProgLanguage.java        |   23 +
 src/plm/core/ui/action/StartExecution.java         |   35 +
 src/plm/core/ui/action/StepExecution.java          |   33 +
 src/plm/core/ui/action/StopExecution.java          |   30 +
 src/plm/core/ui/action/SwitchExo.java              |   32 +
 src/plm/core/ui/action/package-info.java           |    5 +
 src/plm/core/ui/editor/MissionEditor.java          |  355 +
 src/plm/core/ui/editor/MissionEditorApp.java       |   22 +
 src/plm/core/ui/package-info.java                  |    5 +
 src/plm/core/utils/ColorMapper.java                |   48 +
 src/plm/core/utils/FileUtils.java                  |  135 +
 src/plm/core/utils/InvalidColorNameException.java  |   11 +
 src/plm/core/utils/PlmSyntaxPane.java              |   90 +
 src/plm/universe/BrokenWorldFileException.java     |    9 +
 src/plm/universe/Direction.java                    |  112 +
 src/plm/universe/Entity.java                       |  270 +
 src/plm/universe/EntityControlPanel.java           |   22 +
 src/plm/universe/GridWorld.java                    |   94 +
 src/plm/universe/GridWorldCell.java                |   42 +
 src/plm/universe/IEntityStackListener.java         |    7 +
 src/plm/universe/IWorldView.java                   |   15 +
 src/plm/universe/World.java                        |  335 +
 src/plm/universe/bat/BatEntity.java                |  102 +
 src/plm/universe/bat/BatExercise.java              |   69 +
 src/plm/universe/bat/BatTest.java                  |  235 +
 src/{jlm => plm}/universe/bat/BatWorld.fr.html     |    0
 src/{jlm => plm}/universe/bat/BatWorld.html        |    0
 src/plm/universe/bat/BatWorld.java                 |   96 +
 src/plm/universe/bat/BatWorldView.java             |   70 +
 src/plm/universe/bat/package-info.java             |    4 +
 src/plm/universe/bugglequest/AbstractBuggle.java   |  482 +
 src/plm/universe/bugglequest/Baggle.java           |   69 +
 src/plm/universe/bugglequest/Buggle.java           |   33 +
 src/plm/universe/bugglequest/BuggleWorld.fr.html   |   78 +
 src/plm/universe/bugglequest/BuggleWorld.html      |   72 +
 src/plm/universe/bugglequest/BuggleWorld.java      |  555 +
 src/plm/universe/bugglequest/BuggleWorldCell.java  |  255 +
 src/plm/universe/bugglequest/SimpleBuggle.java     |  136 +
 .../exception/AlreadyHaveBaggleException.java      |   13 +
 .../exception/BuggleInOuterSpaceException.java     |   14 +
 .../bugglequest/exception/BuggleWallException.java |   15 +
 .../exception/NoBaggleUnderBuggleException.java    |   14 +
 .../bugglequest/mapeditor/EditionListener.java     |   23 +
 src/plm/universe/bugglequest/mapeditor/Editor.java |  125 +
 .../universe/bugglequest/mapeditor/MainFrame.java  |  262 +
 .../bugglequest/mapeditor/MapEditorApp.java        |   19 +
 .../universe/bugglequest/mapeditor/MapView.java    |  143 +
 .../bugglequest/mapeditor/PropertiesEditor.java    |  389 +
 .../bugglequest/mapeditor/package-info.java        |    5 +
 src/plm/universe/bugglequest/package-info.java     |    5 +
 .../universe/bugglequest/ui/BuggleButtonPanel.java |  240 +
 .../bugglequest/ui/BuggleColorCellRenderer.java    |   48 +
 .../universe/bugglequest/ui/BuggleWorldView.java   |  318 +
 src/{jlm => plm}/universe/bugglequest/ui/egg.png   |  Bin 8993 -> 8993 bytes
 src/plm/universe/bugglequest/ui/package-info.java  |    5 +
 .../universe/bugglequest/ui/rabbit.png             |  Bin 8917 -> 8917 bytes
 src/plm/universe/lightbot/LightBotEditorPanel.java |  137 +
 src/plm/universe/lightbot/LightBotEntity.java      |  220 +
 src/plm/universe/lightbot/LightBotExercise.java    |   82 +
 src/plm/universe/lightbot/LightBotInstruction.java |   98 +
 src/plm/universe/lightbot/LightBotSourceFile.java  |   78 +
 src/plm/universe/lightbot/LightBotWorld.fr.html    |   32 +
 src/plm/universe/lightbot/LightBotWorld.html       |   19 +
 src/plm/universe/lightbot/LightBotWorld.java       |  204 +
 src/plm/universe/lightbot/LightBotWorldCell.java   |  113 +
 src/plm/universe/lightbot/LightBotWorldView2D.java |  137 +
 .../lightbot/LightBotWorldViewIsometric.java       |  312 +
 src/plm/universe/lightbot/package-info.java        |    6 +
 src/plm/universe/package-info.java                 |    8 +
 src/plm/universe/sort/CopyVal.java                 |   25 +
 src/plm/universe/sort/GetVal.java                  |   28 +
 src/plm/universe/sort/Operation.java               |   57 +
 src/plm/universe/sort/SetVal.java                  |   30 +
 src/plm/universe/sort/SortingButtonPanel.java      |  104 +
 src/plm/universe/sort/SortingEntity.java           |   76 +
 src/plm/universe/sort/SortingWorld.fr.html         |   66 +
 src/plm/universe/sort/SortingWorld.html            |   57 +
 src/plm/universe/sort/SortingWorld.java            |  358 +
 src/plm/universe/sort/SortingWorldView.java        |  335 +
 src/plm/universe/sort/Swap.java                    |   30 +
 src/plm/universe/sort/package-info.java            |    6 +
 src/plm/universe/turtles/Circle.java               |   57 +
 src/plm/universe/turtles/Direction.java            |    7 +
 src/plm/universe/turtles/Line.java                 |   69 +
 src/plm/universe/turtles/Shape.java                |    9 +
 src/plm/universe/turtles/SizeHint.java             |   71 +
 src/plm/universe/turtles/Turtle.java               |  426 +
 src/plm/universe/turtles/TurtleButtonPanel.java    |   28 +
 src/plm/universe/turtles/TurtleWorld.fr.html       |   65 +
 src/plm/universe/turtles/TurtleWorld.html          |   63 +
 src/plm/universe/turtles/TurtleWorld.java          |  278 +
 src/plm/universe/turtles/TurtleWorldView.java      |   93 +
 src/plm/universe/turtles/package-info.java         |    6 +
 1383 files changed, 58754 insertions(+), 48115 deletions(-)

diff --git a/COPYING b/COPYING
index 5f76217..bc356e1 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Most of the JLM software was written internally by the team. This
+Most of the PLM software was written internally by the team. This
 software is distributed under the GNU general public license version
 3, which you can find in the archive under the name LICENSE-GPL-3.
 
@@ -12,7 +12,7 @@ their license.
 
 =========================================================================
 
-The pedagogical material distributed with JLM is also covered by the
+The pedagogical material distributed with PLM is also covered by the
 CC-BY-SA license, that you can find at:
 http://creativecommons.org/licenses/by-sa/3.0/
 
@@ -44,8 +44,8 @@ We borrowed the following icons, that are CC-BY-SA too:
 
 * The turtle was borowed from the kturtle project, from KDE edu.
 * The bunny and egg in BuggleQuest universe come from:
-  jlm/universe/bugglequest/ui/egg.png     http://openclipart.org/detail/93979/
-  jlm/universe/bugglequest/ui/rabbit.png  http://openclipart.org/detail/23052/
+  plm/universe/bugglequest/ui/egg.png     http://openclipart.org/detail/93979/
+  plm/universe/bugglequest/ui/rabbit.png  http://openclipart.org/detail/23052/
 * Buttons:
   img/btn-demo.png:       http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/games-solve.png
   img/btn-switch-exo.png: http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/code-class.png
diff --git a/ChangeLog b/ChangeLog
index ec66f43..bb73ebc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+20130830: Release 2.2. The funny times are over
+
+  * Rebrand JLM into PLM (Programmer's Learning Machine)
+  * Turtles: Allow for hints on segment sizes
+  * Turtle.circle(): New primitive to draw circles directly.
+  * New lesson turtleart on the classical Logo geometric figures
+  * Upgrade our twitter4j dependency to use the new twitter API 1.1
+    Twitter dropped support for the 1.0 API a while ago.
+  * Drop the identi.ca spy. It does not work since the upstream move
+    from status.net to pump.io, and I fail fixing it.
+  * Drop our prototypal jabber chat dialog. It was not activated
+    because it's not adapted: student only use it to try to cheat and
+    get easy answers. A forum would be better. Students are
+    authenticated, and the messages moderated (France IOI does that)
+  * Build a plm-light jarfile, without scala and python dependencies.
+    These langs remain usable if the deps are independently installed.
+  * Specify a sain font as default to help Mac users (fix #100)
+
+20130820:
+  * RELEASE 2.1, the 100th day.
+  * Introduce Scala as a new programing language (version 2.10+ required)
+  * Port all exercises to scala.
+  * Change turnLeft()/turnRight() to left()/right() in buggles & turtles
+  * Translate all builtins of buggles, turtles and sorts to French:
+    It is now possible to write avance() instead of forward()
+  * Review all translations for uniformity and to iron out some typos
+  * Test the compilation process in our JUnit tests, for Java and Scala.
+  * Mark many more strings for translation in the engine.
+  * Allow [!java]...[/!] constructs in mission texts to adapt to progLang
+  * In debug mode, all adaptations of all progLangs are displayed, with
+    a color code for each. This was mandatory with a third main progLang
+  * Partially document the black magic fueling ExerciseTemplatingEntity 
+    Erk, this class is based on ... inventive hacks ;)
+  * Property jlm.display.fontsize sets the size of the mission texts
+    (default: 10px; must be valid in a CSS)
+  * MissionEditorApp: little application to edit the mission texts with
+    realtime rendering after applying our pseudo-markdown directives
+  * lessons/welcome/methods/picture/PictureMono*: new exercises on drawing, 
+    but without the color so that it can come early in the learning
+    process, when we don't have methods parameters yet
+  * lessons/welcome/methods/flowerpot/*: two new exercises training on
+    methods (and decomposition)
+  * New lib/jsyntaxpane.jar, from debian package fixing some upstream bugs
+    - Contextual menu now works, as well as Ctrl-Z/Ctrl-Y, etc
 20130804:
   * RELEASE 2.0, the revolutionary night.
   * Remove the array world. It was not helping very much when compared
diff --git a/README.md b/README.md
index 5300814..7fef98d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-Java Learning Machine (JLM)
+Programmer's Learning Machine (PLM)
 =========
 
-The Java Learning Machine (JLM) is a platform dedicated to computer
+The Programmer's Learning Machine (PLM) is a platform dedicated to computer
 programming education. This generic platform offers support to teachers for
 creating programming microworlds suitable to teaching courses. It features an
 integrated and graphical environment, providing a short feedback loop to
@@ -9,11 +9,11 @@ students in order to improve the effectiveness of the autonomous learning
 process.
 
 
-For more information, [visit the JLM web site](http://www.loria.fr/~quinson/Teaching/JLM/).
+For more information, [visit the PLM web site](http://www.loria.fr/~quinson/Teaching/PLM/).
 
 ## License
 
-JLM is licensed under the GNU General Public License 3.
+PLM is licensed under the GNU General Public License 3.
 
 This program is free software: you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
diff --git a/TODO b/TODO
index 790d5e5..41d9a47 100644
--- a/TODO
+++ b/TODO
@@ -9,9 +9,6 @@ to github issues.
 
 * try to remove the *sys-package-mgr* processing messages when jython is loading
 
-* Allow exercises in Scala:
-http://speaking-my-language.blogspot.fr/2009/11/embedded-scala-interpreter.html
-
 ***************** ENGINE IMPROVEMENT
 
  * We could use the same shortcuts than eclipse
diff --git a/build.xml b/build.xml
index dd42273..ab77e3a 100644
--- a/build.xml
+++ b/build.xml
@@ -1,15 +1,30 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project default="dist" name="JLM">
+<project default="dist" name="PLM">
 	
-    <!-- load ChangeLog and set property jlm.version accordingly -->
-    <loadfile property="jlm.version" srcFile="ChangeLog">
+    <!-- load ChangeLog and set property plm.minor.version accordingly -->
+    <loadfile property="plm.minor.version" srcFile="ChangeLog">
         <filterchain>
             <linecontainsregexp>
-              <regexp pattern="[0-9]+:"/>
+              <regexp pattern="[0-9]+:.*"/>
             </linecontainsregexp>          
           <headfilter lines="1"/>
           <striplinebreaks/>
-          <striplinebreaks linebreaks=":"/>
+          <tokenfilter>
+	    <replaceregex pattern=":.*" replace=""/>
+	  </tokenfilter>
+        </filterchain>
+    </loadfile>
+    
+    <loadfile property="plm.major.version" srcFile="lib/resources/plm.configuration.properties">
+        <filterchain>
+            <linecontainsregexp>
+              <regexp pattern="plm.major.version=.*"/>
+            </linecontainsregexp>          
+          <headfilter lines="1"/>
+          <striplinebreaks/>
+          <tokenfilter>
+	    <replacestring from="plm.major.version=" to=""/>
+	  </tokenfilter>
         </filterchain>
     </loadfile>
     
@@ -43,78 +58,73 @@
     
     <target name="dist" depends="i18n-generate-jar, compile, updateversion" description="build a standalone application jar file">
         <mkdir dir="${dist.dir}"/>
-        <jar destfile="${dist.dir}/jlm-${jlm.version}.jar" filesetmanifest="mergewithoutmain">
+        <jar destfile="${dist.dir}/plm-${plm.major.version}-${plm.minor.version}.jar" filesetmanifest="mergewithoutmain">
             <manifest>
                 <attribute name="Built-By" value="M. Quinson and G. Oster" />
-                <attribute name="Main-Class" value="jlm.core.ui.JavaLearningMachine" />
+                <attribute name="Main-Class" value="plm.core.ui.ProgrammersLearningMachine" />
                 <attribute name="Class-Path" value="." />
             </manifest>
             <fileset dir="${classes.dir}" excludes="**/.gitignore **/*.java **/*.css **/*.html"/>
-            <fileset dir="${src.dir}" includes="**/*.py **/*.java **/*.html **/*.css **/*.png **/*.map" excludes="**/.gitignore"/>
-            <fileset dir="${lib.dir}" excludes="*.jar *.pl l10n/*"/>
-            <fileset dir="${lib.dir}" excludes="*.jar *.pl l10n-engine/*"/>
-            <!--<zipfileset excludes="META-INF/*.SF" src="${lib.dir}/twitter4j-2.1.0-SNAPSHOT.jar" /> -->
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/twitter4j-core-2.1.4-SNAPSHOT.jar" />    
+            <fileset dir="${src.dir}" includes="**/*.py **/*.scala **/*.java **/*.html **/*.css **/*.png **/*.map" excludes="**/.gitignore"/>
+            <fileset dir="${lib.dir}" excludes="**/*.jar *.pl lib/l10n/* lib/l10n-engine/*"/>
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/twitter4j-core-3.0.3.jar" />    
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jsyntaxpane-0.9.6~r156.jar" />
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/miglayout-3.7.4.jar" />
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/langtools-beta.jar" />
                         
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/scala/scala-compiler-2.10.2.jar"/>
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/scala/scala-library-2.10.2.jar"/>
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/scala/scala-reflect-2.10.2.jar"/>
+
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/antlr3-runtime.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/asm3-3.2.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jruby-1.5.6-5.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/jython-2.5.1.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/js-1.7R3.jar"/>
 
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/httpclient-4.1.2.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/httpcore-4.1.2.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/commons-logging-1.1.1.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/commons-codec-1.4.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/gettext-commons-0.9.6.jar"/>
             
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/smackx.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/smack.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/json_simple-1.1.jar" />
             
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jlm-messages.jar" />
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/plm-messages.jar" />
 
         </jar>
-    </target>
-    
-    <target name="dist-src" depends="compile, updateversion" description="build a standalone application jar file">
-        <mkdir dir="${dist.dir}"/>
-        <zip destfile="${dist.dir}/jlm-src-${jlm.version}.zip">
-            <fileset dir="${src.dir}" includes="**/*.java **/*.html **/*.css **/*.png **/*.map" excludes="**/.gitignore"/> 
-            <fileset dir="${lib.dir}" excludes="*.jar *.pl"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/twitter4j-core-2.1.4-SNAPSHOT.jar" />    
+
+        <jar destfile="${dist.dir}/plm-light-${plm.major.version}-${plm.minor.version}.jar" filesetmanifest="mergewithoutmain">
+            <manifest>
+                <attribute name="Built-By" value="M. Quinson and G. Oster" />
+                <attribute name="Main-Class" value="plm.core.ui.ProgrammersLearningMachine" />
+                <attribute name="Class-Path" value="." />
+            </manifest>
+            <fileset dir="${classes.dir}" excludes="**/.gitignore **/*.java **/*.css **/*.html"/>
+            <fileset dir="${src.dir}" includes="**/*.py **/*.scala **/*.java **/*.html **/*.css **/*.png **/*.map" excludes="**/.gitignore"/>
+            <fileset dir="${lib.dir}" excludes="**/*.jar *.pl lib/l10n/* lib/l10n-engine/*"/>
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/twitter4j-core-3.0.3.jar" />    
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jsyntaxpane-0.9.6~r156.jar" />
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/miglayout-3.7.4.jar" />
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/langtools-beta.jar" />
-            
-	    
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/antlr3-runtime.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/asm3-3.2.jar"/>
-             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jruby-1.5.6-5.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/jython-2.5.1.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/jython/js-1.7R3.jar"/>
-            
+                        
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/httpclient-4.1.2.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/httpcore-4.1.2.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/commons-logging-1.1.1.jar"/>
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/commons-codec-1.4.jar"/>
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/gettext-commons-0.9.6.jar"/>
             
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/smackx.jar"/>        
-            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/smack.jar"/>
             <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/json_simple-1.1.jar" />
+            
+            <zipfileset excludes="META-INF/*.SF" src="${lib.dir}/plm-messages.jar" />
 
-        </zip>
-    </target>
+        </jar>
 
+    </target>
+    
     <target name="dist-web" depends="compile, updateversion" description="build webstart application jar files">
         <mkdir dir="${site.dir}/lib"/>
-        <jar destfile="${site.dir}/lib/jlm-webstart.jar" filesetmanifest="mergewithoutmain">
+        <jar destfile="${site.dir}/lib/plm-webstart.jar" filesetmanifest="mergewithoutmain">
             <manifest>
                 <attribute name="Built-By" value="M. Quinson and G. Oster" />
-                <attribute name="Main-Class" value="jlm.ui.JavaLearningMachine" />
+                <attribute name="Main-Class" value="plm.ui.ProgrammersLearningMachine" />
                 <attribute name="Class-Path" value="." />
             </manifest>
             <fileset dir="${classes.dir}" excludes="**/.gitignore **/*.java **/*.css **/*.html"/>
@@ -137,14 +147,14 @@
         <mkdir dir="${site.dir}/javadoc/"/>
         <javadoc 
             destdir="${site.dir}/javadoc/">
-            <fileset dir="${src.dir}/jlm" includes="**/*.java" />
+            <fileset dir="${src.dir}/plm" includes="**/*.java" />
             <fileset dir="${src.dir}/universe" includes="**/*.java" />
         </javadoc>
     </target>
 
     <target name="updateversion" description="Update the version number in the properties file">
-      <propertyfile file="${lib.dir}/resources/jlm.configuration.properties">
-        <entry key="jlm.minor.version" value="${jlm.version}" operation="="/>
+      <propertyfile file="${lib.dir}/resources/plm.configuration.properties">
+        <entry key="plm.minor.version" value="${plm.minor.version}" operation="="/>
       </propertyfile>
     </target>
 
@@ -156,12 +166,12 @@
       <taskdef name="gettext-dist"    classname="org.xnap.commons.ant.gettext.GettextDistTask"        classpath="${gettexttasks.jar}"/>
     </target>
     <target name="i18n-extract" description="Extracts message keys from the source code" depends="i18n-init">
-      <gettext-extract keysFile="jlm.pot" poDirectory="lib/l10n-engine">
+      <gettext-extract keysFile="plm.pot" poDirectory="lib/l10n-engine">
         <fileset dir="${src.dir}" includes="**/*.java"/>
       </gettext-extract>
     </target>
     <target name="i18n-update" description="Merges newly extracted messages into existing po files" depends="i18n-extract">
-      <gettext-merge keysFile="jlm.pot" poDirectory="lib/l10n-engine"/>
+      <gettext-merge keysFile="plm.pot" poDirectory="lib/l10n-engine"/>
     </target>
     <target name="i18n-check" description="Checks that the extracted messages are correct" depends="i18n-update">
       <!-- single quote sign is used to escape the format strings in MessageFormat;
@@ -189,8 +199,8 @@
     
     <target name="i18n-generate-jar" description="Generates Java ResourceBundles and jars them up" depends="i18n-update, i18n-check">
       <mkdir dir="${site.dir}/po"/>
-      <gettext-dist targetBundle="org.jlm.i18n.Messages" poDirectory="lib/l10n-engine" outputDirectory="${site.dir}/po" />
-      <jar destfile="lib/jlm-messages.jar" basedir="${site.dir}/po" includes="org/**"/>
+      <gettext-dist targetBundle="org.plm.i18n.Messages" poDirectory="lib/l10n-engine" outputDirectory="${site.dir}/po" />
+      <jar destfile="lib/plm-messages.jar" basedir="${site.dir}/po" includes="org/**"/>
       <delete dir="${site.dir}/po"/>
     </target>
     
@@ -212,10 +222,10 @@
         <bundleapp outputdirectory="dist"
             name="${mac.app.name}"
             displayname="Java Learning Machine"
-            identifier="jlm.core.ui.JavaLearningMachine"
-            mainclassname="jlm.core.ui.JavaLearningMachine"
-			icon="${mac.dir}/JLM.icns">
-            <classpath file="dist/jlm-${jlm.version}.jar" />
+            identifier="plm.core.ui.JavaLearningMachine"
+            mainclassname="plm.core.ui.JavaLearningMachine"
+			icon="${mac.dir}/PLM.icns">
+            <classpath file="dist/plm-${plm.minor.version}.jar" />
         </bundleapp>
 		<copy todir="${mac.bundle.dir}/Contents/Resources/fr.lproj">
 			<fileset dir="${fr.lproj.dir}"/>
diff --git a/img/focus_check.svg b/img/focus_check.svg
index 5658e9c..2d83f32 100644
--- a/img/focus_check.svg
+++ b/img/focus_check.svg
@@ -16,7 +16,7 @@
    inkscape:version="0.47 r22583"
    version="1.0"
    sodipodi:docname="sign_check.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/lib/resources/pedago_focus/sign_check.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/lib/resources/pedago_focus/sign_check.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <defs
diff --git a/img/focus_intro.svg b/img/focus_intro.svg
index 73f1735..82dfec6 100644
--- a/img/focus_intro.svg
+++ b/img/focus_intro.svg
@@ -18,7 +18,7 @@
    version="1.0"
    sodipodi:docname="sign_intro.svg"
    inkscape:output_extension="org.inkscape.output.svg.inkscape"
-   inkscape:export-filename="/home/mquinson/Code/JLM/lib/resources/pedago_focus/sign_intro.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/lib/resources/pedago_focus/sign_intro.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <defs
diff --git a/img/focus_not.svg b/img/focus_not.svg
index a501b1d..d0a1dcc 100644
--- a/img/focus_not.svg
+++ b/img/focus_not.svg
@@ -16,7 +16,7 @@
    version="1.1"
    inkscape:version="0.47 r22583"
    sodipodi:docname="sign_not.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/lib/resources/pedago_focus/sign_not.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/lib/resources/pedago_focus/sign_not.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <defs
diff --git a/img/focus_working.svg b/img/focus_working.svg
index 856e255..e075e2b 100644
--- a/img/focus_working.svg
+++ b/img/focus_working.svg
@@ -17,7 +17,7 @@
    height="580"
    version="1.0"
    sodipodi:docname="sign_working.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/lib/resources/pedago_focus/sign_working.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/lib/resources/pedago_focus/sign_working.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/img/lang_scala.png b/img/lang_scala.png
new file mode 100644
index 0000000..ef8edee
Binary files /dev/null and b/img/lang_scala.png differ
diff --git a/lib/doc/MainWindow.fr.html b/lib/doc/MainWindow.fr.html
index d0e0d78..3d4ad63 100644
--- a/lib/doc/MainWindow.fr.html
+++ b/lib/doc/MainWindow.fr.html
@@ -1,6 +1,6 @@
-<h2>La fenêtre principale de JLM</h2>
+<h2>La fenêtre principale de PLM</h2>
 
-L'environnement de travail de JLM devrait être immédiat à maîtriser, en
+L'environnement de travail de PLM devrait être immédiat à maîtriser, en
 particulier avec les bulles d'aide qui apparaissent quand votre souris
 survole les éléments. Voici une petite explication des composants au cas où
 quelque chose vous échappe. La fenêtre principale est faite de 5 composants
@@ -78,7 +78,7 @@ sélectionné (dans le menu déroulant). Cette vue est constituée d'une grille
 représentant les différentes cases du monde, ainsi que d'une ou plusieurs
 <i>buggles</i> qui attend vos ordres.</li>
 
-	  <li>Un onglet <b>Objective</b> qui permet d'afficher la vue du monde tel qu'il
+	  <li>Un onglet <b>Objectif</b> qui permet d'afficher la vue du monde tel qu'il
 doit être à la fin de l'exercice.</li>
 
 
diff --git a/lib/doc/MainWindow.html b/lib/doc/MainWindow.html
index d05cb6d..0fad798 100644
--- a/lib/doc/MainWindow.html
+++ b/lib/doc/MainWindow.html
@@ -1,6 +1,6 @@
-<h2>The JLM Main Window</h2>
+<h2>The PLM Main Window</h2>
 
-The JLM working environment should be self-explanatory, in particular
+The PLM working environment should be self-explanatory, in particular
 with the tool tips appearing when your mouse is over the elements.
 Here is a little explanation of the components in case you fail to
 understand something. The main window is made of 5 main components:
diff --git a/lib/jb2jlm.pl b/lib/jb2jlm.pl
deleted file mode 100644
index 201576b..0000000
--- a/lib/jb2jlm.pl
+++ /dev/null
@@ -1,109 +0,0 @@
-#! /usr/bin/perl
-use strict;
-
-## Get the mission
-while (<>) { 
-    last if /<table border="0"><tbody><tr><td valign="top" width="700">/;
-}
-my $mission = $_;
-while (<>) {
-    last if /<br><br>/;
-    $mission .= $_;
-}
-$mission =~ s/<[^>]*>//g;
-
-## Get the package name
-my $package = `pwd`;
-chomp $package;
-$package =~ s|/$||;
-$package =~ s|.*/||;
-
-## Get the prototype of the function to run
-while (<>) { last if /spellcheck="false"/}
-chomp;
-my $proto = $_;
-$proto =~ s/<[^>]*>//g;
-$proto =~ s/public //;
-
-## Get the tests
-while (<>) { last if /Expected/;}
-
-my $name;
-my @worlds;
-while (<>) {
-    chomp;
-    next unless /<tr>/;
-    next if /other tests/;
-    s/<tr><td>([^(]*)\(//; #)
-    if (defined $name && $1 ne $name) {
-	die "name redefined from $name to $1\n";
-    }
-    $name=$1;
-    
-    s/&.*//;
-    s/{/new int[] {/g;
-   
-#    print "w:$_\n";
-    push @worlds,$_;
-}
-my $upname= ucfirst $name;
-print "Write $upname.java\n";
-open J,">$upname.java" || die "Cannot open $upname.java: $!\n";
-
-print J "/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */\n\n";	
-print J "package lessons.bat.$package;\n";
-print J "import jlm.lesson.Lesson;\n";
-print J "import jlm.universe.World;\n";
-print J "import universe.bat.BatExercise;\n";
-print J "import universe.bat.BatWorld;\n\n";
-print J "public class $upname extends BatExercise {\n";
-print J "  public $upname(Lesson lesson) {\n";
-print J "    super(lesson);\n";
-print J "    \n";
-my $count = scalar @worlds;
-print J '    World[] myWorlds = new BatWorld['.$count."];\n";
-for (my $i=0;$i<scalar @worlds;$i++) {
-print J '    myWorlds['.$i.'] = new BatWorld('.($i<3?'VISIBLE':'INVISIBLE').', '.$worlds[$i].";\n";
-}
-print J "\n    setup(myWorlds,\"$name\");\n";
-print J "  }\n\n";
-	
-print J "  /* BEGIN SKEL */\n";
-print J "  public void run(World w) {\n";
-print J "    BatWorld bw = (BatWorld) w;\n";
-print J "    bw.result = $name(";
-my $protoargs = $proto;
-$protoargs =~ s/[^(]*\(//; #))
-$protoargs =~ s/\).*//;
-
-my $argcount=0;
-foreach (split (/,/,$protoargs)) {
-    s/^ *//;
-    s/ *$//;
-    s/ .*//;
-    s/int$/Integer/;
-    s/boolean$/Boolean/;
-    print J ", " if ($argcount>0);
-    print J "($_)w.getParameter($argcount)";
-    $argcount++;
-}
-print J ");\n";
-print J "  }\n";
-print J "  /* END SKEL */\n\n";
-
-print J "  /* BEGIN TEMPLATE */\n";
-print J "$proto\n";
-print J "  /* BEGIN SOLUTION */\n";
-print J "  /* END SOLUTION */\n";
-print J "}\n";
-print J "  /* END TEMPLATE */\n";
-print J "}\n";
-close J;
-
-print "Write $upname.html\n";
-open H,">$upname.html" || die "Cannot open $upname.html: $!\n";
-print H "<h1>$upname</h1>\n";
-print H "$mission\n";
-print H "\n<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>\n";
-close H;
-
diff --git a/lib/jb2plm.pl b/lib/jb2plm.pl
new file mode 100644
index 0000000..a715ace
--- /dev/null
+++ b/lib/jb2plm.pl
@@ -0,0 +1,109 @@
+#! /usr/bin/perl
+use strict;
+
+## Get the mission
+while (<>) { 
+    last if /<table border="0"><tbody><tr><td valign="top" width="700">/;
+}
+my $mission = $_;
+while (<>) {
+    last if /<br><br>/;
+    $mission .= $_;
+}
+$mission =~ s/<[^>]*>//g;
+
+## Get the package name
+my $package = `pwd`;
+chomp $package;
+$package =~ s|/$||;
+$package =~ s|.*/||;
+
+## Get the prototype of the function to run
+while (<>) { last if /spellcheck="false"/}
+chomp;
+my $proto = $_;
+$proto =~ s/<[^>]*>//g;
+$proto =~ s/public //;
+
+## Get the tests
+while (<>) { last if /Expected/;}
+
+my $name;
+my @worlds;
+while (<>) {
+    chomp;
+    next unless /<tr>/;
+    next if /other tests/;
+    s/<tr><td>([^(]*)\(//; #)
+    if (defined $name && $1 ne $name) {
+	die "name redefined from $name to $1\n";
+    }
+    $name=$1;
+    
+    s/&.*//;
+    s/{/new int[] {/g;
+   
+#    print "w:$_\n";
+    push @worlds,$_;
+}
+my $upname= ucfirst $name;
+print "Write $upname.java\n";
+open J,">$upname.java" || die "Cannot open $upname.java: $!\n";
+
+print J "/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */\n\n";	
+print J "package lessons.bat.$package;\n";
+print J "import plm.lesson.Lesson;\n";
+print J "import plm.universe.World;\n";
+print J "import universe.bat.BatExercise;\n";
+print J "import universe.bat.BatWorld;\n\n";
+print J "public class $upname extends BatExercise {\n";
+print J "  public $upname(Lesson lesson) {\n";
+print J "    super(lesson);\n";
+print J "    \n";
+my $count = scalar @worlds;
+print J '    World[] myWorlds = new BatWorld['.$count."];\n";
+for (my $i=0;$i<scalar @worlds;$i++) {
+print J '    myWorlds['.$i.'] = new BatWorld('.($i<3?'VISIBLE':'INVISIBLE').', '.$worlds[$i].";\n";
+}
+print J "\n    setup(myWorlds,\"$name\");\n";
+print J "  }\n\n";
+	
+print J "  /* BEGIN SKEL */\n";
+print J "  public void run(World w) {\n";
+print J "    BatWorld bw = (BatWorld) w;\n";
+print J "    bw.result = $name(";
+my $protoargs = $proto;
+$protoargs =~ s/[^(]*\(//; #))
+$protoargs =~ s/\).*//;
+
+my $argcount=0;
+foreach (split (/,/,$protoargs)) {
+    s/^ *//;
+    s/ *$//;
+    s/ .*//;
+    s/int$/Integer/;
+    s/boolean$/Boolean/;
+    print J ", " if ($argcount>0);
+    print J "($_)w.getParameter($argcount)";
+    $argcount++;
+}
+print J ");\n";
+print J "  }\n";
+print J "  /* END SKEL */\n\n";
+
+print J "  /* BEGIN TEMPLATE */\n";
+print J "$proto\n";
+print J "  /* BEGIN SOLUTION */\n";
+print J "  /* END SOLUTION */\n";
+print J "}\n";
+print J "  /* END TEMPLATE */\n";
+print J "}\n";
+close J;
+
+print "Write $upname.html\n";
+open H,">$upname.html" || die "Cannot open $upname.html: $!\n";
+print H "<h1>$upname</h1>\n";
+print H "$mission\n";
+print H "\n<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>\n";
+close H;
+
diff --git a/lib/l10n-engine/en.po b/lib/l10n-engine/en.po
index a46c708..c6e3b87 100644
--- a/lib/l10n-engine/en.po
+++ b/lib/l10n-engine/en.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-08-04 21:21+0200\n"
+"POT-Creation-Date: 2013-08-30 14:51+0200\n"
 "PO-Revision-Date: 2013-05-30 11:25+0200\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
@@ -17,94 +17,514 @@ msgstr ""
 "Content-Type: text/plain; charset=ASCII\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: src/jlm/core/model/Game.java:146
+#: src/lessons/maze/island/IslandMazeEntity.java:10
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:10
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:9
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:12
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:12
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:12
+#: src/lessons/welcome/array/basics/Array1Entity.java:11
+#: src/lessons/welcome/array/basics/Array2Entity.java:12
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."
+msgstr ""
+
+#: src/lessons/maze/island/IslandMazeEntity.java:15
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:15
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:14
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:17
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:17
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:17
+#: src/lessons/welcome/array/basics/Array1Entity.java:16
+#: src/lessons/welcome/array/basics/Array2Entity.java:17
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."
+msgstr ""
+
+#: src/lessons/maze/island/IslandMazeEntity.java:20
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:20
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:19
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:22
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:22
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:22
+#: src/lessons/welcome/array/basics/Array1Entity.java:21
+#: src/lessons/welcome/array/basics/Array2Entity.java:22
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
+msgid "Invalid move"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
+#, java-format
+msgid ""
+"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
+#, java-format
+msgid "Cannot move from slot {0} to itself"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
+#, java-format
+msgid "No disc to move from slot {0}"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
+#, java-format
+msgid ""
+"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
+"but {2} > {3}"
+msgstr ""
+
+#. Create the button
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
+#: src/plm/core/ui/ChooseLessonDialog.java:180
+msgid "Go"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
+#, java-format
+msgid ""
+"The player {0} of the base {1} cannot reach the hole that is too far from "
+"its position"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
+msgid "This is not a baseball world :-("
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
+#, java-format
+msgid "Differing amount of bases: {0} vs {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
+#, java-format
+msgid "Differing amount of players: {0} vs {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
+#, java-format
+msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:371
+#, java-format
+msgid ""
+"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
+"information:\n"
+"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:408
+#, java-format
+msgid "Cannot move from base {0} since it''s not between 0 and {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:411
+#, java-format
+msgid "Cannot move from position {0} since it''s not between 0 and {1})"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:420
+#, java-format
+msgid ""
+"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
+"it in one move"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
+#: src/plm/universe/sort/SortingWorldView.java:51
+msgid "Switch to time view"
+msgstr "Switch to time view"
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
+#: src/plm/universe/sort/SortingWorldView.java:53
+msgid "Switch to state view"
+msgstr "Switch to state view"
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
+msgid "This is not a world of pancakes :-("
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
+msgid "The two worlds are of differing size"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:202
+#, java-format
+msgid "Asked to flip {0} pancakes, but you must flip at least one"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:204
+#, java-format
+msgid ""
+"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:238
+#, java-format
+msgid ""
+"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:257
+#, java-format
+msgid ""
+"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
+"{1}"
+msgstr ""
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:10
+#: src/lessons/welcome/loopfor/LoopForEntity.java:8
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:10
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:9
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:9
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:9
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:10
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:9
+#: src/lessons/welcome/variables/RunFourEntity.java:8
+#: src/lessons/welcome/variables/RunHalfEntity.java:10
+#: src/lessons/welcome/variables/VariablesEntity.java:8
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward with an argument in "
+"this exercise."
+msgstr ""
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:14
+#: src/lessons/welcome/loopfor/LoopForEntity.java:13
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:14
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:14
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:14
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:14
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:14
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:14
+#: src/lessons/welcome/variables/RunFourEntity.java:12
+#: src/lessons/welcome/variables/RunHalfEntity.java:14
+#: src/lessons/welcome/variables/VariablesEntity.java:13
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward with an argument in "
+"this exercise."
+msgstr ""
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+msgid "You fall into water."
+msgstr ""
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+#: src/plm/universe/bugglequest/SimpleBuggle.java:29
+#: src/plm/universe/bugglequest/SimpleBuggle.java:40
+#: src/plm/universe/bugglequest/SimpleBuggle.java:51
+#: src/plm/universe/bugglequest/SimpleBuggle.java:62
+#: src/plm/universe/bugglequest/SimpleBuggle.java:78
+#: src/plm/universe/bugglequest/SimpleBuggle.java:82
+#: src/plm/universe/bugglequest/SimpleBuggle.java:93
+#: src/plm/universe/bugglequest/SimpleBuggle.java:103
+#: src/plm/universe/bugglequest/SimpleBuggle.java:113
+#: src/plm/universe/bugglequest/SimpleBuggle.java:123
+#, fuzzy
+msgid "Test failed"
+msgstr "Exercise failed /o\\"
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:10
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:66
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:71
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:67
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:71
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:26
+#, java-format
+msgid ""
+"I''m sorry Dave, I''m affraid I cant let you use left() both in lines {0} "
+"and {1} in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:45
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:46
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:51
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:50
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:55
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:54
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:58
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:59
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:63
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:63
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:62
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:67
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:63
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:67
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:70
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:75
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:71
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:75
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:74
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:79
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:75
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:79
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this "
+"exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:78
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:83
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:79
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:83
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this "
+"exercise."
+msgstr ""
+
+#.
+#. * FIXME: provide a way to debug
+#. * when templates are broken
+#.
+#. for (String n:classes.keySet())
+#. System.out.println("File "+n+":\n"+classes.get(n));
+#: src/plm/core/CompilerJava.java:289
+#, fuzzy
+msgid "Compilation failed."
+msgstr "Compilation error"
+
+#: src/plm/core/PythonExceptionDecipher.java:24
+#, java-format
+msgid ""
+"Syntax error at line {0}: {1}\n"
+"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:32
+msgid ""
+"NameError raised: You seem to use a non-existent identifier; Please check "
+"for typos\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:35
+msgid "TypeError raised: you are probably misusing a function or something.\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:38
+msgid ""
+"UnboundLocalError raised: you are probably using a global variable that is "
+"not declared as such.\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:44
+msgid "Error: there is no baggle to pickup under the buggle"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:46
+msgid "Error: a buggle cannot carry more than one baggle at the same time"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:48
+msgid "Error: your buggle just teleported to the outer space..."
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:50
+msgid "Error: your buggle just hit a wall. That hurts."
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:53
+#, java-format
+msgid ""
+"Unknown error (please report): {0}\n"
+"Its value is: {1}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:151
+msgid "Scala is usable on your machine. Congratulations."
+msgstr ""
+
+#: src/plm/core/model/Game.java:153
+msgid "Please install Scala version 2.10 or higher to use it in PLM."
+msgstr ""
+
+#: src/plm/core/model/Game.java:155
+msgid "Jython is usable on your machine. Congratulations."
+msgstr ""
+
+#: src/plm/core/model/Game.java:157
+msgid "Please install jython to use the python programming language in PLM."
+msgstr ""
+
+#: src/plm/core/model/Game.java:163
 #, java-format
 msgid ""
 "Warning, the default programming language is neither ''Java'' nor ''python'' "
-"but {0}.\n"
+"or ''Scala'' but {0}.\n"
 "   This language will be used to setup the worlds, possibly leading to "
 "severe issues for the exercises that don''t expect it.\n"
-"   It is safer to change the current language, and restart JLM before "
+"   It is safer to change the current language, and restart PLM before "
 "proceeding.\n"
 "   Alternatively, the property {1} can be changed in your configuration file "
-"($HOME/.jlm/jlm.properties"
+"($HOME/.plm/plm.properties)"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:160
-#, java-format
+#: src/plm/core/model/Game.java:169
 msgid ""
-"Your progress will be posted to http://identi.ca/jlmlovers This can be "
-"turned off through the property {0}"
+"The default programming language is Scala, but your scala installation is "
+"not usable. Switching to Java instead.\n"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:163
-#, java-format
+#: src/plm/core/model/Game.java:172
 msgid ""
-"Your progress will NOT be posted to identica, as requested by the property "
-"{0}"
+"The default programming language is python, but your python installation is "
+"not usable. Switching to Java instead.\n"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:166
+#: src/plm/core/model/Game.java:185
 #, java-format
 msgid ""
 "Your progress will be posted to https://twitter.com/jlmlovers This can be "
 "turned off through the property {0}"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:169
+#: src/plm/core/model/Game.java:188
 #, java-format
 msgid ""
 "Your progress will NOT be posted to twitter, as requested by the property {0}"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:217 src/jlm/core/model/Game.java:218
+#: src/plm/core/model/Game.java:217
+#, java-format
+msgid "Error {0} while retrieving the Scala version: {1}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:226
+#, java-format
+msgid "Scala is too ancient. Found {0} while I need 2.10 or higher."
+msgstr ""
+
+#: src/plm/core/model/Game.java:251
+msgid ""
+"Cannot retrieve the python ScriptEngine. Are jython.jar and its dependencies "
+"in the classpath?"
+msgstr ""
+
+#: src/plm/core/model/Game.java:274
+#, java-format
+msgid ""
+"Resource {0} not found in the classpath.\n"
+"Is {1} in your classpath?"
+msgstr ""
+
+#: src/plm/core/model/Game.java:276
+#, java-format
+msgid "{0} received while searching for resource {1}: {2}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:320 src/plm/core/model/Game.java:321
 #, java-format
 msgid "Cannot switch to lesson {0}: class Main not found."
 msgstr ""
 
-#: src/jlm/core/model/Game.java:219
+#: src/plm/core/model/Game.java:322
 #, fuzzy, java-format
 msgid "Load lesson {0}"
 msgstr "Load lesson"
 
-#: src/jlm/core/model/Game.java:325 src/jlm/core/model/Game.java:357
+#: src/plm/core/model/Game.java:428 src/plm/core/model/Game.java:462
 msgid "Operation cancelled by the user"
 msgstr "Operation cancelled by the user"
 
-#: src/jlm/core/model/Game.java:397
+#: src/plm/core/model/Game.java:453
+#, java-format
+msgid ""
+"Exercise {0} does not support language {1}. Fallback to {2} instead. Please "
+"consider contributing to this project by adapting this exercise to this "
+"language."
+msgstr ""
+
+#: src/plm/core/model/Game.java:502
 #, java-format
 msgid "The lecture {0} has no world that I can select"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:920
+#: src/plm/core/model/Game.java:906
+msgid ""
+"Please install Scala version 2.10 or higher to use it in PLM.\n"
+"\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:907
+msgid "Scala is missing"
+msgstr ""
+
+#: src/plm/core/model/Game.java:911
+msgid ""
+"Please install jython and its dependencies to use the python programming "
+"language in PLM.\n"
+"\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:912
+msgid "Python is missing"
+msgstr ""
+
+#: src/plm/core/model/Game.java:1058
 #, java-format
 msgid "{0} is not writable"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:924
+#: src/plm/core/model/Game.java:1062
 #, java-format
 msgid "{0} is not a directory"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:931
+#: src/plm/core/model/Game.java:1069
 #, java-format
 msgid "Cannot create {0}"
 msgstr ""
 
-#: src/jlm/core/model/Game.java:937
+#: src/plm/core/model/Game.java:1075
 #, java-format
-msgid "Impossible to find a path for JLM datas. Tested {0}"
+msgid "Impossible to find a path for PLM data. Tested {0}"
 msgstr ""
 
-#: src/jlm/core/model/HelpServer.java:27
+#: src/plm/core/model/HelpServer.java:27
 msgid "Asking to the teacher for help"
 msgstr "Asking to the teacher for help"
 
-#: src/jlm/core/model/HelpServer.java:29
+#: src/plm/core/model/HelpServer.java:29
 msgid "Cancel call for help to the teacher"
 msgstr "Cancel call for help to the teacher"
 
-#: src/jlm/core/model/LessonRunner.java:90
+#: src/plm/core/model/LessonRunner.java:91
 #, fuzzy, java-format
 msgid ""
 "Congratulations, you passed this exercise.\n"
@@ -113,21 +533,21 @@ msgstr ""
 "Congratulations, you passed this exercise.\n"
 " {0} tests passed.\n"
 
-#: src/jlm/core/model/LessonRunner.java:92
-#: src/jlm/core/model/LessonRunner.java:98
-#: src/jlm/core/model/LessonRunner.java:107
-#: src/jlm/core/model/LessonRunner.java:113
+#: src/plm/core/model/LessonRunner.java:93
+#: src/plm/core/model/LessonRunner.java:99
+#: src/plm/core/model/LessonRunner.java:108
+#: src/plm/core/model/LessonRunner.java:114
 msgid "Exercice passed \\o/"
 msgstr "Exercice passed \\o/"
 
-#: src/jlm/core/model/LessonRunner.java:96
+#: src/plm/core/model/LessonRunner.java:97
 #, fuzzy
 msgid "Congratulations, you passed this exercise."
 msgstr ""
 "Congratulations, you passed this exercise.\n"
 " {0} tests passed.\n"
 
-#: src/jlm/core/model/LessonRunner.java:106
+#: src/plm/core/model/LessonRunner.java:107
 #, fuzzy, java-format
 msgid ""
 "Congratulations, you passed this exercise.\n"
@@ -136,7 +556,7 @@ msgid ""
 msgstr ""
 "Congratulations, you passed this test. Which exercise will you do now?\n"
 
-#: src/jlm/core/model/LessonRunner.java:112
+#: src/plm/core/model/LessonRunner.java:113
 #, fuzzy
 msgid ""
 "Congratulations, you passed this exercise.\n"
@@ -144,163 +564,301 @@ msgid ""
 msgstr ""
 "Congratulations, you passed this test. Which exercise will you do now?\n"
 
-#: src/jlm/core/model/lesson/Exercise.java:77
+#: src/plm/core/model/lesson/Exercise.java:87
 #, java-format
 msgid "The world ''{0}'' differs"
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:41
+#: src/plm/core/model/lesson/Exercise.java:149
+#: src/plm/core/model/lesson/Exercise.java:175
+#, fuzzy
+msgid "Compilation error:"
+msgstr "Compilation error"
+
+#: src/plm/core/model/lesson/Exercise.java:296
+#, java-format
+msgid ""
+"Cannot compute the answer from file {0}.{1} since I cannot read it (error "
+"was: {2})."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:43
 #, java-format
 msgid "Source file {0}.{1} not found."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:88
+#: src/plm/core/model/lesson/ExerciseTemplated.java:104
 #, java-format
 msgid "{0}: BEGIN TEMPLATE within the template. Please fix your entity."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:108
+#: src/plm/core/model/lesson/ExerciseTemplated.java:125
 #, java-format
 msgid ""
 "{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:122
+#: src/plm/core/model/lesson/ExerciseTemplated.java:143
+#: src/plm/core/model/lesson/ExerciseTemplated.java:167
 #, java-format
 msgid ""
 "{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:126
+#: src/plm/core/model/lesson/ExerciseTemplated.java:147
 #, java-format
 msgid "{0}: Begin solution in template tail. Change it to BEGIN HIDDEN"
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:153
+#: src/plm/core/model/lesson/ExerciseTemplated.java:187
 #, java-format
 msgid ""
 "Parser error in file {0}. This is a parser bug (state={1}), please report."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:158
+#: src/plm/core/model/lesson/ExerciseTemplated.java:192
 #, java-format
 msgid ""
 "{0}: End of file unexpected after the solution but within the template. "
 "Please fix your entity."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:160
+#: src/plm/core/model/lesson/ExerciseTemplated.java:194
 #, java-format
 msgid ""
 "{0}: End of file unexpected (state: {1}). Did you forget to close your "
 "template or solution? Please fix your entity."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:311
+#: src/plm/core/model/lesson/ExerciseTemplated.java:350
+#, java-format
+msgid ""
+"Exercise {0} is said to be compatible with language {1}, but there is no "
+"entity for this language: {2}"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:359
+#, java-format
+msgid "{0}: No entity found. You should fix your paths and such"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:381
 #, java-format
 msgid "World {0} is broken ({1}). Recompute all answer worlds."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:315
+#: src/plm/core/model/lesson/ExerciseTemplated.java:385
 #, java-format
 msgid ""
 "IO exception while reading world {0} ({1}). Recompute all answer worlds."
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:326
+#: src/plm/core/model/lesson/ExerciseTemplated.java:396
 #, java-format
 msgid ""
 "Recompute the answer of {0} despite the cache file, as requested by the "
 "property {1}"
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:349
+#: src/plm/core/model/lesson/ExerciseTemplated.java:421
 #, java-format
 msgid "Error while writing answer world of {0}:"
 msgstr ""
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:353
+#: src/plm/core/model/lesson/ExerciseTemplated.java:425
 #, java-format
 msgid "Cannot write answer world of {0}. Please check the permissions."
 msgstr ""
 
-#: src/jlm/core/model/lesson/Lecture.java:88
-#: src/jlm/core/model/lesson/Lesson.java:84
+#: src/plm/core/model/lesson/Lecture.java:90
+#: src/plm/core/model/lesson/Lesson.java:84
+#, java-format
+msgid "File {0}.html not found."
+msgstr ""
+
+#: src/plm/core/model/lesson/Lecture.java:99
+#: src/plm/core/model/lesson/Lesson.java:94
+#, java-format
+msgid "Cannot find the name of mission in {0}.html"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Ok, quit and lose my data"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Please stop! I'll save it myself first"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:253
+#, java-format
+msgid ""
+"PLM were unable to save your session file for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed so far)?"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:256
+msgid "Your changes are NOT saved"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:259
+msgid "User aborted saving on system error"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Proceed"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Abort"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:357
+#, java-format
+msgid ""
+"PLM were unable to load your code for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed previously)?"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:360
+msgid "Error while loading your session"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:363
+msgid "Abording on user request"
+msgstr ""
+
+#: src/plm/core/ui/AboutLessonDialog.java:24
+msgid "About lesson - "
+msgstr "About lesson - "
+
+#: src/plm/core/ui/AboutPLMDialog.java:34
+msgid "About PLM dialogTitle"
+msgstr "About PLM dialogTitle"
+
+#: src/plm/core/ui/AboutPLMDialog.java:71
+#: src/plm/core/ui/ExerciseFailedDialog.java:49
+msgid "Close"
+msgstr "Close"
+
+#: src/plm/core/ui/AboutWorldDialog.java:32
+#, fuzzy, java-format
+msgid "About world - {0}"
+msgstr "About world - "
+
+#: src/plm/core/ui/ChooseLessonDialog.java:40
+#, fuzzy
+msgid "Choose your lesson"
+msgstr "Choose your course"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:54
+msgid ""
+"<table border=\"0\" align=\"center\"><tr>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"<td valign=\"center\">  <font size=\"+2\">Welcome to the "
+"Programmer's Learning Machine</font>  </td>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"</tr></table>\n"
+"\n"
+"<p><font size=\"+1\">The PLM is a Learning Management System (LMS) aiming at "
+"teaching the art of computer programming through interactive exercises. It "
+"offers an extensive set of varied exercises, allowing you to practice at "
+"your own pace.</font></p><br/>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:132
+#: src/plm/core/ui/MainFrame.java:163
+msgid "PLM lesson files"
+msgstr "PLM lesson files"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:141
+#: src/plm/core/ui/MainFrame.java:172
+msgid "Error"
+msgstr "Error"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:168
+msgid ""
+"<h1>Please pick a lesson</h1>\n"
+"<p>Please click on an icon on the left to select a lesson.</p>\n"
+"<p>Lessons located above are generally simpler than the ones located below.</"
+"p>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:210
+#, java-format
+msgid ""
+"<p>(unable to display the short description of this lesson: file {0} not "
+"found)</p>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:213
+msgid "<p><b>Your score:</b> "
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:221
 #, java-format
-msgid "File {0}.html not found."
+msgid "{0} out of {1} exercises passed."
 msgstr ""
 
-#: src/jlm/core/model/lesson/Lecture.java:97
-#: src/jlm/core/model/lesson/Lesson.java:94
+#: src/plm/core/ui/ChooseLessonDialog.java:225
 #, java-format
-msgid "Cannot find the name of mission in {0}.html"
+msgid "{0} out of {1} exercises passed in {2}."
 msgstr ""
 
-#: src/jlm/core/ui/AboutJLMDialog.java:34
-msgid "About JLM dialogTitle"
-msgstr "About JLM dialogTitle"
-
-#: src/jlm/core/ui/AboutJLMDialog.java:71
-#: src/jlm/core/ui/ExerciseFailedDialog.java:48
-msgid "Close"
-msgstr "Close"
-
-#: src/jlm/core/ui/AboutLessonDialog.java:24
-msgid "About lesson - "
-msgstr "About lesson - "
-
-#: src/jlm/core/ui/AboutWorldDialog.java:32
-#, fuzzy, java-format
-msgid "About world - {0}"
-msgstr "About world - "
+#: src/plm/core/ui/ChooseLessonDialog.java:231
+#, fuzzy
+msgid "You never attempted this lesson."
+msgstr "About this lesson"
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:29
+#: src/plm/core/ui/ExerciseFailedDialog.java:30
 msgid "Exercise failed /o\\"
 msgstr "Exercise failed /o\\"
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:38
+#: src/plm/core/ui/ExerciseFailedDialog.java:39
 msgid "You didn't manage to reach your objective."
 msgstr "You didn't manage to reach your objective."
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:41
+#: src/plm/core/ui/ExerciseFailedDialog.java:42
 msgid "Compilation error"
 msgstr "Compilation error"
 
-#: src/jlm/core/ui/ExerciseView.java:73
+#: src/plm/core/ui/ExerciseView.java:74
 msgid "Switch the displayed world"
 msgstr "Switch the displayed world"
 
-#: src/jlm/core/ui/ExerciseView.java:83
+#: src/plm/core/ui/ExerciseView.java:84
 msgid "Change the speed of execution"
 msgstr "Change the speed of execution"
 
-#: src/jlm/core/ui/ExerciseView.java:90 src/jlm/core/ui/ExerciseView.java:162
+#: src/plm/core/ui/ExerciseView.java:91 src/plm/core/ui/ExerciseView.java:163
 msgid "World"
 msgstr "World"
 
-#: src/jlm/core/ui/ExerciseView.java:91 src/jlm/core/ui/ExerciseView.java:163
+#: src/plm/core/ui/ExerciseView.java:92 src/plm/core/ui/ExerciseView.java:164
 msgid "Current world"
 msgstr "Current world"
 
-#: src/jlm/core/ui/ExerciseView.java:95 src/jlm/core/ui/ExerciseView.java:165
+#: src/plm/core/ui/ExerciseView.java:96 src/plm/core/ui/ExerciseView.java:166
 msgid "Objective"
 msgstr "Objective"
 
-#: src/jlm/core/ui/ExerciseView.java:96 src/jlm/core/ui/ExerciseView.java:166
+#: src/plm/core/ui/ExerciseView.java:97 src/plm/core/ui/ExerciseView.java:167
 msgid "Target world"
 msgstr "Target world"
 
-#: src/jlm/core/ui/ExerciseView.java:104
+#: src/plm/core/ui/ExerciseView.java:105
 msgid "Switch the entity"
 msgstr "Switch the entity"
 
-#: src/jlm/core/ui/FeedbackDialog.java:49
+#: src/plm/core/ui/FeedbackDialog.java:49
 msgid "Report your feedback"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:59
+#: src/plm/core/ui/FeedbackDialog.java:59
 msgid ""
-"<html><p>Thanks for your feedback on JLM. We deeply need this to make the "
+"<html><p>Thanks for your feedback on PLM. We deeply need this to make the "
 "tool match <br>your needs, so please don't hesitate to report any "
 "suggestion, such as typos and <br/>unclear parts in the mission texts, other "
 "improvement to the existing exercises<br/>or prospective exercises. We will "
@@ -309,315 +867,247 @@ msgid ""
 "details, and then click on 'Send' below.</p><p><b>Please provide your email "
 "address so that we can contact you back</b> but <br/>NEVER DISCLOSE A "
 "PASSWORD while reporting issues.</p><p>Note that some technical information "
-"(such as your version of JLM and Java) will <br/>automatically be added to "
+"(such as your version of PLM and Java) will <br/>automatically be added to "
 "your feedback. None of these automatic information <br/>are personal and you "
 "still have to identify yourself if you want to.</p><p>Alternatively, you can "
 "use the <a href='http://github.com/oster/JLM/issues'>github interface</a> "
 "for feedback.</p></html>"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:78
+#: src/plm/core/ui/FeedbackDialog.java:88
 msgid "(your feedback comes here)"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:89
+#: src/plm/core/ui/FeedbackDialog.java:90
 #, fuzzy
 msgid "Cancel"
 msgstr "Cancel call"
 
-#: src/jlm/core/ui/FeedbackDialog.java:94
+#: src/plm/core/ui/FeedbackDialog.java:95
 msgid "Do you really want to cancel your feedback and lose any edit?"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:95
+#: src/plm/core/ui/FeedbackDialog.java:96
 msgid "are you sure?"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:102
+#: src/plm/core/ui/FeedbackDialog.java:103
 msgid "Send feedback"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:142
+#: src/plm/core/ui/FeedbackDialog.java:143
 msgid "Thank you for your feedback"
 msgstr ""
 
-#: src/jlm/core/ui/FeedbackDialog.java:148
-#: src/jlm/core/ui/FeedbackDialog.java:157
+#: src/plm/core/ui/FeedbackDialog.java:149
+#: src/plm/core/ui/FeedbackDialog.java:158
 msgid "Error while uploading your feedback"
 msgstr ""
 
-#: src/jlm/core/ui/JlmHtmlEditorKit.java:142
-#, java-format
-msgid "<img> tag without src attribute in exercise {0}"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:40
-#, fuzzy
-msgid "Choose your lesson"
-msgstr "Choose your course"
-
-#: src/jlm/core/ui/LessonChooser.java:54
-msgid ""
-"<table border=\"0\" align=\"center\"><tr>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"<td valign=\"center\">  <font size=\"+2\">Welcome to the Java "
-"Learning Machine</font>  </td>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"</tr></table>\n"
-"\n"
-"<p><font size=\"+1\">The JLM is a Learning Management System (LMS) aiming at "
-"teaching the art of computer programming through interactive exercises. It "
-"offers an extensive set of varied exercises, allowing you to practice at "
-"your own pace.</font></p><br/>"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:132 src/jlm/core/ui/MainFrame.java:163
-msgid "JLM lesson files"
-msgstr "JLM lesson files"
-
-#: src/jlm/core/ui/LessonChooser.java:141 src/jlm/core/ui/MainFrame.java:172
-msgid "Error"
-msgstr "Error"
-
-#: src/jlm/core/ui/LessonChooser.java:168
-msgid ""
-"<h1>Please pick a lesson</h1>\n"
-"<p>Please click on an icon on the left to select a lesson.</p>\n"
-"<p>Lessons located above are generally simpler than the ones located below.</"
-"p>"
-msgstr ""
-
-#. Create the button
-#: src/jlm/core/ui/LessonChooser.java:180
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
-msgid "Go"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:210
-#, java-format
-msgid ""
-"<p>(unable to display the short description of this lesson: file {0} not "
-"found)</p>"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:213
-msgid "<p><b>Your score:</b> "
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:221
-#, java-format
-msgid "{0} out of {1} exercises passed."
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:225
-#, java-format
-msgid "{0} out of {1} exercises passed in {2}."
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:231
-#, fuzzy
-msgid "You never attempted this lesson."
-msgstr "About this lesson"
-
-#: src/jlm/core/ui/LoggerPanel.java:31 src/jlm/core/ui/LoggerPanel.java:96
+#: src/plm/core/ui/LoggerPanel.java:30 src/plm/core/ui/LoggerPanel.java:95
 msgid "Where error and other messages get written"
 msgstr "Where error and other messages get written"
 
 #. === FILE menu ===
 #. for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
 #. Menus
-#: src/jlm/core/ui/MainFrame.java:152 src/jlm/core/ui/MainFrame.java:647
+#: src/plm/core/ui/MainFrame.java:152 src/plm/core/ui/MainFrame.java:647
 msgid "File"
 msgstr "File"
 
-#: src/jlm/core/ui/MainFrame.java:154
+#: src/plm/core/ui/MainFrame.java:154
 msgid "File related functions"
 msgstr "File related functions"
 
-#: src/jlm/core/ui/MainFrame.java:157 src/jlm/core/ui/MainFrame.java:648
+#: src/plm/core/ui/MainFrame.java:157 src/plm/core/ui/MainFrame.java:648
 msgid "Load lesson"
 msgstr "Load lesson"
 
-#: src/jlm/core/ui/MainFrame.java:179 src/jlm/core/ui/MainFrame.java:649
+#: src/plm/core/ui/MainFrame.java:179 src/plm/core/ui/MainFrame.java:649
 msgid "Switch lesson"
 msgstr "Switch lesson"
 
-#: src/jlm/core/ui/MainFrame.java:191 src/jlm/core/ui/MainFrame.java:416
-#: src/jlm/core/ui/MainFrame.java:644 src/jlm/core/ui/MainFrame.java:650
+#: src/plm/core/ui/MainFrame.java:191 src/plm/core/ui/MainFrame.java:416
+#: src/plm/core/ui/MainFrame.java:644 src/plm/core/ui/MainFrame.java:650
 msgid "Switch exercise"
 msgstr "Switch exercise"
 
-#: src/jlm/core/ui/MainFrame.java:204 src/jlm/core/ui/MainFrame.java:652
+#: src/plm/core/ui/MainFrame.java:204 src/plm/core/ui/MainFrame.java:652
 msgid "Teacher Console"
 msgstr "Teacher Console"
 
 #. Menu item to change the current Course
-#: src/jlm/core/ui/MainFrame.java:223 src/jlm/core/ui/MainFrame.java:653
+#: src/plm/core/ui/MainFrame.java:223 src/plm/core/ui/MainFrame.java:653
 msgid "Choose your course"
 msgstr "Choose your course"
 
-#: src/jlm/core/ui/MainFrame.java:242 src/jlm/core/ui/MainFrame.java:654
+#: src/plm/core/ui/MainFrame.java:242 src/plm/core/ui/MainFrame.java:654
 msgid "Quit"
 msgstr "Quit"
 
 #. === Edit menu ===
-#: src/jlm/core/ui/MainFrame.java:250 src/jlm/core/ui/MainFrame.java:656
+#: src/plm/core/ui/MainFrame.java:250 src/plm/core/ui/MainFrame.java:656
 msgid "Session"
 msgstr "Session"
 
-#: src/jlm/core/ui/MainFrame.java:255 src/jlm/core/ui/MainFrame.java:658
+#: src/plm/core/ui/MainFrame.java:255 src/plm/core/ui/MainFrame.java:658
 msgid "Revert Exercise"
 msgstr "Revert Exercise"
 
-#: src/jlm/core/ui/MainFrame.java:258 src/jlm/core/ui/MainFrame.java:659
+#: src/plm/core/ui/MainFrame.java:258 src/plm/core/ui/MainFrame.java:659
 msgid "Export Session Cache"
 msgstr "Export Session Cache"
 
-#: src/jlm/core/ui/MainFrame.java:261 src/jlm/core/ui/MainFrame.java:660
+#: src/plm/core/ui/MainFrame.java:261 src/plm/core/ui/MainFrame.java:660
 msgid "Import Session Cache"
 msgstr "Import Session Cache"
 
-#: src/jlm/core/ui/MainFrame.java:265 src/jlm/core/ui/MainFrame.java:661
+#: src/plm/core/ui/MainFrame.java:265 src/plm/core/ui/MainFrame.java:661
 msgid "Debug mode"
 msgstr "Debug mode"
 
 #. === Language menu ===
-#: src/jlm/core/ui/MainFrame.java:278 src/jlm/core/ui/MainFrame.java:664
+#: src/plm/core/ui/MainFrame.java:278 src/plm/core/ui/MainFrame.java:664
 msgid "Language"
 msgstr "Language"
 
 #. === Programming language changing ===
-#: src/jlm/core/ui/MainFrame.java:283 src/jlm/core/ui/MainFrame.java:665
+#: src/plm/core/ui/MainFrame.java:283 src/plm/core/ui/MainFrame.java:665
 msgid "Human"
 msgstr "Human"
 
-#: src/jlm/core/ui/MainFrame.java:297 src/jlm/core/ui/MainFrame.java:666
+#: src/plm/core/ui/MainFrame.java:297 src/plm/core/ui/MainFrame.java:666
 msgid "Computer"
 msgstr "Computer"
 
 #. === Help menu ===
-#: src/jlm/core/ui/MainFrame.java:301 src/jlm/core/ui/MainFrame.java:668
+#: src/plm/core/ui/MainFrame.java:301 src/plm/core/ui/MainFrame.java:668
 msgid "Help"
 msgstr "Help"
 
-#: src/jlm/core/ui/MainFrame.java:305 src/jlm/core/ui/MainFrame.java:669
+#: src/plm/core/ui/MainFrame.java:305 src/plm/core/ui/MainFrame.java:669
 msgid "Provide feedback"
 msgstr ""
 
-#: src/jlm/core/ui/MainFrame.java:315 src/jlm/core/ui/MainFrame.java:670
+#: src/plm/core/ui/MainFrame.java:315 src/plm/core/ui/MainFrame.java:670
 msgid "About this lesson"
 msgstr "About this lesson"
 
-#: src/jlm/core/ui/MainFrame.java:328 src/jlm/core/ui/MainFrame.java:671
+#: src/plm/core/ui/MainFrame.java:328 src/plm/core/ui/MainFrame.java:671
 msgid "About this world"
 msgstr "About this world"
 
-#: src/jlm/core/ui/MainFrame.java:344 src/jlm/core/ui/MainFrame.java:673
-msgid "About JLM"
-msgstr "About JLM"
+#: src/plm/core/ui/MainFrame.java:344 src/plm/core/ui/MainFrame.java:673
+msgid "About PLM"
+msgstr "About PLM"
 
 #. Buttons
-#: src/jlm/core/ui/MainFrame.java:377 src/jlm/core/ui/MainFrame.java:638
+#: src/plm/core/ui/MainFrame.java:377 src/plm/core/ui/MainFrame.java:638
 msgid "Run"
 msgstr "Run"
 
-#: src/jlm/core/ui/MainFrame.java:381 src/jlm/core/ui/MainFrame.java:479
-#: src/jlm/core/ui/MainFrame.java:639
+#: src/plm/core/ui/MainFrame.java:381 src/plm/core/ui/MainFrame.java:479
+#: src/plm/core/ui/MainFrame.java:639
 msgid "Step"
 msgstr "Step"
 
-#: src/jlm/core/ui/MainFrame.java:386 src/jlm/core/ui/MainFrame.java:640
+#: src/plm/core/ui/MainFrame.java:386 src/plm/core/ui/MainFrame.java:640
 msgid "Stop"
 msgstr "Stop"
 
-#: src/jlm/core/ui/MainFrame.java:392 src/jlm/core/ui/MainFrame.java:641
+#: src/plm/core/ui/MainFrame.java:392 src/plm/core/ui/MainFrame.java:641
 msgid "Reset"
 msgstr "Reset"
 
-#: src/jlm/core/ui/MainFrame.java:398 src/jlm/core/ui/MainFrame.java:642
+#: src/plm/core/ui/MainFrame.java:398 src/plm/core/ui/MainFrame.java:642
 msgid "Demo"
 msgstr "Demo"
 
-#: src/jlm/core/ui/MainFrame.java:404 src/jlm/core/ui/MainFrame.java:643
-#: src/jlm/core/ui/action/HelpMe.java:37
+#: src/plm/core/ui/MainFrame.java:404 src/plm/core/ui/MainFrame.java:643
+#: src/plm/core/ui/action/HelpMe.java:37
 msgid "Call for Help"
 msgstr "Call for Help"
 
-#: src/jlm/core/ui/MainFrame.java:464
+#: src/plm/core/ui/MainFrame.java:464
 msgid "Next"
 msgstr "Next"
 
-#: src/jlm/core/ui/MainFrame.java:657
+#: src/plm/core/ui/MainFrame.java:657
 msgid "Lesson related functions"
 msgstr "Lesson related functions"
 
-#: src/jlm/core/ui/MissionEditorTabs.java:96
+#: src/plm/core/ui/MissionEditorTabs.java:91
 msgid "Mission"
 msgstr "Mission"
 
-#: src/jlm/core/ui/MissionEditorTabs.java:97
+#: src/plm/core/ui/MissionEditorTabs.java:92
 msgid "Description of the work to do"
 msgstr "Description of the work to do"
 
 #. Create the tab with the code editor as content
-#: src/jlm/core/ui/MissionEditorTabs.java:166
+#: src/plm/core/ui/MissionEditorTabs.java:161
 msgid "Type your code here"
 msgstr "Type your code here"
 
-#: src/jlm/core/ui/StatusBar.java:113
+#: src/plm/core/ui/PlmHtmlEditorKit.java:244
+#, java-format
+msgid "<img> tag without src attribute in exercise {0}"
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:113
 msgid "Saving"
 msgstr "Saving"
 
-#: src/jlm/core/ui/StatusBar.java:117
+#: src/plm/core/ui/StatusBar.java:117
 msgid "Compiling"
 msgstr "Compiling"
 
-#: src/jlm/core/ui/StatusBar.java:131
+#: src/plm/core/ui/StatusBar.java:131
 msgid "Running "
 msgstr "Running "
 
-#: src/jlm/core/ui/StatusBar.java:135
+#: src/plm/core/ui/StatusBar.java:135
 msgid "Playing demo "
 msgstr "Playing demo "
 
-#: src/jlm/core/ui/StatusBar.java:139
+#: src/plm/core/ui/StatusBar.java:139
 #, fuzzy
 msgid "Loading "
 msgstr "Loading"
 
-#: src/jlm/core/ui/action/HelpMe.java:37
+#: src/plm/core/ui/action/HelpMe.java:37
 msgid "Cancel call"
 msgstr "Cancel call"
 
-#: src/jlm/core/ui/action/PlayDemo.java:27
+#: src/plm/core/ui/action/PlayDemo.java:27
 msgid "Run the demo of what you should code for this exercise"
 msgstr "Run the demo of what you should code for this exercise"
 
-#: src/jlm/core/ui/action/PlayDemo.java:28
+#: src/plm/core/ui/action/PlayDemo.java:28
 msgid "Impossible to run the demo right now"
 msgstr "Impossible to run the demo right now"
 
-#: src/jlm/core/ui/action/QuitGame.java:28
+#: src/plm/core/ui/action/QuitGame.java:28
 msgid "Quit the application"
 msgstr "Quit the application"
 
-#: src/jlm/core/ui/action/QuitGame.java:28
+#: src/plm/core/ui/action/QuitGame.java:28
 msgid "Impossible to quit the application right now"
 msgstr "Impossible to quit the application right now"
 
-#: src/jlm/core/ui/action/Reset.java:29
+#: src/plm/core/ui/action/Reset.java:29
 msgid "Reset your world to the initial state"
 msgstr "Reset your world to the initial state"
 
-#: src/jlm/core/ui/action/Reset.java:29
+#: src/plm/core/ui/action/Reset.java:29
 msgid "World cannot be reset right now"
 msgstr "World cannot be reset right now"
 
-#: src/jlm/core/ui/action/StartExecution.java:32
+#: src/plm/core/ui/action/StartExecution.java:32
 msgid "Launch the execution of your code"
 msgstr "Launch the execution of your code"
 
-#: src/jlm/core/ui/action/StartExecution.java:33
+#: src/plm/core/ui/action/StartExecution.java:33
 msgid ""
 "Cannot launch the execution right now. Wait a bit, or interrupt current "
 "activity with the stop button"
@@ -625,537 +1115,485 @@ msgstr ""
 "Cannot launch the execution right now. Wait a bit, or interrupt current "
 "activity with the stop button"
 
-#: src/jlm/core/ui/action/StepExecution.java:22
+#: src/plm/core/ui/action/StepExecution.java:22
 msgid "Execute one step of your code"
 msgstr "Execute one step of your code"
 
-#: src/jlm/core/ui/action/StepExecution.java:23
+#: src/plm/core/ui/action/StepExecution.java:23
 msgid "Impossible to step your code now. Need to stop the execution first?"
 msgstr "Impossible to step your code now. Need to stop the execution first?"
 
-#: src/jlm/core/ui/action/StopExecution.java:22
+#: src/plm/core/ui/action/StopExecution.java:22
 msgid "Stop your code"
 msgstr "Stop your code"
 
-#: src/jlm/core/ui/action/StopExecution.java:23
+#: src/plm/core/ui/action/StopExecution.java:23
 msgid "No execution to stop right now"
 msgstr "No execution to stop right now"
 
-#: src/jlm/core/ui/action/SwitchExo.java:29
+#: src/plm/core/ui/action/SwitchExo.java:29
 msgid "Switch to another exercise"
 msgstr "Switch to another exercise"
 
-#: src/jlm/universe/Entity.java:178
+#: src/plm/core/ui/editor/MissionEditor.java:49
+msgid "PLM - Mission Editor (modified)"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:50
+msgid "PLM - Mission Editor"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:173
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:242
 #, java-format
+msgid "Error while reading {0}"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:180
+msgid "You did not save you changes. Do you want to save it before quiting?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:181
+#: src/plm/core/ui/editor/MissionEditor.java:300
+msgid "Save or loose your change?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:292
+#, fuzzy
+msgid "Open Mission..."
+msgstr "Mission"
+
+#: src/plm/core/ui/editor/MissionEditor.java:299
 msgid ""
-"The execution of your program raised an exception: {0}\n"
-" Please fix your code.\n"
+"You did not save you changes. Do you want to save it before opening another "
+"file?"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:192
+#: src/plm/core/ui/editor/MissionEditor.java:317
+#, fuzzy
+msgid "HTML files"
+msgstr "PLM lesson files"
+
+#: src/plm/core/ui/editor/MissionEditor.java:325
 #, java-format
-msgid "Failed to start an interpreter for {0}"
+msgid ""
+"You chose a translated mission text for edition ({0}).\n"
+"This is wrong. The translations should be handled with po4a in PLM.\n"
+"Please refer to https://github.com/oster/JLM/wiki/Working-with-the-"
+"translations for more information.\n"
+"\n"
+"Proceed anyway?"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:214
+#: src/plm/core/ui/editor/MissionEditor.java:329
+msgid "This is a translated mission text"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:346
+msgid "Quit Map Editor"
+msgstr ""
+
+#: src/plm/universe/Entity.java:176
 #, java-format
 msgid ""
-"No {0} script source for entity {1}. Please report that bug against JLM."
+"The execution of your program raised a {0} exception: {1}\n"
+" Please fix your code.\n"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:236
+#: src/plm/universe/Entity.java:191
 #, java-format
 msgid ""
-"Syntax error at line {0}: {1}\n"
-"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
+"No ScriptEngine for {0}. Please check your classpath and similar settings."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:244
+#: src/plm/universe/Entity.java:211
+#, java-format
 msgid ""
-"NameError raised: You seem to use a non-existent identifier; Please check "
-"for typos\n"
+"No {0} script source for entity {1}. Please report that bug against PLM."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:247
-msgid "TypeError raised: you are probably misusing a function or something.\n"
+#: src/plm/universe/Entity.java:235
+msgid "Received a ScriptException that does not come from Python.\n"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:250
+#: src/plm/universe/Entity.java:240
+#, java-format
 msgid ""
-"UnboundLocalError raised: you are probably using a global variable that is "
-"not declared as such.\n"
+"Script evaluation raised an exception that is not a ScriptException but a "
+"{0}.\n"
+" Please report this as a bug against PLM, with all details allowing to "
+"reproduce it.\n"
+"Exception message: {1}\n"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:256
-msgid "Error: there is no baggle to pickup under the buggle"
+#: src/plm/universe/bat/BatEntity.java:65
+#: src/plm/universe/bat/BatEntity.java:94
+#, java-format
+msgid "This test raised an exception: {0}"
 msgstr ""
 
-#: src/jlm/universe/Entity.java:258
-msgid "Error: a buggle cannot carry more than one baggle at the same time"
+#: src/plm/universe/bugglequest/AbstractBuggle.java:169
+#, java-format
+msgid ""
+"You tried to access a cell with Y={0}, but the maximal Y in this world is "
+"{1}."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:260
-msgid "Error: your buggle just teleported to the outer space..."
+#: src/plm/universe/bugglequest/AbstractBuggle.java:171
+#, java-format
+msgid ""
+"You tried to access a cell with X={0}, but the maximal X in this world is "
+"{1}."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:262
-msgid "Error: your buggle just hit a wall. That hurts."
+#: src/plm/universe/bugglequest/AbstractBuggle.java:190
+#: src/plm/universe/bugglequest/AbstractBuggle.java:226
+#, java-format
+msgid "You tried to set X to {0}, but the maximal X in this world is {1}."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:265
+#: src/plm/universe/bugglequest/AbstractBuggle.java:209
+#: src/plm/universe/bugglequest/AbstractBuggle.java:224
 #, java-format
-msgid ""
-"Unknown error (please report): {0}\n"
-"Its value is: {1}"
+msgid "You tried to set Y to {0}, but the maximal Y in this world is {1}."
 msgstr ""
 
-#: src/jlm/universe/Entity.java:296
-#, java-format
-msgid ""
-"Script evaluation raised an exception that is not a ScriptException but a "
-"{0}.\n"
-" Please report this as a bug against JLM, with all details allowing to "
-"reproduce it.\n"
-"Exception message: {1}"
+#: src/plm/universe/bugglequest/AbstractBuggle.java:343
+msgid "There is no baggle to pick up here."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:345
+msgid "Your are already carrying a baggle."
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:422
+#: src/plm/universe/bugglequest/AbstractBuggle.java:424
 msgid "Its value is 'null', which is never good."
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:429
+#: src/plm/universe/bugglequest/AbstractBuggle.java:431
 #, java-format
 msgid "    Its position is ({0},{1}); expected: ({2},{3}).\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:431
+#: src/plm/universe/bugglequest/AbstractBuggle.java:433
 #, java-format
 msgid "    Its direction is {0}; expected: {1}.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:433
+#: src/plm/universe/bugglequest/AbstractBuggle.java:435
 #, java-format
 msgid "    Its color is {0}; expected: {1}.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:435
+#: src/plm/universe/bugglequest/AbstractBuggle.java:437
 #, java-format
 msgid "    The color of its brush is {0}; expected: {1}.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:437
+#: src/plm/universe/bugglequest/AbstractBuggle.java:439
 msgid "    It should not carry that baggle.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:439
+#: src/plm/universe/bugglequest/AbstractBuggle.java:441
 msgid "    It is not carrying any baggle.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:441
+#: src/plm/universe/bugglequest/AbstractBuggle.java:443
 msgid "    It encountered an issue, such as bumping into a wall.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:443
+#: src/plm/universe/bugglequest/AbstractBuggle.java:445
 msgid "    It didn't encounter any issue, such as bumping into a wall.\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:127
+#: src/plm/universe/bugglequest/BuggleWorld.java:122
+#, java-format
+msgid ""
+"{0}: The path to the map on disk should not include the .map extension (or "
+"it won''t work in jarfiles). Please fix your exercise."
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:130
 #, java-format
 msgid ""
 "{0}.map: this file does not seem to be a serialized BuggleWorld (the file is "
 "empty!)"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:133
+#: src/plm/universe/bugglequest/BuggleWorld.java:136
 #, java-format
 msgid ""
 "{0}.map: This file does not seem to be a serialized BuggleWorld (malformated "
 "first line: {1})"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:139
+#: src/plm/universe/bugglequest/BuggleWorld.java:142
 #, java-format
 msgid "{0}.map: End of file reached before world size specification"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:144
+#: src/plm/universe/bugglequest/BuggleWorld.java:147
 #, java-format
 msgid "{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:170
+#: src/plm/universe/bugglequest/BuggleWorld.java:173
 #, java-format
 msgid "Cannot put a buggle on coordinate {0},{1}: that''s out of the world"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:184
+#: src/plm/universe/bugglequest/BuggleWorld.java:187
 #, java-format
 msgid "Invalid buggle''s direction: {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:191
-#: src/jlm/universe/bugglequest/BuggleWorld.java:198
+#: src/plm/universe/bugglequest/BuggleWorld.java:194
+#: src/plm/universe/bugglequest/BuggleWorld.java:201
 #, java-format
 msgid "Invalid buggle''s color name: {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:210
+#: src/plm/universe/bugglequest/BuggleWorld.java:213
 #, java-format
 msgid "Cannot define a cell on coordinate {0},{1}: that''s out of the world"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:223
+#: src/plm/universe/bugglequest/BuggleWorld.java:226
 #, java-format
 msgid "Invalid color name: {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:229
+#: src/plm/universe/bugglequest/BuggleWorld.java:232
 #, java-format
 msgid "Expecting ''baggle'' or ''nobaggle'' but got {0} instead"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:233
+#: src/plm/universe/bugglequest/BuggleWorld.java:236
 #, java-format
 msgid "Expecting ''topwall'' or ''notopwall'' but got {0} instead"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:237
+#: src/plm/universe/bugglequest/BuggleWorld.java:240
 #, java-format
 msgid "Expecting ''leftwall'' or ''noleftwall'' but got {0} instead"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:247
+#: src/plm/universe/bugglequest/BuggleWorld.java:250
 #, java-format
 msgid ""
 "The cell {0},{1} seem to be defined more than once. At least, there is two "
 "baggles here, which is not allowed."
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:263
+#: src/plm/universe/bugglequest/BuggleWorld.java:266
 #, java-format
 msgid ""
 "Parse error. I was expecting a cell or a buggle description but got: {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:481
+#: src/plm/universe/bugglequest/BuggleWorld.java:543
 #, java-format
 msgid "  The world''s name is {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:485
+#: src/plm/universe/bugglequest/BuggleWorld.java:547
 #, java-format
 msgid "  In ({0},{1})"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:488
+#: src/plm/universe/bugglequest/BuggleWorld.java:550
 #, java-format
 msgid "  Something is wrong about buggle ''{0}'':\n"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:230
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:129
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:136
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:143
+msgid "There is already a baggle here."
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:231
 msgid ", there shouldn't be this baggle"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:232
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:233
 msgid ", there should be a baggle"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:234
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:235
 msgid ", the baggle differs"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:237
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:238
 #, java-format
 msgid ", the ground should not be {0}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:239
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:240
 #, java-format
 msgid ", the ground is expected to be {0}, but it is {1}"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:241
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:242
 #, java-format
 msgid ", the ground reads ''{0}'' (expected: ''{1}'')"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:244
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:245
 msgid ", there shouldn't be any wall at west"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:246
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:247
 msgid ", there should be a wall at west"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:249
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:250
 msgid ", there shouldn't be any wall at north"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:251
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:252
 msgid ", there should be a wall at north"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:176
+#: src/plm/universe/bugglequest/exception/BuggleWallException.java:10
+msgid "Buggles cannot traverse walls"
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:176
 msgid "Create New Map"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:228
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:228
 msgid "Open Map..."
 msgstr ""
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:234
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:234
 #, fuzzy
-msgid "JLM map files"
-msgstr "JLM lesson files"
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:242
-#, java-format
-msgid "Error while reading {0}"
-msgstr ""
+msgid "PLM map files"
+msgstr "PLM lesson files"
 
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
 msgid "Property"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
 msgid "Value"
 msgstr ""
 
 #. The editor for the name
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
 #, fuzzy
 msgid "World name"
 msgstr "World"
 
 #. ---------- world width ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
 #, fuzzy
 msgid "World width"
 msgstr "World"
 
 #. ---------- world height ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
 msgid "World height"
 msgstr ""
 
 #. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
 msgid "Selected cell X"
 msgstr ""
 
 #. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
 msgid "Selected cell Y"
 msgstr ""
 
 #. ---------- Ground color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
 msgid "Ground color (name or r/g/b)"
 msgstr ""
 
 #. ---------- top wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
 msgid "Top wall?"
 msgstr ""
 
 #. ---------- left wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
 msgid "Left wall?"
 msgstr ""
 
 #. ---------- have baggle ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
 msgid "Baggle?"
 msgstr ""
 
 #. ---------- Buggle name ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
 msgid "Buggle name"
 msgstr ""
 
 #. ---------- Buggle direction ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
 msgid "Buggle direction (N|S|E|W)"
 msgstr ""
 
 #. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
 msgid "Buggle color (name or r/g/b)"
 msgstr ""
 
 #. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
 msgid "Brush color (name or r/g/b)"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:55
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:232
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:55
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:232
 msgid "forward"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:69
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:231
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:69
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:231
 msgid "backward"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:83
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:233
-msgid "turn left"
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:83
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:233
+msgid "left"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:91
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:234
-msgid "turn right"
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:91
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:234
+msgid "right"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:99
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:235
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:99
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:235
 msgid "mark"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:222
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:222
 msgid "Wall hugging error"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:223
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:223
 msgid "Your buggle has collided with a wall, it hurts a lot ! ='("
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:236
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:236
 msgid "Brush Color"
 msgstr ""
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:237
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:237
 msgid "Buggle Color"
 msgstr ""
 
-#: src/jlm/universe/sort/SortingButtonPanel.java:63
+#: src/plm/universe/sort/SortingButtonPanel.java:63
 msgid "go"
 msgstr "go"
 
-#: src/jlm/universe/sort/SortingWorldView.java:51
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
-msgid "Switch to time view"
-msgstr "Switch to time view"
-
-#: src/jlm/universe/sort/SortingWorldView.java:53
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
-msgid "Switch to state view"
-msgstr "Switch to state view"
-
-#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
-msgid "Invalid move"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
-#, java-format
-msgid ""
-"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
-#, java-format
-msgid "Cannot move from slot {0} to itself"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
-#, java-format
-msgid "No disc to move from slot {0}"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
-#, java-format
-msgid ""
-"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
-"but {2} > {3}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
-#, java-format
-msgid ""
-"The player {0} of the base {1} cannot reach the hole that is too far from "
-"its position"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
-msgid "This is not a baseball world :-("
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
-#, java-format
-msgid "Differing amount of bases: {0} vs {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
-#, java-format
-msgid "Differing amount of players: {0} vs {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
-#, java-format
-msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:351
-#, java-format
-msgid ""
-"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
-"information:\n"
-"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:388
-#, java-format
-msgid "Cannot move from base {0} since it''s not between 0 and {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:391
-#, java-format
-msgid "Cannot move from position {0} since it''s not between 0 and {1})"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:400
-#, java-format
-msgid ""
-"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
-"it in one move"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
-msgid "This is not a world of pancakes :-("
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
-msgid "The two worlds are of differing size"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:193
-#, java-format
-msgid "Asked to flip {0} pancakes, but you must flip at least one"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:195
-#, java-format
-msgid ""
-"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:229
-#, java-format
-msgid ""
-"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:248
-#, java-format
-msgid ""
-"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
-"{1}"
-msgstr ""
-
 #~ msgid "Do you really want to quit ?"
 #~ msgstr "Do you really want to quit ?"
 
-#~ msgid "Exit the JLM"
-#~ msgstr "Exit the JLM"
+#~ msgid "Exit the PLM"
+#~ msgstr "Exit the PLM"
diff --git a/lib/l10n-engine/fr.po b/lib/l10n-engine/fr.po
index 795dafd..67ea007 100644
--- a/lib/l10n-engine/fr.po
+++ b/lib/l10n-engine/fr.po
@@ -1,62 +1,484 @@
-# French translation of the JLM engine
+# French translation of the PLM engine
 # Copyright (C) 2013 Martin Quinson
-# This file is distributed under the same license as the JLM itself
+# This file is distributed under the same license as the PLM itself
 # Martin Quinson <martin.quinson at loria.fr>, 2013
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: JLM\n"
+"Project-Id-Version: PLM\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-08-04 21:21+0200\n"
-"PO-Revision-Date: 2013-08-04 16:34+0200\n"
-"Last-Translator: Frank STENGEL <fstengel at mac.com>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"Language: \n"
+"POT-Creation-Date: 2013-08-30 14:51+0200\n"
+"PO-Revision-Date: 2013-08-30 14:54+0200\n"
+"Last-Translator: Martin Quinson <martin.quinson at loria.fr> and Frank STENGEL "
+"<fstengel at mac.com>\n"
+"Language-Team: not really\n"
+"Language: French\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "X-Generator: Poedit 1.5.5\n"
 
-#: src/jlm/core/model/Game.java:146
+#: src/lessons/maze/island/IslandMazeEntity.java:10
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:10
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:9
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:12
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:12
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:12
+#: src/lessons/welcome/array/basics/Array1Entity.java:11
+#: src/lessons/welcome/array/basics/Array2Entity.java:12
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser setX() dans "
+"cet exercice."
+
+#: src/lessons/maze/island/IslandMazeEntity.java:15
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:15
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:14
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:17
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:17
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:17
+#: src/lessons/welcome/array/basics/Array1Entity.java:16
+#: src/lessons/welcome/array/basics/Array2Entity.java:17
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser setY() dans "
+"cet exercice."
+
+#: src/lessons/maze/island/IslandMazeEntity.java:20
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:20
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:19
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:22
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:22
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:22
+#: src/lessons/welcome/array/basics/Array1Entity.java:21
+#: src/lessons/welcome/array/basics/Array2Entity.java:22
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser setPos() "
+"dans cet exercice."
+
+#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
+msgid "Invalid move"
+msgstr "Déplacement invalide"
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
+#, java-format
+msgid ""
+"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
+msgstr ""
+"Impossible de bouger du piquet {0} au piquet {1} car les seuls piquets "
+"existants sont 0, 1 et 2."
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
+#, java-format
+msgid "Cannot move from slot {0} to itself"
+msgstr "Impossible de bouger du piquet {0} à lui-même"
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
+#, java-format
+msgid "No disc to move from slot {0}"
+msgstr "Il n''y a pas de disque à déplacer sur le piquet {0}"
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
+#, java-format
+msgid ""
+"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
+"but {2} > {3}"
+msgstr ""
+"Impossible de déplacer un disque du piquet {0} au piquet {1} car les petits "
+"disques doivent rester au dessus des gros mais {2} > {3}."
+
+#. Create the button
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
+#: src/plm/core/ui/ChooseLessonDialog.java:180
+msgid "Go"
+msgstr "Aller"
+
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
+#, java-format
+msgid ""
+"The player {0} of the base {1} cannot reach the hole that is too far from "
+"its position"
+msgstr ""
+"Le joueur {0} de la base {1} ne atteindre le trou, qui se trouve trop loin "
+"de sa position"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
+msgid "This is not a baseball world :-("
+msgstr "Ce n'est pas un monde de baseball :-("
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
+#, java-format
+msgid "Differing amount of bases: {0} vs {1}"
+msgstr "Nombres de bases différents : {0} vs {1}"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
+#, java-format
+msgid "Differing amount of players: {0} vs {1}"
+msgstr "Nombres de joueurs différents : {0} vs {1}"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
+#, java-format
+msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
+msgstr "Le joueur à la base {0}, position {1} diffère : {2} vs {3}\n"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:371
+#, java-format
+msgid ""
+"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
+"information:\n"
+"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
+msgstr ""
+"Ce n''est toujours pas trié !! MERCI DE RAPPORTER CE PROBLÈME, avec les "
+"informations suivantes:\n"
+"Exercice: {0}; Nombre de bases:: {1}; Situation initiale: {2}"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:408
+#, java-format
+msgid "Cannot move from base {0} since it''s not between 0 and {1}"
+msgstr "Impossible de bouger de la base {0} car ce n''est pas entre 0 et {1}"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:411
+#, java-format
+msgid "Cannot move from position {0} since it''s not between 0 and {1})"
+msgstr ""
+"Impossible de bouger de la position {0} car ce n''est pas entre 0 et {1}"
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:420
+#, java-format
+msgid ""
+"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
+"it in one move"
+msgstr ""
+"Le joueur {0} de la base {1} ne atteindre le trou, qui se trouve à la base "
+"{2}, trop loin de sa position"
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
+#: src/plm/universe/sort/SortingWorldView.java:51
+msgid "Switch to time view"
+msgstr "Accéder à la vue temporelle"
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
+#: src/plm/universe/sort/SortingWorldView.java:53
+msgid "Switch to state view"
+msgstr "Accéder à la vue d'état"
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
+msgid "This is not a world of pancakes :-("
+msgstr "Ce n'est pas un monde de crêpes :-("
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
+msgid "The two worlds are of differing size"
+msgstr "Les deux mondes ne sont pas de la même taille"
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:202
+#, java-format
+msgid "Asked to flip {0} pancakes, but you must flip at least one"
+msgstr ""
+"Vous avez demandé de retourner {0} crêpes, mais il faut en retourner au "
+"moins une."
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:204
+#, java-format
+msgid ""
+"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
+msgstr ""
+"Vous avez demandé de retourner {0} crêpes, mais il n''y a que {1} crêpes sur "
+"la pile."
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:238
+#, java-format
+msgid ""
+"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
+msgstr ""
+"Impossible d''obtenir la taille de la crêpe numéro {0} car ce n''est pas "
+"entre 0 et {1}"
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:257
+#, java-format
+msgid ""
+"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
+"{1}"
+msgstr ""
+"Impossible d''obtenir l''orientation de la crêpe numéro {0} car ce n''est "
+"pas entre 0 et {1}"
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:10
+#: src/lessons/welcome/loopfor/LoopForEntity.java:8
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:10
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:9
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:9
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:9
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:10
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:9
+#: src/lessons/welcome/variables/RunFourEntity.java:8
+#: src/lessons/welcome/variables/RunHalfEntity.java:10
+#: src/lessons/welcome/variables/VariablesEntity.java:8
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward with an argument in "
+"this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser avance() "
+"avec un argument dans cet exercice."
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:14
+#: src/lessons/welcome/loopfor/LoopForEntity.java:13
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:14
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:14
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:14
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:14
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:14
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:14
+#: src/lessons/welcome/variables/RunFourEntity.java:12
+#: src/lessons/welcome/variables/RunHalfEntity.java:14
+#: src/lessons/welcome/variables/VariablesEntity.java:13
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward with an argument in "
+"this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser recule() "
+"avec un argument dans cet exercice."
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+msgid "You fall into water."
+msgstr "Vous êtes tombé dans l'eau."
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+#: src/plm/universe/bugglequest/SimpleBuggle.java:29
+#: src/plm/universe/bugglequest/SimpleBuggle.java:40
+#: src/plm/universe/bugglequest/SimpleBuggle.java:51
+#: src/plm/universe/bugglequest/SimpleBuggle.java:62
+#: src/plm/universe/bugglequest/SimpleBuggle.java:78
+#: src/plm/universe/bugglequest/SimpleBuggle.java:82
+#: src/plm/universe/bugglequest/SimpleBuggle.java:93
+#: src/plm/universe/bugglequest/SimpleBuggle.java:103
+#: src/plm/universe/bugglequest/SimpleBuggle.java:113
+#: src/plm/universe/bugglequest/SimpleBuggle.java:123
+msgid "Test failed"
+msgstr "Test raté"
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:10
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:66
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:71
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:67
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:71
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser droite() "
+"dans cet exercice."
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:26
+#, java-format
+msgid ""
+"I''m sorry Dave, I''m affraid I cant let you use left() both in lines {0} "
+"and {1} in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser gauche() à "
+"la fois aux lignes {0} et {1} dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:45
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:46
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:51
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:50
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:55
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser avance() "
+"dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:54
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:58
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:59
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:63
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:63
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser recule() "
+"dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:62
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:67
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:63
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:67
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser gauche() "
+"dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:70
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:75
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:71
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:75
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser retourne() "
+"dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:74
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:79
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:75
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:79
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this "
+"exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser "
+"estFaceMur() dans cet exercice."
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:78
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:83
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:79
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:83
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this "
+"exercise."
+msgstr ""
+"Je suis désolé Dave, je ne crois pas pouvoir te laisser utiliser estDosMur() "
+"dans cet exercice."
+
+#.
+#. * FIXME: provide a way to debug
+#. * when templates are broken
+#.
+#. for (String n:classes.keySet())
+#. System.out.println("File "+n+":\n"+classes.get(n));
+#: src/plm/core/CompilerJava.java:289
+msgid "Compilation failed."
+msgstr "La compilation a échoué."
+
+#: src/plm/core/PythonExceptionDecipher.java:24
+#, java-format
+msgid ""
+"Syntax error at line {0}: {1}\n"
+"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
+msgstr ""
+"Erreur de syntaxe à la ligne {0} : {1}\n"
+"En cas de doute, vérifiez les indentations, et veillez à ne pas mélanger "
+"espaces et tabulations.\n"
+
+#: src/plm/core/PythonExceptionDecipher.java:32
+msgid ""
+"NameError raised: You seem to use a non-existent identifier; Please check "
+"for typos\n"
+msgstr ""
+"Erreur de nom : vous semblez utiliser un identifiant qui n'existe pas. "
+"Auriez-vous fait une typo ?\n"
+
+#: src/plm/core/PythonExceptionDecipher.java:35
+msgid "TypeError raised: you are probably misusing a function or something.\n"
+msgstr ""
+"Erreur de type : vous n'utilisez pas correctement une fonction, ou quelque "
+"chose du genre.\n"
+
+#: src/plm/core/PythonExceptionDecipher.java:38
+msgid ""
+"UnboundLocalError raised: you are probably using a global variable that is "
+"not declared as such.\n"
+msgstr ""
+"Erreur UnboundLocal : vous utilisez probablement une variable qui n'est pas "
+"déclarée, ou quelque chose du genre.\n"
+
+#: src/plm/core/PythonExceptionDecipher.java:44
+msgid "Error: there is no baggle to pickup under the buggle"
+msgstr "Erreur : Il n'y a pas de biscuit à ramasser ici."
+
+#: src/plm/core/PythonExceptionDecipher.java:46
+msgid "Error: a buggle cannot carry more than one baggle at the same time"
+msgstr "Erreur : une buggle ne peut porter qu'un biscuit à la fois."
+
+#: src/plm/core/PythonExceptionDecipher.java:48
+msgid "Error: your buggle just teleported to the outer space..."
+msgstr "Erreur : Votre buggle s'est téléportée dans l'espace."
+
+#: src/plm/core/PythonExceptionDecipher.java:50
+msgid "Error: your buggle just hit a wall. That hurts."
+msgstr "Erreur : Vous avez heurté un mur. Ça fait mal."
+
+#: src/plm/core/PythonExceptionDecipher.java:53
+#, java-format
+msgid ""
+"Unknown error (please report): {0}\n"
+"Its value is: {1}"
+msgstr ""
+"Erreur inconnue (veuillez faire un rapport de bug) : {0}\\n\n"
+"Sa valeur est : {1}"
+
+#: src/plm/core/model/Game.java:151
+msgid "Scala is usable on your machine. Congratulations."
+msgstr "Scala est utilisable sur votre machine. Félicitations."
+
+#: src/plm/core/model/Game.java:153
+msgid "Please install Scala version 2.10 or higher to use it in PLM."
+msgstr ""
+"Veuillez installer Scala version 2.10 ou supérieure pour l'utiliser dans la "
+"PLM."
+
+#: src/plm/core/model/Game.java:155
+msgid "Jython is usable on your machine. Congratulations."
+msgstr "Jython est utilisable sur votre machine. Félicitations."
+
+#: src/plm/core/model/Game.java:157
+msgid "Please install jython to use the python programming language in PLM."
+msgstr ""
+"Veuillez installer jython afin d'utiliser le langage python dans la PLM."
+
+#: src/plm/core/model/Game.java:163
 #, java-format
 msgid ""
 "Warning, the default programming language is neither ''Java'' nor ''python'' "
-"but {0}.\n"
+"or ''Scala'' but {0}.\n"
 "   This language will be used to setup the worlds, possibly leading to "
 "severe issues for the exercises that don''t expect it.\n"
-"   It is safer to change the current language, and restart JLM before "
+"   It is safer to change the current language, and restart PLM before "
 "proceeding.\n"
 "   Alternatively, the property {1} can be changed in your configuration file "
-"($HOME/.jlm/jlm.properties"
+"($HOME/.plm/plm.properties)"
 msgstr ""
 "Attention, le langage de programmation par défaut n''est ni «Java» ni "
-"«python», mais {0}.\n"
+"«python» ni «scala», mais {0}.\n"
 "  Ce langage sera utilisé pour configurer les mondes, ce qui risque de "
 "causer de gros problèmes pour les exercices qui ne sont pas conçus à cet "
 "effet.\n"
-"  Il est plus sûr de changer le langage par défaut puis de redémarrer JLM.\n"
+"  Il est plus sûr de changer le langage par défaut puis de redémarrer PLM.\n"
 "  Vous pouvez également changer la propriété {1} de votre fichier de "
-"configuration ($HOME/.jlm/jlm.properties) pour cela."
+"configuration ($HOME/.plm/plm.properties) pour cela."
 
-#: src/jlm/core/model/Game.java:160
-#, java-format
+#: src/plm/core/model/Game.java:169
 msgid ""
-"Your progress will be posted to http://identi.ca/jlmlovers This can be "
-"turned off through the property {0}"
+"The default programming language is Scala, but your scala installation is "
+"not usable. Switching to Java instead.\n"
 msgstr ""
-"Vos progrès seront postés sur http://identi.ca/jlmlovers Cela peut être "
-"désactivé par la propriété {0}."
+"Vous utilisez Scala par défaut, mais votre installation de Scala est cassée. "
+"Utilisation de Java à la place.\n"
 
-#: src/jlm/core/model/Game.java:163
-#, java-format
+#: src/plm/core/model/Game.java:172
 msgid ""
-"Your progress will NOT be posted to identica, as requested by the property "
-"{0}"
+"The default programming language is python, but your python installation is "
+"not usable. Switching to Java instead.\n"
 msgstr ""
-"Vos progrès ne seront PAS postés sur identica, comme demandé par la "
-"propriété {0}."
+"Vous utilisez python par défaut, mais votre installation de python est "
+"cassée. Utilisation de Java à la place.\n"
 
-#: src/jlm/core/model/Game.java:166
+#: src/plm/core/model/Game.java:185
 #, java-format
 msgid ""
 "Your progress will be posted to https://twitter.com/jlmlovers This can be "
@@ -65,7 +487,7 @@ msgstr ""
 "Vos progrès seront postés sur http://twitter.com/jlmlovers Cela peut être "
 "désactivé par la propriété {0}."
 
-#: src/jlm/core/model/Game.java:169
+#: src/plm/core/model/Game.java:188
 #, java-format
 msgid ""
 "Your progress will NOT be posted to twitter, as requested by the property {0}"
@@ -73,56 +495,128 @@ msgstr ""
 "Vos progrès ne seront PAS postés sur twitter, comme demandé par la propriété "
 "{0}."
 
-#: src/jlm/core/model/Game.java:217 src/jlm/core/model/Game.java:218
+#: src/plm/core/model/Game.java:217
+#, java-format
+msgid "Error {0} while retrieving the Scala version: {1}"
+msgstr "Erreur {0} lors de l''obtention du numéro de version de Scala: {1}"
+
+#: src/plm/core/model/Game.java:226
+#, java-format
+msgid "Scala is too ancient. Found {0} while I need 2.10 or higher."
+msgstr ""
+"Scala est trop vieux. PLM nécessite la version 2.10 ou supérieure, mais la "
+"version trouvée est : {0}"
+
+#: src/plm/core/model/Game.java:251
+msgid ""
+"Cannot retrieve the python ScriptEngine. Are jython.jar and its dependencies "
+"in the classpath?"
+msgstr ""
+"Impossible de démarrer un engin de script pour python. Est ce que jython.jar "
+"et ses dépendences sont dans le classpath?"
+
+#: src/plm/core/model/Game.java:274
+#, java-format
+msgid ""
+"Resource {0} not found in the classpath.\n"
+"Is {1} in your classpath?"
+msgstr ""
+"La ressource {0} est introuvable dans le classpath.\n"
+"Vous devriez peut-être ajouter {1} à votre classpath pour y remédier."
+
+#: src/plm/core/model/Game.java:276
+#, java-format
+msgid "{0} received while searching for resource {1}: {2}"
+msgstr "{0} reçue lors de la recherche de la ressource {1}: {2}"
+
+#: src/plm/core/model/Game.java:320 src/plm/core/model/Game.java:321
 #, java-format
 msgid "Cannot switch to lesson {0}: class Main not found."
 msgstr "Impossible de passer à la leçon {0} : la classe Main est introuvable."
 
-#: src/jlm/core/model/Game.java:219
+#: src/plm/core/model/Game.java:322
 #, java-format
 msgid "Load lesson {0}"
 msgstr "Chargement de la leçon {0}"
 
-#: src/jlm/core/model/Game.java:325 src/jlm/core/model/Game.java:357
+#: src/plm/core/model/Game.java:428 src/plm/core/model/Game.java:462
 msgid "Operation cancelled by the user"
 msgstr "Opération annulée par l'utilisateur"
 
-#: src/jlm/core/model/Game.java:397
+#: src/plm/core/model/Game.java:453
+#, java-format
+msgid ""
+"Exercise {0} does not support language {1}. Fallback to {2} instead. Please "
+"consider contributing to this project by adapting this exercise to this "
+"language."
+msgstr ""
+"L''exercice {0} ne permet pas d''utiliser le langage {1}. Utilisation du {2} "
+"à la place.\n"
+"Vous pourriez contribuer au projet en ajoutant votre langage à cet exercice."
+
+#: src/plm/core/model/Game.java:502
 #, java-format
 msgid "The lecture {0} has no world that I can select"
 msgstr "La lecture {0} n'a aucun monde que je puisse sélectionner."
 
-#: src/jlm/core/model/Game.java:920
+#: src/plm/core/model/Game.java:906
+msgid ""
+"Please install Scala version 2.10 or higher to use it in PLM.\n"
+"\n"
+msgstr ""
+"Veuillez installer Scala version 2.10 ou supérieure pour l'utiliser dans "
+"PLM.\n"
+"\n"
+
+#: src/plm/core/model/Game.java:907
+msgid "Scala is missing"
+msgstr "Scala est manquant"
+
+#: src/plm/core/model/Game.java:911
+msgid ""
+"Please install jython and its dependencies to use the python programming "
+"language in PLM.\n"
+"\n"
+msgstr ""
+"Veuillez installer jython et ses dépendences pour utiliser la PLM en "
+"python.\n"
+"\n"
+
+#: src/plm/core/model/Game.java:912
+msgid "Python is missing"
+msgstr "Python est manquant"
+
+#: src/plm/core/model/Game.java:1058
 #, java-format
 msgid "{0} is not writable"
 msgstr "{0} n'est pas accessible en écriture."
 
-#: src/jlm/core/model/Game.java:924
+#: src/plm/core/model/Game.java:1062
 #, java-format
 msgid "{0} is not a directory"
 msgstr "{0} n'est pas un répertoire."
 
-#: src/jlm/core/model/Game.java:931
+#: src/plm/core/model/Game.java:1069
 #, java-format
 msgid "Cannot create {0}"
 msgstr "Impossible de créer {0}"
 
-#: src/jlm/core/model/Game.java:937
+#: src/plm/core/model/Game.java:1075
 #, java-format
-msgid "Impossible to find a path for JLM datas. Tested {0}"
+msgid "Impossible to find a path for PLM data. Tested {0}"
 msgstr ""
-"Impossible de trouver un emplacement pour sauvegarder les données de JLM. "
+"Impossible de trouver un emplacement pour sauvegarder les données de PLM. "
 "Emplacements testés: {0}"
 
-#: src/jlm/core/model/HelpServer.java:27
+#: src/plm/core/model/HelpServer.java:27
 msgid "Asking to the teacher for help"
 msgstr "Demander de l'aide à l'enseignant"
 
-#: src/jlm/core/model/HelpServer.java:29
+#: src/plm/core/model/HelpServer.java:29
 msgid "Cancel call for help to the teacher"
 msgstr "Annuler la demande d'aide"
 
-#: src/jlm/core/model/LessonRunner.java:90
+#: src/plm/core/model/LessonRunner.java:91
 #, java-format
 msgid ""
 "Congratulations, you passed this exercise.\n"
@@ -131,18 +625,18 @@ msgstr ""
 "Félicitation, vous avez réussi cet exercice.\n"
 "{0} tests passés."
 
-#: src/jlm/core/model/LessonRunner.java:92
-#: src/jlm/core/model/LessonRunner.java:98
-#: src/jlm/core/model/LessonRunner.java:107
-#: src/jlm/core/model/LessonRunner.java:113
+#: src/plm/core/model/LessonRunner.java:93
+#: src/plm/core/model/LessonRunner.java:99
+#: src/plm/core/model/LessonRunner.java:108
+#: src/plm/core/model/LessonRunner.java:114
 msgid "Exercice passed \\o/"
 msgstr "Exercice réussi \\o/"
 
-#: src/jlm/core/model/LessonRunner.java:96
+#: src/plm/core/model/LessonRunner.java:97
 msgid "Congratulations, you passed this exercise."
 msgstr "Félicitation, vous avez réussi cet exercice."
 
-#: src/jlm/core/model/LessonRunner.java:106
+#: src/plm/core/model/LessonRunner.java:107
 #, java-format
 msgid ""
 "Congratulations, you passed this exercise.\n"
@@ -153,7 +647,7 @@ msgstr ""
 "({0} tests passés)\n"
 "Par quel exercice voulez vous continuer ?"
 
-#: src/jlm/core/model/LessonRunner.java:112
+#: src/plm/core/model/LessonRunner.java:113
 msgid ""
 "Congratulations, you passed this exercise.\n"
 "Which exercise will you do now?"
@@ -161,24 +655,38 @@ msgstr ""
 "Félicitation, vous avez réussi cet exercice.\n"
 "Par quel exercice voulez vous continuer ?"
 
-#: src/jlm/core/model/lesson/Exercise.java:77
+#: src/plm/core/model/lesson/Exercise.java:87
 #, java-format
 msgid "The world ''{0}'' differs"
 msgstr "Le monde ''{0}'' diffère"
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:41
+#: src/plm/core/model/lesson/Exercise.java:149
+#: src/plm/core/model/lesson/Exercise.java:175
+msgid "Compilation error:"
+msgstr "Erreur de compilation :"
+
+#: src/plm/core/model/lesson/Exercise.java:296
+#, java-format
+msgid ""
+"Cannot compute the answer from file {0}.{1} since I cannot read it (error "
+"was: {2})."
+msgstr ""
+"Impossible de calculer la réponse à partir du fichier {0}.{1} car il est "
+"illisible (erreur : {2})."
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:43
 #, java-format
 msgid "Source file {0}.{1} not found."
 msgstr "Le fichier source {0}.{1} est introuvable."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:88
+#: src/plm/core/model/lesson/ExerciseTemplated.java:104
 #, java-format
 msgid "{0}: BEGIN TEMPLATE within the template. Please fix your entity."
 msgstr ""
 "{0}: BEGIN TEMPLATE à l'intérieur de la template. Veuillez corriger votre "
 "entité."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:108
+#: src/plm/core/model/lesson/ExerciseTemplated.java:125
 #, java-format
 msgid ""
 "{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity."
@@ -186,7 +694,8 @@ msgstr ""
 "{0}: BEGIN SOLUTION est clos par END TEMPLATE. Veuillez corriger votre "
 "entité."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:122
+#: src/plm/core/model/lesson/ExerciseTemplated.java:143
+#: src/plm/core/model/lesson/ExerciseTemplated.java:167
 #, java-format
 msgid ""
 "{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity."
@@ -194,13 +703,13 @@ msgstr ""
 "{0}: END TEMPLATE sans BEGIN TEMPLATE correspondant. Veuillez corriger votre "
 "entité."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:126
+#: src/plm/core/model/lesson/ExerciseTemplated.java:147
 #, java-format
 msgid "{0}: Begin solution in template tail. Change it to BEGIN HIDDEN"
 msgstr ""
 "{0}: BEGIN SOLUTION après la fin du template. Changez le en BEGIN HIDDEN."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:153
+#: src/plm/core/model/lesson/ExerciseTemplated.java:187
 #, java-format
 msgid ""
 "Parser error in file {0}. This is a parser bug (state={1}), please report."
@@ -208,7 +717,7 @@ msgstr ""
 "Error d''analyse à la lecture du fichier {0}. C''est un bug de l''analyseur "
 "(état={1}), merci de faire un rapport."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:158
+#: src/plm/core/model/lesson/ExerciseTemplated.java:192
 #, java-format
 msgid ""
 "{0}: End of file unexpected after the solution but within the template. "
@@ -217,7 +726,7 @@ msgstr ""
 "{0}: Fin de fichier inattendue après la solution mais avant la fin du "
 "template. Veuillez corriger votre entité."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:160
+#: src/plm/core/model/lesson/ExerciseTemplated.java:194
 #, java-format
 msgid ""
 "{0}: End of file unexpected (state: {1}). Did you forget to close your "
@@ -227,12 +736,26 @@ msgstr ""
 "vous oublié de fermer votre template ou votre solution ? Veuillez corriger "
 "votre entité."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:311
+#: src/plm/core/model/lesson/ExerciseTemplated.java:350
+#, java-format
+msgid ""
+"Exercise {0} is said to be compatible with language {1}, but there is no "
+"entity for this language: {2}"
+msgstr ""
+"L''exercice {0} dit permettre l''usage du langage {1}, mais il n''y a pas "
+"d''entité pour ce langage : {2}"
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:359
+#, java-format
+msgid "{0}: No entity found. You should fix your paths and such"
+msgstr "{0}: aucune entité trouvée. Vous devriez corriger vos réglages."
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:381
 #, java-format
 msgid "World {0} is broken ({1}). Recompute all answer worlds."
 msgstr "Le monde {0} est cassé ({1}). Recalcul de tous les mondes solutions."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:315
+#: src/plm/core/model/lesson/ExerciseTemplated.java:385
 #, java-format
 msgid ""
 "IO exception while reading world {0} ({1}). Recompute all answer worlds."
@@ -240,7 +763,7 @@ msgstr ""
 "Exception d''entrée/sortie lors de la lecture du monde {0} ({1}). Recalcul "
 "de tous les mondes solutions."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:326
+#: src/plm/core/model/lesson/ExerciseTemplated.java:396
 #, java-format
 msgid ""
 "Recompute the answer of {0} despite the cache file, as requested by the "
@@ -249,95 +772,228 @@ msgstr ""
 "Recalcul de la solution de {0} malgré le fichier de cache, comme demandé par "
 "la propriété {1}."
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:349
+#: src/plm/core/model/lesson/ExerciseTemplated.java:421
 #, java-format
 msgid "Error while writing answer world of {0}:"
 msgstr "Erreur lors de l''écriture du monde de correction de {0} :"
 
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:353
+#: src/plm/core/model/lesson/ExerciseTemplated.java:425
 #, java-format
 msgid "Cannot write answer world of {0}. Please check the permissions."
 msgstr ""
 "Impossible d''écrire le monde de correction de {0}. Veuillez vérifier les "
 "permissions."
 
-#: src/jlm/core/model/lesson/Lecture.java:88
-#: src/jlm/core/model/lesson/Lesson.java:84
+#: src/plm/core/model/lesson/Lecture.java:90
+#: src/plm/core/model/lesson/Lesson.java:84
 #, java-format
 msgid "File {0}.html not found."
 msgstr "Le fichier {0}.html est introuvable."
 
-#: src/jlm/core/model/lesson/Lecture.java:97
-#: src/jlm/core/model/lesson/Lesson.java:94
+#: src/plm/core/model/lesson/Lecture.java:99
+#: src/plm/core/model/lesson/Lesson.java:94
 #, java-format
 msgid "Cannot find the name of mission in {0}.html"
 msgstr "Impossible de trouver le nom de la mission dans {0}.html"
 
-#: src/jlm/core/ui/AboutJLMDialog.java:34
-msgid "About JLM dialogTitle"
-msgstr "À propos de JLM"
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Ok, quit and lose my data"
+msgstr "D'accord. Quitter et perdre mes données."
 
-#: src/jlm/core/ui/AboutJLMDialog.java:71
-#: src/jlm/core/ui/ExerciseFailedDialog.java:48
-msgid "Close"
-msgstr "Fermer"
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Please stop! I'll save it myself first"
+msgstr "STOP! je vais d'abord sauvegarder mes données moi-même"
+
+#: src/plm/core/model/session/ZipSessionKit.java:253
+#, java-format
+msgid ""
+"PLM were unable to save your session file for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed so far)?"
+msgstr ""
+"PLM n''a pas pu sauvegarder votre session pour la leçon {0} ({1}:{2}).\n"
+"\n"
+"Voulez-vous continuer malgré tout ? Tout votre travail sera perdu."
+
+#: src/plm/core/model/session/ZipSessionKit.java:256
+msgid "Your changes are NOT saved"
+msgstr "Vos changements n'ont PAS été sauvés."
+
+#: src/plm/core/model/session/ZipSessionKit.java:259
+msgid "User aborted saving on system error"
+msgstr "L'utilisateur a annulé la sauvegarde suite à une erreur système."
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Proceed"
+msgstr "Continuer"
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Abort"
+msgstr "Annuler"
+
+#: src/plm/core/model/session/ZipSessionKit.java:357
+#, java-format
+msgid ""
+"PLM were unable to load your code for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed previously)?"
+msgstr ""
+"PLM n''a pu charger votre session pour la leçon {0} ({1}:{2}).\n"
+"\n"
+"Voulez vous continuer malgré tout (et perdre ce que vous aviez tapé "
+"précédemment) ?"
+
+#: src/plm/core/model/session/ZipSessionKit.java:360
+msgid "Error while loading your session"
+msgstr "Erreur lors du chargement de votre session"
+
+#: src/plm/core/model/session/ZipSessionKit.java:363
+msgid "Abording on user request"
+msgstr "Abandon, comme demandé par l'utilisateur"
 
-#: src/jlm/core/ui/AboutLessonDialog.java:24
+#: src/plm/core/ui/AboutLessonDialog.java:24
 msgid "About lesson - "
 msgstr "À propos de la leçon - "
 
-#: src/jlm/core/ui/AboutWorldDialog.java:32
+#: src/plm/core/ui/AboutPLMDialog.java:34
+msgid "About PLM dialogTitle"
+msgstr "À propos de PLM"
+
+#: src/plm/core/ui/AboutPLMDialog.java:71
+#: src/plm/core/ui/ExerciseFailedDialog.java:49
+msgid "Close"
+msgstr "Fermer"
+
+#: src/plm/core/ui/AboutWorldDialog.java:32
 #, java-format
 msgid "About world - {0}"
 msgstr "À propos du monde - {0}"
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:29
+#: src/plm/core/ui/ChooseLessonDialog.java:40
+msgid "Choose your lesson"
+msgstr "Sélectionner une leçon"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:54
+msgid ""
+"<table border=\"0\" align=\"center\"><tr>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"<td valign=\"center\">  <font size=\"+2\">Welcome to the "
+"Programmer's Learning Machine</font>  </td>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"</tr></table>\n"
+"\n"
+"<p><font size=\"+1\">The PLM is a Learning Management System (LMS) aiming at "
+"teaching the art of computer programming through interactive exercises. It "
+"offers an extensive set of varied exercises, allowing you to practice at "
+"your own pace.</font></p><br/>"
+msgstr ""
+"<table border=\"0\" align=\"center\"><tr>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"<td valign=\"center\">  <font size=\"+2\">Bienvenus dans PLM, "
+"l'exerciseur du programmeur</font>  </td>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"</tr></table>\n"
+"\n"
+"<p><font size=\"+1\">PLM est une plate-forme pédagogique destinée à "
+"simplifier l'apprentissage de la programmation au travers d'exercices "
+"interactifs. De nombreux exercices sont proposés, pour vous permettre "
+"d'apprendre à votre rythme.</font></p><br/>"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:132
+#: src/plm/core/ui/MainFrame.java:163
+msgid "PLM lesson files"
+msgstr "Fichiers de leçons pour la PLM"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:141
+#: src/plm/core/ui/MainFrame.java:172
+msgid "Error"
+msgstr "Erreur"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:168
+msgid ""
+"<h1>Please pick a lesson</h1>\n"
+"<p>Please click on an icon on the left to select a lesson.</p>\n"
+"<p>Lessons located above are generally simpler than the ones located below.</"
+"p>"
+msgstr ""
+"<h1>Veuillez choisir une leçon</h1>\n"
+"<p>Cliquez sur un icône à gauche pour choisir une leçon.</p>\n"
+"<p>Les leçons du haut sont généralement plus simples que celles du bas.</p>"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:210
+#, java-format
+msgid ""
+"<p>(unable to display the short description of this lesson: file {0} not "
+"found)</p>"
+msgstr ""
+"<p>(impossible d''afficher le descriptif court de cette leçon: le fichier "
+"{0} est introuvable)</p>"
+
+#: src/plm/core/ui/ChooseLessonDialog.java:213
+msgid "<p><b>Your score:</b> "
+msgstr "<p><b>Votre score :</b> "
+
+#: src/plm/core/ui/ChooseLessonDialog.java:221
+#, java-format
+msgid "{0} out of {1} exercises passed."
+msgstr "{0} exercices sur {1} réussis."
+
+#: src/plm/core/ui/ChooseLessonDialog.java:225
+#, java-format
+msgid "{0} out of {1} exercises passed in {2}."
+msgstr "{0} exercices sur {1} réussis en {2}."
+
+#: src/plm/core/ui/ChooseLessonDialog.java:231
+msgid "You never attempted this lesson."
+msgstr "Vous n'avez jamais tenté cette leçon."
+
+#: src/plm/core/ui/ExerciseFailedDialog.java:30
 msgid "Exercise failed /o\\"
 msgstr "Exercice raté /o\\"
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:38
+#: src/plm/core/ui/ExerciseFailedDialog.java:39
 msgid "You didn't manage to reach your objective."
 msgstr "Vous n'avez pas atteint votre objectif"
 
-#: src/jlm/core/ui/ExerciseFailedDialog.java:41
+#: src/plm/core/ui/ExerciseFailedDialog.java:42
 msgid "Compilation error"
 msgstr "Erreur de compilation"
 
-#: src/jlm/core/ui/ExerciseView.java:73
+#: src/plm/core/ui/ExerciseView.java:74
 msgid "Switch the displayed world"
 msgstr "Changer le monde affiché"
 
-#: src/jlm/core/ui/ExerciseView.java:83
+#: src/plm/core/ui/ExerciseView.java:84
 msgid "Change the speed of execution"
 msgstr "Changer la vitesse d'exécution"
 
-#: src/jlm/core/ui/ExerciseView.java:90 src/jlm/core/ui/ExerciseView.java:162
+#: src/plm/core/ui/ExerciseView.java:91 src/plm/core/ui/ExerciseView.java:163
 msgid "World"
 msgstr "Monde"
 
-#: src/jlm/core/ui/ExerciseView.java:91 src/jlm/core/ui/ExerciseView.java:163
+#: src/plm/core/ui/ExerciseView.java:92 src/plm/core/ui/ExerciseView.java:164
 msgid "Current world"
 msgstr "Monde courant"
 
-#: src/jlm/core/ui/ExerciseView.java:95 src/jlm/core/ui/ExerciseView.java:165
+#: src/plm/core/ui/ExerciseView.java:96 src/plm/core/ui/ExerciseView.java:166
 msgid "Objective"
 msgstr "Objectif"
 
-#: src/jlm/core/ui/ExerciseView.java:96 src/jlm/core/ui/ExerciseView.java:166
+#: src/plm/core/ui/ExerciseView.java:97 src/plm/core/ui/ExerciseView.java:167
 msgid "Target world"
 msgstr "Monde attendu après exécution du code"
 
-#: src/jlm/core/ui/ExerciseView.java:104
+#: src/plm/core/ui/ExerciseView.java:105
 msgid "Switch the entity"
 msgstr "Changer d'entité"
 
-#: src/jlm/core/ui/FeedbackDialog.java:49
+#: src/plm/core/ui/FeedbackDialog.java:49
 msgid "Report your feedback"
-msgstr "Rapporter un retour"
+msgstr "Signaler un problème dans PLM"
 
-#: src/jlm/core/ui/FeedbackDialog.java:59
+#: src/plm/core/ui/FeedbackDialog.java:59
 msgid ""
-"<html><p>Thanks for your feedback on JLM. We deeply need this to make the "
+"<html><p>Thanks for your feedback on PLM. We deeply need this to make the "
 "tool match <br>your needs, so please don't hesitate to report any "
 "suggestion, such as typos and <br/>unclear parts in the mission texts, other "
 "improvement to the existing exercises<br/>or prospective exercises. We will "
@@ -346,13 +1002,13 @@ msgid ""
 "details, and then click on 'Send' below.</p><p><b>Please provide your email "
 "address so that we can contact you back</b> but <br/>NEVER DISCLOSE A "
 "PASSWORD while reporting issues.</p><p>Note that some technical information "
-"(such as your version of JLM and Java) will <br/>automatically be added to "
+"(such as your version of PLM and Java) will <br/>automatically be added to "
 "your feedback. None of these automatic information <br/>are personal and you "
 "still have to identify yourself if you want to.</p><p>Alternatively, you can "
 "use the <a href='http://github.com/oster/JLM/issues'>github interface</a> "
 "for feedback.</p></html>"
 msgstr ""
-"<html><p>Merci pour votre retour sur JLM. Nous en avons vraiment besoin "
+"<html><p>Merci pour votre retour sur PLM. Nous en avons vraiment besoin "
 "pour<br/>améliorer notre outil et nous assurer qu'il correspond à vos "
 "besoins. N'hésitez<br/>pas à nous signaler toute amélioration possible, "
 "telles que des fautes et des<br/>parties peu claires dans les énoncés, "
@@ -361,331 +1017,249 @@ msgstr ""
 "suggestions.</p><p>Veuillez écrire ici vos suggestions (si possible en "
 "français ou anglais),<br/>avec tous les détails nécessaires, et cliquez "
 "ensuite sur «envoyer».</p><p><b>N'oubliez pas d'indiquer votre email si vous "
-"voulez que nous vous contactions<br/>en retour</b>, mais NE DONNEZ JAMAIS UN "
-"MOT DE PASSE DANS UN FORMULAIRE DE CE GENRE.<br/></p><p>Notez que certaines "
-"données techniques (telles que votre version de JLM ou de Java)<br/>seront "
-"jointes à votre envoi, mais nous ne récoltons aucune donnée personnelle<br/"
-">de cette façon, et il faut que vous vous identifiez vous même si vous le "
-"souhaitez.</p><p>Une autre façon de rapporter du feedback sur JLM est "
-"d'utiliser <a href='http://github.com/oster/JLM/issues'>l'interface github</"
-"a>.</p></html>"
-
-#: src/jlm/core/ui/FeedbackDialog.java:78
-msgid "(your feedback comes here)"
-msgstr "(votre retour vient ici)"
-
-#: src/jlm/core/ui/FeedbackDialog.java:89
-msgid "Cancel"
-msgstr "Annuler"
-
-#: src/jlm/core/ui/FeedbackDialog.java:94
-msgid "Do you really want to cancel your feedback and lose any edit?"
-msgstr ""
-"Voullez vous vraiment annuler votre retour et perdre ce que vous avez écrit ?"
-
-#: src/jlm/core/ui/FeedbackDialog.java:95
-msgid "are you sure?"
-msgstr "êtes vous sûr?"
-
-#: src/jlm/core/ui/FeedbackDialog.java:102
-msgid "Send feedback"
-msgstr "Envoyer"
-
-#: src/jlm/core/ui/FeedbackDialog.java:142
-msgid "Thank you for your feedback"
-msgstr "Merci pour votre retour"
-
-#: src/jlm/core/ui/FeedbackDialog.java:148
-#: src/jlm/core/ui/FeedbackDialog.java:157
-msgid "Error while uploading your feedback"
-msgstr "Erreur lors de l'envoi de votre retour"
-
-#: src/jlm/core/ui/JlmHtmlEditorKit.java:142
-#, java-format
-msgid "<img> tag without src attribute in exercise {0}"
-msgstr "Tag <img> sans attribut src dans l''exercice {0}."
-
-#: src/jlm/core/ui/LessonChooser.java:40
-msgid "Choose your lesson"
-msgstr "Sélectionner une leçon"
-
-#: src/jlm/core/ui/LessonChooser.java:54
-msgid ""
-"<table border=\"0\" align=\"center\"><tr>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"<td valign=\"center\">  <font size=\"+2\">Welcome to the Java "
-"Learning Machine</font>  </td>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"</tr></table>\n"
-"\n"
-"<p><font size=\"+1\">The JLM is a Learning Management System (LMS) aiming at "
-"teaching the art of computer programming through interactive exercises. It "
-"offers an extensive set of varied exercises, allowing you to practice at "
-"your own pace.</font></p><br/>"
-msgstr ""
-"<table border=\"0\" align=\"center\"><tr>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"<td valign=\"center\">  <font size=\"+2\">Bienvenus dans la Java "
-"Learning Machine</font>  </td>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"</tr></table>\n"
-"\n"
-"<p><font size=\"+1\">JLM est une plate-forme pédagogique destinée à "
-"simplifier l'apprentissage de la programmation au travers d'exercices "
-"interactifs. De nombreux exercices sont proposés, pour vous permettre "
-"d'apprendre à votre rythme.</font></p><br/>"
-
-#: src/jlm/core/ui/LessonChooser.java:132 src/jlm/core/ui/MainFrame.java:163
-msgid "JLM lesson files"
-msgstr "Fichiers de leçons pour la JLM"
-
-#: src/jlm/core/ui/LessonChooser.java:141 src/jlm/core/ui/MainFrame.java:172
-msgid "Error"
-msgstr "Erreur"
-
-#: src/jlm/core/ui/LessonChooser.java:168
-msgid ""
-"<h1>Please pick a lesson</h1>\n"
-"<p>Please click on an icon on the left to select a lesson.</p>\n"
-"<p>Lessons located above are generally simpler than the ones located below.</"
-"p>"
-msgstr ""
-"<h1>Veuillez choisir une leçon</h1>\n"
-"<p>Cliquez sur un icône à gauche pour choisir une leçon.</p>\n"
-"<p>Les leçons du haut sont généralement plus simples que celles du bas.</p>"
+"voulez que nous vous contactions<br/>en retour</b>, mais NE DONNEZ JAMAIS UN "
+"MOT DE PASSE DANS UN FORMULAIRE DE CE GENRE.<br/></p><p>Notez que certaines "
+"données techniques (telles que votre version de PLM ou de Java)<br/>seront "
+"jointes à votre envoi, mais nous ne récoltons aucune donnée personnelle<br/"
+">de cette façon, et il faut que vous vous identifiez vous même si vous le "
+"souhaitez.</p><p>Une autre façon de rapporter du feedback sur PLM est "
+"d'utiliser <a href='http://github.com/oster/JLM/issues'>l'interface github</"
+"a>.</p></html>"
 
-#. Create the button
-#: src/jlm/core/ui/LessonChooser.java:180
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
-msgid "Go"
-msgstr "Aller"
+#: src/plm/core/ui/FeedbackDialog.java:88
+msgid "(your feedback comes here)"
+msgstr "(votre retour vient ici)"
 
-#: src/jlm/core/ui/LessonChooser.java:210
-#, java-format
-msgid ""
-"<p>(unable to display the short description of this lesson: file {0} not "
-"found)</p>"
+#: src/plm/core/ui/FeedbackDialog.java:90
+msgid "Cancel"
+msgstr "Annuler"
+
+#: src/plm/core/ui/FeedbackDialog.java:95
+msgid "Do you really want to cancel your feedback and lose any edit?"
 msgstr ""
-"<p>(impossible d''afficher le descriptif court de cette leçon: le fichier "
-"{0} est introuvable)</p>"
+"Voullez vous vraiment annuler votre retour et perdre ce que vous avez écrit ?"
 
-#: src/jlm/core/ui/LessonChooser.java:213
-msgid "<p><b>Your score:</b> "
-msgstr "<p><b>Votre score :</b> "
+#: src/plm/core/ui/FeedbackDialog.java:96
+msgid "are you sure?"
+msgstr "êtes vous sûr?"
 
-#: src/jlm/core/ui/LessonChooser.java:221
-#, java-format
-msgid "{0} out of {1} exercises passed."
-msgstr "{0} exercices sur {1} réussis."
+#: src/plm/core/ui/FeedbackDialog.java:103
+msgid "Send feedback"
+msgstr "Envoyer"
 
-#: src/jlm/core/ui/LessonChooser.java:225
-#, java-format
-msgid "{0} out of {1} exercises passed in {2}."
-msgstr "{0} exercices sur {1} réussis en {2}."
+#: src/plm/core/ui/FeedbackDialog.java:143
+msgid "Thank you for your feedback"
+msgstr "Merci pour votre retour"
 
-#: src/jlm/core/ui/LessonChooser.java:231
-msgid "You never attempted this lesson."
-msgstr "Vous n'avez jamais tenté cette leçon."
+#: src/plm/core/ui/FeedbackDialog.java:149
+#: src/plm/core/ui/FeedbackDialog.java:158
+msgid "Error while uploading your feedback"
+msgstr "Erreur lors de l'envoi de votre retour"
 
-#: src/jlm/core/ui/LoggerPanel.java:31 src/jlm/core/ui/LoggerPanel.java:96
+#: src/plm/core/ui/LoggerPanel.java:30 src/plm/core/ui/LoggerPanel.java:95
 msgid "Where error and other messages get written"
 msgstr "Endroit ou les erreurs et autres messages sont écrits"
 
 #. === FILE menu ===
 #. for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
 #. Menus
-#: src/jlm/core/ui/MainFrame.java:152 src/jlm/core/ui/MainFrame.java:647
+#: src/plm/core/ui/MainFrame.java:152 src/plm/core/ui/MainFrame.java:647
 msgid "File"
 msgstr "Fichier"
 
-#: src/jlm/core/ui/MainFrame.java:154
+#: src/plm/core/ui/MainFrame.java:154
 msgid "File related functions"
 msgstr "Fonction relatives à la gestion de fichiers"
 
-#: src/jlm/core/ui/MainFrame.java:157 src/jlm/core/ui/MainFrame.java:648
+#: src/plm/core/ui/MainFrame.java:157 src/plm/core/ui/MainFrame.java:648
 msgid "Load lesson"
 msgstr "Charger Leçon"
 
-#: src/jlm/core/ui/MainFrame.java:179 src/jlm/core/ui/MainFrame.java:649
+#: src/plm/core/ui/MainFrame.java:179 src/plm/core/ui/MainFrame.java:649
 msgid "Switch lesson"
 msgstr "Sélectionner une leçon"
 
-#: src/jlm/core/ui/MainFrame.java:191 src/jlm/core/ui/MainFrame.java:416
-#: src/jlm/core/ui/MainFrame.java:644 src/jlm/core/ui/MainFrame.java:650
+#: src/plm/core/ui/MainFrame.java:191 src/plm/core/ui/MainFrame.java:416
+#: src/plm/core/ui/MainFrame.java:644 src/plm/core/ui/MainFrame.java:650
 msgid "Switch exercise"
 msgstr "Changer d'exercice"
 
-#: src/jlm/core/ui/MainFrame.java:204 src/jlm/core/ui/MainFrame.java:652
+#: src/plm/core/ui/MainFrame.java:204 src/plm/core/ui/MainFrame.java:652
 msgid "Teacher Console"
 msgstr "Console enseignant"
 
 #. Menu item to change the current Course
-#: src/jlm/core/ui/MainFrame.java:223 src/jlm/core/ui/MainFrame.java:653
+#: src/plm/core/ui/MainFrame.java:223 src/plm/core/ui/MainFrame.java:653
 msgid "Choose your course"
 msgstr "Sélectionner un cours"
 
-#: src/jlm/core/ui/MainFrame.java:242 src/jlm/core/ui/MainFrame.java:654
+#: src/plm/core/ui/MainFrame.java:242 src/plm/core/ui/MainFrame.java:654
 msgid "Quit"
 msgstr "Quitter"
 
 #. === Edit menu ===
-#: src/jlm/core/ui/MainFrame.java:250 src/jlm/core/ui/MainFrame.java:656
+#: src/plm/core/ui/MainFrame.java:250 src/plm/core/ui/MainFrame.java:656
 msgid "Session"
 msgstr "Session"
 
-#: src/jlm/core/ui/MainFrame.java:255 src/jlm/core/ui/MainFrame.java:658
+#: src/plm/core/ui/MainFrame.java:255 src/plm/core/ui/MainFrame.java:658
 msgid "Revert Exercise"
 msgstr "Recommencer l'exercice"
 
-#: src/jlm/core/ui/MainFrame.java:258 src/jlm/core/ui/MainFrame.java:659
+#: src/plm/core/ui/MainFrame.java:258 src/plm/core/ui/MainFrame.java:659
 msgid "Export Session Cache"
 msgstr "Exporter le cache de session"
 
-#: src/jlm/core/ui/MainFrame.java:261 src/jlm/core/ui/MainFrame.java:660
+#: src/plm/core/ui/MainFrame.java:261 src/plm/core/ui/MainFrame.java:660
 msgid "Import Session Cache"
 msgstr "Importer le cache de session"
 
-#: src/jlm/core/ui/MainFrame.java:265 src/jlm/core/ui/MainFrame.java:661
+#: src/plm/core/ui/MainFrame.java:265 src/plm/core/ui/MainFrame.java:661
 msgid "Debug mode"
 msgstr "Mode débogage"
 
 #. === Language menu ===
-#: src/jlm/core/ui/MainFrame.java:278 src/jlm/core/ui/MainFrame.java:664
+#: src/plm/core/ui/MainFrame.java:278 src/plm/core/ui/MainFrame.java:664
 msgid "Language"
 msgstr "Langage"
 
 #. === Programming language changing ===
-#: src/jlm/core/ui/MainFrame.java:283 src/jlm/core/ui/MainFrame.java:665
+#: src/plm/core/ui/MainFrame.java:283 src/plm/core/ui/MainFrame.java:665
 msgid "Human"
 msgstr "Humain"
 
-#: src/jlm/core/ui/MainFrame.java:297 src/jlm/core/ui/MainFrame.java:666
+#: src/plm/core/ui/MainFrame.java:297 src/plm/core/ui/MainFrame.java:666
 msgid "Computer"
 msgstr "Ordinateur"
 
 #. === Help menu ===
-#: src/jlm/core/ui/MainFrame.java:301 src/jlm/core/ui/MainFrame.java:668
+#: src/plm/core/ui/MainFrame.java:301 src/plm/core/ui/MainFrame.java:668
 msgid "Help"
 msgstr "Aide"
 
-#: src/jlm/core/ui/MainFrame.java:305 src/jlm/core/ui/MainFrame.java:669
+#: src/plm/core/ui/MainFrame.java:305 src/plm/core/ui/MainFrame.java:669
 msgid "Provide feedback"
 msgstr "Faire un retour"
 
-#: src/jlm/core/ui/MainFrame.java:315 src/jlm/core/ui/MainFrame.java:670
+#: src/plm/core/ui/MainFrame.java:315 src/plm/core/ui/MainFrame.java:670
 msgid "About this lesson"
 msgstr "À propos de cette leçon"
 
-#: src/jlm/core/ui/MainFrame.java:328 src/jlm/core/ui/MainFrame.java:671
+#: src/plm/core/ui/MainFrame.java:328 src/plm/core/ui/MainFrame.java:671
 msgid "About this world"
 msgstr "À propos de ce monde"
 
-#: src/jlm/core/ui/MainFrame.java:344 src/jlm/core/ui/MainFrame.java:673
-msgid "About JLM"
-msgstr "À propos de JLM"
+#: src/plm/core/ui/MainFrame.java:344 src/plm/core/ui/MainFrame.java:673
+msgid "About PLM"
+msgstr "À propos de PLM"
 
 #. Buttons
-#: src/jlm/core/ui/MainFrame.java:377 src/jlm/core/ui/MainFrame.java:638
+#: src/plm/core/ui/MainFrame.java:377 src/plm/core/ui/MainFrame.java:638
 msgid "Run"
 msgstr "Exécuter"
 
-#: src/jlm/core/ui/MainFrame.java:381 src/jlm/core/ui/MainFrame.java:479
-#: src/jlm/core/ui/MainFrame.java:639
+#: src/plm/core/ui/MainFrame.java:381 src/plm/core/ui/MainFrame.java:479
+#: src/plm/core/ui/MainFrame.java:639
 msgid "Step"
 msgstr "Un pas"
 
-#: src/jlm/core/ui/MainFrame.java:386 src/jlm/core/ui/MainFrame.java:640
+#: src/plm/core/ui/MainFrame.java:386 src/plm/core/ui/MainFrame.java:640
 msgid "Stop"
 msgstr "Stop"
 
-#: src/jlm/core/ui/MainFrame.java:392 src/jlm/core/ui/MainFrame.java:641
+#: src/plm/core/ui/MainFrame.java:392 src/plm/core/ui/MainFrame.java:641
 msgid "Reset"
 msgstr "Réinitialiser"
 
-#: src/jlm/core/ui/MainFrame.java:398 src/jlm/core/ui/MainFrame.java:642
+#: src/plm/core/ui/MainFrame.java:398 src/plm/core/ui/MainFrame.java:642
 msgid "Demo"
 msgstr "Démo"
 
-#: src/jlm/core/ui/MainFrame.java:404 src/jlm/core/ui/MainFrame.java:643
-#: src/jlm/core/ui/action/HelpMe.java:37
+#: src/plm/core/ui/MainFrame.java:404 src/plm/core/ui/MainFrame.java:643
+#: src/plm/core/ui/action/HelpMe.java:37
 msgid "Call for Help"
 msgstr "Appeler à l'aide"
 
-#: src/jlm/core/ui/MainFrame.java:464
+#: src/plm/core/ui/MainFrame.java:464
 msgid "Next"
 msgstr "Suivant"
 
-#: src/jlm/core/ui/MainFrame.java:657
+#: src/plm/core/ui/MainFrame.java:657
 msgid "Lesson related functions"
 msgstr "Fonctions relatives aux leçons"
 
-#: src/jlm/core/ui/MissionEditorTabs.java:96
+#: src/plm/core/ui/MissionEditorTabs.java:91
 msgid "Mission"
 msgstr "Mission"
 
-#: src/jlm/core/ui/MissionEditorTabs.java:97
+#: src/plm/core/ui/MissionEditorTabs.java:92
 msgid "Description of the work to do"
 msgstr "Description de la tache à effectuer"
 
 #. Create the tab with the code editor as content
-#: src/jlm/core/ui/MissionEditorTabs.java:166
+#: src/plm/core/ui/MissionEditorTabs.java:161
 msgid "Type your code here"
 msgstr "Composer votre code ici"
 
-#: src/jlm/core/ui/StatusBar.java:113
+#: src/plm/core/ui/PlmHtmlEditorKit.java:244
+#, java-format
+msgid "<img> tag without src attribute in exercise {0}"
+msgstr "Tag <img> sans attribut src dans l''exercice {0}."
+
+#: src/plm/core/ui/StatusBar.java:113
 msgid "Saving"
 msgstr "Sauvegarde"
 
-#: src/jlm/core/ui/StatusBar.java:117
+#: src/plm/core/ui/StatusBar.java:117
 msgid "Compiling"
 msgstr "Compilation"
 
-#: src/jlm/core/ui/StatusBar.java:131
+#: src/plm/core/ui/StatusBar.java:131
 msgid "Running "
 msgstr "Exécution de "
 
-#: src/jlm/core/ui/StatusBar.java:135
+#: src/plm/core/ui/StatusBar.java:135
 msgid "Playing demo "
 msgstr "Exécution de la démo "
 
-#: src/jlm/core/ui/StatusBar.java:139
+#: src/plm/core/ui/StatusBar.java:139
 msgid "Loading "
 msgstr "Chargement de "
 
-#: src/jlm/core/ui/action/HelpMe.java:37
+#: src/plm/core/ui/action/HelpMe.java:37
 msgid "Cancel call"
 msgstr "Annuler l'appel"
 
-#: src/jlm/core/ui/action/PlayDemo.java:27
+#: src/plm/core/ui/action/PlayDemo.java:27
 msgid "Run the demo of what you should code for this exercise"
 msgstr ""
 "Lancer une démonstration de ce que devrait faire votre code dans cet exercice"
 
-#: src/jlm/core/ui/action/PlayDemo.java:28
+#: src/plm/core/ui/action/PlayDemo.java:28
 msgid "Impossible to run the demo right now"
 msgstr "Impossible de lançer la démo pour l'instant"
 
-#: src/jlm/core/ui/action/QuitGame.java:28
+#: src/plm/core/ui/action/QuitGame.java:28
 msgid "Quit the application"
 msgstr "Quitter l'application"
 
-#: src/jlm/core/ui/action/QuitGame.java:28
+#: src/plm/core/ui/action/QuitGame.java:28
 msgid "Impossible to quit the application right now"
 msgstr "Il est pour l'instant impossible de quitter l'application"
 
-#: src/jlm/core/ui/action/Reset.java:29
+#: src/plm/core/ui/action/Reset.java:29
 msgid "Reset your world to the initial state"
 msgstr "Réinitialise votre monde à l'état initial"
 
-#: src/jlm/core/ui/action/Reset.java:29
+#: src/plm/core/ui/action/Reset.java:29
 msgid "World cannot be reset right now"
 msgstr "Le monde ne peut être réinitialisé pour l'instant"
 
-#: src/jlm/core/ui/action/StartExecution.java:32
+#: src/plm/core/ui/action/StartExecution.java:32
 msgid "Launch the execution of your code"
 msgstr "Démarrer l'exécution de votre code"
 
-#: src/jlm/core/ui/action/StartExecution.java:33
+#: src/plm/core/ui/action/StartExecution.java:33
 msgid ""
 "Cannot launch the execution right now. Wait a bit, or interrupt current "
 "activity with the stop button"
@@ -693,246 +1267,323 @@ msgstr ""
 "Je ne peux démarrer l'exécution de votre code. Attendez un peu ou "
 "interrompez l'activité courante avec le bouton Stop."
 
-#: src/jlm/core/ui/action/StepExecution.java:22
+#: src/plm/core/ui/action/StepExecution.java:22
 msgid "Execute one step of your code"
 msgstr "Exécuter un pas de votre code"
 
-#: src/jlm/core/ui/action/StepExecution.java:23
+#: src/plm/core/ui/action/StepExecution.java:23
 msgid "Impossible to step your code now. Need to stop the execution first?"
 msgstr ""
 "Impossible de parcourir pas à pas votre code. Il est nécessaire d'arrêter "
 "l'exécution d'abord."
 
-#: src/jlm/core/ui/action/StopExecution.java:22
+#: src/plm/core/ui/action/StopExecution.java:22
 msgid "Stop your code"
 msgstr "Arrêter l'exécution de votre code"
 
-#: src/jlm/core/ui/action/StopExecution.java:23
+#: src/plm/core/ui/action/StopExecution.java:23
 msgid "No execution to stop right now"
 msgstr "Il n'y a pas de code en cours d'exécution"
 
-#: src/jlm/core/ui/action/SwitchExo.java:29
+#: src/plm/core/ui/action/SwitchExo.java:29
 msgid "Switch to another exercise"
 msgstr "Accéder à un autre exercice"
 
-#: src/jlm/universe/Entity.java:178
-#, java-format
-msgid ""
-"The execution of your program raised an exception: {0}\n"
-" Please fix your code.\n"
-msgstr ""
-"L''exécution de votre programme a déclanché une exception : {0}\n"
-" Merci de corriger votre code.\n"
+#: src/plm/core/ui/editor/MissionEditor.java:49
+msgid "PLM - Mission Editor (modified)"
+msgstr "PLM - Éditeur de missions (modifié)"
 
-#: src/jlm/universe/Entity.java:192
-#, java-format
-msgid "Failed to start an interpreter for {0}"
-msgstr "Impossible de démarrer un interpréteur pour {0}."
+#: src/plm/core/ui/editor/MissionEditor.java:50
+msgid "PLM - Mission Editor"
+msgstr "PLM - Éditeur de missions"
 
-#: src/jlm/universe/Entity.java:214
+#: src/plm/core/ui/editor/MissionEditor.java:173
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:242
 #, java-format
-msgid ""
-"No {0} script source for entity {1}. Please report that bug against JLM."
-msgstr ""
-"Pas de script {0} pour l''entité {1}. Merci de rapporter ce bug de JLM."
+msgid "Error while reading {0}"
+msgstr "Erreur lors de la lecture de {0}"
 
-#: src/jlm/universe/Entity.java:236
-#, java-format
-msgid ""
-"Syntax error at line {0}: {1}\n"
-"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
+#: src/plm/core/ui/editor/MissionEditor.java:180
+msgid "You did not save you changes. Do you want to save it before quiting?"
 msgstr ""
-"Erreur de syntaxe à la ligne {0} : {1}\n"
-"En cas de doute, vérifiez les indentations, et veillez à ne pas mélanger "
-"espaces et tabulations.\n"
+"Vous n'avez pas sauvegardé vos modifications. Voulez-vous les sauver avant "
+"de quitter?"
+
+#: src/plm/core/ui/editor/MissionEditor.java:181
+#: src/plm/core/ui/editor/MissionEditor.java:300
+msgid "Save or loose your change?"
+msgstr "Sauvegarder ou perdre vos changements ?"
+
+#: src/plm/core/ui/editor/MissionEditor.java:292
+msgid "Open Mission..."
+msgstr "Ouvrir la mission..."
 
-#: src/jlm/universe/Entity.java:244
+#: src/plm/core/ui/editor/MissionEditor.java:299
 msgid ""
-"NameError raised: You seem to use a non-existent identifier; Please check "
-"for typos\n"
+"You did not save you changes. Do you want to save it before opening another "
+"file?"
 msgstr ""
-"Erreur de nom : vous semblez utiliser un identifiant qui n'existe pas. "
-"Auriez-vous fait une typo ?\n"
+"Vous n'avez pas sauvegardé vos modifications. Voulez-vous les sauver avant "
+"d'ouvrir un autre fichier ?"
 
-#: src/jlm/universe/Entity.java:247
-msgid "TypeError raised: you are probably misusing a function or something.\n"
-msgstr ""
-"Erreur de type : vous n'utilisez pas correctement une fonction, ou quelque "
-"chose du genre.\n"
+#: src/plm/core/ui/editor/MissionEditor.java:317
+msgid "HTML files"
+msgstr "Fichiers HTML"
 
-#: src/jlm/universe/Entity.java:250
+#: src/plm/core/ui/editor/MissionEditor.java:325
+#, java-format
 msgid ""
-"UnboundLocalError raised: you are probably using a global variable that is "
-"not declared as such.\n"
+"You chose a translated mission text for edition ({0}).\n"
+"This is wrong. The translations should be handled with po4a in PLM.\n"
+"Please refer to https://github.com/oster/JLM/wiki/Working-with-the-"
+"translations for more information.\n"
+"\n"
+"Proceed anyway?"
 msgstr ""
-"Erreur UnboundLocal : vous utilisez probablement une variable qui n'est pas "
-"déclarée, ou quelque chose du genre.\n"
+"Vous avez choisi d''éditer un texte traduit de mission ({0}).\n"
+"Ce n''est pas ainsi qu''il faut procéder. Les traductions sont gérées avec "
+"l''utilitaire po4a dans PLM.\n"
+"Veuillez vous référer à la documentation https://github.com/oster/JLM/wiki/"
+"Working-with-the-translations pour plus d''informations.\n"
+"\n"
+"Continuer malgré tout ?"
 
-#: src/jlm/universe/Entity.java:256
-msgid "Error: there is no baggle to pickup under the buggle"
-msgstr "Erreur : Il n'y a pas de baggle à ramasser ici."
+#: src/plm/core/ui/editor/MissionEditor.java:329
+msgid "This is a translated mission text"
+msgstr "C'est une mission traduite"
 
-#: src/jlm/universe/Entity.java:258
-msgid "Error: a buggle cannot carry more than one baggle at the same time"
-msgstr "Erreur : une baggle ne peut porter qu'un baggle à la fois."
+#: src/plm/core/ui/editor/MissionEditor.java:346
+msgid "Quit Map Editor"
+msgstr "Quitter l'éditeur de carte"
 
-#: src/jlm/universe/Entity.java:260
-msgid "Error: your buggle just teleported to the outer space..."
-msgstr "Erreur : Votre buggle s'est téléportée dans l'espace."
+#: src/plm/universe/Entity.java:176
+#, java-format
+msgid ""
+"The execution of your program raised a {0} exception: {1}\n"
+" Please fix your code.\n"
+msgstr ""
+"L''exécution de votre programme a déclanché une exception {0} : {1}\n"
+" Merci de corriger votre code.\n"
 
-#: src/jlm/universe/Entity.java:262
-msgid "Error: your buggle just hit a wall. That hurts."
-msgstr "Erreur : Vous avez heurté un mur. Ça fait mal."
+#: src/plm/universe/Entity.java:191
+#, java-format
+msgid ""
+"No ScriptEngine for {0}. Please check your classpath and similar settings."
+msgstr ""
+"Pas d''engin de script pour {0}. Veuillez vérifier votre classpath et autres "
+"réglages similaires."
 
-#: src/jlm/universe/Entity.java:265
+#: src/plm/universe/Entity.java:211
 #, java-format
 msgid ""
-"Unknown error (please report): {0}\n"
-"Its value is: {1}"
+"No {0} script source for entity {1}. Please report that bug against PLM."
 msgstr ""
-"Erreur inconnue (veuillez faire un rapport de bug) : {0}\\n\n"
-"Sa valeur est : {1}"
+"Pas de script {0} pour l''entité {1}. Merci de rapporter ce bug de PLM."
+
+#: src/plm/universe/Entity.java:235
+msgid "Received a ScriptException that does not come from Python.\n"
+msgstr "Reçu une ScriptException qui ne vient pas de python.\n"
 
-#: src/jlm/universe/Entity.java:296
+#: src/plm/universe/Entity.java:240
 #, java-format
 msgid ""
 "Script evaluation raised an exception that is not a ScriptException but a "
 "{0}.\n"
-" Please report this as a bug against JLM, with all details allowing to "
+" Please report this as a bug against PLM, with all details allowing to "
 "reproduce it.\n"
-"Exception message: {1}"
+"Exception message: {1}\n"
 msgstr ""
 "L''évaluation du script a levé une exception qui n''est pas une "
 "ScriptException mais une {0}.\n"
-"Merci de faire un rapport de bug contre JLM, avec tous les détails "
+"Merci de faire un rapport de bug contre PLM, avec tous les détails "
 "nécessaires pour reproduire le problème.\n"
-"Message de l''exception: {1}"
+"Message de l''exception: {1}\n"
+
+#: src/plm/universe/bat/BatEntity.java:65
+#: src/plm/universe/bat/BatEntity.java:94
+#, java-format
+msgid "This test raised an exception: {0}"
+msgstr "Ce teste a levé une exception : {0}"
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:169
+#, java-format
+msgid ""
+"You tried to access a cell with Y={0}, but the maximal Y in this world is "
+"{1}."
+msgstr ""
+"Vous avez accedé à une cellule telle que Y={0}, mais le Y maximal pour ce "
+"monde est {1}."
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:171
+#, java-format
+msgid ""
+"You tried to access a cell with X={0}, but the maximal X in this world is "
+"{1}."
+msgstr ""
+"Vous avez accedé à une cellule telle que X={0}, mais le X maximal pour ce "
+"monde est {1}."
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:190
+#: src/plm/universe/bugglequest/AbstractBuggle.java:226
+#, java-format
+msgid "You tried to set X to {0}, but the maximal X in this world is {1}."
+msgstr ""
+"Vous avez tenté de mettre la valeur de X à {0}, mais le X maximal pour ce "
+"monde est {1}."
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:209
+#: src/plm/universe/bugglequest/AbstractBuggle.java:224
+#, java-format
+msgid "You tried to set Y to {0}, but the maximal Y in this world is {1}."
+msgstr ""
+"Vous avez tenté de mettre la valeur de Y à {0}, mais le Y maximal pour ce "
+"monde est {1}."
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:343
+msgid "There is no baggle to pick up here."
+msgstr "Erreur : Il n'y a pas de biscuit à ramasser ici."
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:345
+msgid "Your are already carrying a baggle."
+msgstr "Vous portez déjà un biscuit."
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:422
+#: src/plm/universe/bugglequest/AbstractBuggle.java:424
 msgid "Its value is 'null', which is never good."
 msgstr "Sa valeur est 'null', ce qui n'est jamais bon."
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:429
+#: src/plm/universe/bugglequest/AbstractBuggle.java:431
 #, java-format
 msgid "    Its position is ({0},{1}); expected: ({2},{3}).\n"
-msgstr "    Sa position est ({0},{1}) ; attendu : ({2},{3}).\n"
+msgstr "    Sa position est ({0},{1}) ; attendue : ({2},{3}).\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:431
+#: src/plm/universe/bugglequest/AbstractBuggle.java:433
 #, java-format
 msgid "    Its direction is {0}; expected: {1}.\n"
-msgstr "    Sa direction est {0} ; attendu : {1}.\n"
+msgstr "    Sa direction est {0} ; attendue : {1}.\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:433
+#: src/plm/universe/bugglequest/AbstractBuggle.java:435
 #, java-format
 msgid "    Its color is {0}; expected: {1}.\n"
-msgstr "    Sa couleur est {0} ; attendu : {1}.\n"
+msgstr "    Sa couleur est {0} ; attendue : {1}.\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:435
+#: src/plm/universe/bugglequest/AbstractBuggle.java:437
 #, java-format
 msgid "    The color of its brush is {0}; expected: {1}.\n"
-msgstr "    La couleur de son pinceau est {0} ; attendu : {1}\n"
+msgstr "    La couleur de son pinceau est {0} ; attendue : {1}\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:437
+#: src/plm/universe/bugglequest/AbstractBuggle.java:439
 msgid "    It should not carry that baggle.\n"
-msgstr "    Il de devrait pas porter de baggle.\n"
+msgstr "    Elle de devrait pas porter de biscuit.\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:439
+#: src/plm/universe/bugglequest/AbstractBuggle.java:441
 msgid "    It is not carrying any baggle.\n"
-msgstr "    Il ne porte pas de baggle.\n"
+msgstr "    Elle ne porte pas de biscuit.\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:441
+#: src/plm/universe/bugglequest/AbstractBuggle.java:443
 msgid "    It encountered an issue, such as bumping into a wall.\n"
-msgstr "    Il a eu un problème tel que rencontrer un mur.\n"
+msgstr "    Elle a eu un problème tel que rencontrer un mur.\n"
 
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:443
+#: src/plm/universe/bugglequest/AbstractBuggle.java:445
 msgid "    It didn't encounter any issue, such as bumping into a wall.\n"
-msgstr "    Il n'a pas eu de problème tel que rencontrer un mur.\n"
+msgstr "    Elle n'a pas eu de problème tel que rencontrer un mur.\n"
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:122
+#, java-format
+msgid ""
+"{0}: The path to the map on disk should not include the .map extension (or "
+"it won''t work in jarfiles). Please fix your exercise."
+msgstr ""
+"{0}: le nom de fichier donné pour lire la carte ne devrait pas inclure "
+"l'extension .map. \n"
+"Sinon, cela ne fonctionnera pas quand la  PLM sera chargée depuis un fichier "
+"jar.\n"
+"Merci de corriger votre exercice."
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:127
+#: src/plm/universe/bugglequest/BuggleWorld.java:130
 #, java-format
 msgid ""
 "{0}.map: this file does not seem to be a serialized BuggleWorld (the file is "
 "empty!)"
 msgstr ""
-"{0}.map : ce fichier ne semble pas est un BuggleWorld sérialisé (fichier "
+"{0}.map : ce fichier ne semble pas être un BuggleWorld sérialisé (fichier "
 "vide !)"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:133
+#: src/plm/universe/bugglequest/BuggleWorld.java:136
 #, java-format
 msgid ""
 "{0}.map: This file does not seem to be a serialized BuggleWorld (malformated "
 "first line: {1})"
 msgstr ""
-"{0}.map : ce fichier ne semble pas est un BuggleWorld sérialisé (première "
+"{0}.map : ce fichier ne semble pas être un BuggleWorld sérialisé (première "
 "ligne malformée : {1})"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:139
+#: src/plm/universe/bugglequest/BuggleWorld.java:142
 #, java-format
 msgid "{0}.map: End of file reached before world size specification"
 msgstr ""
-"{0}.map : fin de fichier (EOF) rencontré avant la spécification de la taille "
-"du monde."
+"{0}.map : fin de fichier (EOF) rencontrée avant la spécification de la "
+"taille du monde."
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:144
+#: src/plm/universe/bugglequest/BuggleWorld.java:147
 #, java-format
 msgid "{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''"
 msgstr "{0}.map:1: ''Size: NNxMM'' était attendu, mais on a lu ''{0}''"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:170
+#: src/plm/universe/bugglequest/BuggleWorld.java:173
 #, java-format
 msgid "Cannot put a buggle on coordinate {0},{1}: that''s out of the world"
 msgstr ""
-"Je ne peux poser un buggle aux coordonnées {0},{1} : c''est en dehors du "
+"Je ne peux poser une buggle aux coordonnées {0},{1} : c''est en dehors du "
 "monde"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:184
+#: src/plm/universe/bugglequest/BuggleWorld.java:187
 #, java-format
 msgid "Invalid buggle''s direction: {0}"
 msgstr "direction invalide de buggle : {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:191
-#: src/jlm/universe/bugglequest/BuggleWorld.java:198
+#: src/plm/universe/bugglequest/BuggleWorld.java:194
+#: src/plm/universe/bugglequest/BuggleWorld.java:201
 #, java-format
 msgid "Invalid buggle''s color name: {0}"
 msgstr "Couleur invalide de buggle : {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:210
+#: src/plm/universe/bugglequest/BuggleWorld.java:213
 #, java-format
 msgid "Cannot define a cell on coordinate {0},{1}: that''s out of the world"
 msgstr ""
 "Je ne peux définir les coordonnées de cellule {0},{1} : c''est en dehors du "
 "monde"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:223
+#: src/plm/universe/bugglequest/BuggleWorld.java:226
 #, java-format
 msgid "Invalid color name: {0}"
 msgstr "Nom de couleur invalide : {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:229
+#: src/plm/universe/bugglequest/BuggleWorld.java:232
 #, java-format
 msgid "Expecting ''baggle'' or ''nobaggle'' but got {0} instead"
-msgstr "«baggle» ou «nobaggle» était attendu, mais on a {0} à la place"
+msgstr "«baggle» ou «nobaggle» était attendu, mais on a «{0}» à la place"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:233
+#: src/plm/universe/bugglequest/BuggleWorld.java:236
 #, java-format
 msgid "Expecting ''topwall'' or ''notopwall'' but got {0} instead"
-msgstr "«topwall» ou «notopwall» était attendu, mais on a {0} à la place"
+msgstr "«topwall» ou «notopwall» était attendu, mais on a «{0}» à la place"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:237
+#: src/plm/universe/bugglequest/BuggleWorld.java:240
 #, java-format
 msgid "Expecting ''leftwall'' or ''noleftwall'' but got {0} instead"
-msgstr "«leftwall» ou «noleftwall» était attendu, mais on a {0} à la place"
+msgstr "«leftwall» ou «noleftwall» était attendu, mais on a «{0}» à la place"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:247
+#: src/plm/universe/bugglequest/BuggleWorld.java:250
 #, java-format
 msgid ""
 "The cell {0},{1} seem to be defined more than once. At least, there is two "
 "baggles here, which is not allowed."
 msgstr ""
 "La cellule {0},{1} semble être définie plusieurs fois. Il y a au moins deux "
-"baggles ici ce qui n'est pas permis."
+"biscuits ici, ce qui n'est pas permis."
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:263
+#: src/plm/universe/bugglequest/BuggleWorld.java:266
 #, java-format
 msgid ""
 "Parse error. I was expecting a cell or a buggle description but got: {0}"
@@ -940,336 +1591,200 @@ msgstr ""
 "Erreur de syntaxe. J''attendais la description d''une cellule ou d''un "
 "buggle mais j''ai eu : {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:481
+#: src/plm/universe/bugglequest/BuggleWorld.java:543
 #, java-format
 msgid "  The world''s name is {0}"
 msgstr "  Le nom du monde est {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:485
+#: src/plm/universe/bugglequest/BuggleWorld.java:547
 #, java-format
 msgid "  In ({0},{1})"
 msgstr "  En ({0},{1})"
 
-#: src/jlm/universe/bugglequest/BuggleWorld.java:488
+#: src/plm/universe/bugglequest/BuggleWorld.java:550
 #, java-format
 msgid "  Something is wrong about buggle ''{0}'':\n"
-msgstr "  Il y a quelque chose qui cloche avec le buggle «{0}»:\n"
+msgstr "  Il y a quelque chose qui cloche avec la buggle «{0}»:\n"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:230
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:129
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:136
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:143
+msgid "There is already a baggle here."
+msgstr "Il y a déjà un biscuit ici."
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:231
 msgid ", there shouldn't be this baggle"
-msgstr ", il ne devrait pas y avoir ce baggle"
+msgstr ", il ne devrait pas y avoir ce biscuit"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:232
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:233
 msgid ", there should be a baggle"
-msgstr ", il devrait y avoir un baggle"
+msgstr ", il devrait y avoir un biscuit"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:234
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:235
 msgid ", the baggle differs"
-msgstr ", le baggle est différent"
+msgstr ", le biscuit est différent"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:237
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:238
 #, java-format
 msgid ", the ground should not be {0}"
 msgstr ", le sol ne devrait pas être {0}"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:239
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:240
 #, java-format
 msgid ", the ground is expected to be {0}, but it is {1}"
 msgstr ", le sol devrait être {0}, mais est {1}"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:241
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:242
 #, java-format
 msgid ", the ground reads ''{0}'' (expected: ''{1}'')"
-msgstr ", on lit \"{0}\" sur le sol (on attendait : \"{1}\")"
+msgstr ", on lit «{0}» sur le sol (on attendait : «{1}»)"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:244
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:245
 msgid ", there shouldn't be any wall at west"
 msgstr ", il ne devrait pas y avoir de mur à l'ouest"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:246
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:247
 msgid ", there should be a wall at west"
 msgstr ", il devrait y avoir un mur à l'ouest"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:249
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:250
 msgid ", there shouldn't be any wall at north"
 msgstr ", il ne devrait pas y avoir de mur au nord"
 
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:251
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:252
 msgid ", there should be a wall at north"
 msgstr ", il devrait y avoir un mur au nord"
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:176
+#: src/plm/universe/bugglequest/exception/BuggleWallException.java:10
+msgid "Buggles cannot traverse walls"
+msgstr "Les buggles ne peuvent pas traverser les murs"
+
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:176
 msgid "Create New Map"
 msgstr "Créer une nouvelle carte"
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:228
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:228
 msgid "Open Map..."
 msgstr "Ouvrir la carte..."
 
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:234
-msgid "JLM map files"
-msgstr "Fichiers de cartes pour la JLM"
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:242
-#, java-format
-msgid "Error while reading {0}"
-msgstr "Erreur lors de la lecture de {0}"
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:234
+msgid "PLM map files"
+msgstr "Fichiers de cartes pour la PLM"
 
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
 msgid "Property"
 msgstr "Propriété"
 
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
 msgid "Value"
 msgstr "Valeur"
 
 #. The editor for the name
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
 msgid "World name"
 msgstr "Nom du monde"
 
 #. ---------- world width ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
 msgid "World width"
 msgstr "Largeur du monde"
 
 #. ---------- world height ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
 msgid "World height"
 msgstr "Hauteur du monde"
 
 #. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
 msgid "Selected cell X"
 msgstr "Cellule sélectionnée X"
 
 #. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
 msgid "Selected cell Y"
 msgstr "Cellule sélectionnée Y"
 
 #. ---------- Ground color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
 msgid "Ground color (name or r/g/b)"
 msgstr "Couleur du sol (nom ou r/g/b)"
 
 #. ---------- top wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
 msgid "Top wall?"
-msgstr "Mur du haut ?"
+msgstr "Mur en haut ?"
 
 #. ---------- left wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
 msgid "Left wall?"
-msgstr "Mur de gauche ?"
+msgstr "Mur à gauche ?"
 
 #. ---------- have baggle ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
 msgid "Baggle?"
-msgstr "Baggle ?"
+msgstr "Biscuit ?"
 
 #. ---------- Buggle name ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
 msgid "Buggle name"
-msgstr "Nom du buggle"
+msgstr "Nom de la buggle"
 
 #. ---------- Buggle direction ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
 msgid "Buggle direction (N|S|E|W)"
-msgstr "Direction du buggle (N|S|E|W)"
+msgstr "Direction de la buggle (N|S|E|W)"
 
 #. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
 msgid "Buggle color (name or r/g/b)"
-msgstr "Couleur du buggle (nom ou r/g/b)"
+msgstr "Couleur de la buggle (nom ou r/g/b)"
 
 #. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
 msgid "Brush color (name or r/g/b)"
 msgstr "Couleur du pinceau (nom ou r/g/b -- rouge/vert/bleu)"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:55
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:232
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:55
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:232
 msgid "forward"
 msgstr "avancer"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:69
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:231
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:69
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:231
 msgid "backward"
 msgstr "reculer"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:83
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:233
-msgid "turn left"
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:83
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:233
+msgid "left"
 msgstr "gauche"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:91
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:234
-msgid "turn right"
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:91
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:234
+msgid "right"
 msgstr "droite"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:99
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:235
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:99
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:235
 msgid "mark"
 msgstr "marquer"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:222
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:222
 msgid "Wall hugging error"
 msgstr "Erreur : impact avec un mur"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:223
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:223
 msgid "Your buggle has collided with a wall, it hurts a lot ! ='("
 msgstr "Votre buggle a percuté un mur. Ça fait très mal ! ='( "
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:236
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:236
 msgid "Brush Color"
 msgstr "Couleur du pinceau"
 
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:237
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:237
 msgid "Buggle Color"
-msgstr "Couleur du buggle"
+msgstr "Couleur de la buggle"
 
-#: src/jlm/universe/sort/SortingButtonPanel.java:63
+#: src/plm/universe/sort/SortingButtonPanel.java:63
 msgid "go"
 msgstr "aller"
-
-#: src/jlm/universe/sort/SortingWorldView.java:51
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
-msgid "Switch to time view"
-msgstr "Accéder à la vue temporelle"
-
-#: src/jlm/universe/sort/SortingWorldView.java:53
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
-msgid "Switch to state view"
-msgstr "Accéder à la vue d'état"
-
-#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
-msgid "Invalid move"
-msgstr "Déplacement invalide"
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
-#, java-format
-msgid ""
-"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
-msgstr ""
-"Impossible de bouger du piquet {0} au piquet {1} car les seuls piquets "
-"existants sont 0, 1 et 2."
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
-#, java-format
-msgid "Cannot move from slot {0} to itself"
-msgstr "Impossible de bouger du piquet {0} à lui-même"
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
-#, java-format
-msgid "No disc to move from slot {0}"
-msgstr "Il n''y a pas de disque à déplacer sur le piquet {0}"
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
-#, java-format
-msgid ""
-"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
-"but {2} > {3}"
-msgstr ""
-"Impossible de déplacer un disque du piquet {0} au piquet {1} car les petits "
-"disques doivent rester au dessus des gros."
-
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
-#, java-format
-msgid ""
-"The player {0} of the base {1} cannot reach the hole that is too far from "
-"its position"
-msgstr ""
-"Le joueur {0} de la base {1} ne atteindre le trou, qui se trouve trop loin "
-"de sa position"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
-msgid "This is not a baseball world :-("
-msgstr "Ce n'est pas un monde de baseball :-("
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
-#, java-format
-msgid "Differing amount of bases: {0} vs {1}"
-msgstr "Nombres de bases différents : {0} vs {1}"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
-#, java-format
-msgid "Differing amount of players: {0} vs {1}"
-msgstr "Nombres de joueurs différents : {0} vs {1}"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
-#, java-format
-msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
-msgstr "Le joueur à la base {0}, position {1} diffère : {2} vs {3}\n"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:351
-#, java-format
-msgid ""
-"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
-"information:\n"
-"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
-msgstr ""
-"Ce n''est toujours pas trié !! MERCI DE RAPPORTER CE PROBLÈME, avec les "
-"informations suivantes:\n"
-"Exercice: {0}; Nombre de bases:: {1}; Situation initiale: {2}"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:388
-#, java-format
-msgid "Cannot move from base {0} since it''s not between 0 and {1}"
-msgstr "Impossible de bouger de la base {0} car ce n''est pas entre 0 et {1}"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:391
-#, java-format
-msgid "Cannot move from position {0} since it''s not between 0 and {1})"
-msgstr ""
-"Impossible de bouger de la position {0} car ce n''est pas entre 0 et {1}"
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:400
-#, java-format
-msgid ""
-"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
-"it in one move"
-msgstr ""
-"Le joueur {0} de la base {1} ne atteindre le trou, qui se trouve à la base "
-"{2}, trop loin de sa position"
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
-msgid "This is not a world of pancakes :-("
-msgstr "Ce n'est pas un monde de crêpes :-("
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
-msgid "The two worlds are of differing size"
-msgstr "Les deux mondes ne sont pas de la même taille"
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:193
-#, java-format
-msgid "Asked to flip {0} pancakes, but you must flip at least one"
-msgstr ""
-"Vous avez demandé de retourner {0} crêpes, mais il faut en retourner au "
-"moins une."
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:195
-#, java-format
-msgid ""
-"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
-msgstr ""
-"Vous avez demandé de retourner {0} crêpes, mais il n''y a que {1} crêpes sur "
-"la pile."
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:229
-#, java-format
-msgid ""
-"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
-msgstr ""
-"Impossible d''obtenir la taille de la crêpe numéro {0} car ce n''est pas "
-"entre 0 et {1}"
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:248
-#, java-format
-msgid ""
-"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
-"{1}"
-msgstr ""
-"Impossible d''obtenir l''orientation de la crêpe numéro {0} car ce n''est "
-"pas entre 0 et {1}"
diff --git a/lib/l10n-engine/jlm.pot b/lib/l10n-engine/jlm.pot
deleted file mode 100644
index c542dc6..0000000
--- a/lib/l10n-engine/jlm.pot
+++ /dev/null
@@ -1,1138 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-08-04 21:21+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: src/jlm/core/model/Game.java:146
-#, java-format
-msgid ""
-"Warning, the default programming language is neither ''Java'' nor ''python'' "
-"but {0}.\n"
-"   This language will be used to setup the worlds, possibly leading to "
-"severe issues for the exercises that don''t expect it.\n"
-"   It is safer to change the current language, and restart JLM before "
-"proceeding.\n"
-"   Alternatively, the property {1} can be changed in your configuration file "
-"($HOME/.jlm/jlm.properties"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:160
-#, java-format
-msgid ""
-"Your progress will be posted to http://identi.ca/jlmlovers This can be "
-"turned off through the property {0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:163
-#, java-format
-msgid ""
-"Your progress will NOT be posted to identica, as requested by the property "
-"{0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:166
-#, java-format
-msgid ""
-"Your progress will be posted to https://twitter.com/jlmlovers This can be "
-"turned off through the property {0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:169
-#, java-format
-msgid ""
-"Your progress will NOT be posted to twitter, as requested by the property {0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:217 src/jlm/core/model/Game.java:218
-#, java-format
-msgid "Cannot switch to lesson {0}: class Main not found."
-msgstr ""
-
-#: src/jlm/core/model/Game.java:219
-#, java-format
-msgid "Load lesson {0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:325 src/jlm/core/model/Game.java:357
-msgid "Operation cancelled by the user"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:397
-#, java-format
-msgid "The lecture {0} has no world that I can select"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:920
-#, java-format
-msgid "{0} is not writable"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:924
-#, java-format
-msgid "{0} is not a directory"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:931
-#, java-format
-msgid "Cannot create {0}"
-msgstr ""
-
-#: src/jlm/core/model/Game.java:937
-#, java-format
-msgid "Impossible to find a path for JLM datas. Tested {0}"
-msgstr ""
-
-#: src/jlm/core/model/HelpServer.java:27
-msgid "Asking to the teacher for help"
-msgstr ""
-
-#: src/jlm/core/model/HelpServer.java:29
-msgid "Cancel call for help to the teacher"
-msgstr ""
-
-#: src/jlm/core/model/LessonRunner.java:90
-#, java-format
-msgid ""
-"Congratulations, you passed this exercise.\n"
-"{0} tests passed."
-msgstr ""
-
-#: src/jlm/core/model/LessonRunner.java:92
-#: src/jlm/core/model/LessonRunner.java:98
-#: src/jlm/core/model/LessonRunner.java:107
-#: src/jlm/core/model/LessonRunner.java:113
-msgid "Exercice passed \\o/"
-msgstr ""
-
-#: src/jlm/core/model/LessonRunner.java:96
-msgid "Congratulations, you passed this exercise."
-msgstr ""
-
-#: src/jlm/core/model/LessonRunner.java:106
-#, java-format
-msgid ""
-"Congratulations, you passed this exercise.\n"
-"({0} tests passed)\n"
-"Which exercise will you do now?"
-msgstr ""
-
-#: src/jlm/core/model/LessonRunner.java:112
-msgid ""
-"Congratulations, you passed this exercise.\n"
-"Which exercise will you do now?"
-msgstr ""
-
-#: src/jlm/core/model/lesson/Exercise.java:77
-#, java-format
-msgid "The world ''{0}'' differs"
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:41
-#, java-format
-msgid "Source file {0}.{1} not found."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:88
-#, java-format
-msgid "{0}: BEGIN TEMPLATE within the template. Please fix your entity."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:108
-#, java-format
-msgid ""
-"{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:122
-#, java-format
-msgid ""
-"{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:126
-#, java-format
-msgid "{0}: Begin solution in template tail. Change it to BEGIN HIDDEN"
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:153
-#, java-format
-msgid ""
-"Parser error in file {0}. This is a parser bug (state={1}), please report."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:158
-#, java-format
-msgid ""
-"{0}: End of file unexpected after the solution but within the template. "
-"Please fix your entity."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:160
-#, java-format
-msgid ""
-"{0}: End of file unexpected (state: {1}). Did you forget to close your "
-"template or solution? Please fix your entity."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:311
-#, java-format
-msgid "World {0} is broken ({1}). Recompute all answer worlds."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:315
-#, java-format
-msgid ""
-"IO exception while reading world {0} ({1}). Recompute all answer worlds."
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:326
-#, java-format
-msgid ""
-"Recompute the answer of {0} despite the cache file, as requested by the "
-"property {1}"
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:349
-#, java-format
-msgid "Error while writing answer world of {0}:"
-msgstr ""
-
-#: src/jlm/core/model/lesson/ExerciseTemplated.java:353
-#, java-format
-msgid "Cannot write answer world of {0}. Please check the permissions."
-msgstr ""
-
-#: src/jlm/core/model/lesson/Lecture.java:88
-#: src/jlm/core/model/lesson/Lesson.java:84
-#, java-format
-msgid "File {0}.html not found."
-msgstr ""
-
-#: src/jlm/core/model/lesson/Lecture.java:97
-#: src/jlm/core/model/lesson/Lesson.java:94
-#, java-format
-msgid "Cannot find the name of mission in {0}.html"
-msgstr ""
-
-#: src/jlm/core/ui/AboutJLMDialog.java:34
-msgid "About JLM dialogTitle"
-msgstr ""
-
-#: src/jlm/core/ui/AboutJLMDialog.java:71
-#: src/jlm/core/ui/ExerciseFailedDialog.java:48
-msgid "Close"
-msgstr ""
-
-#: src/jlm/core/ui/AboutLessonDialog.java:24
-msgid "About lesson - "
-msgstr ""
-
-#: src/jlm/core/ui/AboutWorldDialog.java:32
-#, java-format
-msgid "About world - {0}"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseFailedDialog.java:29
-msgid "Exercise failed /o\\"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseFailedDialog.java:38
-msgid "You didn't manage to reach your objective."
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseFailedDialog.java:41
-msgid "Compilation error"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:73
-msgid "Switch the displayed world"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:83
-msgid "Change the speed of execution"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:90 src/jlm/core/ui/ExerciseView.java:162
-msgid "World"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:91 src/jlm/core/ui/ExerciseView.java:163
-msgid "Current world"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:95 src/jlm/core/ui/ExerciseView.java:165
-msgid "Objective"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:96 src/jlm/core/ui/ExerciseView.java:166
-msgid "Target world"
-msgstr ""
-
-#: src/jlm/core/ui/ExerciseView.java:104
-msgid "Switch the entity"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:49
-msgid "Report your feedback"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:59
-msgid ""
-"<html><p>Thanks for your feedback on JLM. We deeply need this to make the "
-"tool match <br>your needs, so please don't hesitate to report any "
-"suggestion, such as typos and <br/>unclear parts in the mission texts, other "
-"improvement to the existing exercises<br/>or prospective exercises. We will "
-"do our best to integrate your suggestions.</p><p>Please write here your "
-"suggestion (if possible in english or french), with all<br/>necessary "
-"details, and then click on 'Send' below.</p><p><b>Please provide your email "
-"address so that we can contact you back</b> but <br/>NEVER DISCLOSE A "
-"PASSWORD while reporting issues.</p><p>Note that some technical information "
-"(such as your version of JLM and Java) will <br/>automatically be added to "
-"your feedback. None of these automatic information <br/>are personal and you "
-"still have to identify yourself if you want to.</p><p>Alternatively, you can "
-"use the <a href='http://github.com/oster/JLM/issues'>github interface</a> "
-"for feedback.</p></html>"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:78
-msgid "(your feedback comes here)"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:89
-msgid "Cancel"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:94
-msgid "Do you really want to cancel your feedback and lose any edit?"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:95
-msgid "are you sure?"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:102
-msgid "Send feedback"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:142
-msgid "Thank you for your feedback"
-msgstr ""
-
-#: src/jlm/core/ui/FeedbackDialog.java:148
-#: src/jlm/core/ui/FeedbackDialog.java:157
-msgid "Error while uploading your feedback"
-msgstr ""
-
-#: src/jlm/core/ui/JlmHtmlEditorKit.java:142
-#, java-format
-msgid "<img> tag without src attribute in exercise {0}"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:40
-msgid "Choose your lesson"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:54
-msgid ""
-"<table border=\"0\" align=\"center\"><tr>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"<td valign=\"center\">  <font size=\"+2\">Welcome to the Java "
-"Learning Machine</font>  </td>\n"
-"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
-"</tr></table>\n"
-"\n"
-"<p><font size=\"+1\">The JLM is a Learning Management System (LMS) aiming at "
-"teaching the art of computer programming through interactive exercises. It "
-"offers an extensive set of varied exercises, allowing you to practice at "
-"your own pace.</font></p><br/>"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:132 src/jlm/core/ui/MainFrame.java:163
-msgid "JLM lesson files"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:141 src/jlm/core/ui/MainFrame.java:172
-msgid "Error"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:168
-msgid ""
-"<h1>Please pick a lesson</h1>\n"
-"<p>Please click on an icon on the left to select a lesson.</p>\n"
-"<p>Lessons located above are generally simpler than the ones located below.</"
-"p>"
-msgstr ""
-
-#. Create the button
-#: src/jlm/core/ui/LessonChooser.java:180
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
-msgid "Go"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:210
-#, java-format
-msgid ""
-"<p>(unable to display the short description of this lesson: file {0} not "
-"found)</p>"
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:213
-msgid "<p><b>Your score:</b> "
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:221
-#, java-format
-msgid "{0} out of {1} exercises passed."
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:225
-#, java-format
-msgid "{0} out of {1} exercises passed in {2}."
-msgstr ""
-
-#: src/jlm/core/ui/LessonChooser.java:231
-msgid "You never attempted this lesson."
-msgstr ""
-
-#: src/jlm/core/ui/LoggerPanel.java:31 src/jlm/core/ui/LoggerPanel.java:96
-msgid "Where error and other messages get written"
-msgstr ""
-
-#. === FILE menu ===
-#. for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
-#. Menus
-#: src/jlm/core/ui/MainFrame.java:152 src/jlm/core/ui/MainFrame.java:647
-msgid "File"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:154
-msgid "File related functions"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:157 src/jlm/core/ui/MainFrame.java:648
-msgid "Load lesson"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:179 src/jlm/core/ui/MainFrame.java:649
-msgid "Switch lesson"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:191 src/jlm/core/ui/MainFrame.java:416
-#: src/jlm/core/ui/MainFrame.java:644 src/jlm/core/ui/MainFrame.java:650
-msgid "Switch exercise"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:204 src/jlm/core/ui/MainFrame.java:652
-msgid "Teacher Console"
-msgstr ""
-
-#. Menu item to change the current Course
-#: src/jlm/core/ui/MainFrame.java:223 src/jlm/core/ui/MainFrame.java:653
-msgid "Choose your course"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:242 src/jlm/core/ui/MainFrame.java:654
-msgid "Quit"
-msgstr ""
-
-#. === Edit menu ===
-#: src/jlm/core/ui/MainFrame.java:250 src/jlm/core/ui/MainFrame.java:656
-msgid "Session"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:255 src/jlm/core/ui/MainFrame.java:658
-msgid "Revert Exercise"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:258 src/jlm/core/ui/MainFrame.java:659
-msgid "Export Session Cache"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:261 src/jlm/core/ui/MainFrame.java:660
-msgid "Import Session Cache"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:265 src/jlm/core/ui/MainFrame.java:661
-msgid "Debug mode"
-msgstr ""
-
-#. === Language menu ===
-#: src/jlm/core/ui/MainFrame.java:278 src/jlm/core/ui/MainFrame.java:664
-msgid "Language"
-msgstr ""
-
-#. === Programming language changing ===
-#: src/jlm/core/ui/MainFrame.java:283 src/jlm/core/ui/MainFrame.java:665
-msgid "Human"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:297 src/jlm/core/ui/MainFrame.java:666
-msgid "Computer"
-msgstr ""
-
-#. === Help menu ===
-#: src/jlm/core/ui/MainFrame.java:301 src/jlm/core/ui/MainFrame.java:668
-msgid "Help"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:305 src/jlm/core/ui/MainFrame.java:669
-msgid "Provide feedback"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:315 src/jlm/core/ui/MainFrame.java:670
-msgid "About this lesson"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:328 src/jlm/core/ui/MainFrame.java:671
-msgid "About this world"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:344 src/jlm/core/ui/MainFrame.java:673
-msgid "About JLM"
-msgstr ""
-
-#. Buttons
-#: src/jlm/core/ui/MainFrame.java:377 src/jlm/core/ui/MainFrame.java:638
-msgid "Run"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:381 src/jlm/core/ui/MainFrame.java:479
-#: src/jlm/core/ui/MainFrame.java:639
-msgid "Step"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:386 src/jlm/core/ui/MainFrame.java:640
-msgid "Stop"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:392 src/jlm/core/ui/MainFrame.java:641
-msgid "Reset"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:398 src/jlm/core/ui/MainFrame.java:642
-msgid "Demo"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:404 src/jlm/core/ui/MainFrame.java:643
-#: src/jlm/core/ui/action/HelpMe.java:37
-msgid "Call for Help"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:464
-msgid "Next"
-msgstr ""
-
-#: src/jlm/core/ui/MainFrame.java:657
-msgid "Lesson related functions"
-msgstr ""
-
-#: src/jlm/core/ui/MissionEditorTabs.java:96
-msgid "Mission"
-msgstr ""
-
-#: src/jlm/core/ui/MissionEditorTabs.java:97
-msgid "Description of the work to do"
-msgstr ""
-
-#. Create the tab with the code editor as content
-#: src/jlm/core/ui/MissionEditorTabs.java:166
-msgid "Type your code here"
-msgstr ""
-
-#: src/jlm/core/ui/StatusBar.java:113
-msgid "Saving"
-msgstr ""
-
-#: src/jlm/core/ui/StatusBar.java:117
-msgid "Compiling"
-msgstr ""
-
-#: src/jlm/core/ui/StatusBar.java:131
-msgid "Running "
-msgstr ""
-
-#: src/jlm/core/ui/StatusBar.java:135
-msgid "Playing demo "
-msgstr ""
-
-#: src/jlm/core/ui/StatusBar.java:139
-msgid "Loading "
-msgstr ""
-
-#: src/jlm/core/ui/action/HelpMe.java:37
-msgid "Cancel call"
-msgstr ""
-
-#: src/jlm/core/ui/action/PlayDemo.java:27
-msgid "Run the demo of what you should code for this exercise"
-msgstr ""
-
-#: src/jlm/core/ui/action/PlayDemo.java:28
-msgid "Impossible to run the demo right now"
-msgstr ""
-
-#: src/jlm/core/ui/action/QuitGame.java:28
-msgid "Quit the application"
-msgstr ""
-
-#: src/jlm/core/ui/action/QuitGame.java:28
-msgid "Impossible to quit the application right now"
-msgstr ""
-
-#: src/jlm/core/ui/action/Reset.java:29
-msgid "Reset your world to the initial state"
-msgstr ""
-
-#: src/jlm/core/ui/action/Reset.java:29
-msgid "World cannot be reset right now"
-msgstr ""
-
-#: src/jlm/core/ui/action/StartExecution.java:32
-msgid "Launch the execution of your code"
-msgstr ""
-
-#: src/jlm/core/ui/action/StartExecution.java:33
-msgid ""
-"Cannot launch the execution right now. Wait a bit, or interrupt current "
-"activity with the stop button"
-msgstr ""
-
-#: src/jlm/core/ui/action/StepExecution.java:22
-msgid "Execute one step of your code"
-msgstr ""
-
-#: src/jlm/core/ui/action/StepExecution.java:23
-msgid "Impossible to step your code now. Need to stop the execution first?"
-msgstr ""
-
-#: src/jlm/core/ui/action/StopExecution.java:22
-msgid "Stop your code"
-msgstr ""
-
-#: src/jlm/core/ui/action/StopExecution.java:23
-msgid "No execution to stop right now"
-msgstr ""
-
-#: src/jlm/core/ui/action/SwitchExo.java:29
-msgid "Switch to another exercise"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:178
-#, java-format
-msgid ""
-"The execution of your program raised an exception: {0}\n"
-" Please fix your code.\n"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:192
-#, java-format
-msgid "Failed to start an interpreter for {0}"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:214
-#, java-format
-msgid ""
-"No {0} script source for entity {1}. Please report that bug against JLM."
-msgstr ""
-
-#: src/jlm/universe/Entity.java:236
-#, java-format
-msgid ""
-"Syntax error at line {0}: {1}\n"
-"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:244
-msgid ""
-"NameError raised: You seem to use a non-existent identifier; Please check "
-"for typos\n"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:247
-msgid "TypeError raised: you are probably misusing a function or something.\n"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:250
-msgid ""
-"UnboundLocalError raised: you are probably using a global variable that is "
-"not declared as such.\n"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:256
-msgid "Error: there is no baggle to pickup under the buggle"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:258
-msgid "Error: a buggle cannot carry more than one baggle at the same time"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:260
-msgid "Error: your buggle just teleported to the outer space..."
-msgstr ""
-
-#: src/jlm/universe/Entity.java:262
-msgid "Error: your buggle just hit a wall. That hurts."
-msgstr ""
-
-#: src/jlm/universe/Entity.java:265
-#, java-format
-msgid ""
-"Unknown error (please report): {0}\n"
-"Its value is: {1}"
-msgstr ""
-
-#: src/jlm/universe/Entity.java:296
-#, java-format
-msgid ""
-"Script evaluation raised an exception that is not a ScriptException but a "
-"{0}.\n"
-" Please report this as a bug against JLM, with all details allowing to "
-"reproduce it.\n"
-"Exception message: {1}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:422
-msgid "Its value is 'null', which is never good."
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:429
-#, java-format
-msgid "    Its position is ({0},{1}); expected: ({2},{3}).\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:431
-#, java-format
-msgid "    Its direction is {0}; expected: {1}.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:433
-#, java-format
-msgid "    Its color is {0}; expected: {1}.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:435
-#, java-format
-msgid "    The color of its brush is {0}; expected: {1}.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:437
-msgid "    It should not carry that baggle.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:439
-msgid "    It is not carrying any baggle.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:441
-msgid "    It encountered an issue, such as bumping into a wall.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/AbstractBuggle.java:443
-msgid "    It didn't encounter any issue, such as bumping into a wall.\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:127
-#, java-format
-msgid ""
-"{0}.map: this file does not seem to be a serialized BuggleWorld (the file is "
-"empty!)"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:133
-#, java-format
-msgid ""
-"{0}.map: This file does not seem to be a serialized BuggleWorld (malformated "
-"first line: {1})"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:139
-#, java-format
-msgid "{0}.map: End of file reached before world size specification"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:144
-#, java-format
-msgid "{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:170
-#, java-format
-msgid "Cannot put a buggle on coordinate {0},{1}: that''s out of the world"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:184
-#, java-format
-msgid "Invalid buggle''s direction: {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:191
-#: src/jlm/universe/bugglequest/BuggleWorld.java:198
-#, java-format
-msgid "Invalid buggle''s color name: {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:210
-#, java-format
-msgid "Cannot define a cell on coordinate {0},{1}: that''s out of the world"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:223
-#, java-format
-msgid "Invalid color name: {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:229
-#, java-format
-msgid "Expecting ''baggle'' or ''nobaggle'' but got {0} instead"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:233
-#, java-format
-msgid "Expecting ''topwall'' or ''notopwall'' but got {0} instead"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:237
-#, java-format
-msgid "Expecting ''leftwall'' or ''noleftwall'' but got {0} instead"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:247
-#, java-format
-msgid ""
-"The cell {0},{1} seem to be defined more than once. At least, there is two "
-"baggles here, which is not allowed."
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:263
-#, java-format
-msgid ""
-"Parse error. I was expecting a cell or a buggle description but got: {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:481
-#, java-format
-msgid "  The world''s name is {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:485
-#, java-format
-msgid "  In ({0},{1})"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorld.java:488
-#, java-format
-msgid "  Something is wrong about buggle ''{0}'':\n"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:230
-msgid ", there shouldn't be this baggle"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:232
-msgid ", there should be a baggle"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:234
-msgid ", the baggle differs"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:237
-#, java-format
-msgid ", the ground should not be {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:239
-#, java-format
-msgid ", the ground is expected to be {0}, but it is {1}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:241
-#, java-format
-msgid ", the ground reads ''{0}'' (expected: ''{1}'')"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:244
-msgid ", there shouldn't be any wall at west"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:246
-msgid ", there should be a wall at west"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:249
-msgid ", there shouldn't be any wall at north"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/BuggleWorldCell.java:251
-msgid ", there should be a wall at north"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:176
-msgid "Create New Map"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:228
-msgid "Open Map..."
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:234
-msgid "JLM map files"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/MainFrame.java:242
-#, java-format
-msgid "Error while reading {0}"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
-msgid "Property"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
-msgid "Value"
-msgstr ""
-
-#. The editor for the name
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
-msgid "World name"
-msgstr ""
-
-#. ---------- world width ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
-msgid "World width"
-msgstr ""
-
-#. ---------- world height ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
-msgid "World height"
-msgstr ""
-
-#. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
-msgid "Selected cell X"
-msgstr ""
-
-#. ---------- selected cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
-msgid "Selected cell Y"
-msgstr ""
-
-#. ---------- Ground color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
-msgid "Ground color (name or r/g/b)"
-msgstr ""
-
-#. ---------- top wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
-msgid "Top wall?"
-msgstr ""
-
-#. ---------- left wall cell ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
-msgid "Left wall?"
-msgstr ""
-
-#. ---------- have baggle ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
-msgid "Baggle?"
-msgstr ""
-
-#. ---------- Buggle name ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
-msgid "Buggle name"
-msgstr ""
-
-#. ---------- Buggle direction ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
-msgid "Buggle direction (N|S|E|W)"
-msgstr ""
-
-#. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
-msgid "Buggle color (name or r/g/b)"
-msgstr ""
-
-#. ---------- Buggle color ---------------
-#: src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
-msgid "Brush color (name or r/g/b)"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:55
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:232
-msgid "forward"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:69
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:231
-msgid "backward"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:83
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:233
-msgid "turn left"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:91
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:234
-msgid "turn right"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:99
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:235
-msgid "mark"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:222
-msgid "Wall hugging error"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:223
-msgid "Your buggle has collided with a wall, it hurts a lot ! ='("
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:236
-msgid "Brush Color"
-msgstr ""
-
-#: src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java:237
-msgid "Buggle Color"
-msgstr ""
-
-#: src/jlm/universe/sort/SortingButtonPanel.java:63
-msgid "go"
-msgstr ""
-
-#: src/jlm/universe/sort/SortingWorldView.java:51
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
-msgid "Switch to time view"
-msgstr ""
-
-#: src/jlm/universe/sort/SortingWorldView.java:53
-#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
-msgid "Switch to state view"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
-msgid "Invalid move"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
-#, java-format
-msgid ""
-"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
-#, java-format
-msgid "Cannot move from slot {0} to itself"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
-#, java-format
-msgid "No disc to move from slot {0}"
-msgstr ""
-
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
-#, java-format
-msgid ""
-"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
-"but {2} > {3}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
-#, java-format
-msgid ""
-"The player {0} of the base {1} cannot reach the hole that is too far from "
-"its position"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
-msgid "This is not a baseball world :-("
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
-#, java-format
-msgid "Differing amount of bases: {0} vs {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
-#, java-format
-msgid "Differing amount of players: {0} vs {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
-#, java-format
-msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:351
-#, java-format
-msgid ""
-"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
-"information:\n"
-"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:388
-#, java-format
-msgid "Cannot move from base {0} since it''s not between 0 and {1}"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:391
-#, java-format
-msgid "Cannot move from position {0} since it''s not between 0 and {1})"
-msgstr ""
-
-#: src/lessons/sort/baseball/universe/BaseballWorld.java:400
-#, java-format
-msgid ""
-"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
-"it in one move"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
-msgid "This is not a world of pancakes :-("
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
-msgid "The two worlds are of differing size"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:193
-#, java-format
-msgid "Asked to flip {0} pancakes, but you must flip at least one"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:195
-#, java-format
-msgid ""
-"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:229
-#, java-format
-msgid ""
-"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
-msgstr ""
-
-#: src/lessons/sort/pancake/universe/PancakeWorld.java:248
-#, java-format
-msgid ""
-"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
-"{1}"
-msgstr ""
diff --git a/lib/l10n-engine/plm.pot b/lib/l10n-engine/plm.pot
new file mode 100644
index 0000000..f287c50
--- /dev/null
+++ b/lib/l10n-engine/plm.pot
@@ -0,0 +1,1571 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-08-30 14:51+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: src/lessons/maze/island/IslandMazeEntity.java:10
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:10
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:9
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:12
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:12
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:12
+#: src/lessons/welcome/array/basics/Array1Entity.java:11
+#: src/lessons/welcome/array/basics/Array2Entity.java:12
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."
+msgstr ""
+
+#: src/lessons/maze/island/IslandMazeEntity.java:15
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:15
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:14
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:17
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:17
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:17
+#: src/lessons/welcome/array/basics/Array1Entity.java:16
+#: src/lessons/welcome/array/basics/Array2Entity.java:17
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."
+msgstr ""
+
+#: src/lessons/maze/island/IslandMazeEntity.java:20
+#: src/lessons/maze/pledge/PledgeMazeEntity.java:20
+#: src/lessons/maze/randommouse/RandomMouseMazeEntity.java:19
+#: src/lessons/maze/shortestpath/ShortestPathMazeEntity.java:22
+#: src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java:22
+#: src/lessons/maze/wallfollower/WallFollowerMazeEntity.java:22
+#: src/lessons/welcome/array/basics/Array1Entity.java:21
+#: src/lessons/welcome/array/basics/Array2Entity.java:22
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiMovePanel.java:70
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:76
+msgid "Invalid move"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:134
+#, java-format
+msgid ""
+"Cannot move from slot {0} to {1}: the only existing slots are 0, 1 and 2"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:136
+#, java-format
+msgid "Cannot move from slot {0} to itself"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:138
+#, java-format
+msgid "No disc to move from slot {0}"
+msgstr ""
+
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.java:143
+#, java-format
+msgid ""
+"Cannot move disc from slot {0} to {1} small disk must remain over large ones "
+"but {2} > {3}"
+msgstr ""
+
+#. Create the button
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:65
+#: src/plm/core/ui/ChooseLessonDialog.java:180
+msgid "Go"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballMovePanel.java:75
+#, java-format
+msgid ""
+"The player {0} of the base {1} cannot reach the hole that is too far from "
+"its position"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:145
+msgid "This is not a baseball world :-("
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:149
+#, java-format
+msgid "Differing amount of bases: {0} vs {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:152
+#, java-format
+msgid "Differing amount of players: {0} vs {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:158
+#, java-format
+msgid "Player at base {0}, pos {1} differs: {2} vs {3}\n"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:371
+#, java-format
+msgid ""
+"It''s still not sorted!! PLEASE REPORT THIS BUG, along with the following "
+"information:\n"
+"Exercise: {0}; Amount of bases: {1}; Initial situation: {2}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:408
+#, java-format
+msgid "Cannot move from base {0} since it''s not between 0 and {1}"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:411
+#, java-format
+msgid "Cannot move from position {0} since it''s not between 0 and {1})"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorld.java:420
+#, java-format
+msgid ""
+"The player {0} from base {1} is too far from the hole (at base {2}) to reach "
+"it in one move"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:655
+#: src/plm/universe/sort/SortingWorldView.java:51
+msgid "Switch to time view"
+msgstr ""
+
+#: src/lessons/sort/baseball/universe/BaseballWorldView.java:657
+#: src/plm/universe/sort/SortingWorldView.java:53
+msgid "Switch to state view"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:116
+msgid "This is not a world of pancakes :-("
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:120
+msgid "The two worlds are of differing size"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:202
+#, java-format
+msgid "Asked to flip {0} pancakes, but you must flip at least one"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:204
+#, java-format
+msgid ""
+"Asked to flip {0} pancakes, but there is only {1} pancakes on this stack"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:238
+#, java-format
+msgid ""
+"Cannot get the radius of pancake #{0} because it''s not between 0 and {1}"
+msgstr ""
+
+#: src/lessons/sort/pancake/universe/PancakeWorld.java:257
+#, java-format
+msgid ""
+"Cannot get the orientation of pancake #{0} because it''s not between 0 and "
+"{1}"
+msgstr ""
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:10
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:10
+#: src/lessons/welcome/loopfor/LoopForEntity.java:8
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:10
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:9
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:9
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:9
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:10
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:9
+#: src/lessons/welcome/variables/RunFourEntity.java:8
+#: src/lessons/welcome/variables/RunHalfEntity.java:10
+#: src/lessons/welcome/variables/VariablesEntity.java:8
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward with an argument in "
+"this exercise."
+msgstr ""
+
+#: src/lessons/welcome/loopdowhile/PoucetEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseEntity.java:14
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:14
+#: src/lessons/welcome/loopfor/LoopForEntity.java:13
+#: src/lessons/welcome/loopfor/LoopStairsEntity.java:14
+#: src/lessons/welcome/loopwhile/BaggleSeekerEntity.java:14
+#: src/lessons/welcome/loopwhile/LoopWhileEntity.java:14
+#: src/lessons/welcome/loopwhile/WhileMoriaEntity.java:14
+#: src/lessons/welcome/methods/args/MethodsArgsEntity.java:14
+#: src/lessons/welcome/methods/returning/MethodsReturningEntity.java:14
+#: src/lessons/welcome/variables/RunFourEntity.java:12
+#: src/lessons/welcome/variables/RunHalfEntity.java:14
+#: src/lessons/welcome/variables/VariablesEntity.java:13
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward with an argument in "
+"this exercise."
+msgstr ""
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+msgid "You fall into water."
+msgstr ""
+
+#: src/lessons/welcome/loopfor/LoopCourseForestEntity.java:33
+#: src/plm/universe/bugglequest/SimpleBuggle.java:29
+#: src/plm/universe/bugglequest/SimpleBuggle.java:40
+#: src/plm/universe/bugglequest/SimpleBuggle.java:51
+#: src/plm/universe/bugglequest/SimpleBuggle.java:62
+#: src/plm/universe/bugglequest/SimpleBuggle.java:78
+#: src/plm/universe/bugglequest/SimpleBuggle.java:82
+#: src/plm/universe/bugglequest/SimpleBuggle.java:93
+#: src/plm/universe/bugglequest/SimpleBuggle.java:103
+#: src/plm/universe/bugglequest/SimpleBuggle.java:113
+#: src/plm/universe/bugglequest/SimpleBuggle.java:123
+msgid "Test failed"
+msgstr ""
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:10
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:66
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:71
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:67
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:71
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java:26
+#, java-format
+msgid ""
+"I''m sorry Dave, I''m affraid I cant let you use left() both in lines {0} "
+"and {1} in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:45
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:50
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:46
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:51
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:50
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:55
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:54
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:58
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:59
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:63
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:55
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:59
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:63
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:62
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:67
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:63
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:67
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:70
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:75
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:71
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:75
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:74
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:79
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:75
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:79
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this "
+"exercise."
+msgstr ""
+
+#: src/lessons/welcome/traversal/column/TraversalByColumnEntity.java:78
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java:83
+#: src/lessons/welcome/traversal/line/TraversalByLineEntity.java:79
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java:83
+msgid ""
+"I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this "
+"exercise."
+msgstr ""
+
+#.
+#. * FIXME: provide a way to debug
+#. * when templates are broken
+#.
+#. for (String n:classes.keySet())
+#. System.out.println("File "+n+":\n"+classes.get(n));
+#: src/plm/core/CompilerJava.java:289
+msgid "Compilation failed."
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:24
+#, java-format
+msgid ""
+"Syntax error at line {0}: {1}\n"
+"In doubt, check your indentation, and that you don't mix tabs and spaces\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:32
+msgid ""
+"NameError raised: You seem to use a non-existent identifier; Please check "
+"for typos\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:35
+msgid "TypeError raised: you are probably misusing a function or something.\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:38
+msgid ""
+"UnboundLocalError raised: you are probably using a global variable that is "
+"not declared as such.\n"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:44
+msgid "Error: there is no baggle to pickup under the buggle"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:46
+msgid "Error: a buggle cannot carry more than one baggle at the same time"
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:48
+msgid "Error: your buggle just teleported to the outer space..."
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:50
+msgid "Error: your buggle just hit a wall. That hurts."
+msgstr ""
+
+#: src/plm/core/PythonExceptionDecipher.java:53
+#, java-format
+msgid ""
+"Unknown error (please report): {0}\n"
+"Its value is: {1}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:151
+msgid "Scala is usable on your machine. Congratulations."
+msgstr ""
+
+#: src/plm/core/model/Game.java:153
+msgid "Please install Scala version 2.10 or higher to use it in PLM."
+msgstr ""
+
+#: src/plm/core/model/Game.java:155
+msgid "Jython is usable on your machine. Congratulations."
+msgstr ""
+
+#: src/plm/core/model/Game.java:157
+msgid "Please install jython to use the python programming language in PLM."
+msgstr ""
+
+#: src/plm/core/model/Game.java:163
+#, java-format
+msgid ""
+"Warning, the default programming language is neither ''Java'' nor ''python'' "
+"or ''Scala'' but {0}.\n"
+"   This language will be used to setup the worlds, possibly leading to "
+"severe issues for the exercises that don''t expect it.\n"
+"   It is safer to change the current language, and restart PLM before "
+"proceeding.\n"
+"   Alternatively, the property {1} can be changed in your configuration file "
+"($HOME/.plm/plm.properties)"
+msgstr ""
+
+#: src/plm/core/model/Game.java:169
+msgid ""
+"The default programming language is Scala, but your scala installation is "
+"not usable. Switching to Java instead.\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:172
+msgid ""
+"The default programming language is python, but your python installation is "
+"not usable. Switching to Java instead.\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:185
+#, java-format
+msgid ""
+"Your progress will be posted to https://twitter.com/jlmlovers This can be "
+"turned off through the property {0}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:188
+#, java-format
+msgid ""
+"Your progress will NOT be posted to twitter, as requested by the property {0}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:217
+#, java-format
+msgid "Error {0} while retrieving the Scala version: {1}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:226
+#, java-format
+msgid "Scala is too ancient. Found {0} while I need 2.10 or higher."
+msgstr ""
+
+#: src/plm/core/model/Game.java:251
+msgid ""
+"Cannot retrieve the python ScriptEngine. Are jython.jar and its dependencies "
+"in the classpath?"
+msgstr ""
+
+#: src/plm/core/model/Game.java:274
+#, java-format
+msgid ""
+"Resource {0} not found in the classpath.\n"
+"Is {1} in your classpath?"
+msgstr ""
+
+#: src/plm/core/model/Game.java:276
+#, java-format
+msgid "{0} received while searching for resource {1}: {2}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:320 src/plm/core/model/Game.java:321
+#, java-format
+msgid "Cannot switch to lesson {0}: class Main not found."
+msgstr ""
+
+#: src/plm/core/model/Game.java:322
+#, java-format
+msgid "Load lesson {0}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:428 src/plm/core/model/Game.java:462
+msgid "Operation cancelled by the user"
+msgstr ""
+
+#: src/plm/core/model/Game.java:453
+#, java-format
+msgid ""
+"Exercise {0} does not support language {1}. Fallback to {2} instead. Please "
+"consider contributing to this project by adapting this exercise to this "
+"language."
+msgstr ""
+
+#: src/plm/core/model/Game.java:502
+#, java-format
+msgid "The lecture {0} has no world that I can select"
+msgstr ""
+
+#: src/plm/core/model/Game.java:906
+msgid ""
+"Please install Scala version 2.10 or higher to use it in PLM.\n"
+"\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:907
+msgid "Scala is missing"
+msgstr ""
+
+#: src/plm/core/model/Game.java:911
+msgid ""
+"Please install jython and its dependencies to use the python programming "
+"language in PLM.\n"
+"\n"
+msgstr ""
+
+#: src/plm/core/model/Game.java:912
+msgid "Python is missing"
+msgstr ""
+
+#: src/plm/core/model/Game.java:1058
+#, java-format
+msgid "{0} is not writable"
+msgstr ""
+
+#: src/plm/core/model/Game.java:1062
+#, java-format
+msgid "{0} is not a directory"
+msgstr ""
+
+#: src/plm/core/model/Game.java:1069
+#, java-format
+msgid "Cannot create {0}"
+msgstr ""
+
+#: src/plm/core/model/Game.java:1075
+#, java-format
+msgid "Impossible to find a path for PLM data. Tested {0}"
+msgstr ""
+
+#: src/plm/core/model/HelpServer.java:27
+msgid "Asking to the teacher for help"
+msgstr ""
+
+#: src/plm/core/model/HelpServer.java:29
+msgid "Cancel call for help to the teacher"
+msgstr ""
+
+#: src/plm/core/model/LessonRunner.java:91
+#, java-format
+msgid ""
+"Congratulations, you passed this exercise.\n"
+"{0} tests passed."
+msgstr ""
+
+#: src/plm/core/model/LessonRunner.java:93
+#: src/plm/core/model/LessonRunner.java:99
+#: src/plm/core/model/LessonRunner.java:108
+#: src/plm/core/model/LessonRunner.java:114
+msgid "Exercice passed \\o/"
+msgstr ""
+
+#: src/plm/core/model/LessonRunner.java:97
+msgid "Congratulations, you passed this exercise."
+msgstr ""
+
+#: src/plm/core/model/LessonRunner.java:107
+#, java-format
+msgid ""
+"Congratulations, you passed this exercise.\n"
+"({0} tests passed)\n"
+"Which exercise will you do now?"
+msgstr ""
+
+#: src/plm/core/model/LessonRunner.java:113
+msgid ""
+"Congratulations, you passed this exercise.\n"
+"Which exercise will you do now?"
+msgstr ""
+
+#: src/plm/core/model/lesson/Exercise.java:87
+#, java-format
+msgid "The world ''{0}'' differs"
+msgstr ""
+
+#: src/plm/core/model/lesson/Exercise.java:149
+#: src/plm/core/model/lesson/Exercise.java:175
+msgid "Compilation error:"
+msgstr ""
+
+#: src/plm/core/model/lesson/Exercise.java:296
+#, java-format
+msgid ""
+"Cannot compute the answer from file {0}.{1} since I cannot read it (error "
+"was: {2})."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:43
+#, java-format
+msgid "Source file {0}.{1} not found."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:104
+#, java-format
+msgid "{0}: BEGIN TEMPLATE within the template. Please fix your entity."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:125
+#, java-format
+msgid ""
+"{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:143
+#: src/plm/core/model/lesson/ExerciseTemplated.java:167
+#, java-format
+msgid ""
+"{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:147
+#, java-format
+msgid "{0}: Begin solution in template tail. Change it to BEGIN HIDDEN"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:187
+#, java-format
+msgid ""
+"Parser error in file {0}. This is a parser bug (state={1}), please report."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:192
+#, java-format
+msgid ""
+"{0}: End of file unexpected after the solution but within the template. "
+"Please fix your entity."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:194
+#, java-format
+msgid ""
+"{0}: End of file unexpected (state: {1}). Did you forget to close your "
+"template or solution? Please fix your entity."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:350
+#, java-format
+msgid ""
+"Exercise {0} is said to be compatible with language {1}, but there is no "
+"entity for this language: {2}"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:359
+#, java-format
+msgid "{0}: No entity found. You should fix your paths and such"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:381
+#, java-format
+msgid "World {0} is broken ({1}). Recompute all answer worlds."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:385
+#, java-format
+msgid ""
+"IO exception while reading world {0} ({1}). Recompute all answer worlds."
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:396
+#, java-format
+msgid ""
+"Recompute the answer of {0} despite the cache file, as requested by the "
+"property {1}"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:421
+#, java-format
+msgid "Error while writing answer world of {0}:"
+msgstr ""
+
+#: src/plm/core/model/lesson/ExerciseTemplated.java:425
+#, java-format
+msgid "Cannot write answer world of {0}. Please check the permissions."
+msgstr ""
+
+#: src/plm/core/model/lesson/Lecture.java:90
+#: src/plm/core/model/lesson/Lesson.java:84
+#, java-format
+msgid "File {0}.html not found."
+msgstr ""
+
+#: src/plm/core/model/lesson/Lecture.java:99
+#: src/plm/core/model/lesson/Lesson.java:94
+#, java-format
+msgid "Cannot find the name of mission in {0}.html"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Ok, quit and lose my data"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:252
+msgid "Please stop! I'll save it myself first"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:253
+#, java-format
+msgid ""
+"PLM were unable to save your session file for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed so far)?"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:256
+msgid "Your changes are NOT saved"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:259
+msgid "User aborted saving on system error"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Proceed"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:356
+msgid "Abort"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:357
+#, java-format
+msgid ""
+"PLM were unable to load your code for lesson {0} ({1}:{2}).\n"
+"\n"
+" Would you like proceed anyway (and lose any solution typed previously)?"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:360
+msgid "Error while loading your session"
+msgstr ""
+
+#: src/plm/core/model/session/ZipSessionKit.java:363
+msgid "Abording on user request"
+msgstr ""
+
+#: src/plm/core/ui/AboutLessonDialog.java:24
+msgid "About lesson - "
+msgstr ""
+
+#: src/plm/core/ui/AboutPLMDialog.java:34
+msgid "About PLM dialogTitle"
+msgstr ""
+
+#: src/plm/core/ui/AboutPLMDialog.java:71
+#: src/plm/core/ui/ExerciseFailedDialog.java:49
+msgid "Close"
+msgstr ""
+
+#: src/plm/core/ui/AboutWorldDialog.java:32
+#, java-format
+msgid "About world - {0}"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:40
+msgid "Choose your lesson"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:54
+msgid ""
+"<table border=\"0\" align=\"center\"><tr>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"<td valign=\"center\">  <font size=\"+2\">Welcome to the "
+"Programmer's Learning Machine</font>  </td>\n"
+"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n"
+"</tr></table>\n"
+"\n"
+"<p><font size=\"+1\">The PLM is a Learning Management System (LMS) aiming at "
+"teaching the art of computer programming through interactive exercises. It "
+"offers an extensive set of varied exercises, allowing you to practice at "
+"your own pace.</font></p><br/>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:132
+#: src/plm/core/ui/MainFrame.java:163
+msgid "PLM lesson files"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:141
+#: src/plm/core/ui/MainFrame.java:172
+msgid "Error"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:168
+msgid ""
+"<h1>Please pick a lesson</h1>\n"
+"<p>Please click on an icon on the left to select a lesson.</p>\n"
+"<p>Lessons located above are generally simpler than the ones located below.</"
+"p>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:210
+#, java-format
+msgid ""
+"<p>(unable to display the short description of this lesson: file {0} not "
+"found)</p>"
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:213
+msgid "<p><b>Your score:</b> "
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:221
+#, java-format
+msgid "{0} out of {1} exercises passed."
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:225
+#, java-format
+msgid "{0} out of {1} exercises passed in {2}."
+msgstr ""
+
+#: src/plm/core/ui/ChooseLessonDialog.java:231
+msgid "You never attempted this lesson."
+msgstr ""
+
+#: src/plm/core/ui/ExerciseFailedDialog.java:30
+msgid "Exercise failed /o\\"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseFailedDialog.java:39
+msgid "You didn't manage to reach your objective."
+msgstr ""
+
+#: src/plm/core/ui/ExerciseFailedDialog.java:42
+msgid "Compilation error"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:74
+msgid "Switch the displayed world"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:84
+msgid "Change the speed of execution"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:91 src/plm/core/ui/ExerciseView.java:163
+msgid "World"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:92 src/plm/core/ui/ExerciseView.java:164
+msgid "Current world"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:96 src/plm/core/ui/ExerciseView.java:166
+msgid "Objective"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:97 src/plm/core/ui/ExerciseView.java:167
+msgid "Target world"
+msgstr ""
+
+#: src/plm/core/ui/ExerciseView.java:105
+msgid "Switch the entity"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:49
+msgid "Report your feedback"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:59
+msgid ""
+"<html><p>Thanks for your feedback on PLM. We deeply need this to make the "
+"tool match <br>your needs, so please don't hesitate to report any "
+"suggestion, such as typos and <br/>unclear parts in the mission texts, other "
+"improvement to the existing exercises<br/>or prospective exercises. We will "
+"do our best to integrate your suggestions.</p><p>Please write here your "
+"suggestion (if possible in english or french), with all<br/>necessary "
+"details, and then click on 'Send' below.</p><p><b>Please provide your email "
+"address so that we can contact you back</b> but <br/>NEVER DISCLOSE A "
+"PASSWORD while reporting issues.</p><p>Note that some technical information "
+"(such as your version of PLM and Java) will <br/>automatically be added to "
+"your feedback. None of these automatic information <br/>are personal and you "
+"still have to identify yourself if you want to.</p><p>Alternatively, you can "
+"use the <a href='http://github.com/oster/JLM/issues'>github interface</a> "
+"for feedback.</p></html>"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:88
+msgid "(your feedback comes here)"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:90
+msgid "Cancel"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:95
+msgid "Do you really want to cancel your feedback and lose any edit?"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:96
+msgid "are you sure?"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:103
+msgid "Send feedback"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:143
+msgid "Thank you for your feedback"
+msgstr ""
+
+#: src/plm/core/ui/FeedbackDialog.java:149
+#: src/plm/core/ui/FeedbackDialog.java:158
+msgid "Error while uploading your feedback"
+msgstr ""
+
+#: src/plm/core/ui/LoggerPanel.java:30 src/plm/core/ui/LoggerPanel.java:95
+msgid "Where error and other messages get written"
+msgstr ""
+
+#. === FILE menu ===
+#. for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
+#. Menus
+#: src/plm/core/ui/MainFrame.java:152 src/plm/core/ui/MainFrame.java:647
+msgid "File"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:154
+msgid "File related functions"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:157 src/plm/core/ui/MainFrame.java:648
+msgid "Load lesson"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:179 src/plm/core/ui/MainFrame.java:649
+msgid "Switch lesson"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:191 src/plm/core/ui/MainFrame.java:416
+#: src/plm/core/ui/MainFrame.java:644 src/plm/core/ui/MainFrame.java:650
+msgid "Switch exercise"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:204 src/plm/core/ui/MainFrame.java:652
+msgid "Teacher Console"
+msgstr ""
+
+#. Menu item to change the current Course
+#: src/plm/core/ui/MainFrame.java:223 src/plm/core/ui/MainFrame.java:653
+msgid "Choose your course"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:242 src/plm/core/ui/MainFrame.java:654
+msgid "Quit"
+msgstr ""
+
+#. === Edit menu ===
+#: src/plm/core/ui/MainFrame.java:250 src/plm/core/ui/MainFrame.java:656
+msgid "Session"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:255 src/plm/core/ui/MainFrame.java:658
+msgid "Revert Exercise"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:258 src/plm/core/ui/MainFrame.java:659
+msgid "Export Session Cache"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:261 src/plm/core/ui/MainFrame.java:660
+msgid "Import Session Cache"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:265 src/plm/core/ui/MainFrame.java:661
+msgid "Debug mode"
+msgstr ""
+
+#. === Language menu ===
+#: src/plm/core/ui/MainFrame.java:278 src/plm/core/ui/MainFrame.java:664
+msgid "Language"
+msgstr ""
+
+#. === Programming language changing ===
+#: src/plm/core/ui/MainFrame.java:283 src/plm/core/ui/MainFrame.java:665
+msgid "Human"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:297 src/plm/core/ui/MainFrame.java:666
+msgid "Computer"
+msgstr ""
+
+#. === Help menu ===
+#: src/plm/core/ui/MainFrame.java:301 src/plm/core/ui/MainFrame.java:668
+msgid "Help"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:305 src/plm/core/ui/MainFrame.java:669
+msgid "Provide feedback"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:315 src/plm/core/ui/MainFrame.java:670
+msgid "About this lesson"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:328 src/plm/core/ui/MainFrame.java:671
+msgid "About this world"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:344 src/plm/core/ui/MainFrame.java:673
+msgid "About PLM"
+msgstr ""
+
+#. Buttons
+#: src/plm/core/ui/MainFrame.java:377 src/plm/core/ui/MainFrame.java:638
+msgid "Run"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:381 src/plm/core/ui/MainFrame.java:479
+#: src/plm/core/ui/MainFrame.java:639
+msgid "Step"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:386 src/plm/core/ui/MainFrame.java:640
+msgid "Stop"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:392 src/plm/core/ui/MainFrame.java:641
+msgid "Reset"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:398 src/plm/core/ui/MainFrame.java:642
+msgid "Demo"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:404 src/plm/core/ui/MainFrame.java:643
+#: src/plm/core/ui/action/HelpMe.java:37
+msgid "Call for Help"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:464
+msgid "Next"
+msgstr ""
+
+#: src/plm/core/ui/MainFrame.java:657
+msgid "Lesson related functions"
+msgstr ""
+
+#: src/plm/core/ui/MissionEditorTabs.java:91
+msgid "Mission"
+msgstr ""
+
+#: src/plm/core/ui/MissionEditorTabs.java:92
+msgid "Description of the work to do"
+msgstr ""
+
+#. Create the tab with the code editor as content
+#: src/plm/core/ui/MissionEditorTabs.java:161
+msgid "Type your code here"
+msgstr ""
+
+#: src/plm/core/ui/PlmHtmlEditorKit.java:244
+#, java-format
+msgid "<img> tag without src attribute in exercise {0}"
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:113
+msgid "Saving"
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:117
+msgid "Compiling"
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:131
+msgid "Running "
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:135
+msgid "Playing demo "
+msgstr ""
+
+#: src/plm/core/ui/StatusBar.java:139
+msgid "Loading "
+msgstr ""
+
+#: src/plm/core/ui/action/HelpMe.java:37
+msgid "Cancel call"
+msgstr ""
+
+#: src/plm/core/ui/action/PlayDemo.java:27
+msgid "Run the demo of what you should code for this exercise"
+msgstr ""
+
+#: src/plm/core/ui/action/PlayDemo.java:28
+msgid "Impossible to run the demo right now"
+msgstr ""
+
+#: src/plm/core/ui/action/QuitGame.java:28
+msgid "Quit the application"
+msgstr ""
+
+#: src/plm/core/ui/action/QuitGame.java:28
+msgid "Impossible to quit the application right now"
+msgstr ""
+
+#: src/plm/core/ui/action/Reset.java:29
+msgid "Reset your world to the initial state"
+msgstr ""
+
+#: src/plm/core/ui/action/Reset.java:29
+msgid "World cannot be reset right now"
+msgstr ""
+
+#: src/plm/core/ui/action/StartExecution.java:32
+msgid "Launch the execution of your code"
+msgstr ""
+
+#: src/plm/core/ui/action/StartExecution.java:33
+msgid ""
+"Cannot launch the execution right now. Wait a bit, or interrupt current "
+"activity with the stop button"
+msgstr ""
+
+#: src/plm/core/ui/action/StepExecution.java:22
+msgid "Execute one step of your code"
+msgstr ""
+
+#: src/plm/core/ui/action/StepExecution.java:23
+msgid "Impossible to step your code now. Need to stop the execution first?"
+msgstr ""
+
+#: src/plm/core/ui/action/StopExecution.java:22
+msgid "Stop your code"
+msgstr ""
+
+#: src/plm/core/ui/action/StopExecution.java:23
+msgid "No execution to stop right now"
+msgstr ""
+
+#: src/plm/core/ui/action/SwitchExo.java:29
+msgid "Switch to another exercise"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:49
+msgid "PLM - Mission Editor (modified)"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:50
+msgid "PLM - Mission Editor"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:173
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:242
+#, java-format
+msgid "Error while reading {0}"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:180
+msgid "You did not save you changes. Do you want to save it before quiting?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:181
+#: src/plm/core/ui/editor/MissionEditor.java:300
+msgid "Save or loose your change?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:292
+msgid "Open Mission..."
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:299
+msgid ""
+"You did not save you changes. Do you want to save it before opening another "
+"file?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:317
+msgid "HTML files"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:325
+#, java-format
+msgid ""
+"You chose a translated mission text for edition ({0}).\n"
+"This is wrong. The translations should be handled with po4a in PLM.\n"
+"Please refer to https://github.com/oster/JLM/wiki/Working-with-the-"
+"translations for more information.\n"
+"\n"
+"Proceed anyway?"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:329
+msgid "This is a translated mission text"
+msgstr ""
+
+#: src/plm/core/ui/editor/MissionEditor.java:346
+msgid "Quit Map Editor"
+msgstr ""
+
+#: src/plm/universe/Entity.java:176
+#, java-format
+msgid ""
+"The execution of your program raised a {0} exception: {1}\n"
+" Please fix your code.\n"
+msgstr ""
+
+#: src/plm/universe/Entity.java:191
+#, java-format
+msgid ""
+"No ScriptEngine for {0}. Please check your classpath and similar settings."
+msgstr ""
+
+#: src/plm/universe/Entity.java:211
+#, java-format
+msgid ""
+"No {0} script source for entity {1}. Please report that bug against PLM."
+msgstr ""
+
+#: src/plm/universe/Entity.java:235
+msgid "Received a ScriptException that does not come from Python.\n"
+msgstr ""
+
+#: src/plm/universe/Entity.java:240
+#, java-format
+msgid ""
+"Script evaluation raised an exception that is not a ScriptException but a "
+"{0}.\n"
+" Please report this as a bug against PLM, with all details allowing to "
+"reproduce it.\n"
+"Exception message: {1}\n"
+msgstr ""
+
+#: src/plm/universe/bat/BatEntity.java:65
+#: src/plm/universe/bat/BatEntity.java:94
+#, java-format
+msgid "This test raised an exception: {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:169
+#, java-format
+msgid ""
+"You tried to access a cell with Y={0}, but the maximal Y in this world is "
+"{1}."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:171
+#, java-format
+msgid ""
+"You tried to access a cell with X={0}, but the maximal X in this world is "
+"{1}."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:190
+#: src/plm/universe/bugglequest/AbstractBuggle.java:226
+#, java-format
+msgid "You tried to set X to {0}, but the maximal X in this world is {1}."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:209
+#: src/plm/universe/bugglequest/AbstractBuggle.java:224
+#, java-format
+msgid "You tried to set Y to {0}, but the maximal Y in this world is {1}."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:343
+msgid "There is no baggle to pick up here."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:345
+msgid "Your are already carrying a baggle."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:424
+msgid "Its value is 'null', which is never good."
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:431
+#, java-format
+msgid "    Its position is ({0},{1}); expected: ({2},{3}).\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:433
+#, java-format
+msgid "    Its direction is {0}; expected: {1}.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:435
+#, java-format
+msgid "    Its color is {0}; expected: {1}.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:437
+#, java-format
+msgid "    The color of its brush is {0}; expected: {1}.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:439
+msgid "    It should not carry that baggle.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:441
+msgid "    It is not carrying any baggle.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:443
+msgid "    It encountered an issue, such as bumping into a wall.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/AbstractBuggle.java:445
+msgid "    It didn't encounter any issue, such as bumping into a wall.\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:122
+#, java-format
+msgid ""
+"{0}: The path to the map on disk should not include the .map extension (or "
+"it won''t work in jarfiles). Please fix your exercise."
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:130
+#, java-format
+msgid ""
+"{0}.map: this file does not seem to be a serialized BuggleWorld (the file is "
+"empty!)"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:136
+#, java-format
+msgid ""
+"{0}.map: This file does not seem to be a serialized BuggleWorld (malformated "
+"first line: {1})"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:142
+#, java-format
+msgid "{0}.map: End of file reached before world size specification"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:147
+#, java-format
+msgid "{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:173
+#, java-format
+msgid "Cannot put a buggle on coordinate {0},{1}: that''s out of the world"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:187
+#, java-format
+msgid "Invalid buggle''s direction: {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:194
+#: src/plm/universe/bugglequest/BuggleWorld.java:201
+#, java-format
+msgid "Invalid buggle''s color name: {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:213
+#, java-format
+msgid "Cannot define a cell on coordinate {0},{1}: that''s out of the world"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:226
+#, java-format
+msgid "Invalid color name: {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:232
+#, java-format
+msgid "Expecting ''baggle'' or ''nobaggle'' but got {0} instead"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:236
+#, java-format
+msgid "Expecting ''topwall'' or ''notopwall'' but got {0} instead"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:240
+#, java-format
+msgid "Expecting ''leftwall'' or ''noleftwall'' but got {0} instead"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:250
+#, java-format
+msgid ""
+"The cell {0},{1} seem to be defined more than once. At least, there is two "
+"baggles here, which is not allowed."
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:266
+#, java-format
+msgid ""
+"Parse error. I was expecting a cell or a buggle description but got: {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:543
+#, java-format
+msgid "  The world''s name is {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:547
+#, java-format
+msgid "  In ({0},{1})"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorld.java:550
+#, java-format
+msgid "  Something is wrong about buggle ''{0}'':\n"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:129
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:136
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:143
+msgid "There is already a baggle here."
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:231
+msgid ", there shouldn't be this baggle"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:233
+msgid ", there should be a baggle"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:235
+msgid ", the baggle differs"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:238
+#, java-format
+msgid ", the ground should not be {0}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:240
+#, java-format
+msgid ", the ground is expected to be {0}, but it is {1}"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:242
+#, java-format
+msgid ", the ground reads ''{0}'' (expected: ''{1}'')"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:245
+msgid ", there shouldn't be any wall at west"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:247
+msgid ", there should be a wall at west"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:250
+msgid ", there shouldn't be any wall at north"
+msgstr ""
+
+#: src/plm/universe/bugglequest/BuggleWorldCell.java:252
+msgid ", there should be a wall at north"
+msgstr ""
+
+#: src/plm/universe/bugglequest/exception/BuggleWallException.java:10
+msgid "Buggles cannot traverse walls"
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:176
+msgid "Create New Map"
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:228
+msgid "Open Map..."
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/MainFrame.java:234
+msgid "PLM map files"
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+msgid "Property"
+msgstr ""
+
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:58
+msgid "Value"
+msgstr ""
+
+#. The editor for the name
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:72
+msgid "World name"
+msgstr ""
+
+#. ---------- world width ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:84
+msgid "World width"
+msgstr ""
+
+#. ---------- world height ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:104
+msgid "World height"
+msgstr ""
+
+#. ---------- selected cell ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:124
+msgid "Selected cell X"
+msgstr ""
+
+#. ---------- selected cell ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:146
+msgid "Selected cell Y"
+msgstr ""
+
+#. ---------- Ground color ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:167
+msgid "Ground color (name or r/g/b)"
+msgstr ""
+
+#. ---------- top wall cell ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:184
+msgid "Top wall?"
+msgstr ""
+
+#. ---------- left wall cell ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:206
+msgid "Left wall?"
+msgstr ""
+
+#. ---------- have baggle ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:228
+msgid "Baggle?"
+msgstr ""
+
+#. ---------- Buggle name ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:259
+msgid "Buggle name"
+msgstr ""
+
+#. ---------- Buggle direction ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:270
+msgid "Buggle direction (N|S|E|W)"
+msgstr ""
+
+#. ---------- Buggle color ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:299
+msgid "Buggle color (name or r/g/b)"
+msgstr ""
+
+#. ---------- Buggle color ---------------
+#: src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java:315
+msgid "Brush color (name or r/g/b)"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:55
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:232
+msgid "forward"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:69
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:231
+msgid "backward"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:83
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:233
+msgid "left"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:91
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:234
+msgid "right"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:99
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:235
+msgid "mark"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:222
+msgid "Wall hugging error"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:223
+msgid "Your buggle has collided with a wall, it hurts a lot ! ='("
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:236
+msgid "Brush Color"
+msgstr ""
+
+#: src/plm/universe/bugglequest/ui/BuggleButtonPanel.java:237
+msgid "Buggle Color"
+msgstr ""
+
+#: src/plm/universe/sort/SortingButtonPanel.java:63
+msgid "go"
+msgstr ""
diff --git a/lib/l10n/README b/lib/l10n/README
index fdbf4db..ffcb64f 100644
--- a/lib/l10n/README
+++ b/lib/l10n/README
@@ -4,7 +4,7 @@ are located in the ../l10n-engine directory, updated from the main ant
 build.xml file.
 
 Files used to translate the missions:
-- jlm.pot: master file of missions text
+- plm.pot: master file of missions text
 - XX.po: translations of missions into language XX
 Simply run "po4a po4a.conf" from the root directory to update the
 translated html files (check the wiki for more info).
diff --git a/lib/l10n/fr.po b/lib/l10n/fr.po
index f02f3f7..69812e7 100644
--- a/lib/l10n/fr.po
+++ b/lib/l10n/fr.po
@@ -5,12 +5,12 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: JLM mission texts\n"
-"POT-Creation-Date: 2013-08-04 11:21+0300\n"
-"PO-Revision-Date: 2013-08-04 11:27+0200\n"
-"Last-Translator: Automatically generated\n"
+"Project-Id-Version: PLM mission texts\n"
+"POT-Creation-Date: 2013-08-28 21:02+0300\n"
+"PO-Revision-Date: 2013-08-28 21:02+0200\n"
+"Last-Translator: Martin Quinson\n"
 "Language-Team: none\n"
-"Language: \n"
+"Language: French\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
@@ -18,18 +18,18 @@ msgstr ""
 
 #. type: Content of: <h2>
 #: lib/doc/MainWindow.html:1
-msgid "The JLM Main Window"
-msgstr "La fenêtre principale de JLM"
+msgid "The PLM Main Window"
+msgstr "La fenêtre principale de PLM"
 
 #. type: Content of: outside any tag (error?)
 #: lib/doc/MainWindow.html:3
 msgid ""
-"The JLM working environment should be self-explanatory, in particular with "
+"The PLM working environment should be self-explanatory, in particular with "
 "the tool tips appearing when your mouse is over the elements.  Here is a "
 "little explanation of the components in case you fail to understand "
 "something. The main window is made of 5 main components:"
 msgstr ""
-"L'environnement de travail de JLM devrait être immédiat à maîtriser, en "
+"L'environnement de travail de PLM devrait être immédiat à maîtriser, en "
 "particulier avec les bulles d'aide qui apparaissent quand votre souris "
 "survole les éléments. Voici une petite explication des composants au cas où "
 "quelque chose vous échappe. La fenêtre principale est faite de 5 composants "
@@ -215,7 +215,7 @@ msgid ""
 "An <b>Objective</b> tab displaying the world as it must be by the end of the "
 "exercise."
 msgstr ""
-"Un onglet <b>Objective</b> qui permet d'afficher la vue du monde tel qu'il "
+"Un onglet <b>Objectif</b> qui permet d'afficher la vue du monde tel qu'il "
 "doit être à la fin de l'exercice."
 
 #. type: Content of: <ul><li><ul><li>
@@ -272,12 +272,12 @@ msgstr ""
 "elle avance."
 
 #. type: Content of: <h1>
-#: src/jlm/universe/sort/SortingWorld.html:1
+#: src/plm/universe/sort/SortingWorld.html:1
 msgid "Sorting World"
 msgstr "Monde des tris"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/sort/SortingWorld.html:2
+#: src/plm/universe/sort/SortingWorld.html:2
 msgid ""
 "This world provides tools to experiment with the sorting algorithms. It can "
 "be used in two different ways: the first one is naturally to write the "
@@ -293,58 +293,52 @@ msgstr ""
 "différences d'efficacité entre eux."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/sort/SortingWorld.html:8
+#: src/plm/universe/sort/SortingWorld.html:8
 msgid "Methods available to sorting algorithms"
 msgstr "Méthodes disponibles pour les algorithmes de tri"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
+#: src/plm/universe/sort/SortingWorld.html:10
 msgid "<b>Method</b>"
 msgstr "<b>Méthode</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
+#: src/plm/universe/sort/SortingWorld.html:10
 msgid "<b>Action</b>"
 msgstr "<b>Action</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
+#: src/plm/universe/sort/SortingWorld.html:10
 msgid "<b>Cost</b>"
 msgstr "<b>Coût</b>"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:11
-msgid "int getValueCount()"
-msgstr "int getValueCount()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:12
-msgid "getValueCount()"
-msgstr "getValueCount()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:11
+msgid "[!java]int [/!]getValueCount() [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getNombreValeurs() [!scala]:Int[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:13
+#: src/plm/universe/sort/SortingWorld.html:12
 msgid "Returns the amount of values in the array"
 msgstr "Retourne le nombre de valeurs dans le tableau"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:13
-#: src/jlm/universe/sort/SortingWorld.html:38
+#: src/plm/universe/sort/SortingWorld.html:12
+#: src/plm/universe/sort/SortingWorld.html:30
 msgid "none"
 msgstr "aucun"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:15
-msgid "boolean isSmaller(int i, int j)"
-msgstr "boolean isSmaller(int i, int j)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:16
-msgid "isSmaller(i, j)"
-msgstr "isSmaller(i, j)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:14
+msgid ""
+"[!java]boolean [/!]isSmaller([!java]int [/!]i[!scala]:Int[/!], [!java]int "
+"[/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]"
+msgstr ""
+"[!java]boolean [/!]plusPetit([!java]int [/!]i[!scala]:Int[/!], [!java]int "
+"[/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:17
+#: src/plm/universe/sort/SortingWorld.html:15
 msgid ""
 "Returns true if the content of cell i is strictly smaller than the one of "
 "cell j"
@@ -353,146 +347,121 @@ msgstr ""
 "de la case j"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:17
+#: src/plm/universe/sort/SortingWorld.html:15
 msgid "two reads"
 msgstr "deux lectures"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:18
-msgid "boolean isSmallerThan(int i, int val)"
-msgstr "boolean isSmallerThan(int i, int val)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:19
-msgid "isSmallerThan(i, val)"
-msgstr "isSmallerThan(i, val)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:16
+msgid ""
+"[!java]boolean [/!]isSmallerThan([!java]int [/!]i[!scala]:Int[/!], [!"
+"java]int [/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]"
+msgstr ""
+"[!java]boolean [/!]plusPetitQue([!java]int [/!]i[!scala]:Int[/!], [!java]int "
+"[/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:20
+#: src/plm/universe/sort/SortingWorld.html:17
 msgid ""
-"Returns true if the content of cell i is strictly smaller than value "
-"<code>val</code>"
+"Returns true if the content of cell i is strictly smaller than the "
+"<code>value</code>"
 msgstr ""
 "Retourne vrai ssi le contenu de la case i est strictement inférieur à la "
-"valeur val"
+"valeur <code>value</code>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:20
-#: src/jlm/universe/sort/SortingWorld.html:31
+#: src/plm/universe/sort/SortingWorld.html:17
+#: src/plm/universe/sort/SortingWorld.html:25
 msgid "one read"
 msgstr "une lecture"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:22
-msgid "void swap(int i, int j)"
-msgstr "void swap(int i, int j)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:23
-msgid "swap(i, j)"
-msgstr "swap(i, j)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:19
+msgid ""
+"[!java]void [/!]swap([!java]int [/!]i[!scala]:Int[/!], [!java]int [/!]j[!"
+"scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]echange([!java]int [/!]i[!scala]:Int[/!], [!java]int [/!]j[!"
+"scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:24
+#: src/plm/universe/sort/SortingWorld.html:20
 msgid "Swaps the content of cell i and the one of cell j"
 msgstr "Echange le contenu de la case i avec celui de la case j"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:24
+#: src/plm/universe/sort/SortingWorld.html:20
 msgid "two reads, two writes"
 msgstr "deux lectures, deux écritures"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:25
-msgid "void copy(int from, int to)"
-msgstr "void copy(int from, int to)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:26
-msgid "copy(from, to)"
-msgstr "copy(from, to)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:21
+msgid ""
+"[!java]void [/!]copy([!java]int [/!]from[!scala]:Int[/!], [!java]int [/!]to[!"
+"scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]copie([!java]int [/!]depuis[!scala]:Int[/!], [!java]int "
+"[/!]vers[!scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:27
+#: src/plm/universe/sort/SortingWorld.html:22
 msgid "Copy the content of cell 'from' into the cell 'to'"
-msgstr "Copie le contenu de la case 'from' dans la case 'to'"
+msgstr "Copie le contenu de la case 'depuis' dans la case 'vers'"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:27
+#: src/plm/universe/sort/SortingWorld.html:22
 msgid "one read, one write"
 msgstr "une lecture, une écriture"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:29
-msgid "int getValue(int idx)"
-msgstr "int getValue(int idx)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:30
-msgid "getValue(idx)"
-msgstr "getValue(idx)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:24
+msgid "[!java]int [/!]getValue([!java]int [/!]idx[!scala]:Int[/!])"
+msgstr "[!java]int [/!]getValeur([!java]int [/!]idx[!scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:31
+#: src/plm/universe/sort/SortingWorld.html:25
 msgid "Returns the value of cell idx"
 msgstr "Retourne la valeur de la case idx"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:32
-msgid "void setValue(int idx, int val)"
-msgstr "void setValue(int idx, int val)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:33
-msgid "setValue(idx, val)"
-msgstr "setValue(idx, val)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:26
+msgid ""
+"[!java]void [/!]setValue([!java]int [/!]idx[!scala]:Int[/!], [!java]int "
+"[/!]value[!scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]setValeur([!java]int [/!]idx[!scala]:Int[/!], [!java]int "
+"[/!]valeur[!scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:34
-msgid "Sets cell 'idx' to the value 'val'"
-msgstr "Affecte la valeur 'val' à la case 'idx'"
+#: src/plm/universe/sort/SortingWorld.html:27
+msgid "Sets cell 'idx' to the <code>value</code>"
+msgstr "Affecte la valeur 'valeur' à la case 'idx'"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:34
+#: src/plm/universe/sort/SortingWorld.html:27
 msgid "one write"
 msgstr "une écriture"
 
-#. type: Content of: <pre>
-#: src/jlm/universe/sort/SortingWorld.html:36
-#: src/jlm/universe/turtles/TurtleWorld.html:72
-#: src/jlm/universe/bugglequest/BuggleWorld.html:35
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:25
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:25
-#, no-wrap
-msgid "boolean isSelected()"
-msgstr "boolean isSelected()"
-
-#. type: Content of: <pre>
-#: src/jlm/universe/sort/SortingWorld.html:37
-#: src/jlm/universe/turtles/TurtleWorld.html:73
-#: src/jlm/universe/bugglequest/BuggleWorld.html:35
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:26
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:26
-#, no-wrap
-msgid "isSelected()"
-msgstr "isSelected()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:29
+msgid "[!java]boolean [/!]isSelected() [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/sort/SortingWorld.html:38
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:27
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:27
+#: src/plm/universe/sort/SortingWorld.html:30
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:24
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:21
 msgid ""
 "Returns whether the current world is selected in the graphical interface."
 msgstr "Renvoi si le monde actuel est sélectionné dans l'interface graphique."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/sort/SortingWorld.html:42
+#: src/plm/universe/sort/SortingWorld.html:34
 msgid "History view"
 msgstr "Vue de l'historique du monde"
 
 #. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:43
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:7
+#: src/plm/universe/sort/SortingWorld.html:35
 msgid ""
 "It is not enough to sort the array to pass the exercises. Your solution must "
 "strictly follow the expected behavior of each exercise. This is enforced by "
@@ -509,7 +478,7 @@ msgstr ""
 "comportement attendu et le comportement effectif."
 
 #. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:50
+#: src/plm/universe/sort/SortingWorld.html:42
 msgid ""
 "To help in this process, it is possible to graphically explore the history "
 "of your sorting algorithm. Switch to the Objective view and use the "
@@ -522,8 +491,8 @@ msgstr ""
 "l'état courant du monde et la vue de son histoire."
 
 #. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:55
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:19
+#: src/plm/universe/sort/SortingWorld.html:47
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:18
 msgid ""
 "The history view is a bit hairly at the first glance, but actually rather "
 "simple: The time flows from left to right on this graph, and each row is a "
@@ -541,11 +510,11 @@ msgstr ""
 "Quand deux lignes se croises, cela signifie que les valeurs du tableau ont "
 "été échangées à ce moment de l'historique; un embranchement signifie que la "
 "valeur a été copiée; une valeur en violet suivie d'un point d'interrogation "
-"a été lue avec getValue() et une valeur en rouge suivie d'un point "
-"d'exclamation a été écrite avec setValue()."
+"a été lue avec getValeur() et une valeur en rouge suivie d'un point "
+"d'exclamation a été écrite avec setValeur()."
 
 #. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:64
+#: src/plm/universe/sort/SortingWorld.html:56
 msgid ""
 "This view, inspired from Aldo Cortesi, reveals very helpful understand the "
 "inner behavior of sorting algorithms."
@@ -554,17 +523,17 @@ msgstr ""
 "comportement des algorithmes de tri."
 
 #. type: Content of: <h1>
-#: src/jlm/universe/turtles/TurtleWorld.html:1
-msgid "TurtleWorld"
-msgstr "Monde des tortues"
+#: src/plm/universe/turtles/TurtleWorld.html:1
+msgid "The universe of turtles"
+msgstr "L'univers des tortues"
 
 #. type: Content of: <p>
-#: src/jlm/universe/turtles/TurtleWorld.html:3
-msgid "This universe is an adaptation of LOGO for the Java Learning Machine."
+#: src/plm/universe/turtles/TurtleWorld.html:3
+msgid "This is an adaptation of LOGO for the Java Learning Machine."
 msgstr "Cet univers est une adaptation de LOGO pour la Java Learning Machine."
 
 #. type: Content of: <p>
-#: src/jlm/universe/turtles/TurtleWorld.html:5
+#: src/plm/universe/turtles/TurtleWorld.html:5
 msgid ""
 "It is directly inspired from the work of the mathematician Seymour Papert in "
 "the 60's. Inspired from the swiss psycholog Jean Piaget, he came up with a "
@@ -579,267 +548,213 @@ msgstr ""
 "là où elles marchent et à qui on peut donner des ordres simples."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:11
+#: src/plm/universe/turtles/TurtleWorld.html:11
 msgid "Functions to move the turtle"
 msgstr "Fonctions pour déplacer la tortue"
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:13
+#: src/plm/universe/turtles/TurtleWorld.html:13
 #, no-wrap
 msgid ""
-"void forward(double steps)\n"
-"void backward(double steps)"
+"[!java]void [/!]forward([!java]double [/!]steps[!scala]:Double[/!])\n"
+"[!java]void [/!]backward([!java]double [/!]steps[!scala]:Double[/!])"
 msgstr ""
-"void forward(double nbPas)\n"
-"void backward(double nbPas)"
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:15
-#, no-wrap
-msgid ""
-"forward(steps)\n"
-"backward(steps)"
-msgstr ""
-"forward(nbPas)\n"
-"backward(nbPas)"
+"[!java]void [/!]avance([!java]double [/!]steps[!scala]:Double[/!])\n"
+"[!java]void [/!]recule([!java]double [/!]steps[!scala]:Double[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:17
+#: src/plm/universe/turtles/TurtleWorld.html:15
 msgid "Moves forward or backward of the requested amount of steps."
-msgstr "Avance (forward) ou recule (backward) du nombre de pas demandés."
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:19
-#, no-wrap
-msgid ""
-"void turnRight(double angle)\n"
-"void turnLeft(double angle)"
-msgstr ""
-"void turnRight(double angle)\n"
-"void turnLeft(double angle)"
+msgstr "Avance ou recule du nombre de pas demandé."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:21
+#: src/plm/universe/turtles/TurtleWorld.html:17
 #, no-wrap
 msgid ""
-"turnRight(angle)\n"
-"turnLeft(angle)"
+"[!java]void [/!]right([!java]double [/!]angle[!scala]:Double[/!])\n"
+"[!java]void [/!]left([!java]double [/!]angle[!scala]:Double[/!])"
 msgstr ""
-"turnRight(angle)\n"
-"turnLeft(angle)"
+"[!java]void [/!]droite([!java]double [/!]angle[!scala]:Double[/!])\n"
+"[!java]void [/!]gauche([!java]double [/!]angle[!scala]:Double[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:23
+#: src/plm/universe/turtles/TurtleWorld.html:19
 msgid "Turns left or right of the given angle (in degrees)."
-msgstr ""
-"Tourne à gauche (left) ou à droite (right) du nombre de l'angle indiqué (en "
-"degrés)."
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:25
-#, no-wrap
-msgid ""
-"double getX()\n"
-"double getY()"
-msgstr ""
-"double getX()\n"
-"double getY()"
+msgstr "Tourne à gauche ou à droite de l'angle indiqué (en degrés)."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:27
+#: src/plm/universe/turtles/TurtleWorld.html:21
 #, no-wrap
 msgid ""
-"getX()\n"
-"getY()"
+"[!java]double [/!]getX()[!scala]:Double[/!]\n"
+"[!java]double [/!]getY()[!scala]:Double[/!]"
 msgstr ""
-"getX()\n"
-"getY()"
+"[!java]double [/!]getX()[!scala]:Double[/!]\n"
+"[!java]double [/!]getY()[!scala]:Double[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:29
+#: src/plm/universe/turtles/TurtleWorld.html:23
 msgid "Returns the current position of the turtle."
 msgstr "Retourne la position acutelle de la tortue."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:31
+#: src/plm/universe/turtles/TurtleWorld.html:25
 #, no-wrap
 msgid ""
-"void setX(double x)\n"
-"void setY(double y)\n"
-"void setPos(double x, double y)"
+"[!java]void [/!]setX([!java]double [/!]x[!scala]:Double[/!])\n"
+"[!java]void [/!]setY([!java]double [/!]y[!scala]:Double[/!])\n"
+"[!java]void [/!]setPos([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])"
 msgstr ""
-"void setX(double x)\n"
-"void setY(double y)\n"
-"void setPos(double x, double y)"
+"[!java]void [/!]setX([!java]double [/!]x[!scala]:Double[/!])\n"
+"[!java]void [/!]setY([!java]double [/!]y[!scala]:Double[/!])\n"
+"[!java]void [/!]setPos([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])"
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:28
+msgid "Teleports the turtle to a new position (without leaving any trace)."
+msgstr "Téléporte la tortue à une nouvelle position (sans laisser de trace)."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:34
+#: src/plm/universe/turtles/TurtleWorld.html:30
 #, no-wrap
-msgid ""
-"setX(x)\n"
-"setY(y)\n"
-"setPos(x,y)"
-msgstr ""
-"setX(x)\n"
-"setY(y)\n"
-"setPos(x,y)"
+msgid "[!java]void [/!]moveTo([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])"
+msgstr "[!java]void [/!]allerVers([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:37
-msgid "Teleports the turtle to a new position."
-msgstr "Téléporte la tortue à une nouvelle position."
+#: src/plm/universe/turtles/TurtleWorld.html:31
+msgid "Moves the turtle to a new position."
+msgstr "Déplace la tortue à une nouvelle position."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:39
+#: src/plm/universe/turtles/TurtleWorld.html:33
 #, no-wrap
-msgid "double getHeading()"
-msgstr "double getHeading()"
+msgid "[!java]void [/!]circle([!java]double [/!]radius[!scala]:Double[/!])"
+msgstr "[!java]void [/!]cercle([!java]double [/!]rayon[!scala]:Double[/!])"
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:34
+msgid "Draw a circle of the specified radius centered on the turtle."
+msgstr "Dessine un cercle du rayon demandé et centré sur la tortue."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:40
+#: src/plm/universe/turtles/TurtleWorld.html:36
 #, no-wrap
-msgid "getHeading()"
-msgstr "getHeading()"
+msgid "[!java]double [/!]getHeading()[!scala]:Double[/!]"
+msgstr "[!java]double [/!]getCap()[!scala]:Double[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:41
+#: src/plm/universe/turtles/TurtleWorld.html:37
 msgid "Returns the current heading of the turtle (in degrees)."
 msgstr "Retourne le cap actuel de la tortue (en degrés)."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:43
-#, no-wrap
-msgid "void getHeading(double angle)"
-msgstr "void getHeading(double angle)"
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:44
+#: src/plm/universe/turtles/TurtleWorld.html:39
 #, no-wrap
-msgid "getHeading(angle)"
-msgstr "getHeading(angle)"
+msgid "[!java]void [/!]setHeading([!java]double [/!]angle[!scala]:Double[/!])"
+msgstr "[!java]void [/!]setCap([!java]double [/!]angle[!scala]:Double[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:45
+#: src/plm/universe/turtles/TurtleWorld.html:40
 msgid "Sets a new heading to the turtle (in degrees)."
 msgstr "Change le cap de la tortue à l'angle indiqué (en degrés)."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:47
+#: src/plm/universe/turtles/TurtleWorld.html:42
 msgid "Functions about the pen"
 msgstr "Fonctions à propos du stylo"
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:49
-#, no-wrap
-msgid "void penUp()"
-msgstr "void penUp()"
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:50
+#: src/plm/universe/turtles/TurtleWorld.html:44
 #, no-wrap
-msgid "penUp()"
-msgstr "penUp()"
+msgid "[!java]void [/!]penUp()"
+msgstr "[!java]void [/!]leveCrayon()"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:51
+#: src/plm/universe/turtles/TurtleWorld.html:45
 msgid ""
 "Moves the pen up (turtles have pens, not brushes as buggles). The turtle "
 "will not leave any trace during its subsequent moves."
-msgstr "Remonte le stylo de la tortue (les tortues ont des stylos, pas des brosses comme les buggles). La tortue ne laissera plus de trace lors de ses déplacements suivants."
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:54
-#, no-wrap
-msgid "void penDown()"
-msgstr "void penDown()"
+msgstr ""
+"Remonte le crayon de la tortue (les tortues ont des crayons, pas des brosses "
+"comme les buggles). La tortue ne laissera plus de trace lors de ses "
+"déplacements suivants."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:55
+#: src/plm/universe/turtles/TurtleWorld.html:48
 #, no-wrap
-msgid "penDown()"
-msgstr "penDown()"
+msgid "[!java]void [/!]penDown()"
+msgstr "[!java]void [/!]baisseCrayon()"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:56
+#: src/plm/universe/turtles/TurtleWorld.html:49
 msgid ""
 "Moves the pen down. The turtle will leave a trace during its subsequent "
 "moves."
-msgstr "Descend le stylo. La tortue laissera une trace lors de ses prochains déplacements."
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:58
-#, no-wrap
-msgid "boolean isPenDown()"
-msgstr "boolean isPenDown()"
+msgstr ""
+"Descend le stylo. La tortue laissera une trace lors de ses prochains "
+"déplacements."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:59
+#: src/plm/universe/turtles/TurtleWorld.html:51
 #, no-wrap
-msgid "isPenDown()"
-msgstr "isPenDown()"
+msgid "[!java]boolean [/!]isPenDown()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estCrayonBaisse()[!scala]:Boolean[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:60
+#: src/plm/universe/turtles/TurtleWorld.html:52
 msgid "Returns the current pen position as a boolean."
 msgstr "Retourne si le stylo est actuellement baissé ou non."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/turtles/TurtleWorld.html:62
-#: src/jlm/universe/bugglequest/BuggleWorld.html:25
-#: src/lessons/turmites/universe/TurmiteWorld.html:18
+#: src/plm/universe/turtles/TurtleWorld.html:54
+#: src/plm/universe/bugglequest/BuggleWorld.html:25
 #, no-wrap
-msgid "Color getColor()"
-msgstr "Color getColor()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/turtles/TurtleWorld.html:63
-#: src/jlm/universe/bugglequest/BuggleWorld.html:25
-#, no-wrap
-msgid "getColor()"
-msgstr "getColor()"
+msgid "[!java]Color [/!]getColor()[!scala]:Color[/!]"
+msgstr "[!java]Color [/!]getCouleur()[!scala]:Color[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:64
+#: src/plm/universe/turtles/TurtleWorld.html:55
 msgid "Returns the current pen color."
 msgstr "Retourne la couleur actuelle du stylo."
 
 #. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:66
-#, no-wrap
-msgid "void setColor(Color color)"
-msgstr "void setColor(Color color)"
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:67
+#: src/plm/universe/turtles/TurtleWorld.html:57
 #, no-wrap
-msgid "getColor(color)"
-msgstr "getColor(color)"
+msgid "[!java]void [/!]setColor([!java]Color [/!]color[!scala]:Color[/!])"
+msgstr "[!java]void [/!]setCouleur([!java]Color [/!]couleur[!scala]:Color[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:68
+#: src/plm/universe/turtles/TurtleWorld.html:58
 msgid "Changes the pen color."
 msgstr "Modifier la couleur du stylo."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:70
+#: src/plm/universe/turtles/TurtleWorld.html:60
 msgid "Other functions"
 msgstr "Autres fonctions"
 
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:62
+#: src/plm/universe/bugglequest/BuggleWorld.html:35
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:23
+#, no-wrap
+msgid "[!java]boolean [/!]isSelected()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estChoisie()[!scala]:Boolean[/!]"
+
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:74
+#: src/plm/universe/turtles/TurtleWorld.html:63
 msgid ""
 "Returns whether the current turtle is selected in the graphical interface."
-msgstr "Renvoie si la tortue actuelle est sélectionnée dans l'interface graphique."
+msgstr ""
+"Renvoie si la tortue actuelle est sélectionnée dans l'interface graphique."
 
 #. type: Content of: <h1>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:1
-#: src/lessons/turmites/universe/TurmiteWorld.html:1
+#: src/plm/universe/bugglequest/BuggleWorld.html:1
 msgid "BuggleWorld"
 msgstr "Le monde des Buggles"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/bugglequest/BuggleWorld.html:2
-#: src/lessons/turmites/universe/TurmiteWorld.html:2
+#: src/plm/universe/bugglequest/BuggleWorld.html:2
 msgid ""
 "This world was invented by Lyn Turbak, at Wellesley College. It is full of "
 "Buggles, little animals understanding simple orders, and offers numerous "
@@ -852,564 +767,386 @@ msgstr ""
 "objets, colorier le sol, se cogner à des murs, etc."
 
 #. type: Content of: <h2>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:7
-#: src/lessons/turmites/universe/TurmiteWorld.html:7
+#: src/plm/universe/bugglequest/BuggleWorld.html:7
 msgid "Methods understood by buggles"
 msgstr "Méthodes comprises par les buggles"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:9
-#: src/lessons/turmites/universe/TurmiteWorld.html:9
+#: src/plm/universe/bugglequest/BuggleWorld.html:9
 msgid "<b>Moving</b>"
 msgstr "<b>Bouger</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:9
-#: src/lessons/turmites/universe/TurmiteWorld.html:9
+#: src/plm/universe/bugglequest/BuggleWorld.html:9
 msgid "(See also the note on exceptions, below)"
 msgstr "(voir aussi la note sur les exceptions, plus bas)"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10
-#: src/lessons/turmites/universe/TurmiteWorld.html:10
+#: src/plm/universe/bugglequest/BuggleWorld.html:10
+#: src/lessons/turmites/universe/TurmiteWorld.html:9
 msgid "<b>Turn left"
 msgstr "<b>Tourner à gauche"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10
-#: src/lessons/turmites/universe/TurmiteWorld.html:10
+#: src/plm/universe/bugglequest/BuggleWorld.html:10
+#: src/lessons/turmites/universe/TurmiteWorld.html:9
 msgid "Turn right"
 msgstr "Tourner à droite"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10
-#: src/lessons/turmites/universe/TurmiteWorld.html:10
+#: src/plm/universe/bugglequest/BuggleWorld.html:10
+#: src/lessons/turmites/universe/TurmiteWorld.html:9
 msgid "Turn back"
 msgstr "Se retourner"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10
-#: src/lessons/turmites/universe/TurmiteWorld.html:10
+#: src/plm/universe/bugglequest/BuggleWorld.html:10
+#: src/lessons/turmites/universe/TurmiteWorld.html:9
 msgid "Moving forward"
 msgstr "Avancer"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10
-#: src/lessons/turmites/universe/TurmiteWorld.html:10
+#: src/plm/universe/bugglequest/BuggleWorld.html:10
+#: src/lessons/turmites/universe/TurmiteWorld.html:9
 msgid "Moving back</b>"
 msgstr "Reculer</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:11
-#: src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnLeft()"
-msgstr "void turnLeft()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:11
-msgid "turnLeft()"
-msgstr "turnLeft()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:11
+#: src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]left()"
+msgstr "[!java]void [/!]gauche()"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:12
-#: src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnRight()"
-msgstr "void turnRight()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:12
+#: src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]right()"
+msgstr "[!java]void [/!]droite()"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:12
-msgid "turnRight()"
-msgstr "turnRight()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:13
+#: src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]back()"
+msgstr "[!java]void [/!]retourne()"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:14
 #: src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnBack()"
-msgstr "void turnBack()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:13
-msgid "turnBack()"
-msgstr "turnBack()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:14
-msgid "void forward() or void forward(int steps)"
-msgstr "void forward() ou void forward(nbPas)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:14
-msgid "forward() or forward(steps)"
-msgstr "forward() ou forward(nbPas)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:15
-msgid "void backward() or void backward(int steps)"
-msgstr "void backward() ou void backward(nbPas)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:15
-msgid "backward() or backward(steps)"
-msgstr "backward() ou backward(nbPas)"
+msgid ""
+"[!java]void [/!]forward() or [!java]void [/!]forward([!java]int [/!]steps[!"
+"scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]avance() ou [!java]void [/!]avance([!java]int [/!]steps[!"
+"scala]:Int[/!])"
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:15
+#: src/lessons/turmites/universe/TurmiteWorld.html:12
+msgid ""
+"[!java]void [/!]backward() or [!java]void [/!]backward([!java]int [/!]steps[!"
+"scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]recule() or [!java]void [/!]recule([!java]int [/!]steps[!"
+"scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16
-#: src/lessons/turmites/universe/TurmiteWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
 msgid "<b>Get X coordinate"
 msgstr "<b>Obtenir l'abcisse"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16
-#: src/lessons/turmites/universe/TurmiteWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
 msgid "Get Y coordinate"
 msgstr "Obtenir l'ordonnée"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16
-#: src/lessons/turmites/universe/TurmiteWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
 msgid "Set X coordinate"
 msgstr "Changer l'abcisse"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16
-#: src/lessons/turmites/universe/TurmiteWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
 msgid "Set Y coordinate"
 msgstr "Changer l'ordonnée"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16
-#: src/lessons/turmites/universe/TurmiteWorld.html:13
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
 msgid "Set position</b>"
 msgstr "Changer la position</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:17
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "int getX()"
-msgstr "int getX()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:17
+msgid "[!java]int [/!]getX()[!scala]:Int[/!]"
+msgstr "[!java]int [/!]getX()[!scala]:Int[/!]"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:17
-msgid "getX()"
-msgstr "getX()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:18
+msgid "[!java]int [/!]getY()[!scala]:Int[/!]"
+msgstr "[!java]int [/!]getY()[!scala]:Int[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:18
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "int getY()"
-msgstr "int getY()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:18
-msgid "getY()"
-msgstr "getY()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:19
-msgid "void setX(int x)"
-msgstr "void setX(int x)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:19
-msgid "setX(x)"
-msgstr "setX(x)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:20
-msgid "void setY(int y)"
-msgstr "void setY(int y)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:20
-msgid "setY(y)"
-msgstr "setY(y)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:21
-msgid "void setPos(int x,int y)"
-msgstr "void setPos(int x,int y)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:21
-msgid "setPos(x,y)"
-msgstr "setPos(x,y)"
+#: src/plm/universe/bugglequest/BuggleWorld.html:19
+msgid "[!java]void [/!]setX([!java]int [/!]x[!scala]:Int[/!])"
+msgstr "[!java]void [/!]setX([!java]int [/!]x[!scala]:Int[/!])"
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:20
+msgid "[!java]void [/!]setY([!java]int [/!]y[!scala]:Int[/!])"
+msgstr "[!java]void [/!]setY([!java]int [/!]y[!scala]:Int[/!])"
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:21
+msgid ""
+"[!java]void [/!]setPos([!java]int [/!]x[!scala]:Int[/!], [!java]int [/!]y[!"
+"scala]:Int[/!])"
+msgstr ""
+"[!java]void [/!]setPos([!java]int [/!]x[!scala]:Int[/!], [!java]int [/!]y[!"
+"scala]:Int[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:23
-#: src/lessons/turmites/universe/TurmiteWorld.html:16
+#: src/plm/universe/bugglequest/BuggleWorld.html:23
 msgid "<b>Information on the buggle</b>"
 msgstr "<b>Informations sur la buggle</b>"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:24
-#: src/lessons/turmites/universe/TurmiteWorld.html:17
+#: src/plm/universe/bugglequest/BuggleWorld.html:24
 msgid "<b>Get the color"
 msgstr "<b>Obtenir la couleur"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:24
-#: src/lessons/turmites/universe/TurmiteWorld.html:17
+#: src/plm/universe/bugglequest/BuggleWorld.html:24
 msgid "Set the color</b>"
 msgstr "Changer la couleur</b>"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:26
-msgid "void setColor(Color c)"
-msgstr "void setColor(Color c)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:26
-msgid "setColor(color)"
-msgstr "setColor(color)"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:26
+msgid "[!java]void [/!]setColor([!java]Color [/!]c[!scala]:Color[/!])"
+msgstr "[!java]void [/!]setCouleur([!java]Color [/!]c[!scala]:Color[/!])"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:27
-#: src/lessons/turmites/universe/TurmiteWorld.html:19
+#: src/plm/universe/bugglequest/BuggleWorld.html:27
 msgid "<b>Look for a wall forward"
 msgstr "<b>Chercher un mur devant"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:27
-#: src/lessons/turmites/universe/TurmiteWorld.html:19
+#: src/plm/universe/bugglequest/BuggleWorld.html:27
 msgid "Look for a wall backward</b>"
 msgstr "Chercher un mur derriere</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:28
-#: src/lessons/turmites/universe/TurmiteWorld.html:20
-msgid "boolean isFacingWall()"
-msgstr "boolean isFacingWall()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:28
-msgid "isFacingWall()"
-msgstr "isFacingWall()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:28
+msgid "[!java]boolean [/!]isFacingWall()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estFaceMur()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:29
-#: src/lessons/turmites/universe/TurmiteWorld.html:20
-msgid "boolean isBackingWall()"
-msgstr "boolean isBackingWall()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:29
-msgid "isBackingWall()"
-msgstr "isBackingWall()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:29
+msgid "[!java]boolean [/!]isBackingWall()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estDosMur()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30
-#: src/lessons/turmites/universe/TurmiteWorld.html:21
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
 msgid "<b>Get heading"
 msgstr "<b>Obtenir la direction"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30
-#: src/lessons/turmites/universe/TurmiteWorld.html:21
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
 msgid "Set heading</b>"
 msgstr "Changer la direction</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30
-#: src/lessons/turmites/universe/TurmiteWorld.html:21
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
 msgid "valid directions are:"
 msgstr "Les directions valides sont :"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:31
-#: src/lessons/turmites/universe/TurmiteWorld.html:22
-msgid "Direction getDirection()"
-msgstr "Direction getDirection()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:31
-msgid "getDirection()"
-msgstr "getDirection()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:32
-msgid "void setDirection(Direction dir)"
-msgstr "void setDirection(Direction dir)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:32
-msgid "setDirection(direction)"
-msgstr "setDirection(direction)"
+#: src/plm/universe/bugglequest/BuggleWorld.html:31
+msgid "[!java]Direction [/!]getDirection()[!scala]:Direction[/!]"
+msgstr "[!java]Direction [/!]getDirection()[!scala]:Direction[/!]"
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:32
+msgid ""
+"[!java]void [/!]setDirection([!java]Direction [/!]dir[!scala]:Direction[/!])"
+msgstr ""
+"[!java]void [/!]setDirection([!java]Direction [/!]dir[!scala]:Direction[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:33
-#: src/lessons/turmites/universe/TurmiteWorld.html:22
+#: src/plm/universe/bugglequest/BuggleWorld.html:33
 msgid "Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST"
-msgstr "Direction.NORTH, Direction.EAST, Direction.SOUTH et Direction.WEST"
+msgstr ""
+"Direction.NORTH (le nord), Direction.EAST (l'est), Direction.SOUTH (le sud) "
+"et Direction.WEST (l'ouest)"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:34
+#: src/plm/universe/bugglequest/BuggleWorld.html:34
 msgid "Check whether the buggle is currently <b>selected in the interface</b>"
 msgstr ""
 "Renvoi si la buggle est actuellement <b>sélectionnée dans l'interface</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:37
-#: src/lessons/turmites/universe/TurmiteWorld.html:24
+#: src/plm/universe/bugglequest/BuggleWorld.html:37
 msgid "<b>About the brush</b>"
 msgstr "<b>À propos de la brosse</b>"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38
-#: src/lessons/turmites/universe/TurmiteWorld.html:25
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
 msgid "<b>Brush down"
 msgstr "<b>Baisser la brosse"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38
-#: src/lessons/turmites/universe/TurmiteWorld.html:25
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
 msgid "Brush up"
 msgstr "Lever la brosse"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38
-#: src/lessons/turmites/universe/TurmiteWorld.html:25
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
 msgid "Get brush position</b>"
 msgstr "Obtenir la position de la brosse</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:39
-#: src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "void brushUp()"
-msgstr "void brushUp()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:39
-msgid "brushUp()"
-msgstr "brushUp()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:39
+msgid "[!java]void [/!]brushUp()"
+msgstr "[!java]void [/!]leveBrosse()"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:40
-#: src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "void brushDown()"
-msgstr "void brushDown()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:40
-msgid "brushDown()"
-msgstr "brushDown()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:40
+msgid "[!java]void [/!]brushDown()"
+msgstr "[!java]void [/!]baisseBrosse()"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:41
-#: src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "boolean isBrushDown()"
-msgstr "boolean isBrushDown()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:41
-msgid "isBrushDown()"
-msgstr "isBrushDown()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:41
+msgid "[!java]boolean [/!]isBrushDown()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estBrosseLevee()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:42
-#: src/lessons/turmites/universe/TurmiteWorld.html:27
+#: src/plm/universe/bugglequest/BuggleWorld.html:42
 msgid "<b>Change the brush color"
 msgstr "<b>Modifier la couleur de la brosse"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:42
-#: src/lessons/turmites/universe/TurmiteWorld.html:27
+#: src/plm/universe/bugglequest/BuggleWorld.html:42
 msgid "Get the color of the brush</b>"
 msgstr "Obtenir la couleur de la brosse</b>"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:43
-msgid "void setBrushColor(Color c)"
-msgstr "void setBrushColor(Color c)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:43
-msgid "setBrushColor(color)"
-msgstr "setBrushColor(color)"
-
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:44
-#: src/lessons/turmites/universe/TurmiteWorld.html:28
-msgid "Color getBrushColor()"
-msgstr "Color getBrushColor()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:43
+msgid "[!java]void [/!]setBrushColor([!java]Color [/!]c[!scala]:Color[/!])"
+msgstr "[!java]void [/!]setCouleurBrosse([!java]Color [/!]c[!scala]:Color[/!])"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:44
-msgid "getBrushColor()"
-msgstr "getBrushColor()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:44
+msgid "[!java]Color [/!]getBrushColor()[!scala]:Color[/!]"
+msgstr "[!java]Color [/!]getCouleurBrosse()[!scala]:Color[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:46
-#: src/lessons/turmites/universe/TurmiteWorld.html:30
+#: src/plm/universe/bugglequest/BuggleWorld.html:46
 msgid "<b>Interacting with the world</b>"
 msgstr "<b>Interagir avec le monde</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:47
-#: src/lessons/turmites/universe/TurmiteWorld.html:31
+#: src/plm/universe/bugglequest/BuggleWorld.html:47
+#: src/lessons/turmites/universe/TurmiteWorld.html:14
 msgid "<b>Get the color of the ground</b>"
 msgstr "<b>Obtenir la couleur du sol</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:48
-#: src/lessons/turmites/universe/TurmiteWorld.html:31
-msgid "Color getGroundColor()"
-msgstr "Color getGroundColor()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:48
-msgid "getGroundColor()"
-msgstr "getGroundColor()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:48
+#: src/lessons/turmites/universe/TurmiteWorld.html:14
+msgid "[!java]Color [/!]getGroundColor()[!scala]:Color[/!]"
+msgstr "[!java]Color [/!]getCouleurSol()[!scala]:Color[/!]"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50
-#: src/lessons/turmites/universe/TurmiteWorld.html:33
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
 msgid "<b>Look for a baggle on the ground"
-msgstr "<b>Chercher un baggle par terre"
+msgstr "<b>Chercher un biscuit par terre"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50
-#: src/lessons/turmites/universe/TurmiteWorld.html:33
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
 msgid "Look for a baggle in bag"
-msgstr "Chercher un baggle dans ses poches"
+msgstr "Chercher un biscuit dans ses poches"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50
-#: src/lessons/turmites/universe/TurmiteWorld.html:33
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
 msgid "Pickup a baggle"
-msgstr "Prendre un baggle"
+msgstr "Prendre un biscuit"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50
-#: src/lessons/turmites/universe/TurmiteWorld.html:33
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
 msgid "Drop a baggle</b>"
-msgstr "Poser un baggle</b>"
+msgstr "Poser un biscuit</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:51
-#: src/lessons/turmites/universe/TurmiteWorld.html:34
+#: src/plm/universe/bugglequest/BuggleWorld.html:51
 msgid "(see the note on exceptions)"
 msgstr "(voir la note sur les exceptions)"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:52
-#: src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "boolean isOverBaggle()"
-msgstr "boolean isOverBaggle()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:52
-msgid "isOverBaggle()"
-msgstr "isOverBaggle()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:52
+msgid "[!java]boolean [/!]isOverBaggle()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estSurBiscuit()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:53
-#: src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "boolean isCarryingBaggle()"
-msgstr "boolean isCarryingBaggle()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:53
-msgid "isCarryingBaggle()"
-msgstr "isCarryingBaggle()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:53
+msgid "[!java]boolean [/!]isCarryingBaggle()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]porteBiscuit()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:54
-#: src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "void pickupBaggle()"
-msgstr "void pickupBaggle()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:54
-msgid "pickupBaggle()"
-msgstr "pickupBaggle()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:54
+msgid "[!java]void [/!]pickupBaggle()"
+msgstr "[!java]void [/!]prendBiscuit()"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:55
-#: src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "void dropBaggle()"
-msgstr "void dropBaggle()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:55
-msgid "dropBaggle()"
-msgstr "dropBaggle()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:55
+msgid "[!java]void [/!]dropBaggle()"
+msgstr "[!java]void [/!]poseBiscuit()"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57
-#: src/lessons/turmites/universe/TurmiteWorld.html:37
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
 msgid "<b>Look for a message"
 msgstr "<b>Chercher un message"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57
-#: src/lessons/turmites/universe/TurmiteWorld.html:37
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
 msgid "Add a message"
 msgstr "Ajouter un message"
 
 #. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57
-#: src/lessons/turmites/universe/TurmiteWorld.html:37
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
 msgid "Read the message"
 msgstr "Lire le message"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57
-#: src/lessons/turmites/universe/TurmiteWorld.html:37
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
 msgid "Erase the message</b>"
 msgstr "Effacer le message</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:58
-#: src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "boolean isOverMessage()"
-msgstr "boolean isOverMessage()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:58
-msgid "isOverMessage()"
-msgstr "isOverMessage()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:59
-msgid "void writeMessage(String msg)"
-msgstr "void writeMessage(String msg)"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:59
-msgid "writeMessage(msg)"
-msgstr "writeMessage(msg)"
+#: src/plm/universe/bugglequest/BuggleWorld.html:58
+msgid "[!java]boolean [/!]isOverMessage()[!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estSurMessage()[!scala]:Boolean[/!]"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:60
-#: src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "String readMessage()"
-msgstr "String readMessage()"
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:60
-msgid "readMessage()"
-msgstr "readMessage()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:59
+msgid "[!java]void [/!]writeMessage([!java]String [/!]msg[!scala]:String[/!])"
+msgstr "[!java]void [/!]ecritMessage([!java]String [/!]msg[!scala]:String[/!])"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:61
-#: src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "void clearMessage()"
-msgstr "void clearMessage()"
+#: src/plm/universe/bugglequest/BuggleWorld.html:60
+msgid "[!java]String [/!]readMessage()[!scala]:String[/!]"
+msgstr "[!java]String [/!]litMessage()[!scala]:String[/!]"
 
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:61
-msgid "clearMessage()"
-msgstr "clearMessage()"
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:61
+msgid "[!java]void [/!]clearMessage()"
+msgstr "[!java]void [/!]effaceMessage()"
 
 #. type: Content of: <h2>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:64
-#: src/lessons/turmites/universe/TurmiteWorld.html:41
+#: src/plm/universe/bugglequest/BuggleWorld.html:64
 msgid "Note on exceptions"
 msgstr "Note sur les exceptions"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/bugglequest/BuggleWorld.html:65
-#: src/lessons/turmites/universe/TurmiteWorld.html:42
+#: src/plm/universe/bugglequest/BuggleWorld.html:65
 msgid ""
 "Regular buggles throw a BuggleWallException exception if you ask them to "
 "traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you "
@@ -1427,8 +1164,7 @@ msgstr ""
 "exception AlreadyHaveBaggleException."
 
 #. type: Content of: <p>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:71
-#: src/lessons/turmites/universe/TurmiteWorld.html:48
+#: src/plm/universe/bugglequest/BuggleWorld.html:71
 msgid ""
 "SimpleBuggles (ie, the one used in first exercises) display an error message "
 "on problem so that you don't need to know what an exception is."
@@ -1572,7 +1308,7 @@ msgid ""
 "and compiling. Also, they have a good editor that we could reuse. Finally, "
 "they have a strong testing infrastructure with junit ensuring that their "
 "tool still work after modifications (that's something we are seriously "
-"missing in JLM). I'm really thinking that the two tools should converge to "
+"missing in PLM). I'm really thinking that the two tools should converge to "
 "something stronger. The only argument for not doing so (beside the amount of "
 "work it'll take) is that each of us get the credit for each tool where "
 "things would be more fuzzy on a mixed tool. But I don't care, the mixed tool "
@@ -1584,7 +1320,7 @@ msgstr ""
 "interfaces d'aide pour le débuggage et la compilation. Il y a aussi un bon "
 "éditeur que l'on pourrait réutiliser. Finallement, ils ont un infrastructure "
 "solide de tests avec junit assurant que leur outil fonctionne toujours après "
-"modifications ( c'est quelquechose qui manque sérieusement dans la JLM). Je "
+"modifications ( c'est quelquechose qui manque sérieusement dans la PLM). Je "
 "pense vraiment que les deux outils devriaent fusionner en quelquechose de "
 "plus fort. Le seul argument pour ne pas le faire ( en plus de la quantité de "
 "travail nécessaire ) est que chacun d'entre nous reçoit les honneurs pour "
@@ -1644,15 +1380,15 @@ msgstr ""
 msgid ""
 "This gives me the following todo actions: * Check whether tools.jar gives a "
 "working com.sun.jdi package * Find the DrJava bug around debugging to help "
-"them, and so that I can steal parts of their code about it for JLM (it's "
-"BSD'ed while JLM is mainly GPL'ed for now -- I'll have to ask them for an "
+"them, and so that I can steal parts of their code about it for PLM (it's "
+"BSD'ed while PLM is mainly GPL'ed for now -- I'll have to ask them for an "
 "exception). That would be better since their helper interface seem to be "
 "able to deal with several debuggers (eclipse, sun or openjdk). That's quite "
 "a large amount of work I'd like to avoid duplicating.  * Check wheter I can "
 "get tracing info from ASM. It may be more robust to JVM variants than the "
-"debugging approach. On the other hand, debugging is a neat feature for JLM "
-"as is.  * Work on the convergence of JLM and DrJava. Beside of the licencing "
-"issue, it will also complicate the ongoing integration of JLM within Debian, "
+"debugging approach. On the other hand, debugging is a neat feature for PLM "
+"as is.  * Work on the convergence of PLM and DrJava. Beside of the licencing "
+"issue, it will also complicate the ongoing integration of PLM within Debian, "
 "since DrJava is composed of [[5 separated modules|http://drjava.org/docs/"
 "developer/ch02s03.html]] that can only be integrated as separated source "
 "packages. As every java package, no source archive is distributed, and they "
@@ -1662,7 +1398,7 @@ msgstr ""
 "Cela me donne lesactions à faire suivantes: * Vérifier quel tools.jar donne "
 "un package com.sun.jdi qui fonctionne * Trouver le bug de DrJava au niveau "
 "du débuggage pour les aider, et ainsi je pourrai réutiliser des parties de "
-"leur code à ce propos dans la JLM ( c'est un projet BSD tandis que ja JLM "
+"leur code à ce propos dans la PLM ( c'est un projet BSD tandis que ja PLM "
 "est majoritairement GPL jusqu'à présent -- il faudra que je leur demande de "
 "faire une exception). Cela serait mieux puisque leur interface d'aide semble "
 "être capable de travailler avec différents débuggers (eclipse, sun ou "
@@ -1670,9 +1406,9 @@ msgstr ""
 "d'avoir à dupliquer. * Trouver comment je peux obtenir les informations de "
 "traçage d'ASM. Cela semble être plus robuste aux variations de la JVM que "
 "l'approchage via débuggage. D'un autre côté, le débuggage est une "
-"fonctionnalité bien tenue dans la JLM.* Travailler sur la fusion entre JLM "
+"fonctionnalité bien tenue dans la PLM.* Travailler sur la fusion entre PLM "
 "et DrJava. En plus du problème de license, cela compliquera l'intégration "
-"actuelle de JLM dans Debian puisque DrJava est composé de [[5 modules "
+"actuelle de PLM dans Debian puisque DrJava est composé de [[5 modules "
 "séparés|http://drjava.org/docs/developer/ch02s03.html]] qui peuvent "
 "seulement être intégré en tant que source package distincts. Comme tout "
 "package java, aucune source n'est distribuée et ils doivent les récupérer "
@@ -1686,20 +1422,20 @@ msgstr "  "
 
 #. type: Content of: <table><tr><td><font>
 #: src/lessons/chooser/LessonChooser.html:3
-msgid "Welcome to the Java Learning Machine"
-msgstr "Bienvenue dans la Java Learning Machine"
+msgid "Welcome to the Programmer's Learning Machine"
+msgstr "Bienvenue dans PLM, l'exerciseur du programmeur"
 
 #. type: Content of: outside any tag (error?)
 #: src/lessons/chooser/LessonChooser.html:7
 msgid ""
-"The JLM is a Learning Management System (LMS) aiming at teaching the art of "
+"The PLM is a Learning Management System (LMS) aiming at teaching the art of "
 "computer programming through interactive exercises. It offers an extensive "
 "set of varied exercises, allowing you to practice at your own pace."
 msgstr ""
-"Vous venez de lancer la Java Learning Machine.  Il s'agit d'une plate-forme\n"
-"pédagogique destinée à simplifier l'apprentissage de la programmation "
-"offrant\n"
-"un grand nombre d'exercises pour vous permettre de progresser à votre rythme."
+"Vous venez de lancer PLM, l'exerciseur du programmeur (Programmer's Learning "
+"Machine). Il s'agit d'une plate-forme pédagogique destinée à simplifier "
+"l'apprentissage de la programmation offrant un grand nombre d'exercises pour "
+"vous permettre de progresser à votre rythme."
 
 #. type: Content of: <h1>
 #: src/lessons/chooser/LessonChooser.html:11
@@ -1709,10 +1445,10 @@ msgstr "Choisissez une leçon"
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:13
 msgid ""
-"<a href=\"jlm://lessons.welcome\">Welcome lesson</a> This lesson is intended "
+"<a href=\"plm://lessons.welcome\">Welcome lesson</a> This lesson is intended "
 "to lead the first steps in programming of absolute beginners."
 msgstr ""
-"<a href=\"jlm://lessons.welcome\">Premiers pas</a> Cette leçon est destinée "
+"<a href=\"plm://lessons.welcome\">Premiers pas</a> Cette leçon est destinée "
 "à\n"
 "guider les premiers pas en programmation de débutants sans aucune "
 "connaissance préalable."
@@ -1720,48 +1456,48 @@ msgstr ""
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:16
 msgid ""
-"<a href=\"jlm://lessons.maze\">Escape the maze</a> Will you escape the mazes?"
+"<a href=\"plm://lessons.maze\">Escape the maze</a> Will you escape the mazes?"
 msgstr ""
-"<a href=\"jlm://lessons.maze\">Labyrinthes</a> Saurez vous vous échapper du\n"
+"<a href=\"plm://lessons.maze\">Labyrinthes</a> Saurez vous vous échapper du\n"
 "labyrinthe?"
 
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:18
 msgid ""
-"<a href=\"jlm://lessons.bat.string1\">String lesson</a> A bunch of exercises "
+"<a href=\"plm://lessons.bat.string1\">String lesson</a> A bunch of exercises "
 "on strings."
 msgstr ""
-"<a href=\"jlm://lessons.bat.string1\">Chaînes</a> Quelques exercices sur "
+"<a href=\"plm://lessons.bat.string1\">Chaînes</a> Quelques exercices sur "
 "les\n"
 "chaînes de caractères."
 
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:20
 msgid ""
-"<a href=\"jlm://lessons.sort\">Sorting lesson</a> This short lesson proposes "
+"<a href=\"plm://lessons.sort\">Sorting lesson</a> This short lesson proposes "
 "to discover the classical sorting algorithms by practice."
 msgstr ""
-"<a href=\"jlm://lessons.sort\">Algorithmes de tri</a> Cette leçon vous "
+"<a href=\"plm://lessons.sort\">Algorithmes de tri</a> Cette leçon vous "
 "propose\n"
 "de découvrir les algorithmes classiques de tri par la pratique."
 
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:23
 msgid ""
-"<a href=\"jlm://lessons.recursion\">Recursion lesson</a> Build some "
+"<a href=\"plm://lessons.recursion\">Recursion lesson</a> Build some "
 "classical geometric figures through recursion."
 msgstr ""
-"<a href=\"jlm://lessons.recursion\">Récursivité</a> Construisez des figures\n"
+"<a href=\"plm://lessons.recursion\">Récursivité</a> Construisez des figures\n"
 "géométriques classiques par récursivité."
 
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:26
 msgid ""
-"<a href=\"jlm://lessons.lightbot\">LightBot</a> In this little game, you "
+"<a href=\"plm://lessons.lightbot\">LightBot</a> In this little game, you "
 "must program graphically a little robot to instruct it how to switch the "
 "lights off. It is a brain teaser for programmer."
 msgstr ""
-"<a href=\"jlm://lessons.lightbot\">LightBot</a> Dans ce petit jeu, vous "
+"<a href=\"plm://lessons.lightbot\">LightBot</a> Dans ce petit jeu, vous "
 "devez\n"
 "programmer graphiquement un petit robot pour lui faire éteindre des\n"
 "lumières. C'est un petit casse-tête pour programmeurs."
@@ -1769,10 +1505,10 @@ msgstr ""
 #. type: Content of: <ul><li>
 #: src/lessons/chooser/LessonChooser.html:30
 msgid ""
-"<a href=\"jlm://lessons.smn\">Digital Manual Science</a> Some activities "
+"<a href=\"plm://lessons.smn\">Digital Manual Science</a> Some activities "
 "developed for the Sciences Manuelles du Numérique (Digital Manual Science)"
 msgstr ""
-"<a href=\"jlm://lessons.smn\">Sciences Manuelles du Numérique</a> "
+"<a href=\"plm://lessons.smn\">Sciences Manuelles du Numérique</a> "
 "Différentes activitées développées pour les Sciences Manuelles du Numérique"
 
 #. type: Content of: <h1>
@@ -1815,7 +1551,8 @@ msgstr " "
 #: src/lessons/welcome/Main.html:9 src/lessons/welcome/Main.html:92
 #: src/lessons/welcome/Main.html:175 src/lessons/welcome/Main.html:255
 #: src/lessons/welcome/Main.html:349 src/lessons/welcome/Main.html:429
-#: src/lessons/welcome/Main.html:469 src/lessons/welcome/basics/Basics.html:1
+#: src/lessons/welcome/Main.html:469
+#: src/lessons/welcome/instructions/Instructions.html:1
 msgid "Instructions"
 msgstr "Instructions"
 
@@ -1840,7 +1577,7 @@ msgstr "Instructions conditionnelles et expressions"
 #: src/lessons/welcome/Main.html:95 src/lessons/welcome/Main.html:178
 #: src/lessons/welcome/Main.html:258 src/lessons/welcome/Main.html:352
 #: src/lessons/welcome/Main.html:432 src/lessons/welcome/Main.html:472
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:1
+#: src/lessons/welcome/loopwhile/LoopWhile.html:1
 msgid "While loops"
 msgstr "Boucles tant que <tt>(while)</tt>"
 
@@ -1857,7 +1594,7 @@ msgstr "Variables"
 #: src/lessons/welcome/Main.html:133 src/lessons/welcome/Main.html:180
 #: src/lessons/welcome/Main.html:260 src/lessons/welcome/Main.html:354
 #: src/lessons/welcome/Main.html:434 src/lessons/welcome/Main.html:474
-#: src/lessons/welcome/loop/forloop/LoopFor.html:1
+#: src/lessons/welcome/loopfor/LoopFor.html:1
 msgid "For loops"
 msgstr "Boucles pour <tt>(for)</tt>"
 
@@ -1886,12 +1623,11 @@ msgstr "Méthodes"
 msgid "Switch"
 msgstr "Switch"
 
-#. type: Content of: <h2>
+#. type: Content of: <table><tr><td>
 #: src/lessons/welcome/Main.html:18 src/lessons/welcome/Main.html:101
 #: src/lessons/welcome/Main.html:184 src/lessons/welcome/Main.html:264
 #: src/lessons/welcome/Main.html:358 src/lessons/welcome/Main.html:438
 #: src/lessons/welcome/Main.html:478
-#: src/lessons/welcome/array/basics/Array.html:18
 msgid "Arrays"
 msgstr "Tableaux"
 
@@ -1908,7 +1644,7 @@ msgstr "Les instructions Java"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:50
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:1
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:1
 msgid "Writing more complex programs"
 msgstr "Écrire des programmes plus complexes"
 
@@ -1920,7 +1656,7 @@ msgstr "Instructions conditionnelles"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:105
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:1
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:1
 msgid "Baggle Seeking"
 msgstr "Chercheur de baggles"
 
@@ -1932,13 +1668,13 @@ msgstr "Stocker et manipuler des données"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:147
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:1
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:1
 msgid "Do .. while loops"
 msgstr "Boucles jusqu'à<tt> (do ... while)</tt>"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:187
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:1
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:1
 msgid "Building methodically"
 msgstr "Construire avec méthode"
 
@@ -1956,25 +1692,24 @@ msgstr "Méthodes avec paramètres"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:228
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:1
+#: src/lessons/welcome/methods/picture/PictureMono.html:1
 msgid "Methodically drawing"
 msgstr "Dessiner avec méthode"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:241
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:1
+#: src/lessons/welcome/methods/picture/PictureMono2.html:1
 msgid "Methodically drawing (only bigger)"
 msgstr "Dessiner avec méthode (en plus grand)"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:267
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:1
+#: src/lessons/welcome/methods/picture/PictureMono3.html:1
 msgid "Drawing bigger and bigger"
 msgstr "Dessiner de plus en plus grand"
 
-#. type: Content of: <h2>
+#. type: Content of: <table><tr><td>
 #: src/lessons/welcome/Main.html:280
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:1
 msgid "Even more pattern to draw"
 msgstr "Encore des motifs à dessiner"
 
@@ -1990,18 +1725,19 @@ msgstr "Buggle Dance Revolution 2"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:322
-#: src/lessons/welcome/slug/SlugHunting.html:1
+#: src/lessons/welcome/methods/slug/SlugHunting.html:1
 msgid "Slug Hunting"
 msgstr "Chasse à la limace"
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/Main.html:335
-#: src/lessons/welcome/slug/SlugTracking.html:1
+#: src/lessons/welcome/methods/slug/SlugTracking.html:1
 msgid "Slug Tracking"
 msgstr "Pistage de la limace"
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:361 src/lessons/welcome/snake/Snake.html:1
+#: src/lessons/welcome/Main.html:361
+#: src/lessons/welcome/traversal/Snake.html:1
 msgid "Snake World"
 msgstr "Monde de serpents"
 
@@ -2064,6 +1800,33 @@ msgstr "Le concept est supposé maîtrisé"
 msgid "Concept not mandated by the exercise"
 msgstr "Le concept n'est pas indispensable à l'exercice"
 
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:500
+msgid "What will I learn?"
+msgstr "Que vais-je apprendre?"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/Main.html:501
+msgid ""
+"You will learn the very basics of programming. At least, you will be "
+"presented the most important concepts, allowing you to read most simple "
+"algorithms. You will not be able to write or read full programs because you "
+"will still not know about objects, but you will master what is called "
+"\"Tactical programming\", meaning that you will master the syntax enough to "
+"not have any issue with it, allowing you to focus on the fundamental "
+"problems of what you want to solve instead of struggling with syntaxic "
+"difficulties."
+msgstr ""
+"Vous allez apprendre les bases de la programmation. Disons au moins que les "
+"principaux concepts vous auront été présentés, vous permettant de lire et "
+"comprendre la plupart des algorithmes.\n"
+"Vous ne pourrez toujours pas écrire ou même lire des programmes complets en "
+"[!thelang] car la notion d'objet ne fait pas partie des objectifs de cette "
+"leçon, mais vous maîtriserez ce qu'on appelle la «programmation tactique», "
+"ce qui veut dire que votre maîtrise de la syntaxe vous permettra de vous "
+"concentrer sur les problèmes à résoudre sans vous battre contre le "
+"compilateur à propos de la syntaxe."
+
 #. type: Content of: <p>
 #: src/lessons/welcome/short_desc.html:2
 msgid ""
@@ -2082,25 +1845,28 @@ msgstr ""
 "Dans le doute, faites cette leçon, qui vous enseignera les bases de la "
 "programmation."
 
-#. type: Content of: outside any tag (error?)
+#. type: Content of: <p>
 #: src/lessons/welcome/environment/Environment.html:3
 msgid ""
-"You just started the Java Learning Machine. This is a Learning Management "
-"System (LMS) aiming at teaching the art of computer programming through "
+"You just started the Programmer's Learning Machine. This is a Learning "
+"Management System aiming at teaching the art of computer programming through "
 "interactive exercises. It is constituted by a set of exercises grouped by "
-"lessons, allowing you to practice at your own pace. By default, the "
-"environment is configured to be programmed in the Java programming language, "
-"but you can change it from the Language menu if you want."
+"lessons, allowing you to practice at your own pace. Currently, the "
+"environment is configured to be programmed in the [!thelang/] programming "
+"language, but you can change it from the Language menu if you want, or by "
+"clicking on the [!thelang/] icon at the right of the status bar below."
 msgstr ""
-"Vous venez de lancer la Java Learning Machine.  Il s'agit d'une plate-forme "
-"pédagogique destinée à simplifier l'apprentissage de la programmation.  Il "
-"est constitué d'un ensemble d'exercices groupés par leçons, pour vous "
-"permettre de progresser à votre rythme. Par défaut, l'outil est configuré "
-"pour vous permettre de programmer en Java, mais vous pouvez changer de "
-"langage de programmation grâce au menu Langage si vous le désirez."
+"Vous venez de lancer PLM, l'exerciseur du programmeur (Programmer's Learning "
+"Machine).  Il s'agit d'une plate-forme pédagogique destinée à simplifier "
+"l'apprentissage de la programmation.  Il est constitué d'un ensemble "
+"d'exercices groupés par leçons, pour vous permettre de progresser à votre "
+"rythme. Pour l'instant, l'outil est configuré pour vous permettre de "
+"programmer en [!thelang/], mais vous pouvez changer de langage de "
+"programmation grâce au menu Langage si vous le désirez, ou en cliquant sur "
+"l'icône du [!thelang/] à droite de la barre d'état (en bas de la fenêtre)."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:9
+#: src/lessons/welcome/environment/Environment.html:10
 msgid ""
 "In this first lesson, the buggles will lead your first steps in programming."
 msgstr ""
@@ -2108,12 +1874,12 @@ msgstr ""
 "programmation."
 
 #. type: Content of: <h3>
-#: src/lessons/welcome/environment/Environment.html:11
+#: src/lessons/welcome/environment/Environment.html:12
 msgid "The <i>buggles</i>? What is this??"
 msgstr "Les <i>buggles</i> ? Qu'est ce que c'est ??"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:13
+#: src/lessons/welcome/environment/Environment.html:14
 msgid ""
 "The buggles are little animals obeying any order you may give them. In each "
 "exercise, you have to provide them with the right instructions so that the "
@@ -2121,18 +1887,17 @@ msgid ""
 "exercise, you show instruct your buggle to move forward once. You can see "
 "that by checking the difference between the <i>World</i> view and the "
 "<i>Objective</i> one.  Depending on the lessons (and your settings in the "
-"Language menu), your code must be written in either Java, JavaScript, Python "
-"or Ruby (depending on the exercise)."
+"Language menu), your code must be written in either Java, Python or Scala "
+"(depending on the exercise)."
 msgstr ""
 "Les buggles sont de petites bêtes qui obéissent aux ordres que vous leur "
 "donnez. Dans chaque exercice, vous devez donner des ordres à vos buggles "
 "pour faire en sorte que le monde ressemble à l'objectif de l'exercice. Par "
 "exemple dans cet exercice, vous devez instruire votre buggle pour qu'elle "
 "avance d'un pas. Observez la différence entre l'état initial et l'objectif "
-"en utilisant les panneaux à droite. Selon la leçon (et vos réglages dans le "
-"menu Language), vous devez écrire vos programme dans l'un des langages de "
-"programmation suivant : Java, JavaScript, Python ou Ruby (en fonction de "
-"l'exercice)."
+"en utilisant les panneaux à droite. Selon la leçon (et vos réglages), vous "
+"devez écrire vos programme dans l'un des langages de programmation suivant : "
+"Java, Python ou Scala (en fonction de l'exercice)."
 
 #. type: Content of: <h3>
 #: src/lessons/welcome/environment/Environment.html:22
@@ -2146,10 +1911,9 @@ msgid ""
 "look at the several elements composing the main window, move your mouse over "
 "them to show the tooltip, and experiment with the elements to see what they "
 "do.  The white area below is the console: this is where errors and messages "
-"get displayed. If you have access to the net, try to open the forum in the "
-"help menu to check if other people are connected right now. Note that when "
-"you successfully solve an exercise, the good news is spread on twitter.  "
-"Keep posted to the progress of your friends by following @jlmlovers :)"
+"get displayed. Note that when you successfully solve an exercise, the good "
+"news is spread on twitter.  Keep posted to the progress of your friends by "
+"following @jlmlovers :)"
 msgstr ""
 "Avant d'aller plus loin, familiarisez vous avec l'environnement. Observez "
 "les différents éléments composant la fenêtre, et placez la souris sur dessus "
@@ -2158,10 +1922,20 @@ msgstr ""
 "sont affichés. Si vous avez accès à internet, connectez vous au forum par le "
 "menu d'aide pour voir si d'autres personnes sont connectés. Notez que quand "
 "vous réussissez un exercice, la bonne nouvelle est envoyée sur twitter. "
-"Suivez les progrès de vos amis en suivant #jlmlovers :)"
+"Suivez les progrès de vos amis en suivant jlmlovers :)"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:32
+msgid ""
+"If you prefer not to post your successes online, just change the relevant "
+"properties in your config file, that is [!configfile] in your case."
+msgstr ""
+"Si vous préférez ne pas poster vos progrès sur internet, changez simplement "
+"la propriété correspondante dans votre fichier de configuration, qui est [!"
+"configfile] dans votre cas."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:33
+#: src/lessons/welcome/environment/Environment.html:35
 msgid ""
 "If your code contains errors (and code always do at some point), the "
 "computer will display error messages in the console. You obviously have to "
@@ -2169,7 +1943,7 @@ msgid ""
 "sound scary at first glance, but don't panic. The compiler is only somehow "
 "limited in its communication abilities, but he's not mean. If you look "
 "closer, the solution to solve your issue is written in the middle of those "
-"cryptic messages. You'll see, with a bit of habit, we get used to it."
+"cryptic messages. You will see, with a bit of habit, we get used to it."
 msgstr ""
 "Si votre code contient des erreurs (et les programmes finissent toujours par "
 "en contenir), l'ordinateur affichera les messages d'erreur sur la console. "
@@ -2180,13 +1954,13 @@ msgstr ""
 "pour corriger les problèmes est inscrite dans ces messages cryptiques. Vous "
 "verrez, avec un peu d'entraînement, vous vous y habituerez."
 
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/environment/Environment.html:41
+#. type: Content of: <h3>
+#: src/lessons/welcome/environment/Environment.html:43
 msgid "What am I supposed to do?"
 msgstr "Que dois-je faire ?"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/environment/Environment.html:43
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:45
 msgid ""
 "It's time to write your first program. Simply ask your buggle to move one "
 "step forward using the Source Code pane. For that, simply write the "
@@ -2198,22 +1972,15 @@ msgstr ""
 "simplement le code suivant. Cliquer sur les contrôles interactifs ne suffit "
 "pas. Il faut écrire le code après avoir expérimenté interactivement."
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/environment/Environment.html:47
-#: src/lessons/welcome/basics/Basics.html:50
-#, no-wrap
-msgid "forward();"
-msgstr "forward();"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/environment/Environment.html:48
-#: src/lessons/welcome/basics/Basics.html:50
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/environment/Environment.html:49
+#: src/lessons/welcome/instructions/Instructions.html:45
 #, no-wrap
-msgid "forward()"
-msgstr "forward()"
+msgid "forward()[!java];[/!]"
+msgstr "avance()[!java];[/!]"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/environment/Environment.html:49
+#. type: Content of: <p><p>
+#: src/lessons/welcome/environment/Environment.html:50
 msgid ""
 "Do not forget the final <code>;</code> which tells the compiler that the "
 "instruction is over (yes, computers are so dumb that they cannot <i>guess</"
@@ -2223,154 +1990,133 @@ msgstr ""
 "l'instruction est terminée (oui, les ordinateurs sont si stupides qu'il faut "
 "leur préciser des choses aussi simples)."
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/environment/Environment.html:53
-msgid ""
-"Once done, clic on run, and proceed to next exercise using the File menu "
-"entry"
-msgstr ""
-"Une fois terminé, cliquez sur \"run\", et passez à l'exercice suivant avec "
-"le\n"
-"menu File."
-
 #. type: Content of: <p><p>
-#: src/lessons/welcome/environment/Environment.html:55
-msgid "(or keep around to experiment further if you feel so)."
-msgstr "(ou restez ici pour expérimenter un peu si vous le voulez)."
+#: src/lessons/welcome/environment/Environment.html:54
+msgid "Once done, clic on run. You can proceed to next exercise once it works."
+msgstr ""
+"Une fois terminé, cliquez sur «Exécuter». Quand cela fonctionne, vous pouvez "
+"passer à l'exercice suivant."
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/basics/Basics.html:3
+#: src/lessons/welcome/instructions/Instructions.html:3
 msgid ""
 "Congratulations! You just wrote your first program! You got the idea now: "
 "programming is nothing more than giving simple instructions to the computer "
-"that blindly apply them. The main difficulty is to explain stuff to someone "
-"as stupid as a computer..."
+"that blindly apply them. The main difficulty is to explain stuff to "
+"something as stupid as a computer..."
 msgstr ""
 "Félicitations ! Vous venez d'écrire votre premier programme ! Vous avez "
 "compris l'idée maintenant : programmer, c'est simplement donner des "
 "instructions à l'ordinateur, qui les applique aveuglément. La plus grande "
-"difficulté est d'expliquer quoi faire à quelqu'un d'aussi bête que "
+"difficulté est d'expliquer quoi faire à quelque chose d'aussi bête que "
 "l'ordinateur..."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/basics/Basics.html:8
+#: src/lessons/welcome/instructions/Instructions.html:8
 msgid ""
 "Programs are mainly suites of method calls, which are no more than a list of "
 "simple order given to the machine. It is very similar to a recipe stating "
 "<i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>.  In "
 "your programs, such built instructions are called functions or methods, and "
-"you should add parenthesis to invoke them, as in"
+"you should add parenthesis to invoke them:"
 msgstr ""
 "Le programme le plus simple est formé d'une suite d'ordres simples donnés à "
-"la\n"
-"machine. C'est assez comparable à une recette de cuisine où l'on dit "
-"<i>cassez\n"
-"les oeufs puis ajoutez du sel puis mélangez le tout puis faites cuire</i>. "
-"Dans\n"
-"les programmes, de tels instructions  sont appellées fonctions ou\n"
-"méthodes, et vous devez les doter de parenthèses comme dans"
+"la machine. C'est assez comparable à une recette de cuisine où l'on dit "
+"<i>cassez les oeufs puis ajoutez du sel puis mélangez le tout puis faites "
+"cuire</i>. Dans les programmes, de tels instructions  sont appellées "
+"fonctions ou méthodes, et vous devez les doter de parenthèses:"
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:13
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:13
 #, no-wrap
 msgid "nameOfTheMethod()"
 msgstr "nomDeLaMethode()"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:16
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:15
 msgid ""
-"Java want to have the instructions separated by semi-columns (;).  The "
-"previous example would thus be written in a similar way:"
+"[!thelang] wants to have the instructions separated by semi-columns (;)[!"
+"python|scala] or by new lines[/!].  The previous example would thus be "
+"written in the following way[!python|scala] (you can also add semi-columns "
+"at the end of the lines, but this is not mandatory)[/!]."
 msgstr ""
-"Java veut que les instructions soient séparées par des points-virgules (;).\n"
-"L'exemple ci-dessus de recette s'écrirait donc à peu près ainsi:"
+"[!thelang] veut que les instructions soient séparées [!python|scala]soit [/!]par des points-virgules (;)[!python|scala], soit par des retours à la ligne[/!].\n"
+"L'exemple ci-dessus de recette s'écrirait donc à peu près comme ci-dessous. \n"
+"[!python|scala] (vous pouvez aussi ajouter des points-virgules en fin de lignes, mais ce n'est pas indispensable)[/!]."
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:19
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:21
 #, no-wrap
 msgid ""
-"meltTheChocolatePieces();\n"
-"addSugar();\n"
-"coolMix();\n"
-"serve();\n"
+"meltTheChocolatePieces()[!java];[/!]\n"
+"addSugar()[!java];[/!]\n"
+"coolMix()[!java];[/!]\n"
+"serve()[!java];[/!]\n"
 msgstr ""
-"casserLesOeufs();\n"
-"ajouterDuSel();\n"
-"melangerLeTout();\n"
-"faireCuire();\n"
+"casserLesOeufs()[!java];[/!]\n"
+"ajouterDuSel()[!java];[/!]\n"
+"melangerLeTout()[!java];[/!]\n"
+"faireCuire()[!java];[/!]\n"
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:25
-msgid ""
-"Python want to have the instructions separated by either semi-columns (;) or "
-"by new lines. The previous example would thus be written the following way."
-msgstr ""
-"Python veut que les instructions soient séparées soit par des points-"
-"virgules\n"
-"(;), soit par des retours à la ligne.\n"
-"L'exemple ci-dessus de recette s'écrirait donc à peu près ainsi:"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:29
-#, no-wrap
-msgid ""
-"meltTheChocolatePieces()\n"
-"addSugar()\n"
-"coolMix()\n"
-"serve()\n"
-msgstr ""
-"casserLesOeufs()\n"
-"ajouterDuSel()\n"
-"melangerLeTout()\n"
-"faireCuire()\n"
+#: src/lessons/welcome/instructions/Instructions.html:27
+#: src/lessons/welcome/variables/Variables.html:123
+msgid "[!python|scala]"
+msgstr "[!python|scala]"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:35
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:28
 msgid ""
 "It could also be written in the following way, but it's generally considered "
 "as a bad practice to group several instructions on the same line since it "
 "greatly hinders the readability."
 msgstr ""
-"Il serait également possible de l'écrire sous la forme suivante, mais "
-"placer\n"
+"Il serait également possible de l'écrire sous la forme suivante, mais placer "
 "plusieurs instructions sur la même ligne est généralement considéré comme "
-"une\n"
-"très mauvaise habitude car cela complique grandement la relecture du code "
-"après\n"
-"coup."
+"une très mauvaise habitude car cela complique grandement la relecture du "
+"code après coup."
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:39
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:32
 #, no-wrap
 msgid "meltTheChocolatePieces(); addSugar(); coolMix(); serve()\n"
 msgstr "casserLesOeufs(); ajouterDuSel(); melangerLeTout(); faireCuire();\n"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:42
-msgid ""
-"Of course, these specific methods do not exist in Java, but it may be "
-"possible to define them by yourself (we'll see later how to define your how "
-"methods)."
-msgstr ""
-"Bien entendu, ces méthodes n'existent pas en Java, mais il serait possible "
-"de\n"
-"les définir par vous même (nous verrons plus tard comment définir vos "
-"propres méthodes)."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:44
-msgid ""
-"Of course, these specific methods do not exist in Python, but it may be "
-"possible to define them by yourself (we'll see later how to define your how "
-"methods)."
-msgstr ""
-"Bien entendu, ces méthodes n'existent pas en Python, mais il serait possible "
-"de\n"
-"les définir par vous même (nous verrons plus tard comment définir vos "
-"propres méthodes)."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:46
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/instructions/Instructions.html:34
+#: src/lessons/welcome/variables/Variables.html:31
+#: src/lessons/welcome/variables/Variables.html:61
+#: src/lessons/welcome/variables/Variables.html:130
+#: src/lessons/welcome/loopfor/LoopFor.html:69
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:53
+#: src/lessons/welcome/loopdowhile/Poucet.html:33
+#: src/lessons/welcome/methods/args/MethodsArgs.html:65
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:39
+#: src/lessons/welcome/bdr/BDR.html:59 src/lessons/welcome/bdr/BDR.html:193
+#: src/lessons/welcome/bdr/BDR2.html:129
+#: src/lessons/turmites/langton/Langton.html:31
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:64
+#: src/lessons/sort/comb/AlgCombSort.html:34
+#: src/lessons/recursion/square/FourSquare.html:45
+#: src/lessons/welcome/bat/bool1/Max1020.html:5
+#: src/lessons/welcome/array/basics/Array1.html:181
+#: src/lessons/welcome/array/basics/Array1.html:207
+msgid "[/!]"
+msgstr "[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:36
+msgid ""
+"Of course, these specific methods do not exist by default in [!java]Java[/!]"
+"[!scala]Scala[/!][!python]Python[/!], but it may be possible to define them "
+"by yourself (we'll see later how to define your how methods)."
+msgstr ""
+"Bien entendu, ces méthodes n'existent pas en [!java]Java[/!][!scala]Scala[/!]"
+"[!python]Python[/!], mais il serait possible de les définir par vous même "
+"(nous verrons plus tard comment définir vos propres méthodes)."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:40
 msgid ""
 "For now, we'll simply go for the buggle instructions. There is a method for "
 "each button of the interactive control panel. To achieve the same effect "
@@ -2380,97 +2126,73 @@ msgstr ""
 "Pour l'instant, nous allons utiliser les instructions de la buggle. Il\n"
 "y a une méthode pour chaque bouton du contrôle interactif.  Pour faire la "
 "même\n"
-"chose que le bouton <b>forward</b> (faire avancer la buggle d'un pas), il "
+"chose que le bouton <b>avance</b> (faire avancer la buggle d'un pas), il "
 "faut\n"
 "écrire dans l'éditeur :"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:51
-msgid ""
-"Likewise, to achieve the same effect than the <b>backward</b>, <b>turn left</"
-"b> and <b>turn right</b> buttons, you need to use respectively:"
-msgstr ""
-"De même, pour faire l'équivalent des boutons <b>backward</b>, <b>turn left</"
-"b> et <b>turn right</b>, il faut utiliser respectivement :"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:54
-#, no-wrap
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:46
 msgid ""
-"backward();\n"
-"turnLeft();\n"
-"turnRight();\n"
+"Likewise, to achieve the same effect than the <b>backward</b>, <b>left</b> "
+"and <b>right</b> buttons, you need to use respectively:"
 msgstr ""
-"backward();\n"
-"turnLeft();\n"
-"turnRight();\n"
+"De même, pour faire l'équivalent des boutons <b>recule</b>, <b>gauche</b> et "
+"<b>droite</b>, il faut utiliser respectivement :"
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:59
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/instructions/Instructions.html:49
 #, no-wrap
 msgid ""
-"backward()\n"
-"turnLeft()\n"
-"turnRight()\n"
+"backward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"right()[!java];[/!]\n"
 msgstr ""
-"backward()\n"
-"turnLeft()\n"
-"turnRight()\n"
+"recule()[!java];[/!]\n"
+"gauche()[!java];[/!]\n"
+"droite()[!java];[/!]\n"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:63
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:54
 msgid ""
 "The <b>mark</b> button is a bit particular, since it correspond to two "
 "methods: the first one moves the pen up while the second moves it down."
 msgstr ""
-"Le bouton <b>mark</b> est un peu particulier, puisqu'il correspond à deux "
+"Le bouton <b>marquer</b> est un peu particulier, puisqu'il correspond à deux "
 "méthodes : la première lève le crayon, tandis que la seconde le baisse."
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:66
-#, no-wrap
-msgid ""
-"brushUp();\n"
-"brushDown();\n"
-msgstr ""
-"brushUp();\n"
-"brushDown();\n"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:70
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/instructions/Instructions.html:57
 #, no-wrap
 msgid ""
-"brushUp()\n"
-"brushDown()\n"
+"brushUp()[!java];[/!]\n"
+"brushDown()[!java];[/!]\n"
 msgstr ""
-"brushUp()\n"
-"brushDown()\n"
+"leveCrayon()[!java];[/!]\n"
+"baisseCrayon()[!java];[/!]\n"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/basics/Basics.html:73
+#. type: Content of: <p><p>
+#: src/lessons/welcome/instructions/Instructions.html:60
 msgid ""
 "The buggle offers other methods, that are presented from the \"Help/about "
 "this world\" menu and will be introduced on need."
 msgstr ""
-"La buggle offre d'autres méthodes, présentées dans le menu \"Help/about this "
-"world\". Elles seront introduites au fur et à mesure des besoins."
+"La buggle offre d'autres méthodes, présentées dans le menu \"Aide/À propos "
+"de ce monde\". Elles seront introduites au fur et à mesure des besoins."
 
 #. type: Content of: <h3>
-#: src/lessons/welcome/basics/Basics.html:77
-#: src/lessons/welcome/conditions/Conditions.html:147
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:8
-#: src/lessons/welcome/variables/Variables.html:72
-#: src/lessons/welcome/loop/forloop/LoopFor.html:73
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:26
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:26
-#: src/lessons/welcome/methods/basics/Methods.html:59
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:49
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:56
+#: src/lessons/welcome/instructions/Instructions.html:64
+#: src/lessons/welcome/conditions/Conditions.html:108
+#: src/lessons/welcome/loopwhile/LoopWhile.html:32
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:8
+#: src/lessons/welcome/variables/Variables.html:97
+#: src/lessons/welcome/loopfor/LoopFor.html:71
+#: src/lessons/welcome/methods/basics/Methods.html:95
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:37
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:48
 #: src/lessons/welcome/methods/args/MethodsArgs.html:69
-#: src/lessons/welcome/bdr/BDR.html:159 src/lessons/welcome/bdr/BDR2.html:111
-#: src/lessons/welcome/slug/SlugHunting.html:18
-#: src/lessons/welcome/slug/SlugTracking.html:21
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:24
+#: src/lessons/welcome/methods/slug/SlugHunting.html:18
+#: src/lessons/welcome/methods/slug/SlugTracking.html:19
+#: src/lessons/welcome/bdr/BDR.html:149 src/lessons/welcome/bdr/BDR2.html:131
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:17
 #: src/lessons/maze/pledge/PledgeMaze.html:36
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:22
@@ -2478,8 +2200,8 @@ msgstr ""
 msgid "Exercise goal"
 msgstr "Objectif de cet exercice"
 
-#. type: Content of: <p><p><a>
-#: src/lessons/welcome/basics/Basics.html:77
+#. type: Content of: <p><a>
+#: src/lessons/welcome/instructions/Instructions.html:64
 msgid ""
 "<a name=\"Objectives\"> Our second program will be a bit more complicated, "
 "but not much. The goal for your buggle is simply to draw a house (a box), "
@@ -2490,137 +2212,119 @@ msgstr ""
 "une maison (une boîte), et de se cacher dedans. Vérifiez le monde objectif "
 "pour voir exactement ce que cela veut dire."
 
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/instructions/Instructions.html:69
+msgid ""
+"When switching to the next exercise, please note that there is a sub-"
+"exercise following this one.  By default, it is hidden in the menu and you "
+"have to open the sub-menu to see it.  When you switch the exercise, most of "
+"the exercises are hidden because the tree is folded, as follows:"
+msgstr ""
+"Quand vous changerez d'exercice, n'oubliez pas l'exercice d'application qui "
+"suit. Par défaut, il n'est pas visible dans la fenêtre de sélection, et il "
+"faut ouvrir le sous-arbre pour le voir. Lorsque vous ouvrez la fenêtre de "
+"sélection des exercices, la plupart d'entre eux sont cachés, comme cela:"
+
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/instructions/Instructions.html:74
+msgid ""
+"You have to click on the little symbol to the left of the buggle to unfold "
+"the tree, as follows:"
+msgstr ""
+"Vous devez cliquer sur le petit symbole à gauche de la buggle pour déplier "
+"l'arbre, comme cela :"
+
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:2
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:2
 msgid ""
 "Now that we know how to draw things on the board, we'll enjoy this ability "
 "and draw a beautiful G on the board (check Objective panel for details on "
-"what's expected)."
+"what is expected)."
 msgstr ""
 "Maintenant que vous savez écrire des choses sur le sol, nous allons utiliser "
 "cette compétence pour dessiner un merveilleux G par terre. Consultez le "
 "panneau d'objectif pour les détails de ce qui est attendu."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:6
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:6
 msgid ""
 "When you write a quite complex program, it is sometimes useful to <b>add "
 "comments</b> to simplify the code reviews afterward. Here for example, it's "
 "quite easy to get lost in the drawing process, and you may want to add "
 "comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to "
 "move back to initial position</i>. Commenting your code is almost mandatory "
-"if you (or someone else) want to read it afterward, although overcommenting "
+"if you (or someone else) want to read it afterward, although over-commenting "
 "(describing obvious stuff) is a bad idea as the important idea get lost in "
 "the noise."
 msgstr ""
-"Quand vous écrivez un programme un peu complexe, il est souvent pratique\n"
-"d'ajouter des <b>commentaires</b> pour simplifier la relecture du code "
-"après\n"
+"Quand vous écrivez un programme un peu complexe, il est souvent pratique "
+"d'ajouter des <b>commentaires</b> pour simplifier la relecture du code après "
 "coup. Ici par exemple, il est assez facile de se perdre dans les ordres\n"
 "nécessaires au dessin. Il peut être pratique d'ajouter des commentaires "
-"comme\n"
-"<i>fin de la barre verticale</i> ou <i>Fini de dessiner le G. Retournons à "
-"la\n"
-"position initiale</i>. Documenter votre code est presque toujours nécessaire "
-"si\n"
-"quelqu'un (vous ou quelqu'un d'autre) veut le lire après coup. Cependant, "
-"commenter des\n"
-"choses triviales est une mauvaise idée car cela dilue les informations\n"
-"dans des commentaires trop verbeux. En anglais, ce travers s'appelle\n"
-"<i>overcommenting</i>."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:14
-msgid ""
-"There is three types of comments in Java, instructing the compiler to not "
-"read the text you add for humans:"
-msgstr ""
-"Il y a trois sortes de commentaires en Java, indiquant au compilateur qu'il "
-"ne\n"
-"doit pas lire le texte ajouté pour les humains."
+"comme <i>fin de la barre verticale</i> ou <i>Fini de dessiner le G. "
+"Retournons à la position initiale</i>. Documenter votre code est presque "
+"toujours nécessaire si quelqu'un (vous ou quelqu'un d'autre) veut le lire "
+"après coup. Cependant, commenter des choses triviales est une mauvaise idée "
+"car cela dilue les informations dans des commentaires trop verbeux. En "
+"anglais, ce travers s'appelle <i>over-commenting</i>."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:16
-msgid ""
-"There is two types of comments in Python, instructing the compiler to not "
-"read the text you add for humans:"
-msgstr ""
-"Il y a deux sortes de commentaires en Python, indiquant au compilateur qu'il "
-"ne\n"
-"doit pas lire le texte ajouté pour les humains."
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:20
-msgid ""
-"<b>Comments on a single line</b>. When the compiler encounters the "
-"symbols //, it ignores the end of the line."
-msgstr ""
-"<b>Commentaires sur une seule ligne</b>. Dès que le compilateur rencontre "
-"les symboles //, il ignore la fin de la ligne."
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:22
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:14
 msgid ""
-"<b>Comments on several lines</b>. The compiler ignores anything placed "
-"between the symbols /* and */ even if they are placed on differing lines."
+"There is [!java]three[/!][!python|scala]two[/!] types of comments in [!"
+"thelang], instructing the [!java|scala]compiler[/!][!python]interpreter[/!] "
+"to not read the text you add for humans:"
 msgstr ""
-"<b>Commentaires sur plusieurs lignes</b>. Le compilateur ignore tout ce qui "
-"se trouve entre les symboles /* et */, même s'ils sont sur des lignes "
-"différentes"
+"Il y a [!java]three[/!][!python|scala]two[/!] sortes de commentaires en [!"
+"thelang], indiquant au [!java|scala]compilateur[/!][!python]interpréteur[/!] "
+"qu'il ne doit pas lire le texte ajouté pour les humains."
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:27
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:18
 msgid ""
-"<b>Comments on a single line</b>. When the compiler encounters the symbol #, "
-"it ignores the end of the line."
+"<b>Comments on a single line</b>. When the [!java|scala]compiler[/!][!"
+"python]interpreter[/!] encounters the symbol [!java|scala]//[/!][!"
+"python]#[/!], it ignores the end of the line."
 msgstr ""
-"<b>Commentaires sur une seule ligne</b>. Dès que le compilateur rencontre "
-"le\n"
-"symbole #, il ignore la fin de la ligne."
+"<b>Commentaires sur une seule ligne</b>. Quand le [!java|"
+"scala]compilateur[/!][!python]interpréteur[/!] rencontre le symbole [!java|"
+"scala]//[/!][!python]#[/!], il ignore la fin de la ligne."
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:29
-msgid ""
-"<b>Comments on several lines</b>. The compiler ignores anything placed "
-"between a line beginning with ''' and the next line ending with '''."
-msgstr ""
-"<b>Commentaires sur plusieurs lignes</b>. Le compilateur ignore tout ce qui "
-"se\n"
-"trouve entre une ligne commençant par ''' et la prochaine ligne terminant "
-"par '''."
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:34
-#, no-wrap
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:20
 msgid ""
-"methodCallReadByTheCompiler(); <span class=\"comment\">// all this is ignored</span>\n"
-"otherCall(); <span class=\"comment\">/* This is</span>\n"
-"              <span class=\"comment\"> also ignored */</span>\n"
-"yetAnotherCall();\n"
+"<b>Comments on several lines</b>. The [!java|scala]compiler[/!][!"
+"python]interpreter[/!] ignores anything placed between [!java|scala]the "
+"symbols /* and */ even if they are placed on differing lines.[/!] [!python]a "
+"line beginning with ''' and the next line ending with '''.[/!]"
 msgstr ""
-"appelMethodeLuParLeCompilateur(); <span class=\"comment\"> // tout ceci est ignoré</span>\n"
-"autreAppel(); <span class=\"comment\">/* ceci est</span>\n"
-"              <span class=\"comment\"> également ignoré */</span>\n"
-"encoreUnAppel();\n"
+"<b>Commentaires sur plusieurs lignes</b>. [!java|scala]Le compilateur[/!][!"
+"python]L'interpréteur[/!] ignore tout ce qui se trouve entre [!java|"
+"scala]les symboles /* et */, même s'ils sont sur des lignes différentes."
+"[/!]\n"
+"[!python]une ligne commençant par ''' et la prochaine ligne terminant par "
+"'''.[/!]"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:40
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:27
 #, no-wrap
 msgid ""
-"methodCallReadByTheCompiler() <span class=\"comment\"># all this is ignored</span>\n"
-"otherCall() \n"
-"<span class=\"comment\">''' This is</span>\n"
-"<span class=\"comment\">also ignored  '''</span>\n"
-"yetAnotherCall()\n"
+"methodCallReadByThe[!java|scala]Compiler[/!][!python]Interpreter[/!]()[!java];[/!] <span class=\"comment\">[!java|scala]//[/!][!python]#[/!] all this is ignored</span>\n"
+"otherCall()[!java];[/!] [!java|scala]<span class=\"comment\">/* This is</span>\n"
+"              <span class=\"comment\"> also ignored */</span>[/!]\n"
+"[!python]<span class=\"comment\">''' This is</span>\n"
+"<span class=\"comment\">also ignored  '''</span>[/!]\n"
+"yetAnotherCall()[!java];[/!]\n"
 msgstr ""
-"appelMethodeLuParLeCompilateur() <span class=\"comment\"> # tout ceci est ignoré</span>\n"
-"autreAppel() \n"
-"<span class=\"comment\">''' ceci est</span>\n"
-"<span class=\"comment\"> également ignoré '''</span>\n"
-"encoreUnAppel()\n"
+"methodCallReadByThe[!java|scala]Compilateur[/!][!python]Interpreteur[/!]()[!java];[/!] <span class=\"comment\">[!java|scala]//[/!][!python]#[/!] tout ceci est ignoré</span>\n"
+"otherCall()[!java];[/!] [!java|scala]<span class=\"comment\">/* Ceci est</span>\n"
+"              <span class=\"comment\"> également ignoré */</span>[/!]\n"
+"[!python]<span class=\"comment\">''' Ceci est</span>\n"
+"<span class=\"comment\">également ignoré '''</span>[/!]\n"
+"yetAnotherCall()[!java];[/!]\n"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:47
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:34
 msgid ""
 "There is a third kind of comments in Java, between /** and */, which are "
 "read by a specific program called JavaDoc to generate automatically the "
@@ -2633,7 +2337,7 @@ msgstr ""
 "suivre un formalisme précis."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:52
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:39
 msgid ""
 "The comments on several lines are often used to document how to use the "
 "code, while others are more used to describe how this code works."
@@ -2658,386 +2362,325 @@ msgstr ""
 
 #. type: Content of: <p>
 #: src/lessons/welcome/conditions/Conditions.html:8
-msgid "The Java syntax is the following:"
-msgstr "La syntaxe Java est la suivante :"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:9
-msgid "The Python syntax is the following:"
-msgstr "La syntaxe Python est la suivante :"
+msgid "The [!thelang] syntax is the following:"
+msgstr "La syntaxe en [!thelang] est la suivante :"
 
 #. type: Content of: <pre>
 #: src/lessons/welcome/conditions/Conditions.html:10
 #, no-wrap
 msgid ""
-"if (<b>condition</b>) {\n"
-"    <b>whatToDo();</b>\n"
-"}"
-msgstr ""
-"if (<b>condition</b>) {\n"
-"    <b>quoiFaire();</b>\n"
-"}"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/conditions/Conditions.html:13
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>"
-msgstr ""
-"if <b>condition</b>:\n"
-"    <b>quoiFaire()</b>"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:16
-msgid ""
-"If the condition is true, any code enclosed between the { and the "
-"corresponding } will be executed. If not, it will be ignored. Of course, it "
-"is possible to write more than one instruction between the curly brackets "
-"(even another test)."
-msgstr ""
-"Si la condition est vraie, tout le code compris entre le { et le } "
-"correspondant sera exécuté. Si non, il sera ignoré. Bien entendu, il est "
-"possible d'écrire plusieurs instructions entre les deux accolades (voire un "
-"autre test)."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:20
-msgid ""
-"If the condition is true, any code in the block following the colon symbol "
-"will be executed. If not, it will be ignored. Of course, it is possible to "
-"write more than one instruction in the sub-block (even another test)."
-msgstr ""
-"Si la condition est vraie, tout le code du bloc placé après les deux points "
-"(:)\n"
-"sera exécuté. Si non, il sera ignoré. Bien entendu, il est possible "
-"d'écrire\n"
-"plusieurs instructions dans le sous-bloc (voire un autre test)."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:26
-msgid ""
-"Python uses indentation to define code blocks. The standard Python "
-"indentation is 4 spaces. Notice that code blocks do not need any "
-"termination. Indenting starts a block and unindenting ends it. In the "
-"following code the instructions <b>whatToDo()</b> and <b>whatToDoNext()</b> "
-"will be exectuded if the condition is true, then the instruction "
-"<b>whatToDoAnyway()</b> will be executed anyway."
-msgstr ""
-"Python utilise l'indentation pour définir les blocs de code. L'indentation "
-"standard en Python est de quatre espaces. Veuillez noter que les blocs de "
-"code n'ont pas besoin de terminaison. Indenter commence un bloc et "
-"désindenter le termine. Dans le code suivant, les instructions "
-"<b>whatToDo()</b> et <b>whatToDoNext()</b> seront executées si la condition "
-"est vraie, ensuite l'instruction <b>whatToDoAnyway()</b> sera exécutée dans "
-"tous les cas."
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:33
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>\n"
-"    <b>whatToDoNext()</b>\n"
-"<b>whatToDoAnyway()</b>\n"
-msgstr ""
-"if <b>condition</b>:\n"
-"    <b>quoiFaire()</b>\n"
-"    <b>quoiFaireEnsuite()</b>\n"
-"<b>quoiFaireDansTousLesCas()</b>\n"
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:39
-msgid ""
-"Python functions have no explicit begin or end, and no curly braces to mark "
-"where the function code starts and stops. The only delimiter is a colon (:) "
-"and the indentation of the code itself."
-msgstr ""
-"Les fonctions Pythons n'ont pas de début ou de fin explicite, ni d'accolade "
-"pour indiquer où le code commence et où il se termine. Le seul délimiteur "
-"est un double points (:) et l'indentation du code lui même."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:44
-msgid "Example 2.5. Indenting the buildConnectionString Function"
-msgstr "Exemple 2.5. Indenter la fonction buildConnectionString"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:48
-#, no-wrap
-msgid ""
-"def buildConnectionString(params):\n"
-"    \"\"\"Build a connection string from a dictionary of parameters.\n"
-"\n"
-"    Returns string.\"\"\"\n"
-"    return \";\".join([\"%s=%s\" % (k, v) for k, v in params.items()])\n"
-msgstr ""
-"def buildConnectionString(params):\n"
-"    \"\"\"Construit une connection string à partir d'un dictionnaire de paramètres.\n"
-"\n"
-"    Renvoie une chaîne de caractères.\"\"\"\n"
-"    return \";\".join([\"%s=%s\" % (k, v) for k, v in params.items()])\n"
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:55
-msgid ""
-"Code blocks are defined by their indentation. By \"code block\", I mean "
-"functions, if statements, for loops, while loops, and so forth. Indenting "
-"starts a block and unindenting ends it. There are no explicit braces, "
-"brackets, or keywords. This means that whitespace is significant, and must "
-"be consistent. In this example, the function code (including the doc string) "
-"is indented four spaces.  It doesn't need to be four spaces, it just needs "
-"to be consistent. The first line that is not indented is outside the "
-"function."
-msgstr ""
-"Les blocs de code sont définis par leur indentation. Par \"bloc de code\", "
-"je veux dire les fonctions, les branchements conditionnels if, les boucles "
-"for, les boucles while, etc. Indenter commence un bloc et désindenter le "
-"termine. Il n'y a pas de parenthèses, d'accolades, ou de mots clés. Cela "
-"signifie qu'un espace est significatif et doit être cohérent. Dans cet "
-"exemple, le code de la fonction (en comptant la documentation) est indenté "
-"avec quatre espaces. Il n'est pas nécessaire que cela soit quatre espaces, "
-"il faut juste que cela soit cohérent. La première ligne qui n'est pas "
-"indentée est en dehors de la fonction."
+"[!java|scala]if (<b>condition</b>) {\n"
+"    <b>whatToDoIfTrue();</b>\n"
+"    <b>whatToDoNextIfTrue();</b>\n"
+"}[/!][!python]if <b>condition</b>:\n"
+"    <b>whatToDoIfTrue()</b>\n"
+"    <b>whatToDoNextIfTrue()</b>[/!]\n"
+"<b>whatToDoAnyway()[!java];[/!]</b>"
+msgstr ""
+"[!java|scala]if (<b>condition</b>) {\n"
+"    <b>aFaireSiVraie();</b>\n"
+"    <b>aFaireEnsuiteSiVraie();</b>\n"
+"}[/!][!python]if <b>condition</b>:\n"
+"    <b>aFaireSiVraie()</b>\n"
+"    <b>aFaireEnsuiteSiVraie()</b>[/!]\n"
+"<b>aFaireDansTousLesCas()[!java];[/!]</b>"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:18
+msgid ""
+"If the condition is true, the code of the next block will be executed and "
+"then it will continue with the rest of the code.  If the condition is false, "
+"the next block is ignored and the execution continues after it.  The "
+"conditional block can contain several instructions, it can even contain "
+"other tests, along with their sub-blocks."
+msgstr ""
+"Le mot <code>if</code> signifie «si» en anglais. Si la condition est vraie, "
+"alors le code du bloc suivant sera exécuté, puis l'exécution se poursuivra "
+"avec la suite du code, après le bloc. Sinon, si la condition est fausse, le "
+"bloc suivant sera ignoré et l'exécution passera directement au code placé "
+"après lui. Le bloc conditionnel peut contenir plusieurs instructions. Il "
+"peut même contenir d'autre tests, avec leurs sous-blocs associés."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:22
+msgid ""
+"In this example, the instructions <code>whatToDoIfTrue()</code> and "
+"<code>whatToDoNextIfTrue()</code> will be executed if and only if the "
+"condition is true, while the instruction <code>whatToDoAnyway()</code> will "
+"be executed whether or not the condition is true."
+msgstr ""
+"Dans cet exemple, les instructions <code>aFaireSiVraie()</code> et "
+"<code>aFaireSiVraie()</code> seront exécutée si (et seulement si) la "
+"condition est vraie tandis que l'instruction <code>aFaireDansTousLesCas()</"
+"code> sera exécutée que la condition soit vraie ou fausse."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:27
+msgid ""
+"In [!thelang], the blocks of code are [!java|scala]enclosed between curly "
+"brackets: a { sign opens the block, while a } sign closes it.  White spaces "
+"are not important[/!][!java].[/!][!scala], provided that your instructions "
+"are still separated with a semi-column or an end of line.[/!] [!java|"
+"scala]It is still very important to correctly indent your code to keep it "
+"readable.[/!] [!python]marked by the indentation: every lines that are a bit "
+"shifted to the right with white spaces belong to the block. Quite often, "
+"people use 4 spaces for indentation, but it works if you use more or less "
+"spaces. Simply, any lines of the block must use the same amount of spaces.  "
+"The end of Python code blocks are not marked by any specific char.  "
+"Indenting lines starts a block and unindenting ends it. Do not forget the "
+"colon (:) at the end of the <code>if</code> line, python needs it to know "
+"that a new block begins. The fact that python relies on indentation to "
+"delimit blocks is a very good property for beginners: it will force your to "
+"adhere to strict code presentation standards.[/!] It is very easy to get "
+"lost in your own code if it's not properly indented, so you want to clean it "
+"up so that working on your code remains pleasant and productive."
+msgstr ""
+"En [!thelang], les blocs sont \n"
+"[!java|scala]délimités par des accolades : le symbole { commence un bloc "
+"tandis\n"
+"que le symbole } le ferme.  Les caractères blancs ne sont pas pris en \n"
+"compte[/!][!java].[/!][!scala], tant que les instructions restent séparées "
+"soit par des points-virgules, soit par des retour à la ligne.[/!] \n"
+"[!java|scala]Il reste très important d'indenter correctement votre code pour "
+"qu'il reste lisible.[/!] \n"
+"[!python]marqués par l'indentation : toutes les lignes indentés (=décalées "
+"vers la droite par des espaces) font partie du bloc. Il est assez courant "
+"d'utiliser quatre espaces pour indenter le code, mais cela fonctionne quel "
+"que soit le nombre de caractères blancs utilisés pour celà. Simplement, "
+"toutes les lignes d'un bloc donné doivent utiliser le même nombre de blancs. "
+"La fin des blocs de code n'est pas marquée par un symbole particulier: il "
+"s'arrête dès que les lignes ne sont plus indentées. N'oubliez pas les deux "
+"points (:) à la fin de la ligne <code>if</code>, python en a besoin pour "
+"savoir qu'un nouveau bloc commence.\n"
+"Le fait que python utilise l'indentation pour maquer les blocs est un "
+"avantage pour les débutants: cela vous forcera à respecter des critères "
+"stricts de mise en forme de votre code.[/!] \n"
+"Il est très facile de se perdre dans un code qui n'est pas correctement "
+"indenté. Il est donc important que vous fassiez en sorte que votre code "
+"reste clair et lisible pour que le relire et le modifier reste plaisant et "
+"productif."
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:64
+#: src/lessons/welcome/conditions/Conditions.html:43
 msgid ""
-"It is important that the indentations of all the instructions of a block are "
-"consistent, and it is not possible to cut a block. The two following codes "
-"are incorrect and will raise errors."
+"All indentations of a given block must be consistent, and it is not possible "
+"to cut a block. The two following codes are incorrect and will raise errors."
 msgstr ""
-"Il est important que l'indentation de toutes les instructions d'un bloc soit "
-"cohérente, et il n'est pas possible de couper un bloc. Les deux exemples "
-"suivants de code sont incorrects et vont générer des erreurs."
+"Toutes les instructions d'un bloc doivent avoir la même indentation, et il "
+"n'est pas possible de couper un bloc. Les deux exemples suivants de code "
+"sont incorrects et vont générer des erreurs."
 
 #. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:68
+#: src/lessons/welcome/conditions/Conditions.html:46
 #, no-wrap
 msgid ""
 "if <b>condition</b>:\n"
 "    <b>whatToDo()</b>\n"
-"     <b>whatToDoNext()</b>\n"
+"     <b>whatToDoNext()</b> <span class=\"comment\"># one space too much </span>\n"
 "<b>whatToDoAnyway()</b>\n"
 msgstr ""
 "if <b>condition</b>:\n"
 "    <b>quoiFaire()</b>\n"
-"     <b>quoiFaireEnsuite()</b>\n"
+"      <b>quoiFaireEnsuite()</b> <span class=\"comment\"># une espace de trop</span>\n"
 "<b>quoiFaireDansTousLesCas()</b>\n"
 
 #. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:73
+#: src/lessons/welcome/conditions/Conditions.html:51
 #, no-wrap
 msgid ""
 "if <b>condition</b>:\n"
 "    <b>whatToDo()</b>\n"
 "<b>whatToDoAnyway()</b>\n"
-"    <b>whatToDoNext()</b>\n"
+"    <b>whatToDoNext()</b> <span class=\"comment\"># this block is not hanging to a condition line</span>\n"
 msgstr ""
 "if <b>condition</b>:\n"
 "    <b>quoiFaire()</b>\n"
 "<b>quoiFaireDansTousLesCas()</b>\n"
-"    <b>quoiFaireEnsuite()</b>\n"
+"    <b>quoiFaireEnsuite()</b> <span class=\"comment\"># Ce bloc n'est rataché à aucune ligne de condition</span>\n"
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:79
-msgid ""
-"A condition can be a variable of type <tt>boolean</tt>. The code between "
-"curly braces will get executed if the variable is <tt>true</tt> and it will "
-"be ignored if it is <tt>false</tt>."
-msgstr ""
-"Une condition peut être une variable de type <tt>boolean</tt>. Le code entre "
-"accolades sera exécuté si la variable vaut la valeur <tt>true</tt> (vrai), "
-"et il sera ignoré si elle vaut <tt>false</tt> (faux)."
+#: src/lessons/welcome/conditions/Conditions.html:57
+msgid ""
+"The condition must be a <code>[!java]boolean[/!][!scala|python]Boolean[/!]</"
+"code> expression.  The inner block of code will get executed if the "
+"expression is evaluated to <code>[!java|scala]true[/!][!python]True[/!]</"
+"code> and it will be ignored if it is <code>[!java|scala]false[/!][!"
+"python]False[/!]</code>.  <code>[!java|scala]true[/!][!python]True[/!]</"
+"code> and <code>[!java|scala]false[/!][!python]False[/!]</code> are constant "
+"values defined by [!thelang] directly, just as 0 or 1 in mathematics."
+msgstr ""
+"La condition doit être une expression de type <code>[!java]boolean[/!][!"
+"scala|python]Boolean[/!]</code> (expression booléenne).  Le sous-bloc sera "
+"exécuté seulement si cette expression vaut <code>[!java|scala]true[/!][!"
+"python]True[/!]</code> (vrai), et il sera ignoré si sa valeur est <code>[!"
+"java|scala]false[/!][!python]False[/!]</code> (faux).\n"
+"<code>[!java|scala]true[/!][!python]True[/!]</code> et <code>[!java|"
+"scala]false[/!][!python]False[/!]</code> sont des constantes définies "
+"directement par [!thelang], tout comme 0 ou 1 en mathématiques."
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:83
-msgid ""
-"A condition can be a variable of type <tt>boolean</tt>. The code in the "
-"inner bloc will get executed if the variable is <tt>True</tt> and it will be "
-"ignored if it is <tt>False</tt>."
-msgstr ""
-"Une condition peut être une variable de type <tt>boolean</tt>. Le code dans "
-"le\n"
-"bloc indenté sera exécuté si la variable vaut la valeur <tt>True</tt> "
-"(vrai), et il sera ignoré si elle vaut <tt>False</tt> (faux)."
+#: src/lessons/welcome/conditions/Conditions.html:63
+msgid ""
+"The condition can be a <code>[!java]boolean[/!][!scala|python]Boolean[/!]</"
+"code> variable (we will come back on variables in a latter exercise, don't "
+"worry) or an arithmetic test, such as <code>x == 5</code>, which checks "
+"whether the current value of <code>x</code> is 5, or such as <b>!=</b> "
+"(checking inequality, that is, returning [!java|scala]true[/!][!"
+"python]True[/!] only if the left hand-side is different from the right hand-"
+"side), <b><</b> (smaller than), <b>></b> (larger than), <b><=</b> "
+"(smaller or equal to), <b>>=</b> (larger or equal to)."
+msgstr ""
+"La condition peut aussi être une variable booléenne (nous reviendrons sur "
+"les variables dans un autre exercice, pas de panique) ou un test "
+"arithmétique,comme <code>x == 5</code>, qui teste si la valeur actuelle de "
+"<tt>x</tt> est 5, ou bien comme <b>!=</b> (teste l'inégalité, càd si le "
+"membre gauche a une valeur différente du membre droit), <b><</b> "
+"(inférieur à), <b>></b> (supérieur à), <b><=</b> (inférieur ou égal "
+"à), <b>>=</b> (supérieur ou égal à)."
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:88
-msgid ""
-"The condition can also be an arithmetic test, such as <tt>x</tt> <b>==</b> "
-"<tt>5</tt>, which checks whether the current value of <tt>x</tt> is 5, or "
-"such as <b>!=</b> (checking inequality), <b><</b> (smaller than), <b>>"
-"</b> (larger than), <b><=</b> (smaller or equal to), <b>>=</b> (larger "
-"or equal to)."
-msgstr ""
-"La condition peut aussi être un test arithmétique, comme <tt>x</tt> <b>==</"
-"b> <tt>5</tt>, qui vérifie si la valeur actuelle de <tt>x</tt> est 5, ou "
-"bien comme <b>!=</b> (teste l'inégalité), <b><</b> (inférieur à), <b>>"
-"</b> (supérieur à), <b><=</b> (inférieur ou égal à), <b>>=</b> "
-"(supérieur ou égal à)."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:94
+#: src/lessons/welcome/conditions/Conditions.html:70
 msgid ""
 "Beware of the classical trap, which consists in testing the equality of a "
-"variable using = instead of ==. Hopefully, the compiler detects this problem "
-"most of the time, but not always. If the variable is of type boolean, it can "
-"get trapped, so you have to be careful..."
+"variable using = instead of ==. Hopefully, the [!java|scala]compiler[/!][!"
+"python]interpreter[/!] detects this problem most of the time, but it could "
+"get trapped is some cases (such as when you are affecting a boolean "
+"variable). So you'd better to be careful..."
 msgstr ""
 "Attention au piège classique, qui consiste à tester l'égalité d'une variable "
-"avec = au lieu de ==. Heureusement, le compilateur vous indique le plus "
-"souvent ce problème, mais pas tout le temps. Si la variable est de type "
-"booléen, il peut se faire prendre au piège, et il convient donc d'être "
-"attentif..."
+"avec = au lieu de ==. Heureusement, [!java|scala]le compilateur[/!][!"
+"python]l'interpréteur[/!] détecte le plus souvent ce problème et vous le "
+"signale, mais pas tout le temps. Si la variable est de type booléen, il peut "
+"se faire prendre au piège, et il convient donc d'être attentif..."
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:99
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:75
 msgid ""
-"The condition can also be a call to some perticular methods returning a "
-"boolean. For example, the <tt>isFacingWall()</tt> method of the buggle "
+"The condition can also be a call to some particular methods returning a "
+"boolean. For example, the <code>isFacingWall()</code> method of the buggle "
 "returns true if the buggle is facing a wall, and false in the other case."
 msgstr ""
 "La condition peut également être un appel à certaines méthodes "
 "particulières, dont le résultat est un booléen. Par exemple, la méthode "
-"<tt>isFacingWall()</tt> de la buggle renvoie vrai si la buggle est face à un "
+"<tt>estFaceMur()</tt> de la buggle renvoie vrai si la buggle est face à un "
 "mur, et faux sinon."
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:103
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:79
 msgid ""
 "Finally, a condition can be composed of several sub-conditions connected by "
-"boolean operations."
+"boolean operations:"
 msgstr ""
 "Enfin, il est possible de construire une condition composée de plusieurs "
-"sous-conditions reliées par des opérations booléennes."
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:106
-msgid ""
-"<tt>cond1 && cond2</tt> is true when <tt>cond1</tt> <b>and</b> <tt>cond2</"
-"tt> are both true (if <tt>cond1</tt> is false, <tt>cond2</tt> is not even "
-"evaluated)."
-msgstr ""
-"<tt>cond1 && cond2</tt> est vraie si <tt>cond1</tt> <b>et</b> <tt>cond2</tt> "
-"est vraie (si <tt>cond1</tt> est fausse, <tt>cond2</tt> n'est même pas "
-"évaluée)."
+"sous-conditions reliées par des opérations booléennes:"
 
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:109
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:82
 msgid ""
-"<tt>cond1 || cond2</tt> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt> "
-"are true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated)."
+"<code>cond1 [!java|scala]&&[/!][!python]and[/!] cond2</code> is true when "
+"<tt>cond1</tt> <b>and</b> <tt>cond2</tt> are both true (if <tt>cond1</tt> is "
+"false, <tt>cond2</tt> is not even evaluated as we already know that the "
+"conjunction of both propositions cannot be true)."
 msgstr ""
-"<tt>cond1 || cond2</tt> est vraie si <tt>cond1</tt> <b>ou</b> <tt>cond2</tt> "
-"est vraie (si <tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas "
-"évaluée)."
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:111
-msgid "<tt>!cond</tt> is true if <tt>cond</tt> is false."
-msgstr "<tt>!cond</tt> est vraie si <tt>cond</tt> ne l'est pas."
+"<code>cond1 [!java|scala]&&[/!][!python]and[/!] cond2</code> est vraie si "
+"<tt>cond1</tt> <b>et</b> <tt>cond2</tt> est vraie (d'ailleurs, si <tt>cond1</"
+"tt> est fausse, <tt>cond2</tt> n'est même pas évaluée puisqu'on sait déjà "
+"que la conjonction des deux propositions ne peut pas être vraie)."
 
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:112
-#: src/lessons/welcome/conditions/Conditions.html:125
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:85
 msgid ""
-"It is possible to force the order of evaluation by adding parenthesis. In "
-"ambigous cases, do not hesitate to add more parenthesis to remove any "
-"ambiguities on evaluation order."
+"<code>cond1 [!java|scala]||[/!][!python]or[/!] cond2</code> is true if "
+"<tt>cond1</tt> <b>or</b> <tt>cond2</tt> is true (if <tt>cond1</tt> is true, "
+"<tt>cond2</tt> is not even evaluated as we already know that the disjunction "
+"of both propositions cannot be true)."
 msgstr ""
-"On peut forcer l'ordre d'évaluation en ajoutant des parenthèses. En cas de "
-"doute, n'hésitez pas à mettre plus de parenthèses que nécessaire pour lever "
-"les ambiguïtés sur l'ordre d'évaluation."
+"<code>cond1 [!java|scala]||[/!][!python]or[/!] cond2</code> est vraie si "
+"<tt>cond1</tt> <b>ou</b> <tt>cond2</tt> est vraie (d'ailleurs, si <tt>cond1</"
+"tt> est vraie, <tt>cond2</tt> n'est même pas évaluée puisqu'on sait déjà que "
+"la disjonction des deux propositions est vraie)."
 
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:118
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:88
 msgid ""
-"<tt>cond1 and cond2</tt> is true when <tt>cond1</tt> <b>and</b> <tt>cond2</"
-"tt> are both true (if <tt>cond1</tt> is false, <tt>cond2</tt> is not even "
-"evaluated)."
+"<code>[!java|scala]![/!][!python]not [/!]cond</code> is true if <tt>cond</"
+"tt> is false."
 msgstr ""
-"<tt>cond1 and cond2</tt> est vraie si <tt>cond1</tt> <b>et</b> <tt>cond2</"
-"tt> est vraie (si <tt>cond1</tt> est fausse, <tt>cond2</tt> n'est même pas "
-"évaluée)."
+"<code>[!java|scala]![/!][!python]not [/!]cond</code> est vraie si <tt>cond</"
+"tt> ne l'est pas."
 
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:121
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:89
 msgid ""
-"<tt>cond1 or cond2</tt> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt> "
-"are true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated)."
+"When the expression becomes complicated, it is better to add parenthesis to "
+"force the order of evaluation.  Do not hesitate to add more parenthesis to "
+"remove any ambiguities that may appear in an expression."
 msgstr ""
-"<tt>cond1 or cond2</tt> est vraie si <tt>cond1</tt> <b>ou</b> <tt>cond2</tt> "
-"est vraie (si <tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas "
-"évaluée)."
+"Quand les expressions deviennent compliquées, il est préférable d'ajouter "
+"quelques parenthèses pour lever toute ambiguïté sur l'ordre d'évaluation. "
+"N'hésitez pas à mettre suffisamment de parenthèses pour la rendre plus "
+"lisible."
 
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:124
-msgid "<tt>not cond</tt> is true if <tt>cond</tt> is false."
-msgstr "<tt>not cond</tt> est vraie si <tt>cond</tt> ne l'est pas."
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:130
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:93
 msgid ""
-"Finally, it is possible to specify what to do when the condition is false "
-"using the following syntax:"
+"Last, it is possible to specify what to do when the condition is false using "
+"the following syntax. In this case, the instruction "
+"<code>whatToDoIfItsFalse</code> will be executed only if the condition is "
+"false."
 msgstr ""
 "Pour finir, il est possible de spécifier ce qu'il faut faire quand la "
-"condition est fausse, en utilisant la syntaxe suivante :"
+"condition est fausse, en utilisant la syntaxe suivante («else» signifie "
+"«sinon» en anglais). Dans ce cas, l'instruction "
+"<code>aFaireSiLaConditionEstFausse()</code> ne sera exécutée que si la "
+"condition est fausse."
 
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:132
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/conditions/Conditions.html:96
 #, no-wrap
 msgid ""
-"if (<b>condition</b>) {\n"
+"[!java|scala]if (<b>condition</b>) {\n"
 "    <b>whatToDoIfTheConditionIsTrue();</b>\n"
 "} else {\n"
 "    <b>whatToDoIfItsFalse();</b>\n"
-"}"
-msgstr ""
-"if (<b>condition</b>) {\n"
-"    <b>quoiFaireSiLaConditionEstVraie();</b>\n"
-"} else {\n"
-"    <b>quoiFaireSinon();</b>\n"
-"}"
-
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:138
-#, no-wrap
-msgid ""
-"if (<b>condition</b>):\n"
+"}[/!][!python]if (<b>condition</b>):\n"
 "    <b>whatToDoIfTheConditionIsTrue()</b>\n"
 "else:\n"
-"    <b>whatToDoIfItsFalse()</b>\n"
+"    <b>whatToDoIfItsFalse()</b>[/!]"
 msgstr ""
-"if (<b>condition</b>):\n"
-"    <b>quoiFaireSiLaConditionEstVraie()</b>\n"
+"[!java|scala]if (<b>condition</b>) {\n"
+"    <b>aFaireSiLaConditionEstVraie();</b>\n"
+"} else {\n"
+"    <b>aFaireSiElleEstFausse();</b>\n"
+"}[/!][!python]if (<b>condition</b>):\n"
+"    <b>aFaireSiLaConditionEstVraie()</b>\n"
 "else:\n"
-"    <b>quoiFaireSinon()</b>\n"
+"    <b>aFaireSiElleEstFausse()</b>[/!]"
 
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:144
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:105
 msgid ""
 "Don't forget the colon (:) after the else, it is indicating that a new block "
 "is beginning."
 msgstr ""
-"N'oubliez pas les deux points (:) après le else, ils indiquent qu'un "
-"nouveau\n"
+"N'oubliez pas les deux points (:) après le else, ils indiquent qu'un nouveau "
 "bloc débute."
 
-#. type: Content of: <p><p><p><p><p><a>
-#: src/lessons/welcome/conditions/Conditions.html:147
+#. type: Content of: <p><a>
+#: src/lessons/welcome/conditions/Conditions.html:108
 msgid ""
-"<a name=\"Objectives\">If the buggle is facing a wall (predicate "
-"<tt>isFacingWall()</tt>), you must move one step back. If not, you must move "
-"one step forward."
+"<a name=\"Objectives\">If the buggle is facing a wall, you must move one "
+"step back. If not, you must move one step forward. To detect whether you are "
+"facing a wall, simply use the <code>isFacingWall()</code> built-in, that "
+"every buggle understands."
 msgstr ""
-"<a name=\"Objectifs\"> Si la buggle est face à un mur (prédicat "
-"<tt>isFacingWall()</tt>), il faut reculer d'un pas. Sinon, il faut avancer "
-"d'un pas."
+"<a name=\"Objectifs\"> Si la buggle est face à un mur, il faut reculer d'un "
+"pas; Sinon, il faut avancer d'un pas.\n"
+"Pour savoir si on est face à un mur, il suffit d'utiliser la méthode "
+"prédéfinie des buggles nommée <code>estFaceMur()</code>."
 
-#. type: Content of: <p><p><p><p><p><a><p>
-#: src/lessons/welcome/conditions/Conditions.html:151
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/conditions/Conditions.html:113
 msgid ""
 "This exercise is a bit different: your code has to work for several buggles, "
 "each of them being in a specific initial condition. The same code will be "
@@ -3048,13 +2691,126 @@ msgstr ""
 "différente. Le même code sera utilisé pour chacune d'entre elles."
 
 #. type: Content of: <p><a><p>
-#: src/lessons/welcome/conditions/Conditions.html:155
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:32
+#: src/lessons/welcome/conditions/Conditions.html:117
+msgid ""
+"When your program works, move forward to the next exercise, that is hidden "
+"in a sub-tree of the selection window."
+msgstr ""
+"Quand votre programme fonctionne, passez à l'exercice suivant (qui est caché "
+"par défaut dans un sous-arbre de la fenêtre de sélection)."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:3
+msgid ""
+"In addition to conditionals, another handy construction is the ability to "
+"repeat an action while a specific condition does not appear. A while loop is "
+"used for that, with the following syntax."
+msgstr ""
+"En plus des instructions conditionnelles, une autre construction pratique "
+"est de pouvoir répéter une action tant qu'une condition particulière n'est "
+"pas arrivée. On utilise pour cela une boucle <tt>while</tt>, dont la syntaxe "
+"est la suivante :"
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:7
+#, no-wrap
+msgid ""
+"[!java|scala]while (<b>condition</b>) {\n"
+"    <b>action()</b>;\n"
+"}[/!][!python]while <b>condition</b>:\n"
+"    <b>action()</b>[/!]"
+msgstr ""
+"[!java|scala]while (<b>condition</b>) {\n"
+"    <b>action()</b>;\n"
+"}[/!][!python]while <b>condition</b>:\n"
+"    <b>action()</b>[/!]"
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:12
+msgid ""
+"The inner bloc is then executed again and again, as long as the condition "
+"remains true.  More specifically, the buggle tests the value of the "
+"condition. If it's false, it ignores the bloc and continue below.  If it's "
+"true, it executes the bloc.  After that, it tests the condition. If it's now "
+"false (for example because the moves of the block made us facing the wall), "
+"it now ignores the bloc and continue.  If it's still true, it execute the "
+"bloc and reevaluate the condition. It does so as long as the condition "
+"remains true."
+msgstr ""
+"Le bloc est alors exécuté encore et encore, tant que la condition est vraie. "
+"Plus précisément, la buggle teste la valeur de la condition. Si elle est "
+"fausse, le bloc est ignoré et l'exécution continue avec la suite. Si la "
+"condition est vraie, le bloc est exécuté. Ensuite, la buggle réévalue la "
+"condition. Si elle est devenue fausse (par exemple parce que les "
+"déplacements du bloc nous ont mis face au mur), le bloc est maintenant "
+"ignoré et on continue avec la suite. Mais si la condition est toujours "
+"vraie, on exécute une nouvelle fois le bloc avant de réévaluer une fois de "
+"plus la condition. Cela continue ainsi tant que la condition reste vraie."
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:19
+msgid ""
+"Naturally, if the chosen action does not modify the value of the condition, "
+"the buggle will do the action endlessly. The <b>stop</b> button of the "
+"interface becomes then handy. To test this, you can try to type the "
+"following code in the editor:"
+msgstr ""
+"Evidement, si l'action en question ne modifie pas la valeur de la condition, "
+"la buggle va exécuter l'action à l'infini. C'est dans ce genre de cas que le "
+"bouton <b>stop</b> de l'interface devient utile. Pour tester cela, vous "
+"pouvez essayer de taper le code suivant dans l'éditeur :"
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:24
+#, no-wrap
+msgid ""
+"[!java|scala]while (true) {\n"
+"    left();\n"
+"}[/!][!python]while True:\n"
+"    left()[/!]"
+msgstr ""
+"[!java|scala]while (true) {\n"
+"    gauche();\n"
+"}[/!][!python]while True:\n"
+"    gauche()[/!]"
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:29
+msgid ""
+"This will let the buggle turn left as long as <code>[!java|scala]true[/!][!"
+"python]True[/!]</code> remains true (ie, endlessly), or until you stop it "
+"manually using the stop button."
+msgstr ""
+"La buggle va tourner vers la gauche tant que <code>[!java|scala]true[/!][!"
+"python]True[/!]</code> est vrai (sans fin donc) jusqu'à ce que vous "
+"l'arrêtiez manuellement avec le bouton stop."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:32
+msgid ""
+"You now have to write some code so that your buggles move forward until they "
+"encounter a wall. The idea is thus to do something like:"
+msgstr ""
+"Il vous faut maintenant écrire le code nécessaire pour que vos buggles "
+"avancent jusqu'à rencontrer un mur. L'idée est donc de faire :"
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:35
+#, no-wrap
+msgid ""
+"while we are not facing a wall, do:\n"
+"  moveForward()"
+msgstr ""
+"tant que l'on est pas face à un mur, faire :\n"
+"  avancer();"
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:38
 msgid "When your program works, move forward to the next exercise."
 msgstr "Quand votre programme fonctionne, passez à l'exercice suivant."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:2
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:2
 msgid ""
 "The buggle world can sometimes contain some <i>baggles</i>, which are little "
 "biscuits that buggles can carry from one point to another. For that, they "
@@ -3062,22 +2818,73 @@ msgid ""
 "isCarryingBaggle(), pickupBaggle()</code> or <code>dropBaggle()</code>. "
 "Check their documentation in \"Help/About this world\" for more details."
 msgstr ""
-"Le monde des buggles contient parfois des <i>baggles</i>, sorte de petits "
-"biscuits que les buggles peuvent déplacer d'un endroit à un autre. Pour "
-"cela, elles peuvent utiliser des fonctions spécifiques : "
-"<code>isOverBaggle(), isCarryingBaggle(), pickupBaggle()</code> et "
-"<code>dropBaggle()</code>. Tous les détails se trouvent dans la "
-"documentation accessible depuis «Aide/À propos de ce monde»."
+"Le monde des buggles contient parfois des petits biscuits ronds que les "
+"buggles peuvent déplacer d'un endroit à un autre. Pour cela, elles peuvent "
+"utiliser des fonctions spécifiques : <code>estSurBiscuit(), porteBiscuit(), "
+"prendBiscuit()<code> et <code>poseBiscuit()</code>. Tous les détails se "
+"trouvent dans la documentation accessible depuis «Aide/À propos de ce monde»."
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:10
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:10
 msgid ""
 "Let each buggle find its baggle by adapting the code you wrote in previous "
-"exercise (copy/paste what you've done before to save time)."
+"exercise (copy/paste what you've done before if you want)."
 msgstr ""
 "Faites en sorte que chaque buggle trouve son baggle en adaptant le code que "
-"vous aviez écrit pour l'exercice précédent (faites un copie/colle de ce que "
-"vous aviez fait pour gagner du temps)."
+"vous aviez écrit pour l'exercice précédent (vous êtes libre de faire un "
+"copie/colle de ce que vous aviez fait si vous le souhaitez)."
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:1
+msgid "Lost in the Moria"
+msgstr "Perdu dans la Moria"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:3
+msgid ""
+"You buggle got stuck in a mine! Some rocks are blocking the exit, and you "
+"will have to clear your way to the exit. Well of course these are only "
+"baggles and you could simply walk away, but it will be easier to program "
+"your buggle so that it moves those \"rocks\" than convincing your buggle "
+"that it could easily walk away without solving the problem..."
+msgstr ""
+"Votre buggle est coincée dans une mine ! Des rochers bloquent la sortie, et "
+"il va falloir dégager le chemin pour passer. Bon, ok, ce ne sont pas "
+"vraiment des rochers mais juste des biscuits, et votre buggle pourrait "
+"facilement passer au dessus sans se fatiguer. Mais il est probablement plus "
+"simple de programmer votre buggle pour qu'elle déplace ces «rochers» plutôt "
+"que de tenter de la convaincre de passer à la suite sans avoir résolu le "
+"problème..."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:9
+msgid ""
+"So, you have to find the first baggle blocking the exit (simply walk to the "
+"east until you are over a baggle), take it and move it back to the other "
+"side of the tunnel (walk to the west while you are not over a baggle, and "
+"then move back one step to the east and drop your baggle), and iterate until "
+"you find the exit (that is, the wall to the east side). Afterward, move out "
+"as in the objective world."
+msgstr ""
+"Donc, il vous faut trouver le premier biscuit en travers de votre chemin "
+"(marchez vers l'est jusqu'à vous trouver au dessus d'un biscuit), le "
+"ramasser, et retourner à l'autre extrémité du couloir pour le déposer "
+"(marchez vers l'ouest jusqu'à vous trouver au dessus d'un biscuit puis "
+"reculez d'un pas). Il faut ensuite faire de même pour tous les biscuits "
+"jusqu'à trouver la sortie. Une fois ceci fait, marchez vers l'air frais "
+"comme dans le monde objectif."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:16
+msgid ""
+"Once you manage to escape this trap, you can move forward to the next "
+"exercise.  This exercise is a bit more complex, so you can also leave it for "
+"now and come back later if you don't get it right now."
+msgstr ""
+"Quand vous serez parvenu à sortir de ce piège, vous pouvez passez à "
+"l'exercice suivant. Cet exercice est un peu plus difficile que les autres, "
+"et vous pouvez tout à fait le laisser momentanément de coté pour y revenir "
+"plus tard si vous n'y parvenez pas pour l'instant."
 
 #. type: Content of: <p>
 #: src/lessons/welcome/variables/Variables.html:2
@@ -3097,256 +2904,332 @@ msgstr ""
 
 #. type: Content of: <p><h3>
 #: src/lessons/welcome/variables/Variables.html:8
-msgid "Data in Java"
-msgstr "Les données en Java"
+msgid "Data in [!thelang]"
+msgstr "Les données en [!thelang]"
 
-#. type: Content of: <p><h3>
+#. type: Content of: <p><p>
 #: src/lessons/welcome/variables/Variables.html:9
-msgid "Data in Python"
-msgstr "Les données en Python"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/Variables.html:10
 msgid ""
 "In a program, you can use several <i>types</i> of data, such as integers or "
 "strings of chars. If you want to use a data several times, you need to store "
-"it within a <i>variable</i>, which is a memory cell containing a value. It's "
-"not very different from a shelve containing a book: you put your data (say "
-"'5') in the variable (say 'length'), and you can retrieve it latter when you "
-"need it."
+"it within a <i>variable</i>, which is a memory cell containing a value: you "
+"put your data (say the value '5') in the variable (say 'length'), and you "
+"can retrieve it latter when you need it. That's very similar to a box of "
+"label 'gift' in which you would put some stuff, like a bottle of perfume "
+"\"Channel N°5\"."
 msgstr ""
 "Dans un programme, on peut utiliser différents <i>types</i> de données, tels "
 "que les entiers, les nombres à virgules ou les chaînes de caractères. Si on "
 "veut utiliser une donnée plusieurs fois, il faut la stocker dans une "
-"<i>variable</i>, qui est une sorte de case contenant une valeur. Ce n'est "
-"pas très différent d'une étagère contenant un livre: vous rangez votre "
-"donnée (disons '5') dans la variable (disons 'longueur'), et vous pouvez la "
-"retrouver plus tard quand vous en avez besoin."
+"<i>variable</i>, qui est une sorte de case contenant une valeur: vous rangez "
+"votre donnée (disons '5') dans la variable (disons «longueur»), et vous "
+"pouvez la retrouver plus tard quand vous en avez besoin. C'est exactement "
+"comme prendre une boîte avec une étiquette (disons «cadeau») et d'y ranger "
+"quelque chose dedans (disons, un flacon de Channel Numéro 5)."
 
-#. type: Content of: <p><p>
+#. type: Content of: <p><p><h3>
 #: src/lessons/welcome/variables/Variables.html:16
-msgid ""
-"Java is said to be a <i>typed</i> language, which means that it is only "
-"possible to store a value in a variable of the right type. Don't think about "
-"storing the letters of your name into an integer variable. In other "
-"languages (such as Python)  allow you to store any kind of data in any "
-"variable without such restriction, but not in Java."
-msgstr ""
-"Java est un langage <i>typé</i>, ce qui veut dire que l'on ne peut stocker "
-"une valeur que dans une variable du bon type. Pas question de stocker votre "
-"nom dans une variable entière."
+msgid "Variable declarations"
+msgstr "Déclaration de Variables"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:20
-msgid ""
-"The Python language is said to <i>not typed</i>, which means you can store "
-"any type of data into a given variable. Other languages (such as Java) "
-"mandate that each variable store only data of a given type, but there is no "
-"such difficulties here."
-msgstr ""
-"Le langage Python est dit <i>non typé</i>, ce qui signifie qu'une variable "
-"donnée peutcontenir n'importe quel type de donnée. D'autres langages (comme "
-"Java) rendent obligatoire que chaque variable  ne puisse contenir que des "
-"données d'un certain type, mais il n'y a pas de telles difficultés ici."
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:18
+msgid ""
+"<b>Declaring</b> (ie, creating) a variable in [!thelang], is very simple. "
+"You just need to write [!java]its type, a space, and the variable name.[/!] "
+"[!scala]the <code>var</code> keyword, the variable name, a column (:) and "
+"the variable type.[/!] [!python]the variable name, an equal sign (=) and an "
+"initial value.[/!] The variable name is the label to retrieve it afterward[!"
+"python].[/!] [!java|scala] while the type is the kind of data that this "
+"variable accepts to store.[/!] It is forbidden to use spaces in variable "
+"names. So you can name a variable <code>stepAmount</code> if you want, but "
+"<code>step amount</code> is not a valid name."
+msgstr ""
+"Il est très simple de <b>déclarer</b> (c'est-à-dire, créer) une variable en "
+"[!thelang]. Il suffit d'écrire\n"
+"[!java]son type, une espace et le nom de la variable.[/!] \n"
+"[!scala]le mot-clé <code>var</code>, le nom de la variable, deux points (:) "
+"et le type de la variable.[/!] \n"
+"[!python]le nom de la variable, un signe égal (=) et sa valeur initiale."
+"[/!] \n"
+"Le nom de la variable est un label pour la retrouver plus tard[!python]."
+"[/!] \n"
+"[!java|scala] tandis que son type est le genre de données qu'on va pouvoir "
+"stoker dans cette variable.[/!] \n"
+"Il est interdit de mettre des espaces et des accents dans les noms de "
+"variable. \n"
+"Ainsi, on peut nommer une variable <code>dejaFait</code>, mais ni <code>deja "
+"fait</code> ni <code>déjaFait</code> ne sont des identificateurs de "
+"variables valides."
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:25
-msgid ""
-"To <i>declare</i> (ie, create) a variable, you just need to write its type, "
-"a space, and the variable name. From the existing types, we can speak of "
-"<b>int</b> (for integers), <b>double</b> for dot numbers, <b>boolean</b> for "
-"booleans (ie, values being either true or false) and <b>String</b> for char "
-"strings. If you want, you can specify the initial value of the variable by "
-"adding a equal sign (=) followed by the value after the declaration."
-msgstr ""
-"Pour <i>déclarer</i> (i.e. créer) une variable, il suffit d'écrire son type, "
-"un espace et le nom de la variable. Notez qu'il n'est pas possible "
-"d'utiliser d'accents dans les noms de variables, malheureusement. Parmi les "
-"types existants, on trouve: <b>int</b> pour les entiers, <b>double</b> pour "
-"les nombres à virgule, <b>boolean</b> pour les booléens (i.e. les variables "
-"qui peuvent être soit vraies soit fausses) et <b>String</b> pour les chaînes "
-"de caractères.  Si l'on veut, on peut faire suivre la déclaration du signe = "
-"suivi de la valeur initiale à donner à la valeur."
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/variables/Variables.html:28
+#: src/lessons/welcome/variables/Variables.html:40
+#: src/lessons/welcome/methods/args/MethodsArgs.html:34
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:34
+#: src/lessons/welcome/bdr/BDR.html:8 src/lessons/welcome/bdr/BDR2.html:3
+#: src/lessons/recursion/square/FourSquare.html:27
+msgid "[!java|scala]"
+msgstr "[!java|scala]"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:31
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:29
 msgid ""
 "So, to create a variable named <b>x</b> intended to contain integers, one "
-"can write:"
+"should write:"
 msgstr ""
 "Ainsi, pour créer une variable nommée <b>x</b> contenant des entiers, on "
 "écrira :"
 
 #. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:32
+#: src/lessons/welcome/variables/Variables.html:30
 #, no-wrap
-msgid "int x;"
-msgstr "int x;"
+msgid "[!java]int x;[/!][!scala]var x: Int[/!]"
+msgstr "[!java]int x;[/!][!scala]var x: Int[/!]"
 
-#. type: Content of: <p><p>
+#. type: Content of: <p><p><p>
 #: src/lessons/welcome/variables/Variables.html:33
 msgid ""
-"If you want that the variable contains 5 as initial value, you should type:"
-msgstr "Si on veut que sa valeur initiale soit 5, on écrira :"
+"[!java|scala]If you want, you can specify the initial value of the variable "
+"by adding a equal sign (=) followed by the value after the declaration.[/!] "
+"[!scala]If you specify a value, you don't have to specify the type of the "
+"variable, since Scala manages to guess it alone in most cases.  You are "
+"still free to specify the type if you prefer (or if the compiler fail to "
+"determine the type for some reason), but it's optional.[/!] So you want that "
+"the variable contains 5 as initial value, you should type:"
+msgstr ""
+"[!java|scala]Si vous le souhaitez, vous pouvez spécifier une valeur initiale "
+"en faisant suivre la déclaration d'un symbole égal (=) suivi de la valeur à "
+"utiliser.[/!] \n"
+"[!scala]Si vous spécifiez une valeur, il n'est alors plus indispensable de "
+"spécifier le type de la variable, puisque Scala parvient à le deviner tout "
+"seul. Vous êtes libre de le spécifier quand même si vous le désirez (ou si "
+"le compilateur se trompe, comme cela arrive parfois par exemple entre les "
+"différents types de nombres), mais c'est optionnel.[/!]\n"
+"Donc, si vous voulez utiliser 5 comme valeur initiale, il faut écrire:"
 
 #. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:33
+#: src/lessons/welcome/variables/Variables.html:37
 #, no-wrap
-msgid "int x = 5;"
-msgstr "int x = 5;"
+msgid ""
+"[!java]int x=5;[/!][!python]x = 5[/!][!scala]var x: Int =  5 <span class=\"comment\">// I can define the type if I want to</span>\n"
+"var y =  10      <span class=\"comment\">// or I can omit the type if I prefer</span>[/!]"
+msgstr ""
+"[!java]int x=5;[/!][!python]x = 5[/!][!scala]var x: Int =  5 <span class=\"comment\">// je peux quand même donner le type si je veux</span>\n"
+"var y = 10       <span class=\"comment\">// ou bien je peux l'omettre</span>[/!]"
 
 #. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:34
+#: src/lessons/welcome/variables/Variables.html:41
+msgid ""
+"As you can see, the variables are <b>typed</b> in [!thelang], which means "
+"that they are somehow specialized: A given variable can only store data of a "
+"given type; Don't even think of storing numbers in a variable that is "
+"tailored for letters! Other languages (such as Python) are less picky and "
+"allow you to store any kind of data in any variable without restriction.  "
+"This seems easier at the first glance, but this kind of restriction allows "
+"the compiler to catch more logic errors for you, which is also good. In some "
+"sense, Python is easier to write but errors can sneak in more easily than in "
+"[!thelang].  Here are some of the existing types:"
+msgstr ""
+"Comme vous pouvez le voir, les variables sont <b>typées</b> en[!thelang]. "
+"Cela veut dire qu'elles sont en quelque sorte spécialisées: une variable "
+"donnée ne peut stocker qu'un type de données spécifique. N'essayez même pas "
+"de rancher des nombres dans une variable faite pour recevoir des lettres ! \n"
+"D'autres langages (comme le python) sont moins regardants, et on peut ranger "
+"n'importe quel type de données dans n'importe quelle variable sans "
+"restriction. À première vue, cela semble plus simple, mais ce genre de "
+"restriction permet au compilateur de détecter plus d'erreurs de logiques "
+"pour vous, ce qui n'est pas dommage. En quelque sorte, il est plus facile "
+"d'écrire du python, mais le typage empêche certaines erreurs de se glisser "
+"dans vos programmes. \n"
+"Voici quelque uns des types de données existants en [!thelang] :"
+
+#. type: Content of: <p><p><ul><li>
 #: src/lessons/welcome/variables/Variables.html:48
+msgid "<b>[!java]int[/!][!scala]Int[/!]</b>, for integers;"
+msgstr "<b>[!java]int[/!][!scala]Int[/!]</b>, pour les entiers;"
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:49
+msgid "<b>[!java]double[/!][!scala]Double[/!]</b>, for dot numbers;"
+msgstr ""
+"<b>[!java]double[/!][!scala]Double[/!]</b>, pour les nombres à virgule;"
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:50
 msgid ""
-"Later in the program, if you want to <i>affect</i> a new value to the "
-"variable, that's really easy:"
+"<b>[!java]boolean[/!][!scala]Boolean[/!]</b>, for booleans that are values "
+"being either true or false;"
 msgstr ""
-"Plus tard dans le programme, si l'on souhaite <i>affecter</i> une nouvelle "
-"valeur à la variable, c'est très simple :"
+"<b>[!java]boolean[/!][!scala]Boolean[/!]</b>, pour les booléens, c'est-à-"
+"dire les variables dont la valeur est soit \"vrai\" soit \"faux\";"
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:35
-#, no-wrap
-msgid "x = 3;"
-msgstr "x = 3;"
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:51
+msgid "<b>String</b>, for char strings."
+msgstr "<b>String</b>, pour les chaînes de caractères."
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/variables/Variables.html:53
+msgid "[/!] [!python]"
+msgstr "[/!] [!python]"
 
 #. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:36
-msgid ""
-"The syntax to create an integer variable <code>x</code> with 4 as initial "
-"value is the following:"
-msgstr ""
-"La syntaxe pour créer une variable entière <code>x</code> de valeur initiale "
-"4 est la suivante :"
+#: src/lessons/welcome/variables/Variables.html:56
+msgid ""
+"As you can see, the variables are not <b>typed</b> in Python, which means "
+"that they are not specialized in any type of data.  A given variable store "
+"any type of data of a given type: you can store a number in a variable and "
+"latter on store a number in the same variable.  Other languages (such as "
+"Java or Scala) are much more picky and prevent you to mix data types in a "
+"given variable.  This seems annoying at the first glance, but this kind of "
+"restriction allows the compiler to catch more logic errors for you, which is "
+"also good. In some sense, Python is easier to write but errors can sneak in "
+"more easily."
+msgstr ""
+"Comme vous pouvez le voir, les variables ne sont pas <b>typées</b> en "
+"Python, ce qui veut dire qu'elles ne sont pas spécialisées sur un type de "
+"données particulier. Il est tout à fait envisageable de stocker des nombres "
+"dans une variable, puis d'y mettre des lettres un peu plus tard.\n"
+"D'autres langages (comme le Java ou le Scala) sont plus restrictifs et "
+"imposent de spécialiser chaque variable pour un type donné. Cela semble bien "
+"plus contraignant à première vue, mais ce genre de restriction permet au "
+"compilateur de détecter plus d'erreurs de logique pour vous. D'une certaine "
+"manière, il est plus facile d'écrire du Python, mais le typage de ces "
+"langages empêche certaines erreurs de se glisser dans les programmes."
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:38
-#, no-wrap
-msgid "int x = 4;"
-msgstr "int x = 4;"
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:64
+msgid ""
+"If you know that the value of your \"variable\" will never change (eg "
+"because it contains the screen size or some other constant value), then you "
+"should make it a <b>value</b> instead of a variable. Simply change the "
+"<code>var</code> keyword with the <code>val</code> one. The compiler can "
+"then perform more verifications and catch when you inadvertently modify the "
+"value. More interestingly, the compiler can produce faster code in some "
+"cases."
+msgstr ""
+"Si vous savez que votre «variable» ne va jamais changer de valeur (par "
+"exemple parce qu'il s'agit de la taille de l'écran ou une autre constante du "
+"genre), alors vous devriez en faire une <b>valeur</b> plutôt qu'une "
+"variable.\n"
+"Utilisez simplement le mot-clé <code>val</code> au lieu de <code>var</"
+"code>. \n"
+"Le compilateur pourra alors faire plus de vérifications pour aider les "
+"étourdis cherchant à modifier les constantes. Plus intéressant, le "
+"compilateur parvient également à produire du code plus rapide dans certains "
+"cas."
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:39
-#: src/lessons/welcome/variables/Variables.html:50
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:69
 msgid ""
-"This quite the same story for strings, floating point numbers and boolean "
-"values."
+"Variables work very similarly for strings, floating point numbers and "
+"boolean values."
 msgstr ""
 "C'est la même histoire pour les chaînes, nombres à virgule flottante et les "
 "booléens."
 
 #. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:41
+#: src/lessons/welcome/variables/Variables.html:71
 #, no-wrap
 msgid ""
 "String name = \"Martin Quinson\";\n"
 "double height=1.77; <span class=\"comment\">// in meters</span>\n"
-"boolean married=true;"
+"boolean married=true;<span class=\"comment\">// the contrary would be written \"false\"</span>"
 msgstr ""
 "String nom = \"Martin Quinson\";\n"
 "double taille=1.77; <span class=\"comment\">// en mètres</span>\n"
-"boolean marie=true;"
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:45
-msgid ""
-"<i>Declaring</i> (ie, creating) a variable in Python is dead simple: you "
-"just need to give it an initial value by writing its name, the equal sign "
-"and the value."
-msgstr ""
-"<i>Déclarer</i> (ie créer) une variable en Python est extrèmement simple: "
-"vous avez juste besoin de lui donner une valeur initiale en écrivant son "
-"nom, le signe égal et la valeur."
+"boolean marie=true; <span class=\"comment\">// Signifie vrai; le contraire (faux) s'écrirait \"false\"</span>"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:47
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:75
+#, no-wrap
 msgid ""
-"So, to create a variable named <b>x</b> which initial value should be 5, you "
-"should type:"
+"val name:String = \"Martin Quinson\"; <span class=\"comment\">// this cannot be modified (it's a value)</span>\n"
+"var height: Double = 1.77; <span class=\"comment\">// in meters</span>\n"
+"var married = true; <span class=\"comment\">// the contrary would be written \"false\"</span>\n"
+"<span class=\"comment\">// Scala knows that 'true' is a Boolean value, no need to repeat it here</span>"
 msgstr ""
-"Ainsi, pour créer une variable nommée <b>x</b> dont la valeur initiale sera "
-"5, on écrira :"
+"val nom:String = \"Martin Quinson\"; <span class=\"comment\">// impossible de le modifier (c'est une valeur)</span>\n"
+"var taille: Double = 1.77; <span class=\"comment\">// en metre</span>\n"
+"var marie = true; <span class=\"comment\">// Signifie vrai; le contraire (faux) s'écrirait \"false\"</span>\n"
+"<span class=\"comment\">// Scala sait que 'true' est une valeur de type Boolean, pas besoin de le répéter</span>"
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:47
-#, no-wrap
-msgid "x = 5"
-msgstr "x = 5;"
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:49
-#, no-wrap
-msgid "x = 3"
-msgstr "x = 3;"
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:52
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:80
 #, no-wrap
 msgid ""
 "firstName = \"Martin\"\n"
 "lastName = 'Quinson' <span class=\"comment\"># both single and double quote work here</span>\n"
 "motto = \"I never finish anyth' (but I keep trying)\" <span class=\"comment\"># having single quote within double quote is fine</span> \n"
 "height=1.77 <span class=\"comment\"># in meters</span>\n"
-"married=True <span class=\"comment\"># the contrary would be written False</span>"
+"married=True <span class=\"comment\"># the contrary would be written \"False\"</span>"
 msgstr ""
 "prenom = \"Martin\"\n"
 "nom = 'Quinson' <span class=\"comment\"># les simples et les doubles quotes fonctionnent ici</span>\n"
 "devise = \"Je ne finis jam' (mais je continue d'essayer)\" <span class=\"comment\"># avoir des quotes simples dans des doubles quotes fonctionne</span> \n"
 "taille=1.77 <span class=\"comment\"># en mètre</span>\n"
-"marie=True <span class=\"comment\"># le contraire serait marqué False</span>"
+"marie=True <span class=\"comment\"># Signifie 'vrai'; le contraire (faux) serait marqué 'False'</span>"
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:59
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/variables/Variables.html:86
+msgid "Affectations"
+msgstr "Affectations"
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:88
 msgid ""
-"To the right of the equal symbol, you can put an expression containing "
-"constants, variables and operations:"
+"Once your variable is declared, you can <b>affect</b> a new value to it "
+"later in the program. That's really easy:"
 msgstr ""
-"À droite du signe égal, on peut mettre une expression quelconque, qui peut "
-"contenir des constantes, des variables et des opérations :"
+"Une fois que votre variable est déclarée, vous pouvez y <i>affecter</i> une "
+"nouvelle valeur plus tard dans votre programme. C'est vraiment très simple :"
 
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:62
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:89
 #, no-wrap
+msgid "x = 3[!java];[/!]"
+msgstr "x = 3[!java];[/!]"
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:91
 msgid ""
-"x = 3 + 2;\n"
-"x = 3 * x;\n"
-"greeting = \"Hello \"+name;\n"
+"To the right of the equal symbol, you can put an arithmetic expression "
+"containing constants, variables and operations."
 msgstr ""
-"x = 3 + 2;\n"
-"x = 3 * x;\n"
-"hello = \"Salut \"+nom;\n"
+"À droite du signe égal, on peut mettre une expression quelconque, qui peut "
+"contenir des constantes, des variables et des opérations :"
 
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:66
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:93
 #, no-wrap
 msgid ""
-"x = 3 + 2\n"
-"x = 3 * x\n"
-"greeting = \"Hello \"+name\n"
+"x = 3 + 2[!java];[/!]\n"
+"x = 3 * x[!java];[/!]\n"
+"greeting = \"Hello \"+name[!java];[/!] <span class=\"comment\">[!python]#[/!][!scala|java]//[/!] + is (also) the operation to concatenate (ie, to join) strings</span>"
 msgstr ""
-"x = 3 + 2\n"
-"x = 3 * x\n"
-"hello = \"Salut \"+nom\n"
+"x = 3 + 2[!java];[/!]\n"
+"x = 3 * x[!java];[/!]\n"
+"greeting = \"Hello \"+name[!java];[/!] <span class=\"comment\">[!python]#[/!][!scala|java]//[/!] + est (également) l'opérateur pour concaténer les chaînes (càd pour les fusionner</span>"
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:73
+#. type: Content of: <p><p>
+#: src/lessons/welcome/variables/Variables.html:98
 msgid ""
 "It is now time to do more challenging exercises, don't you think? The "
 "objective is now to move forward until you find a baggle, pick it up, and "
 "then move back to your initial location before dropping the baggle."
 msgstr ""
 "Il est temps de faire un exercice un peu plus dur, n'est ce pas ? L'objectif "
-"cette fois est d'avancer jusqu'au baggle qui se trouve devant la buggle, le "
-"ramasser, revenir à la position initiale, puis de poser le baggle."
+"cette fois est d'avancer jusqu'au biscuit qui se trouve devant la buggle, le "
+"ramasser, revenir à la position initiale, puis de poser le biscuit."
 
-#. type: Content of: <p><p><p><p><h3>
-#: src/lessons/welcome/variables/Variables.html:78
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/variables/Variables.html:103
 msgid "How to do this?"
 msgstr "Comment faire ?"
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:79
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:104
 msgid ""
 "To solve this problem, you have to decompose it in easier sub-parts. For "
 "example, you may want to do the following steps:"
@@ -3354,28 +3237,28 @@ msgstr ""
 "Pour résoudre ce problème, il faut le décomposer en parties que vous savez "
 "résoudre. Par exemple, on peut vouloir faire les étapes suivantes :"
 
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:82
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:107
 msgid "Move forward until located over a baggle"
-msgstr "Avancer jusqu'à se trouver sur un baggle"
+msgstr "Avancer jusqu'à se trouver sur un biscuit"
 
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:83
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:108
 msgid "Pickup the baggle"
-msgstr "Ramasser le baggel au sol"
+msgstr "Ramasser le biscuit au sol"
 
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:84
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:109
 msgid "Move backward of the same amount of steps than done in first step"
 msgstr "Reculer du même nombre de cases que ce qu'on a avancé"
 
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:85
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:110
 msgid "Drop back the baggle"
-msgstr "Reposer le baggel au sol"
+msgstr "Reposer le biscuit au sol"
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:88
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:113
 msgid ""
 "Naturally, it is impossible to do the right amount of steps backward at step "
 "3 if you didn't count the amount of steps done in the first phase. You can "
@@ -3385,33 +3268,42 @@ msgstr ""
 "si l'on a pas compté le nombre de pas faits à la première étape. On va pour "
 "cela utiliser une variable, que l'on peut nommer <code>nbPas</code>."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:92
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:117
 msgid ""
-"Create a variable (of type <code>int</code>) before phase 1, initialize it "
-"to 0, and each time you move one step forward, increment its value by one "
-"(<code>stepAmount = stepAmount + 1;</code> or <code>stepAmount++;</code>, "
-"both syntaxes being equivalent)."
+"Create an integer variable before phase 1, initialize it to 0, and each time "
+"you move one step forward, increment its value by one (<code>stepAmount = "
+"stepAmount + 1;</code>[!java] or <code>stepAmount++;</code>, both syntaxes "
+"being equivalent[/!]).  Such variable which takes every values of a given "
+"range is often called a <b>stepper</b>."
 msgstr ""
 "On crée cette variable (de type <code>int</code>) avant l'étape 1, on "
 "l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1 "
-"(<code>nbPas = nbPas + 1;</code> ou <code>nbPas++;</code>, les deux "
-"écritures sont équivalentes)."
+"(<code>nbPas = nbPas + 1;</code>[!java] ou <code>nbPas++;</code>, les deux "
+"écritures sont équivalentes[/!])."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:96
-msgid ""
-"Create a variable before phase 1, initialize it to 0, and each time you move "
-"one step forward, increment its value by one (<code>stepAmount = stepAmount "
-"+ 1</code>)."
-msgstr ""
-"On crée cette variable (de type <code>int</code>) avant l'étape 1, on "
-"l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1 "
-"(<code>nbPas = nbPas + 1;</code> ou <code>nbPas++;</code>, les deux "
-"écritures sont équivalentes)."
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:124
+msgid ""
+"If you know Java or other languages, you will probably try to use the <code>+"
+"+</code> operator to increment the variable, but it's not allowed in [!"
+"thelang].  This is because it would be difficult to define this operator for "
+"every data types.  For example, what should ++ do when applied to a Complex "
+"value or to a String? The problem does not occur in Java as <code>int</code> "
+"is not an object but a primitive type.  (if you don't know the <code>++</"
+"code>, just ignore this paragraph: it does not exist in [!thelang])"
+msgstr ""
+"Si vous connaissez le Java ou d'autres langages du genre, vous serez "
+"probablement tenté d'utiliser l'opérateur <code>++</code> pour incrémenter "
+"la variable. Malheureusement, cet opérateur n'existe pas en [!thelang]. "
+"C'est parce qu'il serait difficile de savoir quoi faire quand on l'applique "
+"à un nombre complexe ou à une chaîne de caractères. Le problème ne se pose "
+"pas en Java, où ++ est défini pour le type <code>int</code> qui n'est pas un "
+"type d'objet mais un type primitif (si vous ne connaissez pas l'opérateur +"
+"+, ignorez simplement ce paragraphe : cela n'existe pas en [!thelang])."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:100
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:132
 msgid ""
 "Then, phase 3 consists in simply creating a new integer variable "
 "<code>doneSteps</code> initialized to 0, and do one step backward until "
@@ -3423,20 +3315,8 @@ msgstr ""
 "<code>dejaFait</code> n'est pas égal à <code>nbPas</code>, en incrémentant "
 "<code>dejaFait</code> à chaque fois."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:105
-msgid ""
-"Please note that it is forbidden to use spaces in variable names. So you can "
-"name you variable <code>stepAmount</code>, but <code>step Amount</code> is "
-"not a valid name."
-msgstr ""
-"Attention, il est interdit d'utiliser des caractères accentués ou des "
-"espaces dans les noms de variables Java. Vous pouvez donc nommer votre "
-"variable <code>dejaFait</code>, mais ni <code>déjaFait</code> ni <code>deja "
-"Fait</code> ne sont des noms valides."
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:109
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:137
 msgid "It's your turn now!"
 msgstr "À vous de jouer !"
 
@@ -3458,8 +3338,8 @@ msgstr ""
 "C'est une compétition traditionnelle par laquelle les jeunes buggles "
 "prouvent leur valeur à la tribu. C'est à la fois une épreuve de force et "
 "d'intelligence puisqu'il faut courir le plus vite possible, mais s'arrêter "
-"dès que vous avez rejoint votre quatrième baggle. Il faut que vous aidiez "
-"les buggles à avancer tout en comptant les baggles pour déterminer quand "
+"dès que vous avez rejoint votre quatrième biscuit. Il faut que vous aidiez "
+"les buggles à avancer tout en comptant les biscuits pour déterminer quand "
 "s'arrêter."
 
 #. type: Content of: <h2>
@@ -3479,8 +3359,8 @@ msgstr ""
 "C'est le second jour de la Grande Course des Buggles. Comme d'habitude, il "
 "faut courir jusqu'à trouver la case où vous devez vous arrêter. Mais cette "
 "fois, vous devez vous arrêter quand vous aurez compté deux fois plus de "
-"baggles que de cases oranges plus une. En d'autres termes, la condition "
-"d'arrêt est la suivante : <code>2 * baggles = caseOrange + 1</code>."
+"biscuits que de cases oranges plus une. En d'autres termes, la condition "
+"d'arrêt est la suivante : <code>2 * biscuits = caseOrange + 1</code>."
 
 #. type: Content of: <p>
 #: src/lessons/welcome/variables/RunHalf.html:8
@@ -3489,18 +3369,17 @@ msgid ""
 "<code>isOverOrange()</code> method."
 msgstr ""
 "Vous pouvez déterminer si vous vous trouvez sur une case orange avec la "
-"méthode <code>isOverOrange()</code>."
+"méthode <code>estSurOrange()</code>."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:3
+#: src/lessons/welcome/loopfor/LoopFor.html:3
 msgid ""
 "While loops are well adapted to situations where you want to achieve an "
 "action while a condition stays true, but it is less adapted to achieve a "
 "given action a predetermined amount of time. For example, when we wanted to "
-"move <code>stepAmount</code> steps backward in previous exercise, you had to "
-"create a new variable, initialize it, and move backward until the new "
-"variable became equal to <code>stepAmount</code>, incrementing the new "
-"variable manually at the end of the loop."
+"move <code>stepAmount</code> steps backward in a previous exercise, we had "
+"to create a new variable, initialize it, and move backward while "
+"incrementing this variable until it became equal to <code>stepAmount</code>."
 msgstr ""
 "Les boucles <tt>while</tt> sont bien adaptées aux situations où l'on veut "
 "réaliser une action tant qu'une condition est réalisée, mais elles sont "
@@ -3512,7 +3391,7 @@ msgstr ""
 "corps de la boucle."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:11
+#: src/lessons/welcome/loopfor/LoopFor.html:10
 msgid ""
 "In such situations, <code>for</code> loops become handy. Their syntax is the "
 "following:"
@@ -3520,195 +3399,204 @@ msgstr ""
 "Dans ce genre de cas, les boucles de type <code>for</code> sont plus "
 "pratique. Leur syntaxe est la suivante :"
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:13
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:12
 #, no-wrap
 msgid ""
-"for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {\n"
-"   <b>action</b>();\n"
-"}"
+"[!java]for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>variable</b> in <b>sequence of values</b>:\n"
+"    <b>action</b>()[/!][!scala] for (<b>variable</b> <- <b>firstValue</b> to <b>lastValue</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
 msgstr ""
-"for (<b>initialisation</b>; <b>condition</b>; <b>incrémentation</b>) {\n"
-"   <b>action</b>();\n"
-"}"
+"[!java]for (<b>initialisation</b>; <b>condition</b>; <b>increment</b>) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>variable</b> in <b>sequence de valeurs</b>:\n"
+"    <b>action</b>()[/!][!scala] for (<b>variable</b> <- <b>premiereValeur</b> to <b>derniereValeur</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:17
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:19
+msgid ""
+"For example to repeat the the loop body <code>n</code> times, [!python] it "
+"is handy to use the instruction <code>range(n)</code> to generate the "
+"sequence n integer value from 0 to n-1.[/!] [!java|scala] one should write:"
+"[/!]"
+msgstr ""
+"Par exemple, pour répéter le corps de boucle <code>n</code> fois, \n"
+"[!python]il est pratique d'utiliser l'instruction <code>range(n)</code>\n"
+"  pour générer la séquence de n entiers allant de 0 à n-1.[/!]\n"
+"[!java|scala]il faut écrire:[/!]"
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:22
 #, no-wrap
 msgid ""
-"for <b>variable</b> in <b>sequence of values</b>:\n"
-"   <b>action</b>()\n"
+"[!java]for (int stepper=0; stepper<n; stepper++) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>stepper</b> in <b>range(n)</b>:\n"
+"    <b>action</b>()[/!][!scala] for (var <b>stepper</b> <- <b>1</b> to <b>n</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
 msgstr ""
-"for <b>variable</b> in <b>séquence de valeurs</b>:\n"
-"   <b>action</b>()\n"
+"[!java]for (int compteur=0; compteur<n; compteur++) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>compteur</b> in <b>range(n)</b>:\n"
+"    <b>action</b>()[/!][!scala] for (var <b>compteur</b> <- <b>1</b> to <b>10</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:21
-msgid "This code is perfectly equivalent to the following:"
+#: src/lessons/welcome/loopfor/LoopFor.html:29
+msgid "This code is then perfectly equivalent to the following one."
 msgstr "Ce code est parfaitement équivalent à celui-ci :"
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:22
-#, no-wrap
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:30
+#, no-wrap
+msgid ""
+"[!java]int stepper = 0;\n"
+"while (stepper < n) {\n"
+"    <b>action</b>();\n"
+"    <b>stepper++</b>;\n"
+"}[/!][!python]stepper=0\n"
+"while stepper < n: \n"
+"    action()\n"
+"    stepper = stepper + 1[/!][!scala]\n"
+"var stepper = 1\n"
+"while (stepper <= n) {\n"
+"    <b>action</b>()\n"
+"    stepper = stepper + 1\n"
+"}[/!]"
+msgstr ""
+"[!java]int compteur = 0;\n"
+"while (compteur < n) {\n"
+"    <b>action</b>();\n"
+"    <b>compteur++</b>;\n"
+"}[/!][!python]compteur=0\n"
+"while compteur < n: \n"
+"    action()\n"
+"    compteur = compteur + 1[/!][!scala]\n"
+"var compteur = 0\n"
+"while (compteur < n) {\n"
+"    <b>action</b>()\n"
+"    compteur = compteur + 1\n"
+"}[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:44
+msgid "The <code>for</code> loop is easier to read, don't you think?"
+msgstr "Le code avec une boucle <code>for</code> est plus simple à lire, non?"
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:46
+#: src/lessons/welcome/bdr/BDR.html:187
+#: src/lessons/turmites/langton/Langton.html:20
+#: src/lessons/welcome/array/basics/Array1.html:200
+msgid "[!java]"
+msgstr "[!java]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:47
 msgid ""
-"<b>initializing</b>;\n"
-"while (<b>condition</b>) {\n"
-"   <b>action</b>();\n"
-"   <b>incrementing</b>;\n"
-"}"
+"It is possible to build more advanced <tt>for</tt> loops since any valid "
+"instruction can be used as initialization, condition and incrementing "
+"instruction. The following example is a bit extreme as there is no need for "
+"a loop body to move the buggle forward until it reaches the wall, but it "
+"works well: all the work is done in the condition and incrementing "
+"instruction."
 msgstr ""
-"<b>initialisation</b>;\n"
-"while (<b>condition</b>) {\n"
-"   <b>action</b>();\n"
-"   <b>incrémentation</b>;\n"
-"}"
+"On peut imaginer des utilisations bien plus avancées des boucles <tt>for</"
+"tt> car toute instruction valide peut être utilisée comme initialisation, "
+"condition et incrémentation. L'exemple suivant est un peu extrême, puisqu'il "
+"n'y a même pas de corps de boucle. La buggle est avancée jusqu'à se "
+"retrouver face au mur dans la condition et l'incrémentation."
 
 #. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:28
+#: src/lessons/welcome/loopfor/LoopFor.html:53
 #, no-wrap
 msgid ""
-"while <b>there is a value in the sequence</b>: \n"
-"   <b>set variable to the next unseen value of the sequence</b>\n"
-"   <b>action</b>()\n"
+"for (; !isFacingWall() ; forward()) { \n"
+"   <span class=\"comment\">/* nothing in the loop body */</span>\n"
+"}\n"
+"<span class=\"comment\">/* the buggle now faces a wall */</span>"
 msgstr ""
-"while <b> il y a une valeur dans la séquence </b>: \n"
-"   <b>mettre la variable à la prochaine valeur non traitée de la séquence</b>\n"
-"   <b>action</b>()\n"
+"for (; !estFaceMur() ; avance()) { \n"
+"   <span class=\"comment\">/* rien dans le corps de boucle */</span>\n"
+"}\n"
+"<span class=\"comment\">/* la buggle est maintenant face à un mur */</span>"
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:33
-msgid ""
-"Please note that in Python the instruction <code>range(n)</code> allows to "
-"get a sequence n integer value from 0 to n-1."
-msgstr ""
-"Veuillez noter qu'en Python, l'instruction <code>range(n)</code> permet "
-"d'obtenir une séquence de n entiers allant de 0 à n-1."
+#: src/lessons/welcome/loopfor/LoopFor.html:57
+#: src/lessons/welcome/bdr/BDR2.html:82
+msgid "[/!] [!scala]"
+msgstr "[/!] [!scala]"
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:36
+#: src/lessons/welcome/loopfor/LoopFor.html:60
 msgid ""
-"For example, both following codes are equivalent. The latter is easier to "
-"read, don't you think?"
+"If you want to nest several loops, you can do it on one line in Scala. This "
+"means that the two following chunks are equivalent:"
 msgstr ""
-"Par exemple, les deux codes suivants sont équivalents. Avouez que la seconde "
-"forme est plus lisible, non ?"
+"Si vous avez l'intention d'imbriquer plusieurs boucles, il est possible de "
+"l'écrire en une seule ligne en Scala. Les deux morceaux de code sont "
+"équivalents:"
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:39
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:61
 #, no-wrap
 msgid ""
-"int done = 0;\n"
-"while (done < stepAmount) {\n"
-"   backward();\n"
-"   done++;\n"
+"for (stepper1 <- 1 to n) {\n"
+"    for (stepper2 <- 1 to m) {\n"
+"       actions()\n"
+"    }\n"
 "}"
 msgstr ""
-"int dejaFait = 0;\n"
-"while (dejaFait < nbPas) {\n"
-"   backward();\n"
-"   dejaFait++;\n"
+"for (compteur1 <- 1 to n) {\n"
+"    for (compteur2 <- 1 to m) {\n"
+"       actions()\n"
+"    }\n"
 "}"
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:44
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:66
 #, no-wrap
 msgid ""
-"for (int done = 0; done < stepAmount; done++) {\n"
-"   backward();\n"
+"for (stepper1 <- 1 to n; stepper2 <- 1 to m) { <span class=\"comment\">// Simply separate both loop conditions with a semi-column</span>\n"
+"    actions()\n"
 "}"
 msgstr ""
-"for (int dejaFait = 0; dejaFait < nbPas; dejaFait++) {\n"
-"   backward();\n"
+"for (compteur1 <- 1 to n; compteur2 <- 1 to m) { <span class=\"comment\">// Séparez simplement les deux conditions de boucle par un point-virgule (;)</span>\n"
+"    actions()\n"
 "}"
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:48
-#, no-wrap
-msgid ""
-"done = 0\n"
-"while done < stepAmount:\n"
-"   backward()\n"
-"   done = done + 1\n"
-msgstr ""
-"dejaFait = 0\n"
-"while dejaFait < nbPas:\n"
-"   backward()\n"
-"   dejaFait = dejaFait + 1\n"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:53
-#, no-wrap
-msgid ""
-"for done in range(stepAmount):\n"
-"   backward()\n"
-msgstr ""
-"for done in range(nbPas):\n"
-"   backward()\n"
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:59
-msgid ""
-"It is possible to build more advanced <tt>for</tt> loops since any valid "
-"instruction can be used as initialization, condition and incrementation. The "
-"following example is a bit extreme since it compute the gcd (greatest common "
-"divisor) of two numbers without loop body and initialization (everything is "
-"in the condition and incrementation)."
-msgstr ""
-"On peut imaginer des utilisations bien plus avancées des boucles <tt>for</"
-"tt> car toute instruction valide peut être utilisée comme initialisation, "
-"condition et incrémentation. L'exemple suivant est un peu extrême, "
-"puisqu'elle calcule le PGCD de deux nombres sans avoir ni de corps de "
-"boucle, ni d'initialisation (tout est fait dans la condition et "
-"l'incrémentation)."
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:65
-#, no-wrap
-msgid ""
-"int x=20, y=3, tmp;\n"
-"for (; y!=0 ; tmp=x, x=y, y=tmp%y) { }\n"
-" <span class=\"comment\">/* the gcd is stored in x */</span>"
-msgstr ""
-"int x=20, y=3, tmp;\n"
-"for (; y!=0 ; tmp=x, x=y, y=tmp%y) { }\n"
-" <span class=\"comment\">/* le PGCD est stocké dans x */</span>"
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:69
-msgid ""
-"If you don't understand every details of this example, don't panic. That's "
-"quite logic since it uses some syntax details that we did not introduce yet."
-msgstr ""
-"Si vous ne comprenez pas tous les détails de cet exemple, pas de panique, "
-"c'est assez logique puisqu'il utilise des points de syntaxe que nous n'avons "
-"pas encore vu."
-
-#. type: Content of: <p><p><p><a>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:73
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:72
 msgid ""
-"<a name=\"Objectives\"> You now have to redo the same exercise than "
-"previously (move forward until being over a baggle, pick it up, move back to "
-"your original location, drop the baggle), but using a <tt>for</tt> loop "
-"instead of a <tt>while</tt> loop to move back to the initial location."
+"You now have to redo the same exercise than previously (move forward until "
+"being over a baggle, pick it up, move back to your original location, drop "
+"the baggle), but using a <code>for</code> loop instead of a <code>while</"
+"code> loop to move back to the initial location."
 msgstr ""
-"<a name=\"Objectifs\"> Il s'agit de refaire le même exercice que "
-"précédemment (avancer jusqu'à trouver un baggle, le ramasser, revenir là où "
-"on était au début puis reposer le baggle), mais en utilisant une boucle "
-"<tt>for</tt> pour revenir au point de départ à la place d'une boucle "
-"<tt>while</tt>."
+"Il s'agit maintenant de refaire le même exercice que précédemment (avancer "
+"jusqu'à trouver un baggle, le ramasser, revenir là où on était au début puis "
+"reposer le baggle), mais en utilisant une boucle <tt>for</tt> pour revenir "
+"au point de départ à la place d'une boucle <code>while</code>."
 
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:78
-msgid "Once done, proceed to next exercise."
-msgstr "Une fois ceci fait, passez à l'exercice suivant."
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:77
+msgid "Once done, you can proceed to next exercise."
+msgstr "Une fois ceci fait, vous pouvez passez à l'exercice suivant."
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:1
+#: src/lessons/welcome/loopfor/LoopStairs.html:1
 msgid "Stairway to Heaven"
 msgstr "la voie du paradis"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:3
+#: src/lessons/welcome/loopfor/LoopStairs.html:3
 msgid ""
 "Your buggle feels a bit depressed today, but it's currently facing a magic "
 "stair: It leads directly to heaven, and each time you walk on it, joyful "
@@ -3719,7 +3607,7 @@ msgstr ""
 "joyeuses jaillissent de partout quand on l'emprunte."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:6
+#: src/lessons/welcome/loopfor/LoopStairs.html:6
 msgid ""
 "Your goal is to take this stair, one step after the other.  First devise the "
 "four instructions you have to give you buggle to take one stair step, and "
@@ -3730,7 +3618,7 @@ msgstr ""
 "marche, puis placez-les dans une boucle pour gravir toutes les marches."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:10
+#: src/lessons/welcome/loopfor/LoopStairs.html:10
 msgid ""
 "And before that, walk a bit forward to reach that stair, and ensure that you "
 "are in the right situation for your loop content to run properly. And once "
@@ -3742,12 +3630,12 @@ msgstr ""
 "faites quelques pas dans votre nouvelle demeure."
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:1
+#: src/lessons/welcome/loopfor/LoopCourse.html:1
 msgid "Training Buggle"
 msgstr "Entraînement de buggle"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:3
+#: src/lessons/welcome/loopfor/LoopCourse.html:3
 msgid ""
 "Today, your buggle wants to get some serious exercise: It wants to run 'till "
 "the track burns! Its super-shoes are just perfect to run like hell, but "
@@ -3759,7 +3647,7 @@ msgstr ""
 "longue..."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:6
+#: src/lessons/welcome/loopfor/LoopCourse.html:6
 msgid ""
 "Your goal is to run the track 10 times, no matter what happens.  Even if the "
 "track suffers, you <b>really HAVE</b> to take that run.  Remember, the track "
@@ -3772,12 +3660,12 @@ msgstr ""
 "y et montrez-leur ce dont ces super-chaussures sont capables."
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:1
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:1
 msgid "Outdoor Training Buggle"
 msgstr "Course en forêt"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:3
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:3
 msgid ""
 "Well, our last training didn't went that well. The track actually burned, "
 "and we are now banned from there.  This time, our buggle decided to practice "
@@ -3797,7 +3685,7 @@ msgstr ""
 "gauche. Il faut faire 7 tours de circuit."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:9
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:9
 msgid ""
 "Oh crap, running on the grass seems to destroy it too! So just take your 7 "
 "loops around the garden, and move along to the next exercise before anyone "
@@ -3808,184 +3696,106 @@ msgstr ""
 "quelqu'un ne constate les dégâts que vous avez fait..."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:3
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:3
 msgid ""
-"In addition to conditionals, another handy construction is the ability to "
-"repeat an action while a specific condition does not appear. A while loop is "
-"used for that, with the following syntax:"
-msgstr ""
-"En plus des instructions conditionnelles, une autre construction pratique "
-"est de pouvoir demander à la buggle de répéter une action tant qu'une "
-"condition particulière n'est pas arrivée. On utilise pour cela une boucle "
-"<tt>while</tt>, dont la syntaxe est la suivante :"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:6
-#, no-wrap
-msgid ""
-"while (<b>condition</b>) {\n"
-"  <b>action()</b>;\n"
-"}"
-msgstr ""
-"while (<b>condition</b>) {\n"
-"  <b>action()</b>;\n"
-"}"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:9
-#, no-wrap
-msgid ""
-"while <b>condition</b>:\n"
-"  <b>action()</b>"
-msgstr ""
-"while (<b>condition</b>) {\n"
-"  <b>action()</b>;\n"
-"}"
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:12
-msgid ""
-"Naturally, if the chosen action does not modify the value of the condition, "
-"the buggle will do the action endlessly. The <b>stop</b> button of the "
-"interface becomes then handy. To test this, you can try to type the "
-"following code in the editor:"
-msgstr ""
-"Evidement, si l'action en question ne modifie pas la valeur de la condition, "
-"la buggle va exécuter l'action à l'infini. C'est dans ce genre de cas que le "
-"bouton <b>stop</b> de l'interface devient utile. Pour tester cela, vous "
-"pouvez essayer de taper le code suivant dans l'éditeur :"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:17
-#, no-wrap
-msgid ""
-"while (true) {\n"
-"  turnLeft();\n"
-"}"
-msgstr ""
-"while (true) {\n"
-"  turnLeft();\n"
-"}"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:20
-#, no-wrap
-msgid ""
-"while True:\n"
-"  turnLeft()"
+"Some cells of the world are yellow, but your buggle cannot stand being in "
+"such cells. Write the necessary code to move forward until the ground gets "
+"white. For that, use the provided method <code>isGroundWhite()</code>."
 msgstr ""
-"while (true) {\n"
-"  turnLeft();\n"
-"}"
+"Certaines cases du monde sont jaunes, mais les buggles ne supportent pas de "
+"s'y trouver. Écrivez le code nécessaire pour avancer jusqu'à ce que le sol "
+"devienne blanc. Vous pourrez utiliser la méthode <code>estSurBlanc()</code> "
+"qui retourne vrai si le sol est blanc.."
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:23
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:7
 msgid ""
-"The buggle will turn left while true is true (ie, endlessly), or until you "
-"stop it manually using the stop button."
+"The trick is that most buggles of this world are currently on this yellow "
+"ground that they dislike so much. That is why they are in panic, and every "
+"buggle rushes one cell forward, even the buggle that was not on a yellow "
+"cell at first. In other worlds, even if the ground is white on the first "
+"cell, you still want to move forward to the next cell."
 msgstr ""
-"La buggle va tourner vers la gauche tant que <code>true</code> est vrai "
-"(sans fin donc) jusqu'à ce que vous l'arrêtiez manuellement avec le bouton "
-"stop."
+"Le truc est que la plupart des buggles de ce monde se trouvent actuellement "
+"sur ce sol jaune qui les énerve tant. Cela explique sans doute leur état de "
+"panique, et le fait que toutes les buggles se ruent vers l'avant au début, "
+"même la buggle qui ne se trouve pas sur du jaune. En d'autres mots, même si "
+"le sol est blanc le premier coup, il faut quand même avancer d'un pas."
 
-#. type: Content of: <p><a>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:26
-msgid ""
-"<a name=\"Objective\">You now have to write some code so that your buggles "
-"move forward until they encounter a wall. The idea is thus to do something "
-"like:"
-msgstr ""
-"<a name=\"Objectifs\"> Il vous faut maintenant écrire le code nécessaire "
-"pour que vos buggles avancent jusqu'à rencontrer un mur. L'idée est donc de "
-"faire :"
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:12
+msgid "The general idea is to do something like:"
+msgstr "L'idée général est donc de faire:"
 
-#. type: Content of: <p><a><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:29
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:13
 #, no-wrap
-msgid ""
-"while we are not facing a wall, do:\n"
-"  moveForward()"
-msgstr ""
-"tant que l'on est pas face à un mur, faire :\n"
-"  avancer();"
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:1
-msgid "Lost in the Moria"
-msgstr "Perdu dans la Moria"
+msgid "move forward until located in a white cell"
+msgstr "avancer jusqu'à se trouver sur une case blanche"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:3
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:15
 msgid ""
-"You buggle got stuck in a mine! Some rocks are blocking the exit, and you "
-"will have to clear your way to the exit. Well of course these are only "
-"baggles and you could simply walk away, but it will be easier to program "
-"your buggle so that it moves those \"rocks\" than convincing your buggle "
-"that it could easily walk away without solving the problem..."
+"The main difficulty is that we want this loop body to be executed once, even "
+"we are already on a white cell.  It would be easy to do so by duplicating "
+"the loop content before the actual loop, but this would be a bad idea: code "
+"duplication is a <b>very</b> bad habit, and you should <b>always</b> avoid "
+"it."
 msgstr ""
-"Votre buggle est coincé dans une mine ! Des rochers bloquent la sortie, et "
-"il va falloir dégager le chemin pour passer. Bon, ok, ce ne sont pas "
-"vraiment des rochers mais juste des baggles, et votre buggle pourrait "
-"facilement passer au dessus sans se fatiguer. Mais il est probablement plus "
-"simple de programmer votre buggle pour qu'elle déplace ces «rochers» plutôt "
-"que de tenter de la convaincre de passer à la suite sans avoir résolu le "
-"problème..."
+"La principale difficulté est que nous voulons exécuter le corps de boucle au "
+"moins une fois, même si la buggle se trouve déjà sur une case blanche. Il "
+"serait facile de dupliquer le corps de la boucle avant la boucle pour cela, "
+"mais  ça serait une <b>très mauvaise idée</b>. Dupliquer du code est une "
+"<b>très mauvaise habitude</b> et il faut toujours éviter de le faire."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:9
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:19
 msgid ""
-"So, you have to find the first baggle blocking the exit (simply walk to the "
-"east until you are over a baggle), take it and move it back to the other "
-"side of the tunnel (walk to the west while you are not over a baggle, and "
-"then move back one step to the east and drop your baggle), and iterate until "
-"you find the exit (that is, the wall to the east side). Afterward, move out "
-"as in the objective world."
+"Code duplication easily turns code maintenance into a nightmare: reading the "
+"code becomes difficult as the reader must ensure that no slight difference "
+"exist between the versions. Debugging the code becomes difficult, as bugs "
+"have to be fixed in all versions. Actually, every modification of the code "
+"becomes difficult. So, really, you should <b>always</b> strive to not "
+"duplicate you code if you can avoid. And the good news is that you always "
+"can..."
 msgstr ""
-"Donc, il vous faut trouver le premier baggle en travers de votre chemin "
-"(marchez vers l'est jusqu'à vous trouver au dessus d'un baggle), le "
-"ramasser, et retourner à l'autre extrémité du couloir pour le déposer "
-"(marchez vers l'ouest jusqu'à vous trouver au dessus d'un baggle puis "
-"reculez d'un pas). Il faut ensuite faire de même pour tous les baggles "
-"jusqu'à trouver la sortie. Une fois ceci fait, marchez vers l'air frais "
-"comme dans le monde objectif."
+"Quand on duplique le code, sa maintenance tourne facilement au cauchemar : "
+"la lecture du code est très pénible puisque le lecteur doit s'assurer qu'il "
+"n'y a effectivement aucune différence, même minime, entre les versions du "
+"même code. Debugger le code devient plus long, puisqu'il faut corriger "
+"toutes les versions. En fait, toutes les modifications deviennent pénibles. "
+"Alors, vraiment, vous devrez <b>toujours</b> vous efforcer d'éviter la "
+"duplication du code quand c'est possible. Et la bonne nouvelle est que c'est "
+"toujours possible..."
 
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:16
-msgid "Once you manage to escape this trap, move forward to the next exercise."
-msgstr ""
-"Quand vous serez parvenu à sortir de ce piège, passez à l'exercice suivant."
+#. type: Content of: <h3>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:24
+msgid "Executing the loop body at least once"
+msgstr "Exécuter le corps de boucle au moins une fois"
 
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:3
-msgid ""
-"Here is another little exercise about loops. It is slightly more complex as "
-"we want the action to be executed in any case, even if the condition is "
-"false right away. Some languages have specific constructs for that, but not "
-"the Python language. No problem, I'm sure you can do it without them, can't "
-"you?"
-msgstr ""
-"Il y a ici un autre petit exercice sur les boucles. Il est légèrement plus "
-"complexe comme nous voulons que l'action soit exécutée dans tous les cas, "
-"même si la condition est directement fausse. Certains langages ont des "
-"constructions spécifiques pour cela, mais pas le langage Python. Mais il n'y "
-"a pas de problème, je suis sûr que vous pouvez faire sans, n'est-ce pas ?"
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:25
+#: src/lessons/welcome/loopdowhile/Poucet.html:27
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:53
+#: src/lessons/welcome/array/basics/Array1.html:98
+msgid "[!python]"
+msgstr "[!python]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:7
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:26
 msgid ""
-"A bad solution would be to duplicate the loop content before the loop, but "
-"code duplication is a <b>very</b> bad habit, and you should always avoid it. "
-"A better solution is to have a dedicated variable indicating whether we are "
-"taking the loop for the first time, as follows:"
+"Some languages have specific constructs for that, but not the Python "
+"language. No problem, we can do it on our own! A good way is to have a "
+"dedicated variable indicating whether we are taking the loop for the first "
+"time or not, as follows."
 msgstr ""
-"Une mauvaise solution serait de dupliquer le contenu de la boucle avant la "
-"boucle à proprement parlé, mais c'est une <b>très mauvaise</b> habitude de "
-"dupliquer du code, et il faut toujours éviter. Une meilleure solution est "
-"d'avoir une variable dédiée qui indique si c'est la première fois que l'on "
+"Certain langage ont une construction spécifique pour cela, mais pas Python. "
+"Qu'à cela ne tienne, on s'en sort très bien sans. Une bonne manière est "
+"d'avoir une variable dédiée indiquant si c'est la première fois que l'on "
 "rentre dans la boucle :"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:10
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:30
 #, no-wrap
 msgid ""
 "firstTime = True\n"
@@ -3996,95 +3806,71 @@ msgstr ""
 "premiereFois = True\n"
 "while premiereFois or (les autres conditions):\n"
 "  premiereFois = False\n"
-"  (le corps de la boucle)"
+"  (le corps de la boucle)\n"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:36
+msgid ""
+"When <code>firstTime</code> is true, the loop body is executed even if the "
+"other conditions would imply the contrary.  Once the loop body has been "
+"executed once, it is set to false and never impact again the decision to "
+"enter the body or not."
+msgstr ""
+"Quand <code>premiereFois</code> est vraie, le corps de la boucle est exécuté "
+"même si les autres conditions impliqueraient le contraire. Une fois que le "
+"corps de boucle a été exécuté, <code>premiereFois</code> est mis à faux et "
+"n'influe plus jamais la décision d'entrer dans le corps de boucle."
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:38
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:60
+#: src/lessons/welcome/array/basics/Array1.html:114
+msgid "[/!] [!java|scala]"
+msgstr "[/!] [!java|scala]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:16
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:42
 msgid ""
 "In a <tt>while</tt> loop, the condition is evaluated before anything else, "
 "and if it's false, the loop body is never evaluated. Sometimes (although not "
 "that often), you would prefer the loop body to get evaluated at least once, "
 "even if the condition is initially false. For that, a variation of the "
-"<tt>while</tt> loop gets used, using the following syntax in Java:"
+"<tt>while</tt> loop gets used, using the following syntax in [!thelang].  [!"
+"java]Do not forget the semi-column (;) after the condition, it is mandatory."
+"[/!]"
 msgstr ""
 "Dans une boucle <tt>while</tt>, la condition est évaluée avant toute chose, "
 "et si elle est fausse, le corps de la boucle n'est jamais exécuté. Il arrive "
 "parfois que l'on veuille que le corps de la boucle soit évalué au moins une "
 "fois, même si la condition est initialement fausse. On utilise pour cela une "
-"variante de la boucle <tt>while</tt>, dont la syntaxe Java est la suivante :"
+"variante de la boucle <tt>while</tt>, dont la syntaxe est la suivante en [!"
+"thelang]."
 
 #. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:22
-#, no-wrap
-msgid ""
-"do {\n"
-"  <b>action()</b>;\n"
-"} while (<b>condition</b>);"
-msgstr ""
-"do {\n"
-"  <b>action()</b>;\n"
-"} while (<b>condition</b>);"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:27
-msgid ""
-"Some cells of the world are yellow, but your buggle cannot stand being in "
-"such cells. Write the necessary code to move forward until the ground gets "
-"white. For that, use the provided method <code>isGroundWhite()</code>."
-msgstr ""
-"Certaines cases du monde sont jaunes, mais les buggles ne supportent pas de "
-"s'y trouver. Écrivez le code nécessaire pour avancer jusqu'à ce que le sol "
-"devienne blanc. Vous pourrez utiliser la méthode <code>isGroundWhite()</"
-"code> qui retourne vrai si le sol est blanc.."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:31
-msgid ""
-"The trick is that most buggles of this world are currently on this yellow "
-"ground that they dislike so much. That is why they are in panic, and every "
-"buggle rushes one cell forward, even the buggle that was not on a yellow "
-"cell at first. In other worlds, even if the ground is white on the first "
-"cell, you still want to move forward to the next cell."
-msgstr ""
-"Le truc est que la plupart des buggles de ce monde se trouvent actuellement "
-"sur ce sol jaune qui les énerve tant. Cela explique sans doute leur état de "
-"panique, et le fait que toutes les buggles se ruent vers l'avant au début, "
-"même la buggle qui ne se trouve pas sur du jaune. En d'autres mots, même si "
-"le sol est blanc le premier coup, il faut quand même avancer d'un pas."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:36
-msgid "The general idea is to do something like:"
-msgstr "L'idée général est donc de faire:"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:37
-#, no-wrap
-msgid "move forward until located in a white cell"
-msgstr "avancer jusqu'à se trouver sur une case blanche"
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:39
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:50
+#, no-wrap
 msgid ""
-"<i>Remark:</i> it is also possible to solve this exercise with a classical "
-"<tt>while</tt> loop, but it's not the goal."
+"do {\n"
+"    <b>action()</b>[!java];[/!]\n"
+"} while (<b>condition</b>)[!java];[/!]"
 msgstr ""
-"<i>Remarque :</i> il est également possible de résoudre cet exercice avec "
-"une boucle <tt>while</tt> classique, mais ce n'est pas l'objectif."
+"do {\n"
+"    <b>action()</b>[!java];[/!]\n"
+"} while (<b>condition</b>)[!java];[/!]"
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:1
+#: src/lessons/welcome/loopdowhile/Poucet.html:1
 msgid "Tracks of buggles"
 msgstr "La buggle Petite Poucette"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:3
+#: src/lessons/welcome/loopdowhile/Poucet.html:3
 msgid ""
 "Your buggle got lost in a strange maze, and you must help it finding the "
 "exit that is represented in orange.  You cannot simply explain the path to "
-"the exit in something like <code>turnRight();forward;forward();forward()</"
-"code> because you have to save two buggles at the same time, that are lost "
-"in similar but not identical worlds.  You can switch to the other world by "
+"the exit in something like <code>right();forward;forward();forward()</code> "
+"because you have to save two buggles at the same time, that are lost in "
+"similar but not identical worlds.  You can switch to the other world by "
 "using the combobox above the world representation (where it's written 'Deep "
 "Forest' right now), and selecting the other entry (that should read 'Deeper "
 "Forest')."
@@ -4092,15 +3878,15 @@ msgstr ""
 "Votre buggle est perdue dans un étrange labyrinthe, et elle a besoin de vous "
 "pour trouver la sortie (représentée par les cases orange). Vous ne pouvez "
 "pas lui donner son chemin tout simplement avec quelque chose comme "
-"<code>turnRight();forward();forward();</code> parce qu'il faut secourir deux "
+"<code>droite();avance();avance();</code> parce qu'il faut secourir deux "
 "buggles à la fois, perdues dans des labyrinthes similaires mais différents. "
 "Vous pouvez passer à l'autre monde en cliquant sur le menu défilant au "
-"dessus de l'endroit où est dessiné le monde. C'est là où est écrit \"Deep "
+"dessus de l'endroit où est dessiné le monde. C'est là où il est écrit \"Deep "
 "Forest\" pour l'instant (forêt profonde), et si vous passez à \"Deeper Forest"
 "\" (forêt encore plus profonde), vous verrez l'autre monde. "
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:9
+#: src/lessons/welcome/loopdowhile/Poucet.html:9
 msgid ""
 "The good news is that the path to the exit is written on the ground. As you "
 "can see, the world is made of several corridors, with baggles on the ground. "
@@ -4115,7 +3901,7 @@ msgstr ""
 "s'il contient 2 baggles ou moins."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:13
+#: src/lessons/welcome/loopdowhile/Poucet.html:13
 msgid ""
 "So, the general form of your code must be something like \"while I did not "
 "find the exit, take the next corridor to decide whether I should turn left "
@@ -4127,87 +3913,77 @@ msgstr ""
 "je n'ai pas trouvé la sortie, prendre le prochain couloir pour décider s'il "
 "faut tourner à gauche ou à droite au prochain embranchement». Vous pouvez "
 "déterminer si vous avez rejoint la sortie (indiquée en orange) avec la "
-"méthode <code>exitReached()</code> fournie."
+"méthode <code>sortieTrouvee()</code> fournie."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:17
+#: src/lessons/welcome/loopdowhile/Poucet.html:17
 msgid ""
 "To take one corridor, you simply have to run from one intersection to "
 "another while counting the baggles you see on your path. The method "
 "<code>crossing()</code> tells you whether your buggle currently stands on an "
 "intersection.  The extra complexity is that at the beginning of a corridor, "
-"you obviously stand on an intersection, but you still want to move on."
+"you obviously stand on an intersection, but you still want to move on.  [!"
+"java|scala]For that, the easiest is to use a <code>do / while</code> loop "
+"instead of a regular <code>while</code> loop to move until the next "
+"intersection.[/!] [!python]For that, use an extra variable indicating "
+"whether you already entered the corridor, as follows. This will ensure that "
+"you execute the loop body at least once (when <code>firstTime</code> is "
+"true) before we actually use the value returned by <code>crossing()</code> "
+"to determine to continue or not.[/!]"
 msgstr ""
 "Pour prendre un couloir, il suffit de courir d'une intersection à l'autre "
-"tout en comptant les baggles en chemin. La méthode <code>crossing()</code> "
-"indique si vous vous trouvez actuellement à un embranchement. Ce qui "
+"tout en comptant les biscuits en chemin. La méthode <code>croisement()</"
+"code> indique si vous vous trouvez actuellement à un embranchement. Ce qui "
 "complique un peu, c'est qu'au début du couloir, vous vous trouvez bien "
-"entendu à une intersection, mais vous souhaitez avancer quand même."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:22
-msgid ""
-"For that, the easiest is to use a <code>do / while</code> loop instead of a "
-"regular <code>while</code> loop to move until the next intersection."
-msgstr ""
-"Pour cela, le plus simple est d'utiliser une boucle <code>do / while</code> "
-"au lieu d'une boucle <code>while</code> pour se déplacer d'une intersection "
-"à l'autre."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:25
-msgid ""
-"For that, use an extra variable indicating whether you already entered the "
-"corridor, as follows. This will ensure that you execute the loop body at "
-"least once (when <code>firstTime</code> is true)  before we actually use the "
-"value returned by <code>crossing()</code> to determine to continue or not."
-msgstr ""
-"Pour cela, utilisez une variable supplémentaire indiquant si vous êtes déjà "
-"entré dans le couloir, comme dans l'exemple suivant. Ainsi, vous exécuterez "
-"le corps de la boucle au moins une fois (quand <code>premiereFois</code> est "
-"vrai) tandis qu'aux tours de boucles suivants, c'est la valeur de retour de "
-"<code>crossing()</code> qui détermine s'il faut s'arrêter ou non."
+"entendu à une intersection, mais vous souhaitez avancer quand même.\n"
+"[!java|scala]Le plus simple pour cela est d'utiliser une boucle <code>do / "
+"while</code> à la place d'une simple boucle <code>while</code> pour se "
+"déplacer d'une intersection à l'autre.[/!]\n"
+"[!python]Pour cela, utilisez une variable supplémentaire indiquant si vous "
+"êtes déjà entré dans le couloir, comme dans l'exemple suivant. Ainsi, vous "
+"exécuterez le corps de la boucle au moins une fois (quand "
+"<code>premiereFois</code> est vrai) tandis qu'aux tours de boucles suivants, "
+"c'est la valeur de retour de <code>croisement()</code> qui détermine s'il "
+"faut s'arrêter ou non.[/!]"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:28
+#: src/lessons/welcome/loopdowhile/Poucet.html:28
 #, no-wrap
 msgid ""
 "firstTime = True\n"
 "while firstTime or not crossing():\n"
 "  firstTime = False\n"
-"  <your body>  \n"
+"  (your body)\n"
 msgstr ""
 "premiereFois = True\n"
-"while premiereFois or not crossing():\n"
+"while premiereFois or not croisement():\n"
 "  premiereFois = False\n"
-"  <your body>  \n"
+"  (le corps de votre boucle)\n"
 
 #. type: Attribute 'alt' of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:34
+#: src/lessons/welcome/loopdowhile/Poucet.html:35
 msgid "I cannot imagine how to count the baggles I see."
 msgstr "Je n'arrive pas à imaginer comment compter les baggles que je vois"
 
 #. type: Content of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:35
+#: src/lessons/welcome/loopdowhile/Poucet.html:36
 msgid ""
 "You need a variable that is initialized to 0, and incremented each time you "
 "see a baggle on the ground. A variable used this way is often called "
-"<i>accumulator</i>."
+"<i>counter</i>."
 msgstr ""
 "Il vous faut une variable initialisée à zéro et incrémentée à chaque fois "
 "que vous voyez un baggle. Une variable utilisée ainsi est souvent appelée un "
-"<i>accumulateur</i>."
+"<i>compteur</i>."
 
 #. type: Content of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:37
+#: src/lessons/welcome/loopdowhile/Poucet.html:38
 msgid ""
-"Don't forget to reset your accumulator to 0 at the beginning of each "
-"corridor!"
-msgstr ""
-"N'oubliez pas de remettre l'accumulateur à 0 au début de chaque couloir!"
+"Don't forget to reset your counter to 0 at the beginning of each corridor!"
+msgstr "N'oubliez pas de remettre le compteur à 0 au début de chaque couloir!"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:40
+#: src/lessons/welcome/loopdowhile/Poucet.html:41
 msgid ""
 "Oh, and when you reach the exit, don't forget to take an extra step to "
 "actually exit the maze!"
@@ -4228,239 +4004,293 @@ msgstr ""
 #. type: Content of: <p>
 #: src/lessons/welcome/methods/basics/Methods.html:7
 msgid ""
-"For example, we saw in previous exercise how to ask the buggle to go get the "
-"baggle in front of it, and bring it back. If there is several baggles on the "
-"board, and if we want to bring all of them on the bottom line, you have to "
-"repeate this code several times, or include it in a loop. In any case, the "
-"result may reveal unpleasant to read, and it would be better if the buggle "
-"could obey an <code>goAndGet()</code> order just like it understands a "
-"<code>forward()</code> one."
-msgstr ""
-"Par exemple, nous avons vu à l'exercice précédent comment demander à la "
-"buggle d'aller chercher la buggle qui se trouve devant elle, et la ramener à "
-"sa position initiale. S'il y a maintenant plusieurs baggles sur le plateau, "
-"et que nous voulons tous les ramener sur la ligne du bas, il faut soit "
-"répéter ce code plusieurs fois, soit l'inclure dans une boucle. Dans les "
-"deux cas, le code résultant n'est pas très lisible, et il serait mieux que "
-"la buggle comprenne un ordre de type <code>goAndGet()</code> tout comme elle "
-"comprend un <code>forward()</code>."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:16
-#: src/lessons/welcome/methods/basics/Methods.html:22
-msgid ""
-"The syntax to write a simple method called <code>goAndGet</code> is the "
-"following:"
-msgstr ""
-"La syntaxe pour écrire une méthode simple nommée <code>goAndGet</code> est "
-"la suivante:"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:18
-#, no-wrap
-msgid ""
-"def goAndGet():\n"
-"  actions();\n"
-"  to();\n"
-"  do();"
-msgstr ""
-"public void goAndGet() {\n"
-"  actions();\n"
-"  aFaire();\n"
-"}"
+"For example, we saw in a previous exercise how to ask the buggle to go get "
+"the baggle in front of it, and bring it back. If there is several baggles on "
+"the board, and if we want to bring all of them on the bottom line, you have "
+"to repeat this code several times, or include it in a loop. In any case, you "
+"should avoid to duplicate your code to keep it pleasant to read and easily "
+"understandable.  It would be better if the buggle could obey an "
+"<code>goAndGet()</code> order just like it understands a <code>forward()</"
+"code> one."
+msgstr ""
+"Par exemple, nous avons vu dans un exercice précédent comment demander à la "
+"buggle d'aller chercher le biscuit qui se trouve devant elle, et la ramener "
+"à sa position initiale. S'il y a maintenant plusieurs biscuits sur le "
+"plateau, et que nous voulons tous les ramener sur la ligne du bas, il faut "
+"soit répéter ce code plusieurs fois, soit l'inclure dans une boucle. Dans "
+"les deux cas, il faut que vous évitiez de dupliquer votre code pour qu'il "
+"reste simple et lisible. Il serait mieux que la buggle comprenne un ordre de "
+"type <code>vaChercher()</code> tout comme elle comprend un <code>avance()</"
+"code>."
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:24
-#, no-wrap
-msgid ""
-"public void goAndGet() {\n"
-"  actions();\n"
-"  to();\n"
-"  do();\n"
-"}"
-msgstr ""
-"public void goAndGet() {\n"
-"  actions();\n"
-"  aFaire();\n"
-"}"
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:15
+msgid "Defining methods"
+msgstr "Définir des méthodes"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:30
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:17
 msgid ""
-"The method body (between curly braces) can contain as many instructions as "
-"you want, and any construction we saw so far (for, while, if, etc)."
+"The [!thelang] syntax to write a simple method called <code>goAndGet</code> "
+"is the following:"
 msgstr ""
-"Le corps de la méthode (entre les accolades) peut contenir autant "
-"d'instructions que vous le souhaitez, et toutes les constructions vues "
-"jusque là (for, while, if, etc)."
+"La syntaxe [!thelang] pour écrire une méthode simple nommée "
+"<code>vaChercher</code> est la suivante:"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:32
-msgid ""
-"The method body (the code that is indended) can contain as many instructions "
-"as you want, and any construction we saw so far (for, while, if, etc)."
-msgstr ""
-"Le corps de la méthode (entre les accolades) peut contenir autant "
-"d'instructions que vous le souhaitez, et toutes les constructions vues "
-"jusque là (for, while, if, etc)."
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:19
+#, no-wrap
+msgid ""
+"[!java]void goAndGet() {[/!][!python]def goAndGet():[/!][!scala]def goAndGet() {[/!]\n"
+"  actions()[!java];[/!]\n"
+"  to()[!java];[/!]\n"
+"  do()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+"[!java]void vaChercher() {[/!][!python]def vaChercher():[/!][!scala]def vaChercher() {[/!]\n"
+"  actions()[!java];[/!]\n"
+"  encoreDesActions()[!java];[/!]\n"
+"  dautresTrucs()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:25
+msgid ""
+"The method body [!java|scala](between curly braces)[/!][!python](the "
+"indented block)[/!] will be executed when we call the method later on (that "
+"is, when we write <code>goAndGet()</code> somewhere in our code). This "
+"method body can contain as many instructions as you want, and any "
+"construction we saw so far (for, while, if, etc).  [!java]The <code>void</"
+"code> keyword means that this method does not return any result. For "
+"example, the <code>isOverBaggle()</code> method does return a result, which "
+"is a boolean indicating whether or not the buggle is located over a baggle. "
+"We will soon learn to define such methods too. For now, just write "
+"<code>void</code> at this location.[/!]"
+msgstr ""
+"Le corps de la méthode\n"
+"[!java|scala](c'est-à-dire le bloc entre accolades)[/!]\n"
+"[!python](c'est-à-dire le bloc indenté)[/!]\n"
+"sera exécuté à chaque appel de cette méthode (c'est-à-dire à chaque fois que "
+"nous écrirons <code>vaChercher()</code> quelque part dans notre code).\n"
+"Ce corps de boucle peut contenir autant d'instructions que l'on veut, et "
+"toutes les constructions que nous avions vu jusque là (comme lesboucles et "
+"les conditionnelles).\n"
+"[!java]Le mot-clé <code>void</code> («néant» en anglais) signifie que cette "
+"méthode ne renvoie pas de résultat. Au contraire, la méthode "
+"<code>estSurBiscuit()</code> renvoie un résultat booleen indiquant si nous "
+"nous trouvons oui ou non sur un biscuit. Nous apprendrons bientôt à faire de "
+"telles méthodes. En attendant, écrivez juste <code>void</code> à cet endroit."
+"[/!]"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:35
-msgid ""
-"We will come back later on the exact signification of the <code>public</"
-"code> keyword. Let's say for now that it means that everybody can use this "
-"method."
-msgstr ""
-"Nous reviendrons plus tard sur le sens exact du mot-clé <code>public</code>. "
-"Disons simplement pour l'instant qu'il indique que tout le monde a le droit "
-"d'utiliser cette méthode."
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:38
+msgid "Documenting methods"
+msgstr "Documenter les méthodes"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:40
+msgid ""
+"You should strive to document your code to keep it readable. When you write "
+"it, its purpose and limitations are clear to you, but most of the time, this "
+"does not last for long. You will soon forget about the details of every "
+"specific method, and this day you will be happy to read its documentation. "
+"In the following example, we use the specific formalism of [!java]javadoc[/!]"
+"[!scala]scaladoc[/!][!python]pydoc[/!], a program that extracts the "
+"documentation of [!thelang] source code to produce html pages. The main "
+"advantage is that it allows to keep the documentation near to the code.  So, "
+"when you change your code, you have less chances to forget to update the "
+"documentation."
+msgstr ""
+"Vous devez toujours vous efforcer de documenter votre code pour qu'il reste "
+"lisible. À l'instant où vous l'écrivez, son objectif et ses limitations vous "
+"semblent clairs, mais la plupart du temps, ça ne dure pas. On oublie vite "
+"les détails d'une méthode particulier, et quand cela arrive, on est content "
+"de pouvoir lire sa documentation. \n"
+"Dans l'exemple ci-dessous, nous utilisons le formalisme spécifique de [!"
+"java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], un programme qui "
+"extrait la documentation du code source pour en faire de belles pages web. "
+"Le principal avantage de cette approche est que la documentation se trouve à "
+"coté du code. Donc, quand on change le code, il y a un peu plus de chance "
+"pour qu'on pense à mettre la documentation à jour."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:49
+msgid ""
+"[!java|scala][!java]javadoc[/!][!scala]scaladoc[/!] comments begin with the "
+"<code>/**</code> marker (with two asterisks). They must be placed right "
+"before the method they document for the tool to find them.[/!] [!"
+"python]pydoc comments should be placed at the beginning of the method body "
+"so that the tool finds them. They should be placed between <code>\"\"\"</"
+"code>, which mark multi-line strings in python.[/!] The first line should be "
+"a brief description of what this method does while any subsequent lines "
+"should provide any important details about the method."
+msgstr ""
+"[!java|scala]Les commentaires [!java]javadoc[/!][!scala]scaladoc[/!] "
+"commencent avec le marqueur <code>/**</code> (avec deux étoiles). Ces "
+"commentaires doivent être placés juste avant la méthode qu'ils documentent "
+"pour que l'outil les trouve[/!]\n"
+"[!python]Les commentaire pydoc doivent être placés au début du corps de la "
+"méthode pour que l'outil les trouve. Ils doivent être placés entre <code>"
+"\"\"\"</code>, qui marquent les chaînes de caractères sur plusieurs lignes "
+"en python.[/!]\n"
+"La première ligne devrait décrire brièvement la méthode tandis que le reste "
+"de la documentation devrait donner tous les points importants de la méthode."
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:39
-msgid ""
-"<code>void</code> means that the method does not return any result. We said "
-"previously that the <code>isOverBaggle()</code> method returns a boolean and "
-"can thus be used as a condition in a if or a while. This means that it is "
-"declared the following way:"
-msgstr ""
-"<code>void</code> indique quant à lui que la méthode ne donne pas de "
-"résultat. Nous avions vu que la méthode <code>isOverBaggle()</code> renvoie "
-"un booléen, et peut donc être utilisé comme une condition dans un if ou un "
-"while. Cela signifie qu'elle a été déclarée de la façon suivante :"
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:58
+#, no-wrap
+msgid ""
+"[!java|scala]/**\n"
+" *  Go, retrieves the baggle in front of the buggle, and brings it back \n"
+" *\n"
+" *   Does not check for walls, so be careful to not call it when walls are present.\n"
+" */[/!]\n"
+"[!java]void goAndGet() {[/!]\n"
+"[!scala]def goAndGet() {[/!]\n"
+"[!python]def goAndGet():\n"
+"  \"\"\"Go, retrieves the baggle in front of the buggle, and brings it back.\n"
+"\n"
+"  Does not check for walls, so be careful to not call it when walls are present.\"\"\"[/!]\n"
+"  actions()[!java];[/!]\n"
+"  to()[!java];[/!]\n"
+"  do()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+"[!java|scala]/**\n"
+" *  Avance, récupère le biscuit, et le ramène à la position d'origine\n"
+" *\n"
+" *  Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur.\n"
+" */[/!]\n"
+"[!java]void goAndGet() {[/!]\n"
+"[!scala]def goAndGet() {[/!]\n"
+"[!python]def goAndGet():\n"
+"  \"\"\"Avance, récupère le biscuit, et le ramène à la position d'origine\n"
+"\n"
+"  Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur.\"\"\"[/!]\n"
+"  actions()[!java];[/!]\n"
+"  to()[!java];[/!]\n"
+"  do()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:43
-#, no-wrap
-msgid "public boolean isOverBaggle() { ... }"
-msgstr "public boolean isOverBaggle() { ... }"
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:74
+msgid "Naming conventions"
+msgstr "Conventions de nommage"
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:45
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:75
 msgid ""
-"We will introduce in next exercise how to do this kind of tricks. For now, "
-"let's just write <code>void</code> at this location."
+"Most programming language forbid the use of spaces in method and variable "
+"identifiers (=their names).  Accented letters are sometimes allowed (as in [!"
+"thelang]), but they can lead to portability issues between operating systems "
+"and should thus be avoided when possible."
 msgstr ""
-"Nous verrons dans le prochain exercice comment faire ce genre de chose. Pour "
-"l'instant, contentons nous d'écrire ce <code>void</code> à cet endroit."
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:48
-msgid ""
-"In Java, the convention is to use lower case for the first letter of a "
-"method name and concatenate every word describing the method using a upper "
-"case for each first letter. It is forbidden to use spaces or accentuated "
-"letters in a method name. That is why we write \"go and get\" as goAndGet()."
-msgstr ""
-"En Java, il est d'usage de mettre la première lettre du nom d'une méthode en "
-"minuscules, et de coller tous les mots décrivant la méthode les uns aux "
-"autres en mettant une majuscule à chacun. Il est interdit de mettre des "
-"espaces ou des accentués dans le nom d'une méthode. C'est pourquoi nous "
-"écrivons \"go and get\" sous la forme \"goAndGet\"."
-
-#. type: Content of: <p><p><p><a>
-#: src/lessons/welcome/methods/basics/Methods.html:59
-msgid ""
-"<a name=\"Objectives\"> The goal of this exercise is to write a method "
-"called <code>goAndGet()</code> which does the same than in previous "
-"exercises (move forward until over a baggle, pick it up, move back to "
-"initial position, drop baggle)."
-msgstr ""
-"<a name=\"Objectifs\"> L'objectif de cet exercice est donc d'écrire une "
-"méthode nommée <code>goAndGet()</code> et qui fait la même chose qu'aux "
-"exercices précédents (avance tant qu'on ne trouve pas de baggle, ramasser le "
-"baggle, reculer à la case départ, poser le baggle)."
+"La plupart des langages de programmation interdisent d'utiliser des espaces "
+"dans les noms de variables et de méthodes. Certains langages (comme le [!"
+"thelang]) autorisent l'usage des caractères accentués dans ces "
+"identificateurs, mais cela pose parfois des problèmes de portabilité entre "
+"les systèmes d'exploitation. C'est pourquoi PLM n'utilise pas d'accents dans "
+"les identificateurs, même si c'est parfois désagréable en français."
 
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:64
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:79
 msgid ""
-"One particularity of this exercise is that all your code should be written "
-"in this function, with nothing out of it. The code that calls your function "
-"will be automagically added when you click on <b>Start</b>."
+"Across all programming languages, there is two main conventions to name "
+"variables and methods. The first one, consists in concatenating all words "
+"with only the first letter of each word in upper case. \"go and get\" "
+"becomes goAndGet().  It is called CamelCase because identifiers written this "
+"way graphically remind of a camel back. The other convention, called "
+"snake_case, is to write every words in lower case, separated with "
+"underscores symbols (_). \"go and get\" becomes go_and_get()."
+msgstr ""
+"Parmi tous les langages de programmation, il y a deux conventions de nomage "
+"majeures. La première consiste à concaténer tous les mots en ne laissant que "
+"la première lettre de chaque mot en majuscule. «va chercher le biscuit» "
+"devient VaChercherLeBiscuit(). Cette convention est nommée CamelCase en "
+"anglais, c'est-à-dire casse du chameau, car les identificateurs écrits de "
+"cette façon font un peu penser au dos d'un chameau. L'autre convention, "
+"nommée snake_case (casse du serpent), consiste à concaténer tous les mots en "
+"minuscule en les séparant du caractère souligné (_). «va chercher le "
+"biscuit» devient va_chercher_le_biscuit()."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:86
+msgid ""
+"Which convention to use is the topic of heated discussion across developers, "
+"but each programming language has its own habits. In Python, Perl and the C "
+"language, the snake_case is often used for methods and variables. Java and "
+"Scala prefer the lowerCamelCase (the very first letter is lower case) for "
+"that."
 msgstr ""
-"La particularité de cet exercice est que tout votre code doit être écrit "
-"dans cette fonction, avec rien en dehors. Le code qui appelle votre fonction "
-"sera automagiquement ajouté quand vous cliquerez sur <b>Start</b>."
+"Le choix de la convention de nommage est le sujet de «discussions» très "
+"animées entre programmeurs, mais certaines habitudes prédominent pour chaque "
+"langage. En Python, Ruby, Perl ou en langage C, la casse_du_serpent "
+"prédomine pour les noms de variables et de méthodes. En Java et en Scala, on "
+"préfère habituellement la casseDuChameau, en laissant la toute première "
+"lettre en minuscule."
 
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:68
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:90
 msgid ""
-"One particularity of this exercise is that you shouldn't write directly the "
-"code that the buggle should execute, but a method it should use. Actually, "
-"in any previous exercise, you wrote the body of a specific method called "
-"<code>run()</code> which gets invoked by the environment when you click on "
-"<b>Start</b>."
+"The CamelCase convention is used everywhere in PLM because this program is "
+"written in Java itself, so we kept our habits when adding new languages. But "
+"the fact that the Python bindings of PLM use the CamelCase instead of the "
+"snake_case is considered as a bug that we will fix in further releases."
 msgstr ""
-"La particularité de cet exercice est que vous n'allez donc pas écrire "
-"directement le code que la buggle va exécuter, mais une méthode qu'elle "
-"utilisera. En fait, dans tous les exercices précédents, vous avez écrit le "
-"corps d'une méthode particulière de la buggle nommée <code>run()</code> et "
-"qui est invoquée par l'environnement quand on clique sur le bouton <b>Start</"
-"b>."
+"La casseDuChameau est utilisé partout dans PLM car c'est un programme écrit "
+"en Java à la base, et que nous avons gardé nos habitudes en écrivant le "
+"support pour d'autres langages. Mais nous considérons le fait Python ne soit "
+"pas en casse_du_serpent comme un bug, que nous corrigerons dans une version "
+"future."
 
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:74
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:96
 msgid ""
-"Don't try to define this method here, since the buggle already knows it. "
-"This would cause trouble to the compiler, which would give you an error "
-"message in exchange. For your information, here is the <code>run()</code> "
-"method of this exercise:"
+"The goal of this exercise is to write a method called <code>goAndGet()</"
+"code> which does the same than in a previous exercises (move forward until "
+"over a baggle, pick it up, move back to initial position, drop baggle)."
 msgstr ""
-"N'essayez pas de définir ici cette méthode, puisque la buggle la connaît "
-"déjà. Cela troublerait le compilateur qui vous donnerait un message d'erreur "
-"en échange. Pour information, voici le corps de la méthode <code>run()</"
-"code> de la buggle de cet exercice:"
+"L'objectif de cet exercice est donc d'écrire une méthode nommée "
+"<code>goAndGet()</code> (va chercher) et qui fait la même chose que dans un "
+"exercice précédent (avance tant qu'on ne trouve pas de baggle, ramasser le "
+"baggle, reculer à la case départ, poser le baggle)."
 
-# type: Content of: <p><a><p><p><pre>
-#. type: Content of: <p><p><p><a><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:79
-#, no-wrap
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:100
 msgid ""
-"public void run() {\n"
-"  for (int i=0; i<7; i++) { \n"
-"    goAndGet();\n"
-"    turnRight();\n"
-"    forward();\n"
-"    turnLeft();\n"
-"  }\n"
-"}"
+"One specificity of this exercise is that you shouldn't write directly the "
+"code that the buggle should execute, but a method it should use. The code "
+"that calls your function will be automagically added when you click on "
+"<b>Start</b>.  For your information, this calling code will look like this:"
 msgstr ""
-"public void run() {\n"
-"  for (int i=0; i<7; i++) { \n"
-"    goAndGet();\n"
-"    turnRight();\n"
-"    forward();\n"
-"    turnLeft();\n"
-"  }\n"
-"}"
+"La particularité de cet exercice est que vous n'écrivez pas directement le "
+"code que votre buggle va exécuter, mais une méthode qui sera appelée quand "
+"vous appuyez sur <b>Exécuter</b>. Pour votre information, le code appelant a "
+"la forme suivante:"
 
-# type: Content of: <p><a><p><p><pre>
-#. type: Content of: <p><p><p><a><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:87
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:105
 #, no-wrap
 msgid ""
-"def run():\n"
-"  for i in range(7): \n"
-"    goAndGet()\n"
-"    turnRight()\n"
-"    forward()\n"
-"    turnLeft()\n"
-"  \n"
-"}"
+"[!java]for (int i=0; i<7; i++) {[/!][!python]for i in range(7):[/!][!scala]for (i <- 1 to 7) {[/!]\n"
+"    goAndGet()[!java];[/!]\n"
+"    right()[!java];[/!]\n"
+"    forward()[!java];[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"def run():\n"
-"  for i in range(7): \n"
-"    goAndGet()\n"
-"    turnRight()\n"
-"    forward()\n"
-"    turnLeft()\n"
-"  \n"
-"}"
+"[!java]for (int i=0; i<7; i++) {[/!][!python]for i in range(7):[/!][!scala]for (i <- 1 to 7) {[/!]\n"
+"    goAndGet()[!java];[/!]\n"
+"    droite()[!java];[/!]\n"
+"    avance()[!java];[/!]\n"
+"    gauche()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
 # type: Content of: <p><a><p><p><p>
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:98
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:112
 msgid ""
-"Your buggle will repeat 7 times (which matches the world's dimension)  "
+"Your buggle will repeat 7 times (which matches the world's dimension)  the "
 "sequence constituted of a call to the <code>goAndGet()</code> method that "
 "you should write, plus a move to get to the next row (turn right, move "
 "forward, turn left). As you can see, the buggle will do one step right from "
@@ -4469,23 +4299,23 @@ msgid ""
 msgstr ""
 "Donc, votre buggle va répéter 7 fois (la taille du monde)  l'opération "
 "<code>goAndGet()</code> que vous allez écrire, plus les opérations "
-"nécessaire à se décaler d'une colonne vers la droite (tourner à droite, "
+"nécessaires pour se décaler d'une colonne vers la droite (tourner à droite, "
 "avancer, tourner à gauche). Notez que la buggle va donc faire un pas vers la "
 "droite alors qu'elle sera tout à droite du monde. Cela la ramènera sur le "
 "bord gauche, car le monde des buggles est torique."
 
 # type: Content of: <p><a><p><p><p>
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:105
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:119
 msgid "You should now write this goAndGet() method."
 msgstr "À vous d'écrire cette méthode goAndGet()."
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:3
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:3
 msgid ""
-"We now would like to learn the buggle to build a doghouse. The seamingly "
-"simpler approach consists in directly writing the needed code as follows (it "
-"works because the buggle of this exercise leaves a red path as it moves)."
+"We now would like to learn the buggle to build a doghouse. The naive "
+"approach consists in directly writing the needed code as follows.  This "
+"works because the buggle of this exercise leaves a red path as it moves."
 msgstr ""
 "Nous souhaitons maintenant apprendre à la buggle à se faire une niche.  La "
 "première approche, la plus simple au premier abord, est d'écrire directement "
@@ -4494,188 +4324,293 @@ msgstr ""
 "déplace)."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:8
-#, no-wrap
-msgid ""
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-msgstr ""
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:23
-#, no-wrap
-msgid ""
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-msgstr ""
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:37
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:7
+#, no-wrap
+msgid ""
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]"
+msgstr ""
+"avance()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"gauche()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"gauche()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"gauche()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"avance()[!java];[/!]\n"
+"gauche()[!java];[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:20
 msgid ""
 "It becomes harder when we want to draw two doghouses: we have to rewrite the "
-"same code twice, which is not really handy. Even worse: it's definitively "
-"not good form to duplicate code this way. Indeed, if you realize that an "
-"error sneaked into a code that you copied at several locations, you will "
+"same code twice, which is not really handy. When the code becomes a bit long "
+"as this one, it becomes easier to see why we insist since a while on the "
+"pure evilness that code duplication represents. Indeed, if you realize that "
+"an error sneaked into a code that you copied at several locations, you will "
 "have to fix it several times. And mind your back if you forget one of these "
 "locations."
 msgstr ""
 "Les problèmes commencent quand nous voulons faire faire deux cabanes à la "
 "buggle : Il faut réécrire le code deux fois, ce qui n'est pas très pratique. "
-"Pire que ça, une telle duplication de code est en général très mal vu. En "
-"effet, si vous vous rendez compte que vous vous êtes trompé dans votre code, "
-"et que vous l'avez recopier à plusieurs endroits, il va falloir le corriger "
-"plusieurs fois. Et gare si vous oubliez de corriger un exemplaire."
+"Quand le code devient un peu long comme dans ce cas, on voit mieux pourquoi "
+"il faut toujours éviter de dupliquer du code. En effet, si vous vous rendez "
+"compte que vous vous êtes trompé dans votre code, et que vous l'avez "
+"recopier à plusieurs endroits, il va falloir le corriger plusieurs fois. Et "
+"gare si vous oubliez de corriger un exemplaire."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:26
+msgid ""
+"There is even a name to this good principle in programming: DRY/SPOT, which "
+"means \"Don't Repeat Yourself / Single Point Of Truth\". The latter part "
+"means that each information must be written in only one location of your "
+"program to avoid the differing locations to get out of synch when you modify "
+"your code."
+msgstr ""
+"Ce principe de programmation a même un nom en anglais : DRY/SPOT (qui "
+"signifie «point sec»). C'est l'acronyme de «Don't Repeat Yourself» (ne vous "
+"répétez pas) et «Single Point Of Truth» (point unique de vérité). Chaque "
+"information doit se trouver à un seul endroit de votre programme pour éviter "
+"que les différentes copies ne se désynchronisent quand vous modifiez votre "
+"programme."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:44
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:31
 msgid ""
-"It is good form to <b>factorize your code</b>, ie to write it only once, for "
-"example in a method. This is what you will do now. It is even possible to go "
-"further by factorizing the method body with a <code>for</code> loop, as seen "
-"previously."
+"So, let's apply this good principle and <b>factorize our code</b>, ie to "
+"write it only once, for example in a method. You should even to go further "
+"by factorizing the method body with a <code>for</code> loop, as seen "
+"previously.  If you do it correctly (what you should), you can use the "
+"method <code>left()</code> only once."
 msgstr ""
-"Il est bien préférable de <b>factoriser votre code</b>, c'est-à-dire "
-"d'écrire le code une seule fois, par exemple dans une méthode. C'est ce que "
-"vous allez faire maintenant. Il est même possible d'aller plus loin en "
-"factorisant le code de la méthode avec une boucle <code>for</code> comme vu "
-"précédemment."
+"Nous allons donc appliquer ce beau principe et <b>factoriser le code</b>, "
+"c'est-à-dire écrire le code une seule fois, par exemple dans une méthode. "
+"Vous devriez même aller plus loin en factorisant le code de la méthode avec "
+"une boucle <code>for</code> comme vu précédemment. Si vous vous y prenez "
+"bien (ce que vous devriez faire), vous n'écrirez qu'un seul appel à la "
+"méthode <code>gauche()</code> dans votre programme."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:49
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:38
 msgid ""
 "The goal of this exercise is to write a method called <code>dogHouse</code> "
-"achieving the same result than the code above. The buggle will call your "
-"creation to create several dog houses around its world. Remind to factorize "
-"your method with a for loop."
+"achieving the same result than the code above, but with a for loop to keep "
+"it short.  The buggle will call your creation to create several dog houses "
+"around its world."
 msgstr ""
-"<a name=\"Objectifs\"> L'objectif de cet exercice est d'écrire une méthode "
-"nommée <code>dogHouse()</code> et exécute le code ci-dessus. La buggle "
-"invoquera plusieurs fois votre oeuvre afin de dessiner des cabanes un peu "
-"partout. Pensez à factoriser le code de votre méthode avec une boucle for."
+"L'objectif de cet exercice est d'écrire une méthode nommée <code>dogHouse()</"
+"code> et ayant un comportement identique au code ci-dessus. La buggle "
+"invoquera plusieurs fois votre œuvre afin de dessiner des cabanes un peu "
+"partout."
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:54
-#: src/lessons/welcome/array/basics/Array.html:229
-#: src/lessons/welcome/array/basics/Array2.html:30
-msgid "You're up."
-msgstr "À vous de jouer."
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono.html:3
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:3
+msgid ""
+"In this exercise, we will reproduce the geometric drawing that you can see "
+"in the \"Objective\" tab."
+msgstr ""
+"Dans cet exercice, nous allons reproduire un dessin géométrique, que vous "
+"pouvez voir en cliquant sur l'onglet «Objectif»."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:6
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:6
+msgid ""
+"Your goal (here and in any well written program) is to write the simplest "
+"possible code. For that, you have to decompose your work in sub-steps, and "
+"write a specific method for each sub-step."
+msgstr ""
+"Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire le "
+"code le plus simple possible. Pour cela, vous veillerez à décomposer le "
+"travail à faire en sous-étape, et à faire réaliser chaque sous-étape par une "
+"méthode particulière."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:10
+msgid ""
+"If you observe carefully the picture to draw, it is constituted of four "
+"parts depicting a sort of V. A possible decomposition is to write a method "
+"in charge of drawing a V from the current position. Its prototype can be: "
+"<code>[!java]void [/!]makeV()</code>"
+msgstr ""
+"Si on observe attentivement le modèle à dessiner, on remarque qu'il est "
+"composé de quatre formes en sorte de V à des positions différentes.  Un "
+"découpage possible est d'écrire une fonction chargée de faire un V à partir "
+"de la position courante. Son prototype peut être : <code>[!java]void "
+"[/!]faireV()</code>"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:15
+msgid ""
+"In this method, you should use the methods <code>brushUp()</code> and "
+"<code>brushDown()</code> to mark the ground (you may want to factorize this "
+"in another method). It may be wise to write the <code>makeV()</code> so that "
+"it places directly the buggle in position for the next V."
+msgstr ""
+"Dans cette méthode, vous devez utiliser les méthodes <code>baisseBrosse()</"
+"code> et <code>leveBrosse()</code> pour marquer le sol. Peut-être que "
+"marquer le sol devrait faire l'objet d'une méthode séparée? Il faudrait "
+"également que  méthode <code>faireV()</code> place directement la buggle en "
+"position pour dessiner le prochain V."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:20
+msgid ""
+"Your turn. Your code of should not be longer than 4 lines (not counting "
+"<code>makeV</code>)..."
+msgstr ""
+"À vous de jouer. Votre code ne devrait pas prendre plus de quatre lignes "
+"(sans compter <code>faireV</code>)..."
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono2.html:3
+msgid ""
+"We will now reproduce an even bigger geometrical drawing. Once again, you "
+"can see the model by clicking on the \"Objective\" tab."
+msgstr ""
+"Nous allons maintenant reproduire un dessin géométrique plus grand. Encore "
+"une fois, vous pouvez voir le modèle en cliquant sur l'onglet «Objectif»."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:6
+msgid ""
+"You can naturally reuse all the code you typed in previous exercise (select "
+"the other exercise, do Ctrl-C, come back to the code of this exercise, do "
+"Ctrl-V)."
+msgstr ""
+"Vous pouvez bien entendu réutiliser tout le code que vous aviez tapé à "
+"l'exercice précédent (sélectionnez l'autre exercice, allez dans le code, "
+"sélectionner tout, faites Ctrl-C, revenez dans le code de l'exercice "
+"courant, faites Ctrl-V)."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:10
+msgid ""
+"But you want to keep your code as simple as possible. For that, define new "
+"methods to deal simply with the repetitions in the pattern. For example, a "
+"method <code>makePattern()</code> achieving the pattern of previous example "
+"seems to be a good idea (but this may not be enough)."
+msgstr ""
+"Mais pour que votre méthode principale reste aussi simple que possible, il "
+"faudra définir de nouvelles méthodes afin de gérer simplement les répétions "
+"du motif. Par exemple, une méthode <code>faireMotif()</code> réalisant le "
+"motif de l'exercice précédent semble être un bon départ (mais ce n'est sans "
+"doute pas suffisant)."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:15
+msgid ""
+"Why don't you give it a shot? The main code method shouldn't take more than "
+"2 lines (included in a for loop)"
+msgstr ""
+"À vous de jouer. Le code principal ne devrait pas prendre plus de 2 lignes "
+"( incluses dans une boucle for)."
 
 #. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono3.html:3
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:3
+msgid ""
+"As you can imagine, you have to reproduce the geometric drawing depicted in "
+"the \"Objectives\" tab. As you can see, it is even bigger than the previous "
+"one."
+msgstr ""
+"Vous vous en doutez, il vous faut encore une fois reproduire un dessin "
+"géométrique dont le modèle se trouve dans l'onglet «Objectif». Comme vous le "
+"voyez, il est encore plus grand que le précédent."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono3.html:7
+msgid ""
+"You thus have to declare even more methods to use the repetitions of the "
+"pattern and factorize your code.  Your turn..."
+msgstr ""
+"Il va donc falloir définir encore plus de méthodes afin de tirer partie des "
+"répétitions du motif pour factoriser votre code. À vous de jouer..."
+
+#. type: Content of: <p>
 #: src/lessons/welcome/methods/returning/MethodsReturning.html:3
 msgid ""
 "Writing a method returning a result is not really more work than writing a "
-"method without any result. <span class=\"Java\">You simply have to specify "
-"the data type of expected results before the method name</span>. And, then "
-"write a <code>return</code> instruction in your method body to specify the "
-"actual value to return."
-msgstr ""
-"Écrire des méthodes retournant un résultat n'est pas bien plus compliqué "
-"qu'écrire une méthode n'en renvoyant pas. <span class=\"Java\"> Vous devez "
-"simplement indiquer le type du résultat attendu avant le nom de la méthode</"
-"span>. Il faut écrire dans le corps de la méthode une instruction "
-"<code>return</code> qui précise la valeur à renvoyer."
+"method without any result.  [!java]You simply have to specify the data type "
+"of expected results before the method name (where we previously had "
+"<code>void</code>).[/!] [!scala]You simply have to add a column (:) after "
+"the parenthesis and write the type of data that your method will return, and "
+"add an equal sign (=). This syntax is actually rather close to defining a "
+"variable, with its type, that is actually a function.[/!] You can use the "
+"<code>return</code> instruction anywhere in your method body to specify that "
+"the computation is done (the method is not further executed), and that the "
+"result is the the value following the <code>return</code> keyword."
+msgstr ""
+"Écrire une méthode retournant un résultat n'est pas tellement plus dur que "
+"pour les méthodes sans résultat.\n"
+"[!java]Il suffit d'écrire le type de données renvoyées par votre méthode "
+"avant son nom (là où nous écrivions <code>void</code> avant).[/!] \n"
+"[!scala]Il suffit d'ajouter deux points (:), le type de données renvoyées "
+"par votre méthode et le signe égal (=) entre  les parenthèses de la "
+"déclaration et l'accolade du bloc. Cette syntaxe est assez proche de la "
+"définition d'une variable (avec son type) dont la valeur serait une fonction."
+"[/!]\n"
+"Vous pouvez utiliser l'instruction <code>return</code> n'importe ou dans le "
+"corps de votre méthode pour spécifier que le calcul est fini (la suite de la "
+"méthode n'est pas exécutée) et donner la valeur à donner à l'appelant après "
+"le mot-clé <code>return</code>."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:9
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:12
 #, no-wrap
 msgid ""
-"double pi() {\n"
-"    return 3.14159;\n"
-"}\n"
-"boolean isNumberTwoEven() {\n"
-"    return true;\n"
-"}\n"
+"[!java]double pi() {[/!][!scala]def pi(): Double = {[/!][!python]def pi():[/!]\n"
+"    return 3.14159[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"double pi() {\n"
-"    return 3.14159;\n"
-"}\n"
-"boolean deuxEstIlPair() {\n"
-"    return true;\n"
-"}\n"
+"[!java]double pi() {[/!][!scala]def pi(): Double = {[/!][!python]def pi():[/!]\n"
+"    return 3.14159[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <pre>
+#. type: Content of: <p>
 #: src/lessons/welcome/methods/returning/MethodsReturning.html:16
-#, no-wrap
 msgid ""
-"def pi():\n"
-"    return 3.14159\n"
-"\n"
-"def isNumberTwoEven():\n"
-"    return True\n"
+"Actually, you can also use that <code>return</code> keyword in methods that "
+"do not return any result, to interupt the computation. Of course, you should "
+"not provide any value to return in that case."
 msgstr ""
-"def pi():\n"
-"    return 3.14159\n"
-"\n"
-"def deuxEstIlPair():\n"
-"    return True\n"
+"En fait, vous pouvez également utiliser le mot-clé <code>return</code> dans "
+"les méthodes ne renvoyant pas de résultat, pour interrompre leur exécution. "
+"Dans ce cas, il ne faut bien entendu pas donner de valeur à droite du "
+"<code>return</code>."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:23
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:19
 msgid ""
 "It is possible to have several <code>return</code> instructions in several "
-"branches of a conditional. It is even forbidden to have one execution path "
-"of your body without any <code>return</code>, or to write some code after "
-"the <code>return</code> instruction."
+"branches of a conditional. In fac, it is forbidden to have any execution "
+"path of your body without any <code>return</code>, or to write some code "
+"after the <code>return</code> instruction. Indeed, if the machine reaches "
+"the end of the method without finding any <code>return</code>, it cannot "
+"know what actual value to give back to the method caller.  Moreover, "
+"<code>return</code> interrupts immediately the method execution (why bother "
+"looking further when you know the method result?). So, if there is some code "
+"after a <code>return</code>, it must be an error and the compiler warns you."
 msgstr ""
 "Il est possible d'avoir plusieurs instructions <code>return</code> dans "
 "différentes branches de <code>if</code>. Ce qui est interdit, c'est d'avoir "
 "une branche du code qui n'est pas terminée par un <code>return</code>, ou "
-"d'écrire du code après le <code>return</code>."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:28
-msgid ""
-"Indeed, if the machine reaches the end of the method without finding any "
-"<code>return</code>, it cannot know what actual value to give back to the "
-"method caller. Moreover, <code>return</code> interrupts immediately the "
-"method execution (why bother looking further when you know the method "
-"result?). So, if there is some code after a <code>return</code>, it must be "
-"an error and the compiler warns you."
-msgstr ""
+"d'écrire du code après le <code>return</code>.\n"
 "En effet, si la machine arrive à la fin de la méthode sans avoir rencontré "
 "de <tt>return</tt>, elle ne peut pas savoir quelle valeur communiquer à "
 "celui qui a appelé la méthode. De plus, le <tt>return</tt> interrompt "
@@ -4685,57 +4620,47 @@ msgstr ""
 "l'indique."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:35
-#, no-wrap
-msgid ""
-"boolean negation(boolean cond) {\n"
-"    if (cond == true) {\n"
-"        return true;\n"
-"        <span class=\"comment\">/* no code allowed here */</span>\n"
-"    } else {\n"
-"        return false;\n"
-"        <span class=\"comment\">/* here neither */</span>\n"
-"    }\n"
-"    <span class=\"comment\">/* even here, forget it */</span>\n"
-"}"
-msgstr ""
-"boolean negation(boolean cond) {\n"
-"    if (cond == true) {\n"
-"        return true;\n"
-"        <span class=\"comment\">/* interdit d'écrire du code ici */</span>\n"
-"    } else {\n"
-"        return false;\n"
-"        <span class=\"comment\">/* ici aussi */</span>\n"
-"    }\n"
-"    <span class=\"comment\">/* même ici */</span>\n"
-"}"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:45
-#, no-wrap
-msgid ""
-"def negation(cond):\n"
-"    if cond == True:\n"
-"        return True\n"
-"        <span class=\"comment\"># no code allowed here</span>\n"
-"    else:\n"
-"        return False\n"
-"        <span class=\"comment\"># here neither</span>\n"
-"    \n"
-"    <span class=\"comment\"># even here, forget it</span>\n"
-msgstr ""
-"def negation(cond):\n"
-"    if cond == True:\n"
-"        return True\n"
-"        <span class=\"comment\"># interdit d'écrire du code ici</span>\n"
-"    else:\n"
-"        return False\n"
-"        <span class=\"comment\"># ici aussi</span>\n"
-"    \n"
-"    <span class=\"comment\"># même ici</span>\n"
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:30
+#, no-wrap
+msgid ""
+"[!java|scala][!java]boolean [/!][!scala]def [/!]isFrontFree()[!scala]:Boolean =[/!] {\n"
+"    if (isFacingWall() == true) {\n"
+"        return false;\n"
+"        <span class=\"comment\">/* no code allowed here */</span>\n"
+"    } else {\n"
+"        return true;\n"
+"        <span class=\"comment\">/* here neither */</span>\n"
+"    }\n"
+"    <span class=\"comment\">/* even here, forget it */</span>\n"
+"}[/!][!python]def isFrontFree():\n"
+"    if isFacingWall() == True:\n"
+"        return False\n"
+"        <span class=\"comment\"># no code allowed here</span>\n"
+"    else\n"
+"        return True\n"
+"        <span class=\"comment\"># here neither</span>\n"
+"<span class=\"comment\"># even here, forget it</span>[/!]"
+msgstr ""
+"[!java|scala][!java]boolean [/!][!scala]def [/!]estDevantLibre()[!scala]:Boolean =[/!] {\n"
+"    if (estFaceMur() == true) {\n"
+"        return false;\n"
+"        <span class=\"comment\">/* interdit d'écrire du code ici */</span>\n"
+"    } else {\n"
+"        return true;\n"
+"        <span class=\"comment\">/* pareil ici */</span>\n"
+"    }\n"
+"    <span class=\"comment\">/* même ici, oubliez */</span>\n"
+"}[/!][!python]def estDevantLibre():\n"
+"    if estFaceMur() == True:\n"
+"        return False\n"
+"        <span class=\"comment\"># interdit d'écrire du code ici</span>\n"
+"    else\n"
+"        return True\n"
+"        <span class=\"comment\"># pareil ici</span>\n"
+"<span class=\"comment\"># même ici, oubliez</span>[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:56
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:48
 msgid ""
 "You will once again write a method that the buggle will use. Its name must "
 "be <code>haveBaggle</code>, and it returns a boolean value indicating "
@@ -4745,43 +4670,43 @@ msgstr ""
 "<a name=\"Objectifs\"> Vous allez encore une fois écrire une méthode qui "
 "sera utilisée par la buggle. Son nom doit être <code>haveBaggle</code>, et "
 "elle doit renvoyer un booléen indiquant si la colonne face à la buggle "
-"contient un baggle ou non. Votre buggle va s'en servir pour chercher la "
-"première colonne contenant un baggle et s'y arrêter."
+"contient un biscuit ou non. Votre buggle va s'en servir pour chercher la "
+"première colonne contenant un biscuit et s'y arrêter."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:61
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:53
 msgid ""
 "The easier for this method is to use a boolean variable called "
 "<code>seenBaggle</code> indicating whether or not we saw a baggle so far. It "
 "initial value is 'false'."
 msgstr ""
 "Le plus simple pour écrire cette méthode est peut être d'utiliser une "
-"variable booléenne <code>vuBaggle</code> indiquant si on a vu un baggle "
+"variable booléenne <code>vuBiscuit</code> indiquant si on a vu un biscuit "
 "jusque là. Initialement, elle contient faux."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:65
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:57
 msgid ""
 "Then, move 6 steps forward (the world contains 7 cells and we already are "
 "one one of them). For each cell, if it contains a baggle, we store true in "
 "<code>sawBaggle</code> (and we don't do anything but moving forward if not)."
 msgstr ""
 "Ensuite, on avance de 6 cases (le monde contient 7 cases, et on est déjà sur "
-"l'une d'entre elles). Pour chaque case, si elle contient un baggle, on range "
-"la valeur vrai dans <tt>vuBaggle</tt> (et on ne fait rien d'autre qu'avancer "
-"si non)."
+"l'une d'entre elles). Pour chaque case, si elle contient un biscuit, on "
+"range la valeur vrai dans <tt>vuBiscuit</tt> (et on ne fait rien d'autre "
+"qu'avancer si non)."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:69
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:61
 msgid ""
 "At the end, we move back by 6 steps, and we return the value of "
 "<code>seenBaggle</code> to the caller."
 msgstr ""
 "Quand on est arrivé à la fin, on recule de 6 cases, et on retourne le "
-"contenu de <tt>vuBaggle</tt> à l'appelant."
+"contenu de <tt>vuBiscuit</tt> à l'appelant."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:73
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:65
 msgid ""
 "This exercise is a bit different since there is two initial worlds, each "
 "with a specific objective. Your code must work for each of them. Observe "
@@ -4795,29 +4720,31 @@ msgstr ""
 "que vous souhaitez observer."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:78
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:70
 msgid ""
 "When your method <code>haveBaggle</code> works, proceed to next exercise."
 msgstr ""
 "Quand votre méthode <tt>haveBaggle</tt> fonctionne, passez à l'exercice "
 "suivant."
 
-#. type: Content of: outside any tag (error?)
+#. type: Content of: <p>
 #: src/lessons/welcome/methods/args/MethodsArgs.html:3
 msgid ""
 "Don't you get tired of writing again and again the code to move by a fixed "
 "amount of steps? On the other hand, writing <tt>forward2()</tt>, "
 "<tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>, "
-"<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help"
+"<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help, "
+"to say the less."
 msgstr ""
 "N'êtes vous pas fatigué d'écrire encore et encore le code qui permet "
-"d'avancer ou de reculer d'un nombre prédéterminé pas ? Oui, mais écrire les "
-"méthode <tt>forward2()</tt>, <tt>forward3()</tt>, <tt>forward4()</tt>, et "
-"<tt>backward2()</tt>, <tt>backward3()</tt>, <tt>backward4()</tt>, et ainsi "
-"de suite, ça ne constitue pas un réel gain de temps..."
+"d'avancer ou de reculer d'un nombre prédéterminé de pas ? Oui, mais écrire "
+"les méthode <tt>avance2()</tt>, <tt>avance3()</tt>, <tt>avance4()</tt>, et "
+"<tt>recule2()</tt>, <tt>recule3()</tt>, <tt>recule4()</tt>, et ainsi de "
+"suite, ça ne constitue pas un réel gain de temps. Et puis, c'est carrément "
+"moche !"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:8
+#: src/lessons/welcome/methods/args/MethodsArgs.html:9
 msgid ""
 "Luckily, it is possible to pass <b>parameters</b> to your methods. You have "
 "to specify their type and name between the parenthesis after the method "
@@ -4829,30 +4756,20 @@ msgstr ""
 "suivent le nom de la méthode. Ensuite, on peut les utiliser dans le corps de "
 "la fonction comme s'il s'agissait de variables définies ici."
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:13
-#, no-wrap
-msgid ""
-"double divideByTwo(double x) {\n"
-"  return x / 2;\n"
-"}"
-msgstr ""
-"double diviseParDeux(double x) {\n"
-"  return x / 2;\n"
-"}"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:17
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:14
 #, no-wrap
 msgid ""
-"def divideByTwo(x):\n"
-"  return x / 2\n"
+"[!java]double [/!]divideByTwo([!java]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala]{[/!][!python]:[/!]\n"
+"     return x / 2[!java];[/!]\n"
+"[!scala|java]}[/!]"
 msgstr ""
-"def diviseParDeux(x):\n"
-"  return x / 2\n"
+"[!java]double [/!]diviseParDeux([!java]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala]{[/!][!python]:[/!]\n"
+"     return x / 2[!java];[/!]\n"
+"[!scala|java]}[/!]"
 
-#. type: Content of: <p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:21
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:18
 msgid ""
 "As caller, you have to specify the initial value of this \"variables\" "
 "between the call's parenthesis."
@@ -4860,20 +4777,14 @@ msgstr ""
 "À l'usage, il faut indiquer les valeurs qu'elles doivent prendre entre les "
 "parenthèses de l'appel."
 
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:23
-#, no-wrap
-msgid "double y = divideByTwo(3.14);"
-msgstr "double y = diviseParDeux(3.14);"
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:25
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:20
 #, no-wrap
-msgid "y = divideByTwo(3.14)"
-msgstr "y = diviseParDeux(3.14);"
+msgid "[!java]double [/!][!scala]val [/!]result = divideByTwo(3.14)[!java];[/!]"
+msgstr "[!java]double [/!][!scala]val [/!]result = diviseParDeux(3.14)[!java];[/!]"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:28
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:22
 msgid ""
 "If you want several parameters, you need to separate them with comas (,)  "
 "both in the declaration and calls."
@@ -4881,64 +4792,61 @@ msgstr ""
 "Si on veut avoir plusieurs paramètres, il faut les séparer par des virgules, "
 "lors de la déclaration comme lors de l'appel."
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:31
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:25
 #, no-wrap
 msgid ""
-"double divide(double x, double y) {\n"
-"  return x / y;\n"
-"}"
+"[!java]double divide(double x, double y) {[/!]\n"
+"[!scala]def divide(x:Double, y:Double): Double = {[/!]\n"
+"[!python]def divide(x, y):[/!]\n"
+"     return x / y[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"double divise(double x, double y) {\n"
-"  return x / y;\n"
-"}"
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:34
-#, no-wrap
-msgid "double y = divide(3.14 , 1.5);"
-msgstr "double y = divise(3.14 , 1.5);"
+"[!java]double divise(double x, double y) {[/!]\n"
+"[!scala]def divise(x:Double, y:Double): Double = {[/!]\n"
+"[!python]def divise(x, y):[/!]\n"
+"     return x / y[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:36
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:30
 #, no-wrap
 msgid ""
-"def divide(double x, double y):\n"
-"  return x / y\n"
-"}"
+"[!java]double res = divide(3.14 , 1.5);[/!]\n"
+"[!scala]val res = divide(3.14 , 1.5)[/!]\n"
+"[!python]res = divide(3.14 , 1.5)[/!]"
 msgstr ""
-"def divise(double x, double y):\n"
-"  return x / y\n"
-"}"
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:39
-#, no-wrap
-msgid "y = divide(3.14 , 1.5)"
-msgstr "y = divise(3.14 , 1.5);"
+"[!java]double res = divise(3.14 , 1.5);[/!]\n"
+"[!scala]val res = divise(3.14 , 1.5)[/!]\n"
+"[!python]res = divise(3.14 , 1.5)[/!]"
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:42
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:35
 msgid ""
-"In Java, you can declare several methods of the same name as long as they "
-"don't have the same parameter types and number (they are said to have "
-"different <b>signature</b>)."
+"In [!thelang], you can declare several methods of the same name as long as "
+"they don't have the same <b>signature</b>, that is, the same amount of "
+"parameters and the same parameters' types."
 msgstr ""
-"En Java, il est possible d'avoir plusieurs méthodes du même nom, à condition "
-"qu'elles n'aient pas le même nombre et les mêmes types de paramètres (on dit "
-"qu'elles n'ont pas la même <b>signature</b>)."
+"En [!thelang], il est possible d'avoir plusieurs méthodes du même nom, à "
+"condition qu'elles n'aient pas la même <b>signature</b>, c'est à dire le "
+"même nombre de paramètres et les mêmes types de paramètres."
 
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:45
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:39
 #, no-wrap
 msgid ""
-"int max(int x, int y) {\n"
+"[!java]double max(double x, double y)[/!][!scala]def max(x:Double, int y:Double): Double =[/!] {\n"
+"  if (x > y) {\n"
+"    return x;\n"
+"  }\n"
+"  return y;\n"
+"}[!java]int max(int x, int y)[/!][!scala]def max(x:Int, int y:Int): Int =[/!] {\n"
 "  if (x > y) {\n"
 "    return x;\n"
 "  }\n"
 "  return y;\n"
 "}\n"
-"int max(int x, int y, int z) {\n"
+"[!java]int max(int x, int y; int z)[/!][!scala]def max(x:Int, int y:Int, int z:Int): Int =[/!] {\n"
 "  if (x > y && x > z) {\n"
 "    return x;\n"
 "  }\n"
@@ -4948,163 +4856,172 @@ msgid ""
 "  return z;\n"
 "}"
 msgstr ""
-"int max(int x, int y) {\n"
-"  if (x > y) {\n"
-"    return x;\n"
-"  }\n"
-"  return y;\n"
+"[!java]double max(double x, double y)[/!][!scala]def max(x:Double, int y:Double): Double =[/!] {\n"
+"  if (x > y) {\n"
+"    return x;\n"
+"  }\n"
+"  return y;\n"
+"}[!java]int max(int x, int y)[/!][!scala]def max(x:Int, int y:Int): Int =[/!] {\n"
+"  if (x > y) {\n"
+"    return x;\n"
+"  }\n"
+"  return y;\n"
 "}\n"
-"int max(int x, int y, int z) {\n"
-"  if (x > y && x > z) {\n"
-"    return x;\n"
-"  }\n"
-"  if (y > z) {\n"
-"    return y;\n"
-"  }\n"
-"  return z;\n"
+"[!java]int max(int x, int y; int z)[/!][!scala]def max(x:Int, int y:Int, int z:Int): Int =[/!] {\n"
+"  if (x > y && x > z) {\n"
+"    return x;\n"
+"  }\n"
+"  if (y > z) {\n"
+"    return y;\n"
+"  }\n"
+"  return z;\n"
 "}"
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:63
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:60
 msgid ""
 "Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It "
 "works anyway because a <tt>return</tt> interrupts the method execution. If "
-"we arrive to the last line of <code>max(int,int)</code>, we know that "
-"<code>x<=y</code> because on the other case, the <tt>return</tt> of line "
-"2 would have stopped the execution."
+"we arrive to the last line of <code>[!java]max(int,int)[/!][!scala]max(Int,"
+"Int):Int[/!]</code>, we know that <code>x<=y</code> because otherwise, "
+"the <tt>return</tt> of line 2 would have stopped the execution."
 msgstr ""
 "Remarquez que nous avons ici laissé de coté les <tt>else</tt> de chaque "
 "alternative. Cela fonctionne tout de même car un <tt>return</tt> interrompt "
-"l'exécution de la méthode. Si on arrive à la dernière ligne de <code>max(int,"
-"int)</code>, on est donc sur que <code>x<=y</code> car dans le cas "
-"contraire, le <tt>return</tt> de la deuxième ligne aurait arrêté l'exécution "
-"de la fonction."
+"l'exécution de la méthode. Si on arrive à la dernière ligne de <code>[!"
+"java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>, on est donc sûr "
+"que <code>x<=y</code> car dans le cas contraire, le <tt>return</tt> de la "
+"deuxième ligne aurait arrêté l'exécution de la fonction."
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:69
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:70
+msgid ""
+"This time, you have to write a <code> [!java]move(int stepCount,boolean "
+"forward)[/!] [!scala]move(stepCount: Int,forward: Boolean)[/!] [!"
+"python]move(stepCount,forward)[/!] </code> method which moves forward by "
+"<code>stepCount</code> steps if <code>forward</code> is true, and moves back "
+"of that amount of steps if the boolean is false."
+msgstr ""
+"Cette fois, vous devez écrire une méthode \n"
+"<code>[!java]deplace(int nbPas,boolean versLAvant)[/!] [!"
+"scala]deplace(nbPas: Int,versLAvant: Boolean)[/!] [!python]deplace(nbPas,"
+"versLAvant)[/!] </code> qui se déplace de <code>nbPas</code> pas. Si "
+"<code>versLAvant</code> est vrai, il faut avancer de ce nombre de pas; dans "
+"le cas contraire, il faut reculer."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:78
+msgid ""
+"This time, there is only one world but seven buggles, all sharing the same "
+"code.  This code should not be really problematic for you to write, actually."
+msgstr ""
+"Cette fois, il y a un seul monde, et sept buggles, qui exécutent toutes le "
+"code que vous allez écrire.\n"
+"Cet exercice ne devrait pas vous poser de problème particulier."
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:1
+msgid "Flower Pot"
+msgstr "Pot de fleur"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:3
 msgid ""
-"This time, you have to write a <code>move(int stepCount,boolean forward)</"
-"code> method which move forward of <code>stepCount</code> if <code>forward</"
-"code> is true, and move back of that amount of steps if the boolean is "
-"false. The buggle will use some methods we did not introduce yet to guess "
-"its position and orientation in order to determine the amount of steps to do "
-"and their direction, but it is not relevant here."
-msgstr ""
-"<a name=\"Objectifs\"> Il s'agit cette fois d'écrire une méthode "
-"<code>move(int nbPas, boolean forward)</code> qui avance de <code>nbPas</"
-"code> si <code>forward</code> est vrai, et recule d'autant de pas si le "
-"booléen est faux. La buggle s'en servira pour retourner sur la ligne du "
-"haut. Elle utilisera au passage des méthodes que l'on ne connaît pas encore "
-"pour deviner sa position et sa direction actuelles afin de calculer le sens "
-"et le nombre de pas à faire (mais ce n'est pas important ici)."
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:76
-msgid ""
-"This time, there is only one world, and seven buggles. But it does not "
-"change anything for you, since the same code is used for any buggles."
-msgstr ""
-"Cette fois, il y a un seul monde, et sept buggles. Mais ça ne change pas "
-"grand chose pour vous, puisque toutes sont ici régies par le même code."
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:79
-msgid ""
-"The code of the method to write should not be really problematic for you."
-msgstr ""
-"Le code de la méthode à proprement parler ne devrait pas poser de problème."
-
-#. type: Content of: <p><p><p><p><h2>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:81
-msgid "What's coming next?"
-msgstr "Et ensuite?"
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:82
-msgid ""
-"You now know the very basics of programming. At least, we introduced all the "
-"important concepts, and you should be able to read most code by now. If you "
-"want to play safe, you should proceed to the next exercises of this lesson "
-"to solidify your knowledge by reusing these concepts in various simple "
-"situations. After taking them, you'll master what's called \"Tactical "
-"programming\", meaning that you will master the syntax enough to not have "
-"any issue with it, allowing you to focus on the fundamental problems of what "
-"you want to solve instead of struggling with syntaxic difficulties. Some of "
-"these exercises are even fun to do ;)"
-msgstr ""
-"Vous connaissez maintenant les bases de la programmation. Disons au moins "
-"que vous avez vu les concepts les plus important et que vous devriez être "
-"capable de lire et comprendre la plupart des programmes écrits. Pour plus de "
-"sécurité, vous devriez faire les autres exercices de cette leçon pour "
-"solidifier vos acquis en les réutilisant dans diverses situations. Après "
-"cela, vous maîtriserez ce qu'on appelle la \"programmation tactique\", ce "
-"qui veut dire que votre maîtrise de la syntaxe vous permettra de vous "
-"concentrer sur les problèmes à résoudre sans vous battre contre le "
-"compilateur à propos de la syntaxe. Certains de ces exercices sont même "
-"amusants à résoudre ;)"
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:90
-msgid ""
-"If you are in a hurry and want more, you can skip these exercises and "
-"proceed directly to more interesting challenges. For example, the "
-"<i>Labyrinths</i> lesson will teach you about maze escaping algorithms, "
-"which are not rocket science but require several improvements to work for "
-"any kind of maze. The <i>Lightbot</i> lesson is a little programming game "
-"where you control a little robot wanting to light the world. Since it is not "
-"programmed in a language but graphically, the first exercises can be used as "
-"an introduction activity to what programming means for real beginners, but "
-"the last exercises constitute challenges and brain teaser even to "
-"professional programmers."
-msgstr ""
-"Si vous êtes pressés et voulez plus, vous pouvez sauter ces exercices et "
-"passer directement à des exercices plus complets et plus intéressants. Par "
-"exemple, la leçon sur les <i>Labyrinthes</i> vous apprendra à sortir d'un "
-"labyrinthe. Les algorithmes impliqués ne sont pas ultra complexes, mais vous "
-"serez amenés à améliorer votre code à plusieurs reprises afin de pouvoir "
-"sortir de n'importe quel type de labyrinthe. La leçon <i>LightBot</i> est un "
-"petit jeu de programmation où vous contrôlez un robot voulant éclairer le "
-"monde. Comme il est programmé graphiquement et non dans un language "
-"syntaxique, les premiers exercices peuvent être utilisés comme une "
-"introduction à ce que programmer veut dire pour les débutants. Mais les "
-"derniers exercices sont plus difficiles et devraient constituer des casse-"
-"têtes même pour les programmeurs professionnels."
+"Your buggle decided to flower a bit the pot it lives in. You have to help it "
+"reproducing the drawing of its dreams (check the \"Objective\" tab to see "
+"it)."
+msgstr ""
+"Votre buggle a décidé de fleurir un peu le pot de fleur dans lequel elle "
+"vit. Vous devez l'aider à reproduire le motif dont elle rêve (vous pouvez le "
+"voir dans l'onglet «Objectif»)."
 
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:3
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:6
 msgid ""
-"In this exercise, we will reproduce the geometric drawing that you can see "
-"in the \"Objective\" tab."
+"For that, you have to write a <code>growFlowers()</code> method that does "
+"not take any parameter and does not return any result. As the pattern is a "
+"bit complex, you should try to decompose this drawing in sub-steps so that "
+"your code remains short and easy to read. A method to draw one flower of the "
+"color passed in parameter sounds like a good start, but it is probably not "
+"enough."
 msgstr ""
-"Dans cet exercice, nous allons reproduire un dessin géométrique, que vous "
-"pouvez voir en cliquant sur l'onglet \"Objective\"."
+"Pour cela, vous devez écrire une méthode nommée <code>growFlower()</code> "
+"(«fait pousser les fleurs» en anglais). Cette méthode ne prend aucun "
+"paramètre et ne renvoie aucun résultat. Comme le motif est un peu complexe, "
+"il faut que vous le décomposiez en sous-motifs pour que votre code reste "
+"simple et agréable à lire. Une méthode dessinant une fleur est un bon début, "
+"même si ce n'est probablement pas assez."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:6
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:12
 msgid ""
-"Your goal (here and in any well written program) is to write the simplest "
-"possible <code>run()</code>. For that, you have to decompose your work in "
-"sub-steps, and write a specific method for each sub-step."
+"For your information, this drawing uses five colors that are listed below.  "
+"[!java|scala]The data type of these constants is <code>Color</code>, that "
+"naturally describes a particular color.[/!]"
 msgstr ""
-"Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire "
-"une méthode <code>run()</code> la plus simple possible. Pour cela, vous "
-"veillerez à décomposer le travail à faire en sous-étape, et à faire réaliser "
-"chaque sous-étape par une méthode particulière."
+"Pour information, ce dessin utilise les cinq couleurs ci-dessous. \n"
+"[!java|scala]Le type de données de ces constantes est <code>Color</code>, "
+"qui décrit naturellement une couleur donnée[/!]"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:17
+msgid "<tt>Color.RED</tt>"
+msgstr "<tt>Color.RED</tt> pour le rouge"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:18
+msgid "<tt>Color.PINK</tt>"
+msgstr "<tt>Color.PINK</tt> pour le rose"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:19
+msgid "<tt>Color.CYAN</tt>"
+msgstr "<tt>Color.CYAN</tt> pour le bleu clair"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:20
+msgid "<tt>Color.ORANGE</tt>"
+msgstr "<tt>Color.ORANGE</tt> pour le orange"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:21
+msgid "<tt>Color.GREEN</tt>"
+msgstr "<tt>Color.GREEN</tt> pour le vert"
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:22
+msgid "<tt>Color.YELLOW</tt>"
+msgstr "<tt>Color.YELLOW</tt> pour le jaune"
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:1
+msgid "Flower Display Case"
+msgstr "Jardinière de fleurs"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:10
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:3
 msgid ""
-"Your goal (here and in any well written program) is to write the simplest "
-"possible main code. For that, you have to decompose your work in sub-steps, "
-"and write a specific method for each sub-step."
+"Whao! That's not a little pot anymore! That's a huge large flower display "
+"case! Your buggle can't help but starts flowering this gorgeous place. You "
+"should help it to prevent that it bumps into a wall..."
 msgstr ""
-"Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire "
-"une méthode principale la plus simple possible. Pour cela, vous veillerez à "
-"décomposer le travail à faire en sous-étape, et à faire réaliser chaque sous-"
-"étape par une méthode particulière."
+"Whaou! Ce n'est plus un petit pot de fleurs, c'est carrément une énorme "
+"jardinière! Votre buggle est déjà partie la fleurir, et vous devriez aller "
+"l'aider pour éviter qu'elle ne se cogne à une bordure..."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:14
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:7
+msgid "PS: the newly used color is <code>Color.BLUE</code>."
+msgstr ""
+"PS: La nouvelle couleur utilisée (pour le bleu) est <code>Color.BLUE</code>"
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:1
+msgid "Colorful drawing"
+msgstr "Dessins colorés"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:10
 msgid ""
 "If you observe carefully the picture to draw, it is constituted of four "
 "parts depicting a sort of V using a different color. A possible "
@@ -5118,208 +5035,280 @@ msgstr ""
 "courante. Son prototype peut être :"
 
 #. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:18
-#, no-wrap
-msgid "void makeV(Color c)"
-msgstr "void makeV(Color c)"
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:19
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:14
 #, no-wrap
-msgid "makeV(c)"
-msgstr "makeV(c)"
+msgid "[!java]void [/!]makeV([!java]Color [/!]c[!scala]: Color[/!])[!python]  <span class=\"comment\"># parameter c is of type Color</span>[/!]"
+msgstr "[!java]void [/!]faireV([!java]Color [/!]c[!scala]: Color[/!])[!python]  <span class=\"comment\"># le paramètre c est de type Color</span>[/!]"
 
 #. type: Content of: <p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:21
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:16
 msgid ""
 "The <code>Color</code> data type naturally describes a particular color. "
-"Your <code>run()</code> method should probably call <code>makeV</code> with "
-"the following arguments (a different color for each call):"
+"Your code should probably call <code>makeV</code> with the following "
+"arguments (a different color for each call):"
 msgstr ""
 "Le type de données <code>Color</code> représente naturellement une couleur "
-"en particulier.  Votre méthode <code>run()</code> invoquera sans doute "
-"<code>makeV</code> avec les arguments suivants (une couleur différente à "
-"chaque appel) :"
+"en particulier.  Votre code invoquera sans doute <code>faireV</code> avec "
+"les arguments suivants (une couleur différente à chaque appel) :"
 
 #. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:26
-msgid "Color.yellow"
-msgstr "Color.yellow"
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:20
+msgid "Color.YELLOW"
+msgstr "Color.YELLOW (jaune)"
 
 #. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:27
-msgid "Color.red"
-msgstr "Color.red"
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:21
+msgid "Color.RED"
+msgstr "Color.RED (rouge)"
 
 #. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:28
-msgid "Color.blue"
-msgstr "Color.blue"
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:22
+msgid "Color.BLUE"
+msgstr "Color.BLUE (bleu)"
 
 #. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:29
-msgid "Color.green"
-msgstr "Color.green"
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:23
+msgid "Color.GREEN"
+msgstr "Color.GREEN (vert)"
 
 #. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:32
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:26
 msgid ""
 "In <code>makeV()</code>, you should use the <code>setBrushColor()</code> "
 "method (predefined in the buggle) to change the color of the buggle's brush, "
 "as well as <code>brushUp()</code> and <code>brushDown()</code> to change the "
 "brush position."
 msgstr ""
-"Dans la méthode <code>makeV()</code>, il faut utiliser la méthode "
-"<code>setBrushColor()</code>, qui est prédéfinie dans la buggle, pour "
-"changer la couleur du pinceau, ainsi que <code>brushUp()</code> et "
-"<code>brushDown()</code> pour lever et baisser le pinceau."
+"Dans la méthode <code>faireV()</code>, il faut utiliser la méthode "
+"<code>setCouleurBrosse()</code>, qui est prédéfinie dans la buggle, pour "
+"changer la couleur du pinceau, ainsi que <code>leveBrosse()</code> et "
+"<code>baisseBrosse()</code> pour lever et baisser le pinceau."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:37
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:31
 msgid ""
 "It may be wise to write the <code>makeV()</code> so that it places directly "
 "the buggle in position for the next V."
 msgstr ""
-"Il faudrait également que la méthode <code>makeV()</code> place la buggle en "
-"position pour dessiner le prochain V directement."
+"Il faudrait également que la méthode <code>faireV()</code> place la buggle "
+"en position pour dessiner le prochain V directement."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:40
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:35
+msgid ""
+"Your turn now. I'm sure you can imagine the other methods you need to keep "
+"your code simple and pleasant to read.  Complete the run which prototype is "
+"already given. It will be called automatically (once).  [!java]the public "
+"keyword means more or less that anybody can call this method, which is good "
+"because the PLM infrastructure calls it directly.[/!]"
+msgstr ""
+"À vous de jouer. Je suis sûr que vous parviendrez à trouver d'autres "
+"méthodes à ajouter pour décomposer ce problème et faire en sorte que votre "
+"code reste simple et agréable à lire. Complétez la méthode <code>run()</"
+"code> qui sera appelée automatiquement une fois. \n"
+"[!java]Le mot-clé <code>public</code> signifie plus ou moins que tout le "
+"monde a le droit d'invoquer cette méthode. Ça tombe bien, l'infrastructure "
+"de la PLM va l'invoquer directement.[/!]"
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:1
+msgid "Larger colorful drawing"
+msgstr "Grand dessin coloré"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:7
 msgid ""
-"Your turn. The <code>run()</code> method should not be longer than 4 lines..."
+"You thus have to declare even more methods to use the repetitions of the "
+"pattern and factorize your code. Another solution is to <i>parametrize</i> "
+"your functions to reuse the code you wrote previously by changing the size."
 msgstr ""
-"À vous de jouer. La méthode <code>run()</code> ne devrait pas prendre plus "
-"de quatre lignes..."
+"Il va donc falloir définir encore plus de méthodes afin de tirer partie des "
+"répétitions du motif pour factoriser votre code. Ou alors, il va falloir "
+"<i>paramétrer</i> vos fonctions pour réutiliser ce que vous aviez écrit en "
+"changant les tailles."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:11
+#: src/lessons/welcome/traversal/Snake.html:39
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:46
+#: src/lessons/welcome/traversal/line/TraversalByLine.html:10
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:10
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:6
+msgid "Your turn..."
+msgstr "À vous de jouer..."
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/PatternPicture.html:1
+msgid "Another Colorful Pattern"
+msgstr "Autre motif coloré"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:3
+#: src/lessons/welcome/methods/picture/PatternPicture.html:3
 msgid ""
-"We will now reproduce an even bigger geometrical drawing. Once again, you "
-"can see the model by clicking on the \"Objective\" tab."
+"Here is yet another exercise where you have to reproduce the pattern "
+"provided in the \"Objective\" tab."
 msgstr ""
-"Nous allons maintenant reproduire un dessin géométrique plus grand. Encore "
-"une fois, vous pouvez voir le modèle en cliquant sur l'onglet \"Objective\"."
+"Voici de nouveau un exercice où il faut reproduire un motif donné dans "
+"l'onglet «Objectif»."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:6
+#: src/lessons/welcome/methods/picture/PatternPicture.html:6
 msgid ""
-"You can naturally reuse all the code you typed in previous exercise (select "
-"the other exercise, do Ctrl-C, come back to the code of this exercise, do "
-"Ctrl-V)."
+"This one is a bit more difficult than the one seen previously. Look for "
+"repeating patterns, even if the color changes, and write a method drawing "
+"each of them."
 msgstr ""
-"Vous pouvez bien entendu réutiliser tout le code que vous aviez tapé à "
-"l'exercice précédent (sélectionnez l'autre exercice, allez dans le code, "
-"sélectionner tout, faites Ctrl-C, revenez dans le code de l'exercice "
-"courant, faites Ctrl-V)."
+"Celui-ci est un peu plus difficile que ceux vus précédement. Cherchez les "
+"motifs qui se répètent, même si la couleur change, et faites une méthode "
+"dessinant chacun d'entre eux."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PatternPicture.html:10
+msgid "Good luck!"
+msgstr "Bon courage !"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:10
+#: src/lessons/welcome/methods/slug/SlugHunting.html:3
 msgid ""
-"But you want to keep your main<code>run()</code> as simple as possible. For "
-"that, define new methods to deal simply with the repetitions in the pattern. "
-"For example, a method <code>makePattern()</code> achieving the pattern of "
-"previous example seems to be a good idea (but this may not be enough)."
+"Now that your <code>isFacingTrail()</code> method is working, it's time to "
+"write the code to organize the hunting party. Copy/paste your code from the "
+"previous exercise, and complete the <code>hunt()</code> method."
 msgstr ""
-"Mais pour que votre méthode principale <code>run()</code> reste aussi simple "
-"que possible, il faudra définir de nouvelles méthodes afin de gérer "
-"simplement les répétions du motif. Par exemple, une méthode "
-"<code>makePattern()</code> réalisant le motif de l'exercice précédent semble "
-"être un bon départ (mais ce n'est sans doute pas suffisant)."
+"Maintenant que votre méthode <code>isFacingTrail()</code> fonctionne, il est "
+"temps d'écrire le code de la chasse à proprement parler. Copie/collez le "
+"code que vous aviez fait pour l'exercice précédent, et complétez la méthode "
+"<code>hunt()</code> (<i>hunt</i> signifie <i>chasse</i> en anglais)."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:16
+#: src/lessons/welcome/methods/slug/SlugHunting.html:7
 msgid ""
-"But you want to keep your main code as simple as possible. For that, define "
-"new methods to deal simply with the repetitions in the pattern. For example, "
-"a method <code>makePattern()</code> achieving the pattern of previous "
-"example seems to be a good idea (but this may not be enough)."
+"Following a track is not very difficult: move forward as long as you have "
+"the track in front of you.  If there is not track in front of you anymore, "
+"check if the rest of the track is on your left or on your right, and follow "
+"it further."
 msgstr ""
-"Mais pour que votre méthode principale reste aussi simple que possible, il "
-"faudra définir de nouvelles méthodes afin de gérer simplement les répétions "
-"du motif. Par exemple, une méthode <code>makePattern()</code> réalisant le "
-"motif de l'exercice précédent semble être un bon départ (mais ce n'est sans "
-"doute pas suffisant)."
+"Suivre une piste n'est pas très difficile : avancez tant que vous êtes face "
+"à la piste. Si la piste n'est plus devant vous, cherchez si elle se trouve à "
+"gauche ou à droite, et suivez-la encore."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:22
+#: src/lessons/welcome/methods/slug/SlugHunting.html:11
 msgid ""
-"Why don't you give it a shot? The <code>run()</code> method shouldn't take "
-"more than 2 lines (included in a for loop)"
+"To ensure that you don't mix the track you come from with the one in front "
+"of you, the easier is to erase the track when you follow it. Use the method "
+"<code>brushDown()</code> to put your brush down and mark the ground, and "
+"<code>brushUp()</code> to move it up again."
 msgstr ""
-"À vous de jouer. La méthode <code>run()</code> ne devrait pas prendre plus "
-"de 2 lignes, incluses dans une boucle for..."
+"Pour ne pas confondre la partie de la trace à suivre avec celle que votre "
+"buggle a déjà suivie, il est conseillé d'effacer la piste derrière vous. "
+"Pour cela, utilisez la méthode <code>baisseBrosse()</code> pour baisser "
+"votre brosse, et <code>leveBrosse()</code> pour la relever."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:25
+#: src/lessons/welcome/methods/slug/SlugHunting.html:15
 msgid ""
-"Why don't you give it a shot? The main code method shouldn't take more than "
-"2 lines (included in a for loop)"
+"Finally, do not forget to capture your prey once you found it (using "
+"<code>pickupBaggle()</code>)."
 msgstr ""
-"À vous de jouer. Le code de la méthode principale ne devrait pas prendre "
-"plus de 2 lignes ( incluses dans une boucle for)"
+"Enfin, n'oubliez de capturer votre proie une fois que vous l'aurez débusquée "
+"(avec <code>prendBiscuit()</code>)."
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:3
+#: src/lessons/welcome/methods/slug/SlugHunting.html:19
 msgid ""
-"As you can imagine, you have to reproduce the geometric drawing depicted in "
-"the \"Objectives\" tab. As you can see, it is even bigger than the previous "
-"one."
+"<a name=\"Objectives\"> Complete the <code>hunt()</code> method. You "
+"probably want to copy over the <code>isFacingTrail()</code> method that you "
+"wrote in previous exercise.  </a>"
 msgstr ""
-"Vous vous en doutez, il vous faut encore une fois reproduire un dessin "
-"géométrique dont le modèle se trouve dans l'onglet \"Objective\". Comme vous "
-"le voyez, il est encore plus grand que le précédent."
+"<a name=\"Objectifs\"> Complétez la méthode <code>hunt()</code>. Vous voulez "
+"probablement copier votre méthode <code>isFacingTrail()</code> de l'exercice "
+"précédent."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:7
+#: src/lessons/welcome/methods/slug/SlugTracking.html:3
 msgid ""
-"You thus have to declare even more methods to use the repetitions of the "
-"pattern and factorize your code. Another solution is to <i>parametrize</i> "
-"your functions to reuse the code you wrote previously by changing the size."
+"Your buggle is super happy! It just found the green dribbling trail, "
+"certainly left by a big yummy slug.  At its end, the buggle is certain to "
+"entertain itself with this appetizing slug (represented as a baggle)."
 msgstr ""
-"Il va donc falloir définir encore plus de méthodes afin de tirer partie des "
-"répétitions du motif pour factoriser votre code. Ou alors, il va falloir "
-"<i>paramétrer</i> vos fonctions pour réutiliser ce que vous aviez écrit en "
-"changant les tailles."
+"Votre buggle est super contente ! Elle vient de trouver une grosse traînée "
+"baveuse sur le sol, certainement laissée par une grosse limace. Au bout de "
+"cette piste, la buggle est sûre de se régaler d'un bon jus de limace "
+"(représentée par un baggle)."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:11
-#: src/lessons/welcome/snake/Snake.html:46
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:52
-#: src/lessons/welcome/traversal/line/TraversalByLine.html:10
-#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:10
-#: src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:6
-msgid "Your turn..."
-msgstr "À vous de jouer..."
+#: src/lessons/welcome/methods/slug/SlugTracking.html:7
+msgid ""
+"To reach that goal, you had to write a boolean method <tt>isFacingTrail</"
+"tt>, which determines whether we are facing a green cell or not. Of course, "
+"if we are facing a wall, it should return false without bumping into it. You "
+"should make sure that this method has no <b>side effect</b>, i.e. that it "
+"does not change the state of the calling buggle nor of its world."
+msgstr ""
+"Pour arriver au résultat, vous devez écrire la méthode booléenne "
+"<code>isFacingTrail()</code>, qui permet de savoir si on est face à une case "
+"verte ou non. Bien sûr, si on est face à un mur, elle doit répondre faux "
+"sans se cogner. Il faudrait de plus que cette méthode soit <b>sans effet de "
+"bord</b>, c'est-à-dire qu'elle ne modifie ni la buggle qui l'appelle, ni le "
+"monde environnant."
 
-#. type: Content of: <h3>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:2
-msgid "(and methods to write)"
-msgstr "(et des méthodes à écrire)"
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:12
+msgid ""
+"Your tool to that end is the <code>getGroundColor()</code> that returns the "
+"color of the current cell. Just go to the cell you want to test and run that "
+"function.  [!java]You cannot test whether this color is equal to <code>Color."
+"green</code> with an <code>==</code> sign but instead you have to write "
+"something like <code>getGroundColor().equals(Color.green)</code>. This is "
+"because green is an <i>object</i> in Java, and <code>.equals()</code> is the "
+"way to go to test equality between Java objects.[/!]"
+msgstr ""
+"Votre outil pour cela est la méthode <code>getCouleurSol()</code> qui "
+"retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut "
+"vous rendre dans la case à tester avant d'appeler cette méthode. \n"
+"[!java]Vous ne pouvez pas simplement utiliser <code>==</code> pour tester si "
+"la couleur retournée est le vert, mais vous devez plutôt écrire quelque "
+"chose comme <code>getCouleurSol().equals(Color.green)</code>. C'est parce "
+"que les couleurs sont des <i>objets</i> en Java, et que <code>.equals()</"
+"code> est la marche à suivre pour tester l'égalité d'objets Java.[/!]"
 
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:4
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:20
 msgid ""
-"Here is yet another exercise where you have to reproduce the pattern "
-"provided in the \"Objective\" tab."
+"Complete the <code>isFacingTrail()</code> method (which gets called "
+"automatically)."
 msgstr ""
-"Voici de nouveau un exercice où il faut reproduire un motif donné dans "
-"l'onglet \"Objective\"."
+"Complétez la méthode <code>isFacingTrail()</code> qui sera appelée "
+"automatiquement comme il faut."
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/slug/SlugSnail.html:1
+msgid "Slugs and Snails"
+msgstr "Limaces et escargots"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:7
+#: src/lessons/welcome/methods/slug/SlugSnail.html:3
 msgid ""
-"This one is a bit more difficult than the one seen previously. Look for "
-"repeating patterns, even if the color changes, and write a method drawing "
-"each of them."
+"Yuhu! This time, your buggle found the tracks of much more preys! In the "
+"first world, that's a yummy Kitty Slug (leaving a pink trail) while on the "
+"second world, that's a big fat snail that awaits your buggle at the end of "
+"the orange trail."
 msgstr ""
-"Celui-ci est un peu plus difficile que ceux vus précédement. Cherchez les "
-"motifs qui se répètent, même si la couleur change, et faites une méthode "
-"dessinant chacun d'entre eux."
+"YES! Cette fois encore, votre buggle a débusqué de bonnes proies! Dans le "
+"premier monde, c'est une délicieuse limace Kitty (qui laisse des traces "
+"rose) tandis que dans le second monde, un bon gros escargot du désert attend "
+"la buggle au bout de sa piste orange."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:11
-msgid "Good luck!"
-msgstr "Bon courage !"
+#: src/lessons/welcome/methods/slug/SlugSnail.html:7
+msgid ""
+"You have to copy/paste your code again, and change it so that your methods "
+"take the color of the trail to follow as a parameter. Beside of this, your "
+"code should work as earlier."
+msgstr ""
+"Il vous faut copie/coller votre code encore une fois, et le modifier pour "
+"que vos méthodes prennent la couleur de piste à suivre en paramètre. À part "
+"cela, votre code devrait faire comme avant."
 
 #. type: Content of: <h2>
 #: src/lessons/welcome/bdr/BDR.html:1
@@ -5341,12 +5330,12 @@ msgstr ""
 "quelques détails à étudier."
 
 #. type: Content of: <h3>
-#: src/lessons/welcome/bdr/BDR.html:8
+#: src/lessons/welcome/bdr/BDR.html:9
 msgid "Conditionals without curly braces"
 msgstr "Conditionnelles sans accolades"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:10
+#: src/lessons/welcome/bdr/BDR.html:11
 msgid ""
 "There is one detail we omitted about the conditional syntax: if a branch "
 "contains only one instruction, then the curly braces become optional. So, "
@@ -5358,7 +5347,7 @@ msgstr ""
 "équivalents:"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:14
+#: src/lessons/welcome/bdr/BDR.html:15
 #, no-wrap
 msgid ""
 "if (<b>condition</b>) {\n"
@@ -5374,7 +5363,7 @@ msgstr ""
 "}"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:19
+#: src/lessons/welcome/bdr/BDR.html:20
 #, no-wrap
 msgid ""
 "if (<b>condition</b>) \n"
@@ -5388,34 +5377,36 @@ msgstr ""
 "    <b>quoiFaireSinon();</b>"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:24
+#: src/lessons/welcome/bdr/BDR.html:25
 msgid ""
-"But beware, this becomes dangerous if you chain the <tt>if</tt> instructions "
-"like this:"
+"Actually, you can do the same for loops body that are reduced to one "
+"instruction only.  But beware, this becomes dangerous if you chain the "
+"<tt>if</tt> instructions like this:"
 msgstr ""
-"Mais attention, ceci peut être dangereux si on enchaîne les <tt>if</tt> "
-"comme dans l'exemple suivant."
+"Vous pouvez faire de même avec les boucles dont le corps se réduit à une "
+"seule instruction. Mais attention, ceci peut être dangereux si on enchaîne "
+"les <tt>if</tt> comme dans l'exemple suivant."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:26
+#: src/lessons/welcome/bdr/BDR.html:27
 #, no-wrap
 msgid ""
 "if (isOverBaggle())    \n"
 "     if (x == 5)\n"
-"          turnLeft();\n"
+"          left();\n"
 "else\n"
-"     turnRight();\n"
+"     right();\n"
 "forward();"
 msgstr ""
-"if (isOverBaggle())    \n"
+"if (estSurBiscuit())    \n"
 "     if (x == 5)\n"
-"          turnLeft();\n"
+"          gauche();\n"
 "else\n"
-"     turnRight();\n"
-"forward();"
+"     droite();\n"
+"avance();"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:33
+#: src/lessons/welcome/bdr/BDR.html:34
 msgid ""
 "In fact, it does not turn right when there is no baggle on the ground AND x "
 "equals 5, but when the buggle found a baggle on the ground and x equals "
@@ -5430,50 +5421,52 @@ msgstr ""
 "précédemment) :"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:38
+#: src/lessons/welcome/bdr/BDR.html:39
 #, no-wrap
 msgid ""
 "if (isOverBaggle())    \n"
 "        if (x == 5)\n"
-"            turnLeft();\n"
+"            left();\n"
 "        else\n"
-"            turnRight();\n"
+"            right();\n"
 "forward();"
 msgstr ""
-"if (isOverBaggle())    \n"
+"if (estSurBiscuit())    \n"
 "        if (x == 5)\n"
-"            turnLeft();\n"
+"            gauche();\n"
 "        else\n"
-"            turnRight();\n"
-"forward();"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:45
-msgid ""
-"The first lesson of this is that the indentation is very helpful to help "
-"humans understanding, but it's of no importance for the actual meaning of "
-"the code. We could have written the following code and obtain the same "
-"result. But beware, if you want a human to read and review your code, you "
-"really want to indent it correctly. That's for example the case if you want "
-"a professor to read it (to grade it or to answer a question about it), or if "
-"you want to reuse your code later."
-msgstr ""
-"La première leçon, c'est que l'indentation aide les humains à comprendre, "
-"mais elle est sans importance pour la signification du code. On aurait tout "
-"aussi bien pu écrire le code suivant et obtenir le même résultat. Mais "
-"attention, si on veut qu'un humain puisse relire le code, l'indentation "
-"devient très importante voire indispensable. C'est par exemple le cas si "
-"votre code doit être relu par un professeur (pour qu'il le note ou pour lui "
-"poser une question), ou si vous comptez réutiliser votre code plus tard."
+"            droite();\n"
+"avance();"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:46
+msgid ""
+"The first lesson of this is that the indentation is very important to help "
+"humans understanding, even if it does not change the actual meaning of the "
+"code. We could have written the following code and obtain the same result. "
+"But if you want a human to read and review your code, you really want to "
+"indent it correctly. That's for example the case if you want a professor to "
+"read it (to grade it or to answer a question about it), or if you want to "
+"reuse your code later, or even if you need to debug your code yourself."
+msgstr ""
+"La première leçon, c'est que l'indentation est très importante pour que les "
+"humains puissent comprendre le code, mais elle ne change pas la "
+"signification du code pour la machine. On aurait tout aussi bien pu écrire "
+"le code suivant et obtenir le même résultat. Mais attention, si on veut "
+"qu'un humain puisse relire le code, l'indentation est quasi indispensable. "
+"C'est par exemple le cas si votre code doit être relu par un professeur "
+"(pour qu'il le note ou pour lui poser une question), ou si vous comptez "
+"réutiliser votre code plus tard, ou même si vous devez debugger votre propre "
+"code après l'avoir écrit."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:53
+#: src/lessons/welcome/bdr/BDR.html:54
 #, no-wrap
-msgid "if (isOverBaggle()) if (x == 5) turnLeft(); else turnRight(); forward();"
-msgstr "if (isOverBaggle()) if (x == 5) turnLeft(); else turnRight(); forward();"
+msgid "if (isOverBaggle()) if (x == 5) left(); else right(); forward();"
+msgstr "if (estSurBiscuit()) if (x == 5) gauche(); else droite(); avance();"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:55
+#: src/lessons/welcome/bdr/BDR.html:56
 msgid ""
 "The second lesson is that a <tt>else</tt> branch always connects to the "
 "closest <tt>if</tt>. This may be a bit troublesome in some case, and it may "
@@ -5485,30 +5478,30 @@ msgstr ""
 "ambiguïté."
 
 #. type: Content of: <h3>
-#: src/lessons/welcome/bdr/BDR.html:59
+#: src/lessons/welcome/bdr/BDR.html:61
 msgid "Chaining conditionals"
 msgstr "Enchaînements de conditionnelles"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:61
+#: src/lessons/welcome/bdr/BDR.html:63
 msgid "You sometimes want to ask the buggle something similar to:"
 msgstr ""
 "Il arrive que l'on veuille demander à la buggle quelque chose similaire à :"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:62
+#: src/lessons/welcome/bdr/BDR.html:64
 #, no-wrap
 msgid ""
 "if it's raining, take an umbrella;\n"
 "if not, and if it's a hot day, take a bottle of water;\n"
-"if not and if it's July 4th, take an american flag"
+"if not and if it's July 4th, take an American flag"
 msgstr ""
 "s'il pleut, prend un parapluie; \n"
 "si non, s'il fait chaud, prend une bouteille d'eau; \n"
 "si non, si nous sommes le 14 juillet, prend un drapeau français"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:66
+#: src/lessons/welcome/bdr/BDR.html:68
 msgid ""
 "The trap is that we want at most one of these actions to be taken. That is "
 "to say, if it's raining a very hot July 4th, we don't want the buggle to get "
@@ -5521,502 +5514,431 @@ msgstr ""
 "juste avec un parapluie. Le code suivant est donc faux."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:71
-#, no-wrap
-msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
-"}\n"
-"if (hot()) {\n"
-"    takeWater();\n"
-"} \n"
-"if (todayIsJuly4th()) {\n"
-"    takeFlag();\n"
-"}"
-msgstr ""
-"if (ilPleut()) {\n"
-"  prendreParapluie();\n"
-"}\n"
-"if (ilFaitChaud()) {\n"
-"  prendreDeLEau();\n"
-"} \n"
-"if (sommes14Juillet()) {\n"
-"  prendreDrapeau();\n"
-"}"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:81
+#: src/lessons/welcome/bdr/BDR.html:73
 #, no-wrap
 msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
+"[!java|scala]if (rainy())\n"
+"    takeUmbrella();\n"
+"if (hot())\n"
+"    takeWater();\n"
+"if (todayIsJuly4th())\n"
+"    takeFlag();[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
 "if hot():\n"
-"    takeWater()\n"
+"    takeWater()\n"
 "if todayIsJuly4th():\n"
-"    takeFlag()\n"
-msgstr ""
-"if ilPleut():\n"
-"    prendreParapluie()\n"
+"    takeFlag()[/!]"
+msgstr ""
+"[!java|scala]if (ilPleut())\n"
+"    prendreParapluie();\n"
+"if (ilFaitChaud())\n"
+"    prendreDeLEau();\n"
+"if (sommes14Juillet())\n"
+"    prendreDrapeau();[/!][!python]if ilPleut():\n"
+"    prendreParapluie()\n"
 "if ilFaitChaud():\n"
-"    prendreDeLEau()\n"
+"    prendreDeLEau()\n"
 "if sommes14Juillet():\n"
-"    prendreDrapeau()\n"
+"    prendreDrapeau()[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:90
+#: src/lessons/welcome/bdr/BDR.html:86
 msgid ""
 "Indeed, since the conditions are evaluated one after the other, there is a "
 "risk that you go to the July 4th march on a rainy day. Instead, we should "
-"use something like this:"
+"use something like this to ensure that once we found a true condition, we "
+"won't evaluate the next ones."
 msgstr ""
 "En effet, toutes les conditions sont évaluées les unes après les autres, et "
 "on risque donc d'aller au défilé un jour de pluie. À la place, il faut donc "
-"écrire quelque chose comme :"
+"écrire quelque chose comme ce qui suit pour s'assurer que si l'on trouve une "
+"condition vraie, on n'évalue pas les suivants."
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:94
+#: src/lessons/welcome/bdr/BDR.html:91
 #, no-wrap
 msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
+"[!java|scala]if (rainy()) {\n"
+"    takeUmbrella();\n"
 "} else {\n"
-"    if (hotDay()) {\n"
-"        takeWater();\n"
-"    } else {\n"
-"        if (todayIsJuly4th()) {\n"
-"            takeFlag();\n"
-"        }\n"
-"    }\n"
-"}"
-msgstr ""
-"if (ilPleut()) {\n"
-"    prendreParapluie();\n"
-"} else {\n"
-"    if (ilFaitChaud()) {\n"
-"        prendreDeLEau();\n"
-"    } else {\n"
-"        if (sommes14Juillet()) {\n"
-"            prendreDrapeau();\n"
-"        }\n"
-"    }\n"
-"}"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:106
-#, no-wrap
-msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
+"    if (hotDay()) {\n"
+"        takeWater();\n"
+"    } else {\n"
+"        if (todayIsJuly4th()) {\n"
+"            takeFlag();\n"
+"        }\n"
+"    }\n"
+"}[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
 "else:\n"
-"    if hotDay():\n"
-"        takeWater()\n"
-"    else:\n"
-"        if todayIsJuly4th():\n"
-"            takeFlag()\n"
-msgstr ""
-"if ilPleut():\n"
-"    prendreParapluie()\n"
+"    if hotDay():\n"
+"        takeWater()\n"
+"    else:\n"
+"        if todayIsJuly4th():\n"
+"            takeFlag()[/!]"
+msgstr ""
+"[!java|scala]if (ilPleut()) {\n"
+"    prendreParapluie();\n"
+"} else {\n"
+"    if (ilFaitChaud()) {\n"
+"        prendreDeLEau();\n"
+"    } else {\n"
+"        if (sommes14Juillet()) {\n"
+"            prendreDrapeau();\n"
+"        }\n"
+"    }\n"
+"}[/!][!python]if ilPleut():\n"
+"    prendreParapluie()\n"
 "else:\n"
-"    if ilFaitChaud():\n"
-"        prendreDeLEau()\n"
-"    else:\n"
-"        if sommes14Juillet():\n"
-"            prendreDrapeau()\n"
+"    if ilFaitChaud():\n"
+"        prendreDeLEau()\n"
+"    else:\n"
+"        if sommes14Juillet():\n"
+"            prendreDrapeau()[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:117
+#: src/lessons/welcome/bdr/BDR.html:111
 msgid ""
-"Such a cascade of conditionals are quite difficult to read, and it is better "
-"to omit the curly braces for the <tt>else</tt> statements. Some languages "
-"even introduce a specific construct for these <tt>else if</tt> (but Java "
-"doesn't)."
+"Unfortunately, such a cascade of conditionals is quite difficult to read. It "
+"is better to [!java|scala]omit the curly braces for the <tt>else</tt> "
+"statements. Some languages even introduce a specific construct for these "
+"<tt>else if</tt>, but not [!thelang].[/!] [!python]change the sub-blocks "
+"using the <code>elif</code> keyword to mark explicitly these \"else if\" "
+"branches.[/!]"
 msgstr ""
 "Une telle cascade de conditionnelles est un peu difficile à lire, et il est "
-"préférable d'omettre les accolades associées aux <tt>else</tt> comme suit. "
-"Il y a même certains langages qui introduisent un mot-clé spécial pour ces "
-"<tt>else if</tt> (mais pas Java)."
+"préférable\n"
+"[!java|scala] d'omettre les accolades associées aux <tt>else</tt> comme "
+"suit. Il y a même certains langages qui introduisent un mot-clé spécial pour "
+"ces <tt>else if</tt> (mais pas [!thelang]).[/!]\n"
+"[!python] d'introduire les sous-blocs avec le mot-clé <code>elif</code> "
+"(abréviation de «else if») pour expliciter ces branches «sinon si».[/!]"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:121
+#: src/lessons/welcome/bdr/BDR.html:118
 #, no-wrap
 msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
+"[!java|scala]if (rainy()) { \n"
+"    takeUmbrella();\n"
 "} else if (hotDay()) {\n"
-"    takeWater();\n"
+"    takeWater();\n"
 "} else if (todayIsJuly4th()) {\n"
-"    takeFlag();\n"
-"}"
-msgstr ""
-"if (ilPleut()) {\n"
-"  prendreParapluie();\n"
-"} else if (ilFaitChaud()) {\n"
-"  prendreDeLEau();\n"
-"} else if (sommes14Juillet()) {\n"
-"  prendreDrapeau();\n"
-"}"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:129
-msgid ""
-"Such a cascade of conditionals are quite difficult to read, and it is better "
-"to omit extra indentation for the <tt>else</tt> statements. In Python, there "
-"is a specific construct for this: <tt>elif</tt>."
-msgstr ""
-"Une telle cascade de conditionnelles est un peu difficile à lire, et il est\n"
-"préférable d'omettre les indentations supplémentaires associées aux\n"
-"<tt>else</tt> comme suit. Le mot-clé <tt>elif</tt> du langage Python permet "
-"de\n"
-"faire ceci facilement."
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/bdr/BDR.html:132
-#, no-wrap
-msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
+"    takeFlag();\n"
+"}[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
 "elif hotDay():\n"
-"    takeWater()\n"
+"    takeWater()\n"
 "elif todayIsJuly4th():\n"
-"    takeFlag()\n"
+"    takeFlag()[/!]"
 msgstr ""
-"if ilPleut():\n"
-"    prendreParapluie()\n"
+"[!java|scala]if (ilPleut()) { \n"
+"    prendreParapluie();\n"
+"} else if (ilFaitChaud()) {\n"
+"    prendreDeLEau();\n"
+"} else if (sommes14Juillet()) {\n"
+"    prendreDrapeau();\n"
+"}[/!][!python]if ilPleut():\n"
+"    prendreDrapeau()\n"
 "elif ilFaitChaud():\n"
-"    prendreDeLEau()\n"
+"    prendreDeLEau()\n"
 "elif sommes14Juillet():\n"
-"    prendreDrapeau()\n"
+"    prendreDrapeau()[/!]"
 
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/bdr/BDR.html:140
-msgid "Graffitis in the Buggle World"
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:131
+msgid "Graffiti in the Buggle World"
 msgstr "Les graffitis dans le monde des buggles"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:142
+#: src/lessons/welcome/bdr/BDR.html:133
 msgid ""
-"Buggles can write graffitis on the ground of their world. For that, they use "
+"Buggles can tag graffitis on the ground of their world. For that, they use "
 "the four following methods:"
 msgstr ""
 "Les buggles peuvent écrire des choses par terre dans leur monde. Pour ce "
 "faire, elles utilisent les quatre méthodes suivantes:"
 
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:146
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:137
 msgid ""
-"<code>boolean isOverMessage()</code>: returns <code>true</code> if and only "
-"if there is a message on the ground."
+"<code>[!java]boolean[/!] isOverMessage()[!scala]:Boolean[/!]</code>: returns "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> if and only if there is "
+"a message on the ground."
 msgstr ""
-"<code>boolean isOverMessage()</code> : renvoie vrai (<code>true</code>) si "
-"et seulement s'il y a un message écrit par terre."
+"<code>[!java]boolean[/!] estSurMessage()[!scala]:Boolean[/!]</code>: renvoie "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> si et seulement s'il y a "
+"un message écrit par terre."
 
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:148
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:140
 msgid ""
-"<code>boolean isOverMessage()</code>: returns <code>True</code> if and only "
-"if there is a message on the ground."
+"<code>[!java]String[/!] readMessage()[!scala]: String[/!]</code>: returns "
+"the message written on the ground (or an empty string if nothing is written)."
 msgstr ""
-"<code>boolean isOverMessage()</code> : renvoie vrai (<code>True</code>) si "
-"et seulement s'il y a un message écrit par terre."
+"<code>[!java]String [/!]readMessage()[!java]: String[/!]</code> : renvoie le "
+"message qu'il y a écrit par terre (s'il y a rien, on obtient une chaîne "
+"vide)."
 
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:150
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:142
 msgid ""
-"<code>String readMessage()</code>: returns the message written on the ground "
-"(or an empty string if nothing is written)."
+"<code>[!java]void[/!] writeMessage([!java]String [/!]msg[!scala]: "
+"String[/!])</code>: writes the specified message down on the ground. If "
+"there is already a message on the ground, the new content is added at the "
+"end of the existing message."
 msgstr ""
-"<code>String readMessage()</code> : renvoie le message qu'il y a écrit par "
-"terre (s'il y a rien, on obtient une chaîne vide)."
+"<code>[!java]void[/!] writeMessage([!java]String [/!]msg[!java]: "
+"String[/!])</code> : écrit le message spécifié en argument par terre. S'il y "
+"a déjà quelque chose écrit par terre, on ajoute le nouveau message à la fin "
+"du précédent."
 
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:152
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:145
 msgid ""
-"<code>void writeMessage(String msg)</code>: writes the specified message "
-"down on the ground. If there is already a message on the ground, the new "
-"content is added at the end of the existing message."
+"<code>[!java]void [/!]clearMessage()</code>: clears what is written on the "
+"ground."
 msgstr ""
-"<code>void writeMessage(String msg)</code> : écrit le message spécifié en "
-"argument par terre. S'il y a déjà quelque chose écrit par terre, on ajoute "
-"le nouveau message à la fin du précédent."
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:155
-msgid "<code>void clearMessage()</code>: clears what is written on the ground."
-msgstr "<code>void clearMessage()</code> : efface ce qui est écrit par terre."
+"<code>[!java]void [/!]clearMessage()</code> : efface ce qui est écrit par "
+"terre."
 
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:159
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:149
 msgid ""
-"<a name=\"Objectives\">The goal is then to organize a BDR game between the "
-"buggles by learning them to move according to the instructions written on "
-"the ground. These instructions are messages written on the ground, with the "
-"following signification:"
+"The goal is then to organize a BDR game between the buggles by learning them "
+"to move according to the instructions written on the ground. These "
+"instructions are messages written on the ground, with the following "
+"signification:"
 msgstr ""
-"<a name=\"Objectifs\"> L'objectif est donc d'organiser une partie de BDR "
-"entre les buggles en leur apprenant à bouger en fonction des indications "
-"écrites par terre.  Ces indications sont des messages au sol, avec le code "
-"suivant:"
+"L'objectif est donc d'organiser une partie de BDR entre les buggles en leur "
+"apprenant à bouger en fonction des indications écrites par terre.  Ces "
+"indications sont des messages au sol, avec le code suivant:"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:127
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:155 src/lessons/welcome/bdr/BDR2.html:138
 msgid "Message"
 msgstr "Indication"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:166 src/lessons/welcome/bdr/BDR2.html:128
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:156 src/lessons/welcome/bdr/BDR2.html:139
 msgid "What to do"
 msgstr "Quoi faire"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:167
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:157
 msgid "Mnemonic"
 msgstr "Mnémotechnique"
 
 #. type: Content of: <table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:130
+#: src/lessons/welcome/bdr/BDR.html:159 src/lessons/welcome/bdr/BDR2.html:141
 #: src/lessons/turmites/turmitecreator/TurmiteCreator.html:30
 #: src/lessons/turmites/turmitecreator/TurmiteCreator.html:33
 msgid "R"
 msgstr "R"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:130
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:159 src/lessons/welcome/bdr/BDR2.html:141
 msgid "Turn right and move one step forward"
 msgstr "Tourner à droite et avancer d'une case"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:159
 msgid "Right"
 msgstr "Right"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:131
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160 src/lessons/welcome/bdr/BDR2.html:142
 msgid "L"
 msgstr "L"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:131
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160 src/lessons/welcome/bdr/BDR2.html:142
 msgid "Turn left and move one step forward"
 msgstr "Tourner à gauche et avancer d'une case"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160
 msgid "Left"
 msgstr "Left"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171 src/lessons/welcome/bdr/BDR2.html:132
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161 src/lessons/welcome/bdr/BDR2.html:143
 msgid "I"
 msgstr "I"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161
 msgid "Turn back (U-turn) and move one step forward"
-msgstr "Tourner en sens inverse (demi tour) et avancer d'une case"
+msgstr "Se retourner (demi-tour) et avancer d'une case"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161
 msgid "Inverse"
 msgstr "Inverse"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173 src/lessons/welcome/bdr/BDR2.html:134
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163 src/lessons/welcome/bdr/BDR2.html:145
 msgid "A"
 msgstr "A"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173 src/lessons/welcome/bdr/BDR2.html:134
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163 src/lessons/welcome/bdr/BDR2.html:145
 msgid "Move one step forward"
 msgstr "Avancer d'une case"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163
 msgid "First letter of the alphabet"
 msgstr "Première lettre de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174 src/lessons/welcome/bdr/BDR2.html:135
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164 src/lessons/welcome/bdr/BDR2.html:146
 msgid "B"
 msgstr "B"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174 src/lessons/welcome/bdr/BDR2.html:135
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164 src/lessons/welcome/bdr/BDR2.html:146
 msgid "Move two steps forward"
 msgstr "Avancer de deux cases"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164
 msgid "Second letter of the alphabet"
 msgstr "Deuxième lettre de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175 src/lessons/welcome/bdr/BDR2.html:136
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:147
 msgid "C"
 msgstr "C"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175 src/lessons/welcome/bdr/BDR2.html:136
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:147
 msgid "Move three steps forward"
 msgstr "Avancer de trois cases"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165
 msgid "Third letter of the alphabet"
 msgstr "Troisième lettre de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177 src/lessons/welcome/bdr/BDR2.html:141
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167 src/lessons/welcome/bdr/BDR2.html:152
 msgid "Z"
 msgstr "Z"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177 src/lessons/welcome/bdr/BDR2.html:141
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167 src/lessons/welcome/bdr/BDR2.html:152
 msgid "Move one step backward"
 msgstr "Reculer d'une case"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167
 msgid "One letter before the end of the alphabet"
 msgstr "A une lettre de la fin de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178 src/lessons/welcome/bdr/BDR2.html:142
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168 src/lessons/welcome/bdr/BDR2.html:153
 msgid "Y"
 msgstr "Y"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178 src/lessons/welcome/bdr/BDR2.html:142
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168 src/lessons/welcome/bdr/BDR2.html:153
 msgid "Move two steps backward"
 msgstr "Reculer de deux cases"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168
 msgid "Two letters before the end of the alphabet"
 msgstr "A deux lettres de la fin de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179 src/lessons/welcome/bdr/BDR2.html:143
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:154
 msgid "X"
 msgstr "X"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179 src/lessons/welcome/bdr/BDR2.html:143
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:154
 msgid "Move three steps backward"
 msgstr "Reculer de trois cases"
 
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169
 msgid "Three letters before the end of the alphabet"
 msgstr "A trois lettres de la fin de l'alphabet"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><p>
-#: src/lessons/welcome/bdr/BDR.html:182 src/lessons/welcome/bdr/BDR2.html:149
-msgid "In any other case, you should stop"
-msgstr "Dans tous les autres cas, il faut s'arrêter."
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:184
-msgid ""
-"Write the code of the dance in the <code>run()</code> method which prototype "
-"is already in the editor."
-msgstr ""
-"Écrivez le code de la danse dans la méthode <code>run()</code> dont le "
-"prototype se trouve déjà dans l'éditeur."
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:158
+msgid "<i>(anything else)</i>"
+msgstr "<i>(n'importe quoi d'autre)</i>"
 
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:187
-msgid ""
-"Write the code of the dance directly in the editor, out of any function."
-msgstr ""
-"Ecrivez directement le code de la danse dans l'éditeur, en dehors de toute "
-"fonction."
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:158
+msgid "Stop dancing."
+msgstr "Arrêter de dancer."
 
-#. type: Content of: <p><a><h3>
-#: src/lessons/welcome/bdr/BDR.html:190
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:173
 msgid "Indications"
 msgstr "Indications"
 
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:192
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:175
 msgid ""
 "This exercise may seem a bit complex at the first glance, but it comes down "
-"to summarizing the information above in a sequence of conditionals."
+"to summarizing the information of the table in a sequence of conditionals."
 msgstr ""
 "Cet exercice peut sembler un peu compliqué, mais il s'agit principalement de "
 "traduire le contenu du tableau ci-dessus dans un enchaînement de "
 "conditionnelles."
 
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:197
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:178
 msgid ""
-"The first subtlety is that we use the <code>char getIndication()</code> "
-"instead of <code>String readMessage()</code>. This method, only known by the "
-"buggles of this exercise, return the first char of the message written on "
-"the ground (or ' ' if nothing is written down)."
-msgstr ""
-"La première subtilité est que nous utiliserons la méthode <code>char "
-"getIndication()</code> à la place de <code>String readMessage()</code>. "
-"Cette méthode, qui n'est connue que des buggles des exercice BDR, renvoie le "
-"premier caractère du message au sol (ou ' ' s'il n'y a rien d'écrit au sol)."
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:202
-msgid ""
-"The other subtlety is to keep working as long as there is some work to do, i."
-"e., as long as we did not find a cell which content is not described in the "
-"table. The easier for that is to use a boolean variable (<code>finished</"
-"code>)  that is initialized to <code>false</code> as termination condition "
-"for the loop.  As soon as the buggle find a cell with a value not described "
-"in the table, the boolean variable is set to <code>false</code>.  Thus the "
+"You have to keep dancing as long as there is some dancing steps to do, i.e., "
+"as long as we are not in cell which content is not described in the table.  "
+"The easier for that is to use a boolean variable (<code>finished</code>)  as "
+"termination condition to a <code>while</code> loop.  It should be "
+"initialized to <code>[!java|scala]false[/!][!python]False[/!]</code>, and "
+"switched to <code>[!java|scala]true[/!][!python]True[/!]</code> as soon as "
+"the buggle find a cell with a value not described in the table.  Thus the "
 "loop, will stop and the program will terminate."
 msgstr ""
-"L'autre subtilité est de travailler tant qu'on du travail à faire, i.e. tant "
-"qu'on a pas trouvé une case n'étant pas décrite dans le tableau. Le plus "
-"simple pour cela est d'utiliser une variable booléenne (<code>fini</code>) "
-"en condition d'arrêt d'une boucle. Cette variable est initialisée à la "
-"valeur faux (<code>false</code>). Si on trouve une case ne répondant à "
-"aucune ligne du tableau, on change la valeur de cette variable à vrai "
-"(<code>true</code>. Cela arrête la boucle, et le programme s'arrête."
+"Vous devez continuer à danser tant qu'il reste des pas de danse à faire. c-à-"
+"d tant qu'on a pas trouvé une case n'étant pas décrite dans le tableau. Le "
+"plus simple pour cela est d'utiliser une variable booléenne (<code>fini</"
+"code>) en condition d'arrêt d'une boucle while. Cette variable est "
+"initialisée à la valeur faux (<code>[!java|scala]false[/!][!"
+"python]False[/!]</code>). Si on trouve une case ne répondant à aucune ligne "
+"du tableau, on change la valeur de cette variable à vrai (<code>[!java|"
+"scala]true[/!][!python]True[/!]</code>). Cela arrête la boucle, et le "
+"programme."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:188
+msgid ""
+"Another subtlety is that detecting if strings are equals is a bit annoying "
+"in Java.  So, we use the <code>char getIndication()</code> instead of "
+"<code>String readMessage()</code>.  This method, only known by the buggles "
+"of this exercise, returns the first char of the message written on the "
+"ground (or ' ' -- the space char -- if nothing is written down). It enables "
+"to work with chars instead of strings, that is much simpler in Java."
+msgstr ""
+"Une autre subtilité est que déterminer si des chaînes de caractères est un "
+"peu pénible en Java. Nous utiliserons donc la méthode <code>char "
+"getIndication()</code> à la place de <code>String litMessage()</code>. Cette "
+"méthode, qui n'est connue que des buggles des exercice BDR, renvoie le "
+"premier caractère du message au sol (ou ' ' --une espace-- s'il n'y a rien "
+"d'écrit au sol). Cela nous permet de travailler avec des caractères "
+"(<code>char</code>), qui sont moins pénibles que les chaînes."
 
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:209
-msgid ""
-"The other subtlety is to keep working as long as there is some work to do, i."
-"e., as long as we did not find a cell which content is not described in the "
-"table. The easier for that is to use a boolean variable (<code>finished</"
-"code>)  that is initialized to <code>False</code> as termination condition "
-"for the loop.  As soon as the buggle find a cell with a value not described "
-"in the table, the boolean variable is set to <code>False</code>.  Thus the "
-"loop, will stop and the program will terminate."
-msgstr ""
-"L'autre subtilité est de travailler tant qu'on du travail à faire, i.e. tant "
-"qu'on a pas trouvé une case n'étant pas décrite dans le tableau. Le plus "
-"simple pour cela est d'utiliser une variable booléenne (<code>fini</code>) "
-"en condition d'arrêt d'une boucle. Cette variable est initialisée à la "
-"valeur faux (<code>False</code>). Si on trouve une case ne répondant à "
-"aucune ligne du tableau, on change la valeur de cette variable à vrai "
-"(<code>True</code>. Cela arrête la boucle, et le programme s'arrête."
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:217
-msgid ""
-"The functions having <code>void</code> as return type can contain some "
-"<tt>return</tt> without any associated value. It interrupts immediately "
-"their execution."
-msgstr ""
-"Les fonctions dont le type de retour est <tt>void</tt> peuvent contenir des "
-"<tt>return</tt> sans valeur associée. Cela interrompt immédiatement leur "
-"exécution."
-
-#. type: Content of: <p><a><h3>
-#: src/lessons/welcome/bdr/BDR.html:221
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:195
 msgid "Tips and Hints"
 msgstr "Trucs et astuces"
 
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:223
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:197
 msgid ""
-"If you fail understanding why the buggle does not execute the expected "
+"If you fail to understand why the buggle does not execute the expected "
 "steps, try adding <code>brushDown()</code> in your method. This asks the "
 "buggle to put down a brush leaving a trail when it moves. It should help you "
 "understanding its trajectory, but do not forget to remove this call when you "
@@ -6024,15 +5946,15 @@ msgid ""
 "asked to let the buggle dance, not to vandalize the dance floor."
 msgstr ""
 "Si vous ne parvenez plus à comprendre pourquoi votre buggle n'exécute pas "
-"les pas de danse demandés, essayez d'ajouter <code>brushDown()</code> dans "
-"votre méthode. Cela demandera à la buggle de poser un crayon par terre, "
-"laissant une trace au sol quand elle avance. Cela devrait vous aider à "
-"suivre sa trajectoire, mais pensez à retirer cette appel lorsque vous voulez "
-"tester si votre solution marche : on vous demande de faire danser les "
+"les pas de danse demandés, essayez d'ajouter <code>baisseBrosse()</code> "
+"dans votre méthode. Cela demandera à la buggle de poser une brosse par "
+"terre, laissant une trace au sol quand elle avance. Cela devrait vous aider "
+"à suivre sa trajectoire, mais pensez à retirer cette appel lorsque vous "
+"voulez tester si votre solution marche : on vous demande de faire danser les "
 "buggles, pas de dégrader le dance floor."
 
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:230
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:204
 msgid "When your program finally works, move on to the next exercise."
 msgstr "Quand votre programme fonctionne enfin, passez à l'exercice suivant."
 
@@ -6042,7 +5964,7 @@ msgid "Buggle Dance Revolution 2 (BDR2)"
 msgstr "Buggle Dance Revolution 2 (BDR2)"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR2.html:3
+#: src/lessons/welcome/bdr/BDR2.html:4
 msgid ""
 "BDR is cool, but it's a bit chaotic. First, the buggles giggle in any "
 "directions, and then the code you had to write to let them move is rather "
@@ -6057,12 +5979,12 @@ msgstr ""
 "profiterons de cette accalmie pour nettoyer un peu le code grâce aux "
 "nouveaux éléments que nous allons maintenant étudier."
 
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/bdr/BDR2.html:9
-msgid "<tt>switch</tt> conditionals"
-msgstr "Branchement conditionnel <tt>switch</tt>"
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR2.html:10
+msgid "[!java]<code>switch</code> conditionals[/!][!scala]Pattern matching[/!]"
+msgstr "[!java]Conditionnelle <code>switch</code>[/!][!scala]Les filtrages[/!]"
 
-#. type: Content of: <p><p>
+#. type: Content of: <p>
 #: src/lessons/welcome/bdr/BDR2.html:12
 msgid ""
 "The hardest part of previous code is certainly the conditional cascading. "
@@ -6072,53 +5994,70 @@ msgstr ""
 "conditionnelles. Quelque part dans votre programme, vous avez sans doute "
 "écrit quelque chose comme:"
 
-#. type: Content of: <p><p><pre>
+#. type: Content of: <p><pre>
 #: src/lessons/welcome/bdr/BDR2.html:15
 #, no-wrap
 msgid ""
-"if (getIndication() == 'R') {\n"
-"  turnRight();\n"
+"if ([!java]getIndication() == 'R'[/!][!scala]readMessage() == \"R\"[/!]) {\n"
+"  right();\n"
 "  forward();\n"
-"} else if (getIndication() == 'L') {\n"
-"  turnLeft();\n"
+"} else if ([!java]getIndication() == 'L'[/!][!scala]readMessage() == \"L\"[/!]) {\n"
+"  left();\n"
 "  forward();\n"
-"} else if (getIndication() == 'I') {\n"
-"  turnBack();\n"
+"} else if ([!java]getIndication() == 'I'[/!][!scala]readMessage() == \"I\"[/!]) {\n"
+"  back();\n"
 "  forward();\n"
-"/* other else if */\n"
+"<span class=\"comment\">/* other else if */</span>\n"
 "} else {\n"
-"  return;\n"
+"  finished = true;\n"
 "}\n"
 msgstr ""
-"if (getIndication() == 'R') {\n"
-"  turnRight();\n"
-"  forward();\n"
-"} else if (getIndication() == 'L') {\n"
-"  turnLeft();\n"
-"  forward();\n"
-"} else if (getIndication() == 'I') {\n"
-"  turnBack();\n"
-"  forward();\n"
-"/* d'autres else if */\n"
+"if ([!java]getIndication() == 'R'[/!][!scala]litMessage() == \"R\"[/!]) {\n"
+"  droite();\n"
+"  avance();\n"
+"} else if ([!java]getIndication() == 'L'[/!][!scala]litMessage() == \"L\"[/!]) {\n"
+"  gauche();\n"
+"  avance();\n"
+"} else if ([!java]getIndication() == 'I'[/!][!scala]litMessage() == \"I\"[/!]) {\n"
+"  retourne();\n"
+"  avance();\n"
+"<span class=\"comment\">/* d'autre if */</span>\n"
 "} else {\n"
-"  return;\n"
+"  fini = true;\n"
 "}\n"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:31
+#. type: Content of: <p><p>
+#: src/lessons/welcome/bdr/BDR2.html:30
 msgid ""
 "When you review this code, it may not be clear at the first glance that it "
-"is simply a choice with 4 branches depending on the value of "
-"getIndication(). To improve this, we will use a <code>switch</code> "
-"construct, which Java syntax is the following:"
-msgstr ""
-"Quand on relit ce programme, on ne voit pas forcément tout de suite qu'il "
-"s'agit simplement d'un choix à 4 branches selon la valeur de "
-"getIndication(). Pour faire mieux, on va utiliser la construction "
-"<tt>switch</tt>, dont la syntaxe est la suivante:"
+"is simply a choice with 4 branches depending on the value of [!"
+"java]getIndication()[/!][!scala]readMessage()[/!].  To improve this, we will "
+"use a [!java]<code>switch</code> construct, which Java syntax is the "
+"following:[/!] [!scala] pattern matching, which is a very powerful construct "
+"that greatly generalizes the <code>if</code>. It is arguably one one the "
+"major advantages of Scala when compared to languages such as Java or "
+"python.  It is not new either, as other languages such as OCaml or Haskell "
+"offer this feature since long, but still.  It's really cool![/!]"
+msgstr ""
+"À la première lecture du code, il n'est pas évident qu'il ne s'agit que d'un "
+"choix avec 4 branches en fonction du résultat de [!java]getIndication()[/!][!"
+"scala]litMessage()[/!].\n"
+"Pour améliorer ceci, nous allons utiliser [!java]un <code>switch</code>, "
+"dont la syntaxe est la suivante en Java.[/!]\n"
+"[!scala] un filtrage (pattern matching en anglais), qui est une construction "
+"très agréable qui généralisant le <code>if</code>. Il s'agit sans aucun "
+"doute de l'un des avantages majeurs du langage Scala par rapport à d'autres "
+"tels que le Java ou le Python. Cette construction n'est cependant pas "
+"révolutionnaire puisqu'elle existe depuis assez longtemps dans des langages "
+"comme OCaml ou Haskell, mais il n'empêche. Elle est carrément cool![/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR2.html:39
+msgid "[/!] [!java]"
+msgstr "[/!] [!java]"
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:37
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:43
 #, no-wrap
 msgid ""
 "switch (<b>expression</b>) {\n"
@@ -6151,8 +6090,8 @@ msgstr ""
 "    <b>queFaireSiExpressionVautAucuneDesValeursProposees();</b>\n"
 "}"
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:53
+#. type: Content of: <p><p>
+#: src/lessons/welcome/bdr/BDR2.html:58
 msgid ""
 "Observe that each branch of a <tt>switch</tt> must be ended by a "
 "<code>break</code>. If you forget this, the machine keeps going and execute "
@@ -6165,8 +6104,8 @@ msgstr ""
 "le switch. Il y a même quelques <b>très rares</b> cas où ce comportement est "
 "pratique."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:58
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:63
 msgid ""
 "It is then possible to rewrite previous BDR code in a cleaner way using the "
 "<tt>switch</tt> construct:"
@@ -6174,21 +6113,21 @@ msgstr ""
 "On peut réécrire le code BDR précédent bien plus clairement grâce à la "
 "construction <tt>switch</tt> de la façon suivante."
 
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:61
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:66
 #, no-wrap
 msgid ""
 "switch (getIndication()) {\n"
 "  case 'R':\n"
-"    turnRight(); \n"
+"    right(); \n"
 "    forward(); \n"
 "    break;\n"
 "  case 'L':\n"
-"    turnLeft();\n"
+"    left();\n"
 "    forward(); \n"
 "    break;\n"
-"  case 'U':\n"
-"    turnBack();\n"
+"  case 'I':\n"
+"    back();\n"
 "    forward();\n"
 "    break;\n"
 "  default: \n"
@@ -6197,453 +6136,311 @@ msgid ""
 msgstr ""
 "switch (getIndication()) {\n"
 "  case 'R':\n"
-"    turnRight(); \n"
-"    forward(); \n"
+"    droite(); \n"
+"    avance(); \n"
 "    break;\n"
 "  case 'L':\n"
-"    turnLeft();\n"
-"    forward(); \n"
+"    gauche();\n"
+"    avance(); \n"
 "    break;\n"
-"  case 'U':\n"
-"    turnBack();\n"
-"    forward();\n"
+"  case 'I':\n"
+"    retourne();\n"
+"    avance();\n"
 "    break;\n"
 "  default: \n"
 "    return;\n"
 "}"
 
-#. type: Content of: <p><p><p><p><h2>
-#: src/lessons/welcome/bdr/BDR2.html:79
-msgid "Variables shared between methods"
-msgstr "Variables partagées par les méthodes"
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:82
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:84
+#, no-wrap
 msgid ""
-"Another issue in your code is that it begins to be a bit long to be written "
-"as a single method. We would like to split it up in two methods:"
+"<i>expression</i> <b>match</b> {\n"
+"  <b>case</b> <i>possible value</i> <b>=></b> instructions\n"
+"  <b>case</b> <i>other value</i>     <b>=></b> other instructions\n"
+"  <b>case</b> <i>another value</i> <b>=></b> yet another instructions\n"
+"  <b>case _                 =></b> default instructions\n"
+"}\n"
 msgstr ""
-"Un autre problème de votre code est qu'il commence à être un peu long pour "
-"être dans une seule fonction. On voudrait découper en deux méthodes:"
+"<i>expression</i> <b>match</b> {\n"
+"  <b>case</b> <i>valeur possible</i>  <b>=></b> instructions\n"
+"  <b>case</b> <i>autre valeur</i>     <b>=></b> d'autres instructions\n"
+"  <b>case</b> <i>troisieme valeur</i> <b>=></b> encore d'autres instructions\n"
+"  <b>case _                 =></b> instructions par défaut\n"
+"}\n"
 
-#. type: Content of: <p><p><p><p><p><ul><li>
-#: src/lessons/welcome/bdr/BDR2.html:85
-msgid ""
-"<code>danceOneStep()</code> would take care of achieving a single dance step"
-msgstr "<code>danceOneStep()</code> s'occuperait de faire un pas de danse"
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:91
+msgid ""
+"The expression provided before the keyword <code>match</code>, and then the "
+"branches are evaluated one after the other until we find one which value "
+"provided between <code>case</code> and <code>=&gt</code> is equal to the "
+"expression's value.  The <code>_</code> symbol acts as a wildcard, so the "
+"<code>_</code> branch <i>always</i> matches.  Here is an example where a "
+"variable <code>name</code> is matched."
+msgstr ""
+"L'expression fournie avant le mot-clé <code>match</code> est évaluée, et "
+"ensuite, les branches sont évaluées les unes après les autres jusqu'à en "
+"trouver une où la valeur entre le <code>case</code> et le <code>=></code> "
+"correspond à la valeur de l'expression. Le symbole <code>_</code> agit comme "
+"un joker qui correspond à tout. Cela veut dire que la dernière ligne telle "
+"qu'elle est écrite correspond toujours à la valeur fournie, quelle qu'elle "
+"soit. Voici un petit exemple où une variable <code>nom</code> est mis en "
+"correspondance."
 
-#. type: Content of: <p><p><p><p><p><ul><li>
-#: src/lessons/welcome/bdr/BDR2.html:86
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:96
+#, no-wrap
 msgid ""
-"<code>run()</code> would take care of the dance as a whole. It would do the "
-"steps while we didn't encounter a cell not asking any further move."
+"name match {\n"
+"  case \"Martin\" => println(\"Hello Martin, how are you?\")\n"
+"  case \"Gerald\" => println(\"Hey Gerald! How are you doing?\")\n"
+"  case _            => println(\"Welcome stranger.\")\n"
+"}"
 msgstr ""
-"<code>run()</code> s'occuperait de faire la danse en entier, c'est à dire "
-"de\n"
-"faire des pas de danse tant que l'on n'est pas arrivé à une case ne "
-"demandant pas d'aller plus loin."
+"nom match {\n"
+"  case \"Martin\" => println(\"Salut Martin, comment vas-tu?\")\n"
+"  case \"Gerald\" => println(\"He Gerald! Ça va?\")\n"
+"  case _            => println(\"Bonjour, étranger.\")\n"
+"}"
 
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:90
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:102
 msgid ""
-"The difficulty is to make sure that <tt>danceOneStep()</tt> keeps <tt>run()</"
-"tt> informed that there is no further dance step to achieve. The simpler "
-"solution is to have a boolean function visible from both methods indicating "
-"whether there is more steps to do or if we're done. For that, we have to "
-"write out the following of any method:"
+"It is possible to have more than one instruction per branch, and merge "
+"branches when the values are separated by a | symbol."
 msgstr ""
-"Le problème est de faire en sorte que <tt>danceOneStep()</tt> prévienne\n"
-"<tt>run()</tt> qu'il n'y a plus de pas possible. La solution la plus simple "
-"est\n"
-"encore d'avoir une variable booléenne visible depuis les deux fonctions\n"
-"indiquant s'il reste des pas à faire, ou si on a fini. On écrira donc en "
-"dehors\n"
-"de toute méthode :"
+"Il est aussi possible d'avoir plusieurs instructions par branches, et même "
+"d'avoir plusieurs valeurs sur une branche donnée, séparées par le caractère "
+"<code>|</code>."
 
-#. type: Content of: <p><p><p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:95
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:104
 #, no-wrap
-msgid "boolean moreMusic = true;"
-msgstr "boolean moreMusic = true;"
-
-#. type: Content of: <p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:97
 msgid ""
-"Note that it is possible to write variable declarations out of any methods, "
-"but that instructions must be in a method. In Java such <i>global</i> "
-"variables are called <b>fields</b>."
+"name match {\n"
+"  case \"Martin\" | \"Gerald\" => println(\"Hello \"+name+\", how are you?\"); openTheDoor()\n"
+"  case _                            => println(\"Hello stranger. Please do not pass.\"); lockTheDoor()\n"
+"}"
 msgstr ""
-"Notez que s'il est possible d'écrire des déclarations en dehors des "
-"méthodes, les instructions doivent obligatoirement être placées dans des "
-"méthodes. En Java, on appelle ces variables <i>globales</i> à plusieurs "
-"méthodes des <b>champs</b>."
+"nom match {\n"
+"  case \"Martin\" | \"Gerald\" => println(\"Bonjour \"+nom+\", entre.\"); ouvreLaPorte()\n"
+"  case _                            => println(\"Bonjour étranger. Passe ton chemin sans entrer.\"); fermeLaPorte()\n"
+"}"
 
-#. type: Content of: <p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:101
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:109
 msgid ""
-"Then, the <tt>danceOneStep()</tt> must be changed to update this variable to "
-"<tt>false</tt> when there is nothing more to do. For that, simply add "
-"<code>moreMusic = false;</code> before any <tt>return</tt>."
+"You can even add guards to your branches. These are extra conditions that "
+"must be respected for the branch to get applied. This is handy if you want "
+"match on value ranges, as follows."
 msgstr ""
-"Ensuite, la fonction <tt>danceOneStep()</tt> doit être modifiée pour mettre\n"
-"cette valeur à <tt>false</tt> quand il n'y a plus rien à faire. Pour cela,\n"
-"ajoutez simplement <code>moreMusic = false;</code> avant tout <tt>return</"
-"tt>."
-
-#. type: Content of: <p><p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:105
-msgid "It is then possible to use the following <tt>run()</tt> method:"
-msgstr "On peut alors utiliser la fonction <tt>run()</tt> suivante:"
+"Il est même possible d'ajouter des gardes à vos branches. Il s'agit de "
+"conditions supplémentaires qui doivent être respectées pour que la branche "
+"soit appliquée. C'est par exemple pratique pour faire du filtrage sur un "
+"ensemble de valeurs."
 
-#. type: Content of: <p><p><p><p><p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:106
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:111
 #, no-wrap
 msgid ""
-"public void run() {\n"
-"  while (moreMusic)\n"
-"    danseOneStep();\n"
+"age match {\n"
+"  case i if i<10 => println(\"Hey kid!\")\n"
+"  case i if i<20 => println(\"Hey dude!\")\n"
+"  case i if i<30 => println(\"Hello young man\")\n"
+"  case _           => println(\"Hello Sir\")\n"
 "}"
 msgstr ""
-"public void run() {\n"
-"  while (moreMusic)\n"
-"    danceOneStep();\n"
+"age match {\n"
+"  case i if i<10 => println(\"Salut gamin!\")\n"
+"  case i if i<20 => println(\"Salut mec\")\n"
+"  case i if i<30 => println(\"Bonjour jeune home\")\n"
+"  case _           => println(\"Bonjour monsieur\")\n"
 "}"
 
-#. type: Content of: <a>
-#: src/lessons/welcome/bdr/BDR2.html:111
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:24
-msgid "<a name=\"Objectives\">"
-msgstr "<a name=\"Objectifs\">"
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:112
-msgid "Apply the improvement we just saw to rewrite your buggle code."
-msgstr ""
-"Réécrivez le code des buggles en appliquant les améliorations que nous "
-"venons de voir."
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:114
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:117
 msgid ""
-"You don't have to write the <tt>run()</tt> method since the buggle already "
-"know it. If you put it anyway, the compiler will complain about this "
-"multiple definition without noticing that both declarations match. Simply "
-"declare the variable <tt>moreMusic</tt> and the <tt>danceOneStep()</tt> "
-"method."
+"Note that there is no need to check whether the value is higher than 10 on "
+"the second line because the first matching branch is used. So, if the second "
+"branch gets evaluated, then the first one did not match."
 msgstr ""
-"Vous n'avez pas à écrire la fonction <tt>run</tt>, que les buggles "
-"connaissent déjà. Si vous tentez de la définir malgré tout, le compilateur "
-"se plaindra de trouver deux définitions de la même fonction, sans se rendre "
-"compte qu'il s'agit de la même fonction. Contentez vous de déclarer la "
-"variable <tt>moreMusic</tt> et la méthode <tt>danceOneStep()</tt>."
+"Remarquez qu'il n'est pas nécessaire de vérifier à la seconde ligne que la "
+"valeur est supérieure à 10 puisque les lignes sont considérées dans l'ordre. "
+"Si la seconde ligne est considérée, c'est que la première ne correspondait "
+"pas."
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
+#. type: Content of: <p><p><p><p>
 #: src/lessons/welcome/bdr/BDR2.html:120
+msgid "Finally, it is possible also to match several variables in one shoot!"
+msgstr ""
+"Enfin, il est même possible de filtrer sur plusieurs variables à la fois!"
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:121
+#, no-wrap
 msgid ""
-"This dance step is slightly more complex but actually better looking. Beside "
-"of that, that's the same old story."
+"(x,y) match {\n"
+" case (0,0) => println(\"that's the origin\")\n"
+" case (_,0) => println(\"On the ordinate\")\n"
+" case (0,_) => println(\"On the abscissa\")\n"
+" case (_,_) => println(\"Some random point\")\n"
+"}"
 msgstr ""
-"Ce pas de danse est légèrement plus compliqué mais il est plus beau. En "
-"dehors de cela, c'est la même chose que précédemment."
+"(x,y) match {\n"
+" case (0,0) => println(\"C'est le point origine\")\n"
+" case (_,0) => println(\"C'est un point de l'ordonée\")\n"
+" case (0,_) => println(\"C'est un point de l'abscisse\")\n"
+" case (_,_) => println(\"C'est un point quelconque\")\n"
+"}"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:123
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:128
 msgid ""
-"Here are the ground indications to use for BDR2. Note that we can now move a "
-"buggle up to 6 cells in one dance step."
+"I told you that scala's pattern matching is very powerful! I actually love "
+"this feature!"
 msgstr ""
-"Voici les indications au sol à utiliser pour BDR2. Remarquez qu'on peut "
-"maintenant avancer la buggle de 6 cases d'un coup."
+"Je vous avais bien dit que le filtrage scala était une construction "
+"surpuissante ! Je l'adore !"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
+#. type: Content of: <p><p><p><p>
 #: src/lessons/welcome/bdr/BDR2.html:132
+msgid ""
+"[!java|scala]Apply the improvement we just saw to rewrite your buggle code "
+"with the following dance steps. [/!] [!python]Let's teach a new dance step "
+"to the buggles. It is slightly more complex but actually better looking. "
+"Beside of that, that's the same old story.[/!] Note that we can now move up "
+"to 6 cells in one dance step."
+msgstr ""
+"[!java|scala]Appliquez les améliorations que nous venons de voir pour "
+"adapter le code de votre buggle au nouveau pas de danse explicité ci-dessous."
+"[/!] \n"
+"[!python]Nous allons maintenant apprendre un nouveau pas de dance à nos "
+"buggles. Il est un peu plus complexe, mais sinon, c'est toujours la même "
+"histoire.[/!] \n"
+"Remarquez qu'il est maintenant possible d'avancer jusqu'à 6 cases à la fois."
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:143
 msgid "Turn back and move one step forward"
-msgstr "Tourner en sens inverse (demi-tour) et avancer d'une case"
+msgstr "Se retourner (faire demi-tour) et avancer d'une case"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:137
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:148
 msgid "D"
 msgstr "D"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:137
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:148
 msgid "Move four cells forward"
 msgstr "Avancer de quatre cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:138
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:149
 msgid "E"
 msgstr "E"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:138
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:149
 msgid "Move five cells forward"
 msgstr "Avancer de cinq cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:139
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:150
 msgid "F"
 msgstr "F"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:139
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:150
 msgid "Move six cells forward"
 msgstr "Avancer de six cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:144
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:155
 msgid "W"
 msgstr "W"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:144
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:155
 msgid "Move four cells backward"
 msgstr "Reculer de quatre cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:145
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:156
 msgid "V"
 msgstr "V"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:145
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:156
 msgid "Move five cells backward"
 msgstr "Reculer de cinq cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:146
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:157
 msgid "U"
 msgstr "U"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:146
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:157
 msgid "Move six cells backward"
 msgstr "Reculer de six cases"
 
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:151
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:162
 msgid "When you program works again, proceed to next exercise."
 msgstr ""
 "Quand votre programme fonctionne de nouveau, passez à l'exercice suivant."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:3
-msgid ""
-"Now that your <code>isFacingTrail()</code> method is working, it's time to "
-"write the code to organize the hunting party. Copy/paste your code from the "
-"previous exercise, and complete the <code>hunt()</code> method."
-msgstr ""
-"Maintenant que votre méthode <code>isFacingTrail()</code> fonctionne, il est "
-"temps d'écrire le code de la chasse à proprement parler. Copie/collez le "
-"code que vous aviez fait pour l'exercice précédent, et complétez la méthode "
-"<code>hunt()</code> (<i>hunt</i> signifie <i>chasse</i> en anglais)."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:7
-msgid ""
-"Following a track is not very difficult: move forward as long as you have "
-"the track in front of you.  If there is not track in front of you anymore, "
-"check if the rest of the track is on your left or on your right, and follow "
-"it further."
-msgstr ""
-"Suivre une piste n'est pas très difficile : avancez tant que vous êtes face "
-"à la piste. Si la piste n'est plus devant vous, cherchez si elle se trouve à "
-"gauche ou à droite, et suivez-la encore."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:11
-msgid ""
-"To ensure that you don't mix the track you come from with the one in front "
-"of you, the easier is to erase the track when you follow it. Use the method "
-"<code>brushDown()</code> to put your brush down and mark the ground, and "
-"<code>brushUp()</code> to move it up again."
-msgstr ""
-"Pour ne pas confondre la partie de la trace à suivre avec celle que votre "
-"buggle a déjà suivie, il est conseillé d'effacer la piste derrière vous. "
-"Pour cela, utilisez la méthode <code>brushDown()</code> pour baisser votre "
-"crayon, et <code>brushUp()</code> pour le relever."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:15
-msgid ""
-"Finally, do not forget to capture your prey once you found it (using "
-"<code>pickupBaggle()</code>)."
-msgstr ""
-"Enfin, n'oubliez de capturer votre proie une fois que vous l'aurez débusquée "
-"(avec <code>pickupBaggle()</code>)."
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/slug/SlugHunting.html:19
-msgid ""
-"<a name=\"Objectives\"> Complete the <code>hunt()</code> method. You "
-"probably want to copy over the <code>isFacingTrail()</code> method that you "
-"wrote in previous exercise.  </a>"
-msgstr ""
-"<a name=\"Objectifs\"> Complétez la méthode <code>hunt()</code>. Vous voulez "
-"probablement copier votre méthode <code>isFacingTrail()</code> de l'exercice "
-"précédent."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:3
-msgid ""
-"Your buggle is super happy! It just found the green dribbling trail, "
-"certainly left by a big yummy slug.  At its end, the buggle is certain to "
-"entertain itself with this appetizing slug (represented as a baggle)."
-msgstr ""
-"Votre buggle est super contente ! Elle vient de trouver une grosse traînée "
-"baveuse sur le sol, certainement laissée par une grosse limace. Au bout de "
-"cette piste, la buggle est sûre de se régaler d'un bon jus de limace "
-"(représentée par un baggle)."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:7
-msgid ""
-"To reach that goal, you had to write a boolean method <tt>isFacingTrail</"
-"tt>, which determines whether we are facing a green cell or not. Of course, "
-"if we are facing a wall, it should return false without bumping into it. You "
-"should make sure that this method has no <b>side effect</b>, i.e. that it "
-"does not change the state of the calling buggle nor of its world."
-msgstr ""
-"Pour arriver au résultat, vous devez écrire la méthode booléenne "
-"<code>isFacingTrail()</code>, qui permet de savoir si on est face à une case "
-"verte ou non. Bien sûr, si on est face à un mur, elle doit répondre faux "
-"sans se cogner. Il faudrait de plus que cette méthode soit <b>sans effet de "
-"bord</b>, c'est-à-dire qu'elle ne modifie  ni la buggle qui l'appelle, ni le "
-"monde environnant."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:12
-msgid ""
-"Your tool to that end is the <code>getGroundColor()</code> that returns the "
-"color of the current cell. Just go to the cell you want to test and run that "
-"function. You cannot test whether this color is equal to <code>Color.green</"
-"code> with an <code>==</code> sign but instead you have to write something "
-"like <code>getGroundColor().equals(Color.green)</code>. This is because "
-"green is an <i>object</i> in Java, and <code>.equals()</code> is the way to "
-"go to test equality between Java objects."
-msgstr ""
-"Votre outil pour cela est la méthode <code>getGroundColor()</code> qui "
-"retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut "
-"vous rendre dans la case à tester avant d'appeler cette méthode. Vous ne "
-"pouvez pas simplement utiliser <code>==</code> pour tester si la couleur "
-"retournée est le vert, mais vous devez plutôt écrire quelque chose comme "
-"<code>getGroundColor().equals(Color.green)</code>. C'est parce que les "
-"couleurs sont des <i>objets</i> en Java, et que <code>.equals()</code> est "
-"la marche à suivre pour tester l'égalité d'objets Java."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:18
-msgid ""
-"Your tool to that end is the <code>getGroundColor()</code> that returns the "
-"color of the current cell. Just go to the cell you want to test and run that "
-"function."
-msgstr ""
-"Votre outil pour cela est la méthode <code>getGroundColor()</code> qui "
-"retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut "
-"vous rendre dans la case à tester avant d'appeler cette méthode."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:22
-msgid ""
-"Complete the <code>isFacingTrail()</code> method (which gets called "
-"automatically)."
-msgstr ""
-"Complétez la méthode <code>isFacingTrail()</code> qui sera appelée "
-"automatiquement comme il faut."
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/slug/SlugSnail.html:1
-msgid "Slugs and Snails"
-msgstr "Limaces et escargots"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugSnail.html:3
-msgid ""
-"Yuhu! This time, your buggle found the tracks of much more preys! In the "
-"first world, that's a yummy Kitty Slug (leaving a pink trail) while on the "
-"second world, that's a big fat snail that awaits your buggle at the end of "
-"the orange trail."
-msgstr ""
-"YES! Cette fois encore, votre buggle a débusqué de bonnes proies! Dans le "
-"premier monde, c'est une délicieuse limace Kitty (qui laisse des traces "
-"rose) tandis que dans le second monde, un bon gros escargot du désert attend "
-"la buggle au bout de sa piste orange."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugSnail.html:7
-msgid ""
-"You have to copy/paste your code again, and change it so that your methods "
-"take the color of the trail to follow as a parameter. Beside of this, your "
-"code should work as earlier."
-msgstr ""
-"Il vous faut copie/coller votre code encore une fois, et le modifier pour "
-"que vos méthodes prennent la couleur de piste à suivre en paramètre. À part "
-"cela, votre code devrait faire comme avant."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:3
+#: src/lessons/welcome/traversal/Snake.html:3
 msgid ""
 "We will now teach the buggle to explore its world. Its initial position is "
 "the bottom left corner, and it should visit any cells up to the top "
-"(coloring the ground on its path. The main loop of the <code>run()</code> "
-"method (that you should write) is something like:"
+"(coloring the ground on its path. The main loop of your code is something "
+"like:"
 msgstr ""
 "Nous allons maintenant apprendre à la buggle à explorer son monde. Sa "
 "position de départ est en bas à gauche, et elle doit visiter toutes les "
 "cases juqu'en haut (en coloriant le sol sur son passage).  La boucle "
-"principale de la méthode <code>run()</code> (que vous devez écrire)  est de "
-"la forme :"
+"principale de votre code doit être de la forme :"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:8
+#: src/lessons/welcome/traversal/Snake.html:7
 #, no-wrap
 msgid ""
 " move brush down\n"
 " while we did not reach the final position\n"
 "   move like a snake\n"
 msgstr ""
-" baisser le crayon\n"
-" tant que l'on est pas à la position finale\n"
-"   avancer comme un serpent\n"
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:13
-msgid "The prototype of this method (its first line) must be:"
-msgstr "Le prototype de cette méthode (sa première ligne) doit être :"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:14
-#, no-wrap
-msgid "public void run()"
-msgstr "public void run()"
+" baisser le crayon\n"
+" tant que l'on est pas à la position finale\n"
+"   avancer comme un serpent\n"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:15
+#: src/lessons/welcome/traversal/Snake.html:12
 msgid ""
-"(we will come back later on the meaning of <code>public</code>). We thus "
-"have to write two methods in addition to <code>run()</code>. The former "
-"returns a boolean indicating whether we are on a final position while the "
-"latter does not return any result and move one snake step forward."
+"We thus have to write two specific methods: The first one returns a boolean "
+"indicating whether we are on a final position while the second moves one "
+"snake step forward."
 msgstr ""
-"(nous verrons plus tard ce que ce <code>public</code> signifie).  Il faut "
-"donc écrire deux méthodes en plus de <code>run()</code>. L'une renvoit un "
-"booléen et indique si l'on se trouve à une position finale, tandis que "
-"l'autre ne renvoit pas de résultat et avance d'un pas."
+"Il faut donc écrire deux méthodes spécifiques. L'une renvoie un booléen "
+"indiquant si l'on se trouve à la position finale, tandis que l'autre avance "
+"d'un pas de serpent."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:20
+#: src/lessons/welcome/traversal/Snake.html:16
 msgid "We reached the final position if and only if both conditions are true:"
 msgstr ""
 "On se trouve sur une position finale si et seulement si les deux conditions "
 "suivantes sont vraies.:"
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:22
+#: src/lessons/welcome/traversal/Snake.html:18
 msgid "We are facing a wall"
 msgstr "On est face à un mur"
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:23
+#: src/lessons/welcome/traversal/Snake.html:19
 msgid ""
 "There is a wall on the north of the buggle. So, if the buggle is facing "
 "east, you should check whether there is a wall on the left, and if the "
@@ -6654,7 +6451,7 @@ msgstr ""
 "il faut vérifier s'il y a un mur à droite."
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:26
+#: src/lessons/welcome/traversal/Snake.html:22
 msgid ""
 "We can get the current heading of the buggle using the <code>getDirection()</"
 "code>, and we know whether it looks east using <code>getDirection() == "
@@ -6665,19 +6462,19 @@ msgstr ""
 "<code>getDirection() == Direction.EAST</code> (WEST pour ouest)."
 
 #. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:29
+#: src/lessons/welcome/traversal/Snake.html:25
 msgid ""
-"For the checking itself, nothing magical: you have to turn the buggle and "
-"check whether it is facing a wall afterward."
+"To check, nothing magical: you have to turn the buggle and check whether it "
+"is facing a wall afterward."
 msgstr ""
 "Pour la vérification elle-même, rien de magique : il faut se tourner et "
 "regarder si on est face à un mur une fois tourné."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:33
+#: src/lessons/welcome/traversal/Snake.html:28
 msgid ""
 "Then, a snake step can be achieved by moving one step forward if we are not "
-"facing a wall, and moving to the upper line else (ie, if you look to the "
+"facing a wall, and moving to the upper line else (i.e., if you look to the "
 "west facing a wall, you have to turn right, forward and turn right)."
 msgstr ""
 "Ensuite un pas de serpent se fait en avancant d'un pas si l'on est pas face "
@@ -6685,53 +6482,38 @@ msgstr ""
 "l'ouest face à un mur, il faut tourner à droite, avancer, tourner à droite)."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:37
+#: src/lessons/welcome/traversal/Snake.html:32
 msgid ""
-"Hint: the main loop of the <code>run()</code> method must continue while the "
-"testing function returns false. Their is thus two way of writing it:"
+"Hint: the main loop of your code must continue while the testing function "
+"returns false. Their is thus two way of writing it:"
 msgstr ""
-"Indication: la boucle principale de la méthode <code>run()</code> doit "
-"continuer tant que la fonction adéquate renvoie faux. On peut l'écrire de "
-"deux façons:"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:39
-#, no-wrap
-msgid "while (testingFunction() == false)"
-msgstr "while (fonctionTest() == false)"
+"Indication: la boucle principale de votre code doit continuer tant que la "
+"fonction adéquate renvoie faux. On peut l'écrire de deux façons:"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:40
+#: src/lessons/welcome/traversal/Snake.html:34
 #, no-wrap
-msgid "while testingFunction() == False:"
-msgstr "while fonctionTest() == false:"
+msgid "while (testingFunction() == [!java|scala]false) {[/!][!python]False):[/!]"
+msgstr "while (fonctionTest() == [!java|scala]false) {[/!][!python]False):[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:41
-msgid "or"
-msgstr "ou bien"
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:42
-#, no-wrap
-msgid "while (! testingFunction())"
-msgstr "while (! fonctionTest())"
+#: src/lessons/welcome/traversal/Snake.html:35
+msgid ""
+"[!python]You may prefer to write it as:[/!] [!java|scala]Since the "
+"exclamation mark (!) denotes the boolean negation in [!thelang], you may "
+"write it as:[/!]"
+msgstr ""
+"[!python]Vous pouvez préférer l'écrire ainsi:[/!] \n"
+"[!java|scala]Comme le point d'exclamation (!) dénote la négation booléenne "
+"en [!thelang], vous pouvez aussi l'écrire:[/!]"
 
 #. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:43
+#: src/lessons/welcome/traversal/Snake.html:37
 #, no-wrap
-msgid "while not testingFunction():"
-msgstr "while not fonctionTest():"
+msgid "while ([!java|scala]![/!][!python]not [/!]testingFunction())[!java|scala] {[/!][!python]:[/!]"
+msgstr "while ([!java|scala]![/!][!python]not [/!]fonctionTest())[!java|scala] {[/!][!python]:[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:44
-msgid ""
-"It works because the exclamation mark (!) means in Java a boolean negation."
-msgstr ""
-"Cela fonctionne car le point d'exclamation en java indique une négation "
-"booléenne."
-
-#. type: Content of: outside any tag (error?)
 #: src/lessons/welcome/traversal/column/TraversalByColumn.html:3
 msgid ""
 "The goal of this serie of exercises is to let the buggle traverse its world. "
@@ -6743,20 +6525,11 @@ msgstr ""
 
 #. type: Content of: <p>
 #: src/lessons/welcome/traversal/column/TraversalByColumn.html:6
-msgid ""
-"The main loop of the <code>run()</code> method (that you must write) is "
-"something like:"
-msgstr ""
-"La boucle principale de la méthode <code>run()</code> (que vous devez "
-"écrire)  est de la forme :"
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:8
 msgid "The main loop of your code should be something like:"
 msgstr "La boucle principale du code que vous devez écrire est de la forme :"
 
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:10
+#. type: Content of: <pre>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:8
 #, no-wrap
 msgid ""
 " while we are not on the final position\n"
@@ -6767,8 +6540,8 @@ msgstr ""
 "   aller à la prochaine position\n"
 "   marquer le numéro de case au sol \n"
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:15
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:13
 msgid ""
 "In contrary to the exercises we saw so far, we won't use the "
 "<code>forward()</code>, <code>backward()</code> and similar methods. "
@@ -6778,18 +6551,18 @@ msgid ""
 "buggle to the cell where x=3 and y=5."
 msgstr ""
 "À la différence des exercices vus jusque là, nous n'allons pas utiliser les "
-"méthodes <code>forward()</code>, <code>backward()</code> et autres, mais "
-"nous allons calculer les coordonnées de la prochaine position de la buggle, "
-"et utiliser la méthode <code>setPos(x, y)</code> pour <i>téléporter</i> la "
+"méthodes <code>avance()</code>, <code>recule()</code> et autres, mais nous "
+"allons calculer les coordonnées de la prochaine position de la buggle, et "
+"utiliser la méthode <code>setPos(x, y)</code> pour <i>téléporter</i> la "
 "buggle directement à cette position. Par exemple, <code>setPos(3, 5)</code> "
 "téléporte la buggle sur la case où x=3 et y=5."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:22
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:20
 msgid ""
 "Your first task is thus to write a boolean function indicating whether the "
-"buggle the final position or not, ie if it reached the bottom right corner "
-"of the world. For this, you can use <code>getWorldWidth()</code> and "
+"buggle reached the final position or not, ie if it reached the bottom right "
+"corner of the world. For this, you can use <code>getWorldWidth()</code> and "
 "<code>getWorldHeight()</code> which return respectively the world's width "
 "and height. Your test is about comparing the buggle's current position (that "
 "you can access with <code>getX()</code> and <code>getY()</code>) to the "
@@ -6798,21 +6571,21 @@ msgstr ""
 "Le premier objectif est donc d'écrire une fonction booléenne indiquant si la "
 "buggle a atteint la position finale ou non, càd si elle est arrivée en bas à "
 "droite du monde.  Vous utiliserez pour cela les méthodes "
-"<code>getWorldWidth()</code> et <code>getWorldHeight()</code> qui retournent "
-"respectivement la largeur et la hauteur du monde.  Votre test est de "
-"comparer les coordonnées actuelles de votre buggle (que vous pouvez "
+"<code>getMondeHauteur()</code> et <code>getMondeLargueur()</code> qui "
+"retournent respectivement la hauteur et la largeur du monde.  Votre test est "
+"de comparer les coordonnées actuelles de votre buggle (que vous pouvez "
 "retrouver avec les méthodes <code>getX()</code> et <code>getY()</code>) aux "
 "dimensions du monde."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:29
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:27
 msgid "Beware, the first line and column are numbered 0 and not 1..."
 msgstr ""
 "Attention, la première ligne et la première colonne sont numérotées 0 et non "
 "1..."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:31
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:29
 msgid ""
 "Then, you have to write the code to reach the next position. In this "
 "exercise, you have to traverse the world row after row. So, if you are at "
@@ -6824,8 +6597,8 @@ msgstr ""
 "tout en bas d'une colonne, il faut aller en haut de la colonne suivante et "
 "sinon, il faut aller à la case du dessous."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:36
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:34
 msgid ""
 "At this point, you can launch your program to check that the buggle "
 "correctly traverse the world in the expected order, and that it stops when "
@@ -6836,40 +6609,29 @@ msgstr ""
 "faut. Pensez à utiliser le bouton <b>stop</b> pour arrêter l'exécution si "
 "votre programme ne se termine pas correctement."
 
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:40
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:38
 msgid ""
-"It is now time to write done the cell numbers. For that, you will need a "
-"counter initialiser to zero at the begining of your <code>run()</code> "
-"method, and incremented by one at each step (for example with <code>counter "
-"+= 1;</code>). Then, you have to write the value on the ground, for example "
-"with <code>writeMessage(counter);</code>."
+"It is now time to write down the cell numbers. For that, you will need a "
+"counter initialiser to zero at the begining of your code, and incremented by "
+"one at each step (for example with <code>counter += 1;</code>).  Then, you "
+"have to use <code>writeMessage()</code> to write the value on the ground."
 msgstr ""
 "Il est temps d'écrire au sol les numéros de case. Pour cela, vous aurez "
-"besoin d'un compteur initialisé à zéro au début de votre méthode "
-"<code>run()</code>, et incrémenté de un à chaque pas (par exemple avec "
-"<code>cpt += 1;</code>). Ensuite, il faut écrire la valeur de ce compteur au "
-"sol à chaque pas, par exemple avec <code>writeMessage(cpt);</code>."
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:46
-msgid ""
-"You probably need to write the first or last value out of the main loop, "
-"depending on whether you prefer to use a <code>while {}</code> or a <code>do "
-"{} while</code>..."
-msgstr ""
-"Il est sans doute nécessaire d'écrire la valeur de la première ou dernière "
-"case en dehors de la boucle principale, selon que vous utilisez un "
-"<code>while {}</code> ou un <code>do {} while</code>..."
+"besoin d'un compteur initialisé à zéro au début de votre code, et incrémenté "
+"à chaque pas (par exemple avec <code>cpt += 1;</code>). Ensuite, il faut "
+"écrire cette valeur au sol (avec <code>ecritMessage()</code>)."
 
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:50
+#. type: Content of: <p><p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:43
 msgid ""
-"You may want to write the first value out of the main <code>while ...:</"
-"code> loop."
+"You probably need to write the first [!java|scala]or last [/!]value out of "
+"the main loop [!java|scala], depending on whether you prefer to use a "
+"<code>while</code> or a <code>do/while</code> one[/!]."
 msgstr ""
-"Si vous le souhaitez, vous pouvez écrire la première valeur en dehors de la "
-"boucle <code>while ....:</code>."
+"Il est sans doute nécessaire d'écrire la valeur de la première[!java|scala] "
+"ou dernière[/!] case en dehors de la boucle principale[!java|scala], selon "
+"que vous utilisez une boucle <code>while</code> ou <code>do/while</code>[/!]."
 
 #. type: Content of: outside any tag (error?)
 #: src/lessons/welcome/traversal/line/TraversalByLine.html:3
@@ -6938,17 +6700,18 @@ msgstr ""
 #: src/lessons/turmites/Main.html:7
 msgid ""
 "This mechanism were invented in 1986 by Chris Langton, and later generalized "
-"in several ways (as we shall see in the next exercises). It was proven in "
-"2000 that the ant's trajectory can be used to compute any boolean circuit, "
-"and thus that the ant is capable of universal computation (ie, any possible "
-"computation can be achieved using the ant as a computing device). Yet "
-"another subject of fascination..."
+"in several ways (as we shall see in the next exercises). It was proven that "
+"Turmites and Turing machines are of equal power: An ant's trajectory can be "
+"used to compute any boolean circuit, and thus that an ant is capable of "
+"universal computation. Put simply, any possible computation can be achieved "
+"using a turmite as a computing device. Yet another subject of fascination..."
 msgstr ""
 "Ce mécanisme a été inventé en 1986 par Chris Langton, et généralisé après de "
 "plusieures façons (comme nous le verrons dans les prochains exercices). Il a "
-"été prouvé en 2000 que la trajectoire de la fourmi peut être utilisée pour "
-"calculer n'importe quel circuit booléen, et que la fourmi est capable de "
-"calcul universel ( ie, n'importe quel calcul possible peut être réalisé en "
+"été prouvé que les turmites et les machines de Turing sont aussi puissantes "
+"les unes que les autres : une trajectoire de  fourmi peut être utilisée pour "
+"calculer n'importe quel circuit booléen, et la fourmi est donc capable de "
+"calcul universel (càd, n'importe quel calcul possible peut être réalisé en "
 "utilisant la fourmi comme instrument de calcul). Encore un autre sujet de "
 "fascination..."
 
@@ -6976,13 +6739,13 @@ msgstr ""
 
 #. type: Content of: <h3>
 #: src/lessons/turmites/Main.html:21 src/lessons/sort/pancake/Main.html:29
-#: src/lessons/sort/baseball/Main.html:27
-msgid "What can I do to improve this JLM universe?"
-msgstr "Que puis-je faire pour améliorer cet univers de JLM?"
+#: src/lessons/sort/baseball/Main.html:27 src/lessons/turtleart/Main.html:11
+msgid "What can I do to improve this PLM universe?"
+msgstr "Que puis-je faire pour améliorer cet univers de PLM?"
 
 #. type: Content of: <p>
 #: src/lessons/turmites/Main.html:23 src/lessons/sort/pancake/Main.html:31
-#: src/lessons/sort/baseball/Main.html:29
+#: src/lessons/sort/baseball/Main.html:29 src/lessons/turtleart/Main.html:13
 msgid ""
 "As usual, there are several things that could be done in the code of this "
 "universe to improve it:"
@@ -7053,8 +6816,8 @@ msgid ""
 msgstr ""
 "Les règles sont absolument triviales: pour calculer quel sera le prochain "
 "pas, vous devez regarder la couleur actuelle du sol ( en utilisant "
-"<code>getGroundColor()</code>). Si c'est blanc, changez la en noir, tournez "
-"à droite et avancez d'une case. Si la couleur du sol est le noir, changez la "
+"<code>getCouleurSol()</code>). Si c'est blanc, changez la en noir, tournez à "
+"droite et avancez d'une case. Si la couleur du sol est le noir, changez la "
 "en blanc, tournez à gauche et avancez d'une case."
 
 #. type: Content of: <p>
@@ -7070,21 +6833,21 @@ msgstr ""
 "Il est difficile de trouver des règles plus simples, n'est-ce pas ? Et bien, "
 "allons-y et codons-les maintenant. Vous avez à compléter la méthode "
 "<code>step()</code>, qui définit le comportement de la fourmi à chaque pas. "
-"Vous utiliserez probablement la méthode <code>getGroundColor()</code> pour "
+"Vous utiliserez probablement la méthode <code>getCouleurSol()</code> pour "
 "récupérer la valeur de la case sur laquelle la fourmi se trouve. Les "
 "couleurs intéressantes sont tout simplement <code>Color.black</code> pour le "
 "noir ou <code>Color.white</code> pour le blanc."
 
 #. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:20
+#: src/lessons/turmites/langton/Langton.html:21
 msgid ""
-"To compare colors, you cannot use the equal sign (=), because these things "
+"To compare colors, you cannot use the equal signs (==), because these things "
 "are not scalar values but objects. Instead, you need to write something like "
 "the following:"
 msgstr ""
-"Pour comparer les couleurs, il n'est pas possible d'utiliser le signe égal "
-"(=) parce ces choses ne sont pas des valeurs scalaires normales mais des "
-"objets. À la place, vous devez écrire quelque chose comme cela :"
+"Pour comparer les couleurs, il n'est pas possible d'utiliser le double signe "
+"égal (==) parce ces choses ne sont pas des valeurs scalaires normales mais "
+"des objets. À la place, vous devez écrire quelque chose comme cela :"
 
 #. type: Content of: <pre>
 #: src/lessons/turmites/langton/Langton.html:24
@@ -7105,7 +6868,7 @@ msgstr ""
 "}\n"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:32
+#: src/lessons/turmites/langton/Langton.html:33
 msgid ""
 "Changing the ground color is not difficult, but a bit long: you have to "
 "change the brush color of your buggle, set the brush down (to mark the "
@@ -7117,14 +6880,14 @@ msgid ""
 msgstr ""
 "Changer la couleur du sol n'est pas difficile, seulement un peu long : vous "
 "avez à changer la couleur de la brosse de votre buggle, l'abaisser (pour "
-"marquer la case courante -- avec <code>brushDown()</code>), et relever la "
-"brosse (avec <code>brushUp()</code>) pour éviter des problèmes lorsque la "
+"marquer la case courante -- avec <code>baisseBrosse()</code>), et relever la "
+"brosse (avec <code>leveBrosse()</code>) pour éviter des problèmes lorsque la "
 "buggle va se déplacer. Vous être naturellement libre d'organiser votre code "
 "comme vous le souhaitez, mais vous pouvez vouloir écrire une méthode "
-"<code>setGroundColor(couleur)</code> pour factoriser le tout."
+"<code>setCouleurSol(couleur)</code> pour factoriser le tout."
 
 #. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:39
+#: src/lessons/turmites/langton/Langton.html:40
 msgid ""
 "As you can see from the execution of this exercise, the interest in this "
 "algorithm is that after about 10000 steps of relative chaotic behavior, the "
@@ -7189,48 +6952,38 @@ msgid ""
 "<code>step</code> function. But this time, it receives two arrays as "
 "parameters.  The first one defines the rules to follow depending on the "
 "ground color while the second one gives the sequence of colors to use. For "
-"example, the basic ant would have <code>{'R', 'L'}</code> and <code>{Color."
-"white, Color.black}</code> as arguments."
-msgstr ""
-"Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très "
-"compliqué, même si ce n'est pas complètement trivial. Comme précédemment, "
-"vous avez à écrire une fonction <code>step</code>. Mais cette fois, elle "
-"reçoit deux tableaux comme paramètres. Le premier définit les règles à "
-"suivre selon la couleur du sol tandis que le deuxième done la séquence de "
-"couleur à utiliser. Par exemple, la fourmi de base aurait <code>{'R', 'L'}</"
-"code> et <code>{Color.white, Color.black}</code> comme arguments."
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:24
-msgid ""
-"Changing your buggle into a generic Langton's ant is not very complicated, "
-"although it is not completely trivial. As previously, you have to write a "
-"<code>step</code> function. But this time, it receives two arrays as "
-"parameters.  The first one defines the rules to follow depending on the "
-"ground color while the second one gives the sequence of colors to use. For "
-"example, the basic ant would have <code>['R', 'L']</code> and <code>[Color."
-"white, Color.black]</code> as arguments."
+"example, the basic ant would have [!java]<code>{'R', 'L'}</code> and "
+"<code>{Color.white, Color.black}</code>[/!] [!python]<code>['R', 'L']</code> "
+"and <code>[Color.white, Color.black]</code>[/!] [!scala]<code>Array('R', "
+"'L')</code> and <code>Array(Color.white, Color.black)</code>[/!] as "
+"arguments."
 msgstr ""
 "Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très "
 "compliqué, même si ce n'est pas complètement trivial. Comme précédemment, "
 "vous avez à écrire une fonction <code>step</code>. Mais cette fois, elle "
 "reçoit deux tableaux comme paramètres. Le premier définit les règles à "
 "suivre selon la couleur du sol tandis que le deuxième done la séquence de "
-"couleur à utiliser. Par exemple, la fourmi de base aurait <code>['R', 'L']</"
-"code> et <code>[Color.white, Color.black]</code> comme arguments."
+"couleur à utiliser. Par exemple, la fourmi de base aurait \n"
+"[!java]<code>{'R', 'L'}</code> et <code>{Color.white, Color.black}</"
+"code>[/!]\n"
+"[!python]<code>['R', 'L']</code> et <code>[Color.white, Color.black]</"
+"code>[/!]\n"
+"[!scala]<code>Array('R', 'L')</code> et <code>Array(Color.white, Color."
+"black)</code>[/!]\n"
+"comme arguments."
 
 #. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:31
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:28
 msgid "At each step, you thus have to apply the following pseudo-code:"
 msgstr "A chaque pas, vous avez toujours à appliquer le pseudo-code suivant :"
 
 #. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:33
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:30
 msgid "Find the position of the ground color in the color sequence;"
 msgstr "Trouver la position de la couleur du sol dans la séquence de couleur;"
 
 #. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:34
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:31
 msgid ""
 "Turn left or right depending on the content of the rule array at that "
 "position;"
@@ -7239,7 +6992,7 @@ msgstr ""
 "position;"
 
 #. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:35
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:32
 msgid ""
 "Mark the current ground with the next color in the sequence (the last color "
 "being followed by the first one);"
@@ -7248,13 +7001,13 @@ msgstr ""
 "séquence ( la dernière couleur est suivie par la première);"
 
 #. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:36
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:33
 msgid "Move forward by one step."
 msgstr "Avancer d'un pas"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:39
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:70
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:36
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:66
 msgid "You now should have enough information to succeed."
 msgstr "Vous devriez maintenant avoir assez d'informations pour réussir."
 
@@ -7293,11 +7046,12 @@ msgid ""
 "the current's cell ground color in the color sequence. But this time, the "
 "<code>rule</code> data depends both on the current color and the current "
 "state.  <code>rule</code> actually contains 3 information in each situation: "
-"the color to write, the move to do, and the next state value. For example, "
-"rule[1][0] contains the informations to use when <code>state==1</code> and "
-"<code>color==0</code>. In other worlds, you can retrieve the information "
-"relative to your current situation by using <code>rule[state][currentColor]</"
-"code>."
+"the color to write, the move to do, and the next state value. For example, [!"
+"java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contains the informations "
+"to use when <code>state==1</code> and <code>color==0</code>.  In other "
+"worlds, you can retrieve the information relative to your current situation "
+"by using <code>[!java|python]rule[state][currentColor][/!][!scala]rule(state)"
+"(currentColor)[/!]</code>."
 msgstr ""
 "Une fois encore, vous devez seulement écrire la méthode <code>step()</code>, "
 "qui s'occupe de faire faire un pas à la turmite. Une fois encore, vous devez "
@@ -7305,14 +7059,16 @@ msgstr ""
 "couleurs. Mais cette fois, <code>rule</code> dépend à la fois de la couleur "
 "courante et de l'état courant. <code>rule</code> contient en fait trois "
 "informations dans chaque situation : la couleur à mettre, le mouvement à "
-"effectuer, et la valeur du prochain état. Par exemple, rule[1][0] contient "
+"effectuer, et la valeur du prochain état. \n"
+"Par exemple, [!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contient "
 "l'information à utiliser quand <code>state==1</code> et <code>color==0</"
 "code>. En d'autres mots, vous pouvez récupérer l'information relative à "
-"votre situation actuelle en utilisant <code>rule[etatCourant]"
-"[couleurActuelle]</code>"
+"votre situation actuelle en utilisant \n"
+"<code>[!java|python]rule[etatCourant][couleurActuelle][/!][!"
+"scala]rule(etatCourant)(couleurActuelle)[/!]</code>"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:22
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:24
 msgid ""
 "Each such information set contains 3 values. The first one is the rank of "
 "the color to write on the ground. The second is the move to do, with the "
@@ -7332,94 +7088,81 @@ msgstr ""
 "est la valeur du prochain <code>state</code> à avoir après cette itération."
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:29
-msgid ""
-"Since these arbitrary notations are somehow difficult to remember, the "
-"template code defines a set of constants that you should use instead of the "
-"direct numerical values. Their names are NOTURN, LEFT, RIGHT and so on. The "
-"modifiers <code>final static</code> before their type is the way to mark "
-"variables as constant in Java (sorry if the notation seems complex). Using "
-"such constants greatly help making the code easier to read. This allows to "
-"write things this way:"
-msgstr ""
-"Puisque ces notations arbitraires sont parfois difficiles à se souvenir, le "
-"code fourni définit un ensemble de constantes que vous pouvez utiliser à la "
-"place des valeurs numériques. Leurs noms sont LEFT, RIGHT, etc.\n"
-"Le modifieur <code>final static</code> avant leur type est la façon "
-"d'indiquer les variables comme constantes en Java (désolés si la notation "
-"semble complexe).\n"
-"Utiliser de telles constantes rend le code beaucoup plus simple à lire :"
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:31
+msgid ""
+"Since these arbitrary notations are somehow difficult to remember, you "
+"should define a set of constants that you should use instead of the direct "
+"numerical values.  Their names could be NOTURN, LEFT, RIGHT and so on.  [!"
+"scala]Just declare them using the keyword <code>val</code> instead of "
+"<code>var</code>.  You should always use <code>val</code> instead of "
+"<code>var</code> when possible anyway.[/!] [!java]The modifiers <code>final "
+"static</code> before their type is the way to mark variables as constant in "
+"Java.  You should write for example <code>static final int NOTURN=1;</code> "
+"Sorry for the complexity of this notation. [/!] [!python]By convention, such "
+"constant variables are written in upper case in python.  Technically, you "
+"can still modify them, but that would be a very bad idea.[/!] You should "
+"write them out of any method so that they are globally visible."
+msgstr ""
+"Puisque ces notations arbitraires sont parfois difficiles à se souvenir, "
+"vous devriez définir un ensemble de constantes que vous pouvez utiliser à la "
+"place des valeurs numériques. Leurs noms pourraient être GAUCHE, DROITE, "
+"etc.\n"
+"[!scala]Déclarez simplement ces valeurs avec le mot-clé <code>val</code> au "
+"lieu de <code>var</code>. De toute façon, on devrait toujours utiliser "
+"<code>val</code> au lieu de <code>var</code> quand on peut.[/!]\n"
+"[!java]Les modificateurs <code>final static</code> devant le nom du type est "
+"la façon Java de marquer des constant en Java. \n"
+"  Vous devriez écrire par exemple <code>static final int TOUTDROIT=1;</"
+"code>\n"
+"  Désolé de la complexité de cette notation. [/!]\n"
+"[!python]Par convention, de telles «variables constantes» sont écrites tout "
+"en majuscule en Python.\n"
+"  Rien ne vous empêche d'un point de vue technique de les modifier, mais ca "
+"serait une très mauvaise idée.[/!]\n"
+"Vous devriez les écrire en dehors de toute méthode pour les rendre visible "
+"de partout."
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:35
-msgid ""
-"Since these arbitrary notations are somehow difficult to remember, the "
-"template code defines a set of constants that you should use instead of the "
-"direct numerical values. Their names are NOTURN, LEFT, RIGHT and so on. By "
-"convention, such constant variables are written in upper case in python. "
-"Technically, you can still modify them, but that would be a very bad idea. "
-"Using such constants greatly help making the code easier to read, as it "
-"allows to write things this way:"
-msgstr ""
-"Puisque ces notations arbitraires sont parfois difficiles à se souvenir, le "
-"code fourni définit un ensemble de constantes que vous pouvez utiliser à la "
-"place des valeurs numériques. Leurs noms sont NOTURN, LEFT, RIGHT, etc. "
-"(pour TOUTDROIT, GAUCHE, DROITE). Par convention, de telles constantes sont "
-"écrites en majuscules en python. Techniquement, vous pouvez modifier la "
-"valeur de ces variables, but ce serait une très mauvause idée.\n"
-"Utiliser de telles constantes rend le code beaucoup plus simple à lire :"
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:42
-#, no-wrap
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:43
 msgid ""
-"  if (rule[state][currentColor][NEXT_MOVE] == LEFT) {\n"
-"    turnLeft();\n"
-"  }\n"
+"Using such constants greatly help making the code easier to read. Compare "
+"the next two code chunks:"
 msgstr ""
-"  if (rule[state][currentColor][NEXT_MOVE] == LEFT) {\n"
-"    turnLeft();\n"
-"  }\n"
+"Utilisez de telles constantes aident beaucoup à rendre le code plus "
+"lisible.\n"
+"Comparez les deux morceaux de code suivant:"
 
 #. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:47
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:45
 #, no-wrap
 msgid ""
-"  if rule[state][currentColor][NEXT_MOVE] == LEFT:\n"
-"    turnLeft()\n"
+"[!java]if (rule[state][currentColor][NEXT_MOVE] == LEFT) {[/!][!python]if rule[state][currentColor][NEXT_MOVE] == LEFT:[/!][!scala]if (rule(state)(currentColor)(NEXT_MOVE) == LEFT) {[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"  if rule[state][currentColor][NEXT_MOVE] == LEFT:\n"
-"    turnLeft()\n"
+"[!java]if (rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE) {[/!][!python]if rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE:[/!][!scala]if (rule(etat)(couleurActuelle)(MVT_SUIVANT) == GAUCHE) {[/!]\n"
+"    gauche()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:50
-msgid "This is much more easier to read than the following way:"
-msgstr "C'est beaucoup plus simple à lire que ceci :"
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:52
-#, no-wrap
-msgid ""
-"  if (rule[x][y][1] == 2) {\n"
-"    turnLeft();\n"
-"  }\n"
-msgstr ""
-"  if (rule[x][y][1] == 2) {\n"
-"    turnLeft();\n"
-"  }\n"
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:48
+msgid "This is much more easier to read (although longer) than the following:"
+msgstr "C'est un peu plus long, mais bien plus agréable à lire que ceci :"
 
 #. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:57
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:49
 #, no-wrap
 msgid ""
-"  if rule[x][y][1] == 2:\n"
-"    turnLeft()\n"
+"[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"  if rule[x][y][1] == 2:\n"
-"    turnLeft()\n"
+"[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]\n"
+"    gauche()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:61
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:53
 msgid ""
 "Finally, you probably want to write a <code>elif</code> branch for the "
 "<code>STOP</code> condition too. Having a <code>else</code> branch "
@@ -7442,13 +7185,25 @@ msgstr ""
 "n'y a rien à faire. Cela indique à Python qu'il y a bien une branche à cet "
 "emplacement, mais qu'elle ne fait rien."
 
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:62
+msgid ""
+"You should probably use a [!java]switch case[/!][!scala]pattern matching[/!] "
+"construct to keep your code readable.  If you can't remember what it is, "
+"check <a href=\"plm://lessons.welcome/bdr.BDR2\">this exercise</a>."
+msgstr ""
+"Vous devriez probablement utiliser un [!java]switch[/!][!scala]filtrage[/!] "
+"pour que votre code reste lisible. \n"
+"Si vous avez oublié ce que c'est, retournez à <a href=\\\"plm://lessons."
+"welcome/bdr.BDR2\\\">cet exercice</a>."
+
 #. type: Content of: <h2>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:72
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:68
 msgid "Bibliographical notes"
 msgstr "Notes bibliographiques"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:73
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:69
 msgid ""
 "According to wikipedia, turmites were invented independently by the end of "
 "the eighties. It has been shown that turmites in general are exactly "
@@ -7480,7 +7235,7 @@ msgstr ""
 "Cet exercice vous permet de construire vos propres turmites. Pour réussir "
 "cet exercice, vous devez simplement écrire une méthode <code>init()</code> "
 "qui initialise <code>rule</code> pour utiliser les tables de transitions "
-"suivantes (de Wikipedia), met la position initiale du buggle à (8;33), et "
+"suivantes (de Wikipedia), met la position initiale de la buggle à (8;33), et "
 "demande de faire 8342 pas."
 
 #. type: Content of: <table><tr><th>
@@ -7585,24 +7340,16 @@ msgstr ""
 #: src/lessons/turmites/turmitecreator/TurmiteCreator.html:62
 msgid ""
 "Here are some 2-color turmites, extracted from http://demonstrations.wolfram."
-"com/Turmites/ They are not written using the python syntax, but converting "
-"them should be easy."
-msgstr ""
-"Voici quelques turmites bicolores, issues de http://demonstrations.wolfram."
-"com/Turmites/ Elles n'ont pas été écrites avec la syntaxe Python, mais les "
-"convertir ne devrait pas poser beaucoup de problèmes."
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:64
-msgid ""
-"Here are some 2-color turmites, extracted from http://demonstrations.wolfram."
-"com/Turmites/"
+"com/Turmites/ [!python|scala]They are not written using the [!thelang] "
+"syntax, but converting them should be easy.[/!]"
 msgstr ""
 "Voici quelques turmites bicolores, issues de http://demonstrations.wolfram."
-"com/Turmites/"
+"com/Turmites/ \n"
+"[!scala|python]Elles n'ont pas été écrites avec la syntaxe [!thelang], mais "
+"les convertir ne devrait pas poser beaucoup de problèmes.[/!]"
 
 #. type: Content of: <pre>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:67
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:66
 #, no-wrap
 msgid ""
 "{{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant\n"
@@ -7698,7 +7445,7 @@ msgstr ""
 "{{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway\n"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:114
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:113
 msgid ""
 "Langton's ants may not share the expressiveness power of the turmites, but "
 "they remain fascinating too. You can experiment with them using the "
@@ -7719,7 +7466,7 @@ msgstr ""
 "pas !"
 
 #. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:121
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:120
 msgid ""
 "Quite a lot of Langton's ants build highways: RL, of course, but also "
 "RLRLRLLRLR (about 2500 steps).  The chaotic behavior of ants before the "
@@ -7743,7 +7490,7 @@ msgstr ""
 "transcendant avant leur route."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:129
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:128
 msgid ""
 "Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), "
 "RRLLLRLLLRRR (30,000 steps), RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR "
@@ -7764,7 +7511,7 @@ msgstr ""
 "rapidement son comportement stable (15 000 pas suffisent)."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:136
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:135
 msgid ""
 "Finally, some ants are just build artistic patterns. You should check this "
 "video for some beautiful ones: http://www.youtube.com/watch?v=1X-gtr4pEBU. "
@@ -7780,7 +7527,7 @@ msgstr ""
 "(le premier mouvement visible doit être vu comme le dernier)."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:141
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:140
 msgid ""
 "As you can see by exploring the above set of turmites, they are usually not "
 "as colorful as the ants, but this may be because very few colors suffice to "
@@ -7805,50 +7552,21 @@ msgstr ""
 "La page web est ici : http://code.google.com/p/ruletablerepository/wiki/"
 "TwoDimensionalTuringMachines"
 
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:12
-msgid "void forward() or void forward(int)"
-msgstr "void forward() ou void forward(int)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:12
-msgid "void backward() or void backward(int)"
-msgstr "void backward() ou void backward(int)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setX(int)"
-msgstr "void setX(int)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setY(int)"
-msgstr "void setY(int)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setPos(int,int)"
-msgstr "void setPos(int,int)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:18
-msgid "void setColor(Color)"
-msgstr "void setColor(Color)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:22
-msgid "void setDirection(Direction)"
-msgstr "void setDirection(Direction)"
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:28
-msgid "void setBrushColor(Color)"
-msgstr "void setBrushColor(Color)"
+#. type: Content of: <h1>
+#: src/lessons/turmites/universe/TurmiteWorld.html:1
+msgid "Turmite universe"
+msgstr "L'univers des turmites"
 
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "void writeMessage(String)"
-msgstr "void writeMessage(String)"
+#. type: Content of: <p>
+#: src/lessons/turmites/universe/TurmiteWorld.html:3
+msgid ""
+"This universe is very similar to the buggle one, but you will probably not "
+"use all buggles methods.  So, this page only recap the buggle methods that "
+"you will use."
+msgstr ""
+"Cet univers est très semblable à celui des buggles, mais vous n'utiliserez "
+"probablement pas toutes les méthodes des buggles. Cette page résume donc les "
+"quelques méthodes que vous serez amenés à utiliser."
 
 #. type: Content of: <h3>
 #: src/lessons/sort/Main.html:1 src/lessons/sort/short_desc.html:1
@@ -7912,36 +7630,53 @@ msgstr "Tri à bulle"
 #. type: Content of: <p>
 #: src/lessons/sort/bubble/AlgBubbleSort1.html:3
 msgid ""
-"Welcome to the sorting world. It allows you to experiment with the existing "
-"sorting algorithms. The list of buildins that you can use in your algorithms "
-"is available in the world reference documentation (\"Help\"->\"About this "
-"world\")."
+"Welcome to the sorting universe. It allows you to experiment with the "
+"existing sorting algorithms. The list of buildins that you can use in your "
+"algorithms is available in the world reference documentation (\"Help\"->"
+"\"About this world\")."
+msgstr ""
+"Bienvenu dans l'univers des tris. Il permet d'expérimenter avec les "
+"algorithmes de tri existants. La liste des primitives que vous pouvez "
+"utiliser dans vos programmes est disponible dans la documentation de "
+"référence du monde (Aide / À propos de cet univers)."
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:7
+msgid ""
+"It is not enough to sort the array to pass the exercises. Your solution must "
+"strictly follow the expected behavior of each exercise. This is enforced by "
+"checking that your algorithm needs the same amount of read and write "
+"operations to sort the array."
 msgstr ""
-"Bienvenu au monde des tris. Il permet d'expérimenter avec les algorithmes de "
-"tri existants. La liste des primitives que vous pouvez utiliser dans vos "
-"programmes est disponible dans la documentation de référence du monde "
-"(Aide / À propos de ce monde)."
+"Il ne suffit pas de trier le tableau pour passer les exercices. Votre "
+"solution doit suivre scrupuleusement le comportement attendu de chaque "
+"exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et "
+"d'écriture sur le tableau effectuées lors de ce tri."
 
 #. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:14
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:12
 msgid ""
-"To help in this process, it is posible to graphically explore the history of "
-"your sorting algorithm. Switch to the Objective view and use the contextual "
-"menu (right click) to switch from the the view of the current state to the "
-"view of its history."
+"When your algorithm diverges from the expectation, understanding the "
+"difference between your code and the expected solution can reveal very "
+"difficult. To help in this process, it is posible to graphically explore the "
+"history of your sorting algorithm. Switch to the Objective view and use the "
+"contextual menu (right click)  to switch from the the view of the current "
+"state to the view of its history."
 msgstr ""
-"Pour cela, il est possible d'explorer graphiquement l'historique de "
-"n'importe quel monde de tri. Passez par exemple au monde Objectif et "
-"utilisez son menu contextuel (clic droit) pour choisir entre la vue de "
-"l'état courant du monde et la vue de son histoire."
+"Quand votre algorithme diverge de l'attendu, il peut être difficile de "
+"comprendre la différence de comportement. Pour cela, il est possible "
+"d'explorer graphiquement l'historique de n'importe quel monde de tri. Passez "
+"par exemple au monde Objectif et utilisez son menu contextuel (clic droit) "
+"pour choisir entre la vue de l'état courant du monde et la vue de son "
+"histoire."
 
 #. type: Content of: <h2>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:28
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:27
 msgid "First attempt at BubbleSort"
 msgstr "Première tentative pour le tri à bulle"
 
 #. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:30
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:29
 msgid ""
 "This first sorting algorithm is the most simple one: Bubble sort consists in "
 "progressively moving up the smaller elements of the array, as if they were "
@@ -7967,18 +7702,18 @@ msgstr ""
 "jamais utilisé en pratique."
 
 #. type: Attribute 'alt' of: <div>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:40
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:39
 #: src/lessons/sort/bubble/AlgBubbleSort2.html:11
 msgid "Show Tip (Pseudo-code)"
 msgstr "Montrer l'indice (le pseudo-code)"
 
 #. type: Content of: <div><p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:41
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:40
 msgid "The pseudo-code of the BubbleSort algorithm is the following:"
 msgstr "Le pseudo-code de l'algorithme du tri à bulles est donc le suivant :"
 
 #. type: Content of: <div><pre>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:42
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:41
 #, no-wrap
 msgid ""
 "do: \n"
@@ -8474,8 +8209,8 @@ msgstr ""
 #. type: Content of: <p><p>
 #: src/lessons/sort/shell/AlgShellSort.html:37
 msgid ""
-"Interesingly enough, determining the best gap sequence for shell sort turns "
-"into a contemporary research issue in computer science. For example, an "
+"Interestingly enough, determining the best gap sequence for shell sort turns "
+"into a research issue of our century in computer science. For example, an "
 "article of 2001 introduces the following sequence, which seems to be optimal "
 "in practice for arrays of size up to 10^5: {1, 4, 10, 23, 57, 132, 301, 701, "
 "1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th "
@@ -8483,8 +8218,8 @@ msgid ""
 "Vol. 2138)."
 msgstr ""
 "De façon intéressante, déterminer la meilleure séquence de gap pour le shell "
-"sort s'avère être un problème de recherche actuel en informatique. Par "
-"exemple, un article publié en 2001 propose la suite suivante, qui semble "
+"sort s'avère être un problème de recherche de notre siècle en informatique. "
+"Par exemple, un article publié en 2001 propose la suite suivante, qui semble "
 "optimale en pratique pour des tailles de tableau allant jusqu'à 10^5: {1, 4, "
 "10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the "
 "Average Case of Shellsort, 13th International Symposium on Fundamentals of "
@@ -8603,9 +8338,55 @@ msgstr ""
 "     ajouter ecart à i\n"
 " tant que l'écart est plus grand que 1 ou que le dernier parcours a inversé au moins un élément\n"
 
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/comb/AlgCombSort.html:26
+#: src/lessons/maze/island/IslandMaze.html:66
+#: src/lessons/welcome/bat/bool1/Max1020.html:5
+msgid "[!scala]"
+msgstr "[!scala]"
+
 #. type: Content of: <p>
 #: src/lessons/sort/comb/AlgCombSort.html:26
 msgid ""
+"One tricky part is that we want to divide gap, that is an integer, by 1.3, "
+"that is a double.  The type system of scala won't let us do this, because "
+"such discrepency usually denotes a programmer error.  As this is not an "
+"error this time, we have to convert gap to Double for the time of the "
+"operation, and then convert the result back to Int to store it into gap. "
+"This should be written this way:"
+msgstr ""
+"L'un des problèmes à résoudre est que la variable <code>ecart</code> est "
+"entière, et que nous voulons la diviser par 1.3, qui est un double. Le "
+"système de types de scala ne vous laissera pas faire une chose pareil sans "
+"broncher. C'est que ce genre de disparité est souvent le signe de problèmes "
+"que le programmeur n'a pas vu. Comme ce n'est pas une erreur dans notre cas, "
+"nous allons devoir convertir <code>ecart</code> en double pour le temps de "
+"l'opération, puis convertir le résultat de retour en entier pour le stocker "
+"dans <code>ecart</code>. Cela s'écrit de la manière suivante:"
+
+#. type: Content of: <pre>
+#: src/lessons/sort/comb/AlgCombSort.html:30
+#, no-wrap
+msgid "gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int]"
+msgstr "ecart = (ecart.asInstanceOf[Double] / 1.3).asInstanceOf[Int]"
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:31
+msgid ""
+"This is rather verbose, but actually, this notation is not very complex. And "
+"remember that the type checker is your friend. It's picky and sometimes "
+"annoying (as on this one), but it often catches weird bugs that would have "
+"been a pain to debug if not catched by the type checker."
+msgstr ""
+"C'est un peu bavard, mais finalement, cette écriture n'est pas très "
+"complexe. Et n'oubliez pas que le système de types est votre ami. Il est un "
+"peu tatillon et parfois un peu pénible (comme aujourd'hui), mais au fond, il "
+"trouve souvent des bugs bizarres qui auraient été très pénibles à débugger "
+"s'il ne les avait pas attrapé à la source."
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:36
+msgid ""
 "This algorithm was invented by Wlodek Dobosiewicz in 1980, and later "
 "rediscovered and popularized by Stephen Lacey and Richard Box, who described "
 "it in Byte Magazine in April 1991."
@@ -8713,12 +8494,12 @@ msgstr ""
 "tortue Logo."
 
 #. type: Content of: <h2>
-#: src/lessons/recursion/square/Square.html:1
+#: src/lessons/recursion/square/FourSquare.html:1
 msgid "The small cousines of Buggles"
 msgstr "Les petites cousines des Buggles"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/square/Square.html:3
+#: src/lessons/recursion/square/FourSquare.html:3
 msgid ""
 "Today, we will meet the small cousines of the buggles: the turtles. In fact, "
 "turtles are much olders than the buggles. They were invented in the 70's by "
@@ -8734,7 +8515,7 @@ msgstr ""
 "Wellesley College plus tard."
 
 #. type: Content of: <p>
-#: src/lessons/recursion/square/Square.html:9
+#: src/lessons/recursion/square/FourSquare.html:9
 msgid ""
 "Turtles are thus a bit like buggles, but smaller. Just like buggles, you can "
 "order them to move forward, to turn, to move backward, etc. Just like "
@@ -8746,8 +8527,8 @@ msgstr ""
 "Comme les buggles, elles laissent une trace sur leur passage quand elles "
 "avancent (simplement, le trait est bien plus fin)."
 
-#. type: Content of: <p><p>
-#: src/lessons/recursion/square/Square.html:14
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:14
 msgid ""
 "The main difference is that where buggles can only move of right angles, "
 "turtles can move of any arbitrary angles specified by a real number (a "
@@ -8764,70 +8545,74 @@ msgstr ""
 "objets, et il y a parfois des murs dans leur univers, mais tout cela dépasse "
 "complètement les tortues."
 
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:21
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:21
 msgid ""
 "From a practical point of view, most of the methods you knew about buggles "
 "still work with turtles, with some minor adaptations. In particular, the "
-"<code>forward()</code> method takes the amount of steps to do as a double "
-"(see \"About this world\" for more details)."
+"<code>forward()</code> method takes the amount of steps to do not as an "
+"integer, but as a [!python]point number[/!][!java|scala]double[/!] (see "
+"\"About this world\" for more details)."
 msgstr ""
 "D'un point de vue pratique, la plupart des méthodes que vous connaissez à "
 "propos des buggles fonctionnent également avec les tortues, à quelques "
-"variantes près. En particulier, la méthode <code>forward</code> prend en "
-"argument le nombre de pas donné comme un nombre double (voir «Aide / À "
-"propos de ce monde» dans le menu pour plus de détails)."
+"variantes près. En particulier, la méthode <code>avance</code> prend en "
+"argument le nombre de pas donné comme un [!python]nombre à virgule[/!][!"
+"scala|java]double[/!] (voir «Aide / À propos de ce monde» dans le menu pour "
+"plus de détails)."
 
-#. type: Content of: <p><p><p><h3>
-#: src/lessons/recursion/square/Square.html:26
+#. type: Content of: <h3>
+#: src/lessons/recursion/square/FourSquare.html:28
 msgid "Doubles? But what is it?"
 msgstr "Des doubles ? Mais qu'est ce que c'est ?"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:27
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/square/FourSquare.html:29
 msgid "It's simply a point number. Example:"
 msgstr "C'est simplement un nombre à virgule. Exemple:"
 
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/recursion/square/Square.html:29
+#. type: Content of: <pre>
+#: src/lessons/recursion/square/FourSquare.html:31
 #, no-wrap
 msgid ""
 "double x = 3.72;\n"
 "x + 1.234 // Value = 4.954\n"
-"x + 2 // Value = 5.72 (2 converted to 2.0 automatically)\n"
-"x * 2 // Value = 7.44 (2 converted to 2.0 automatically)\n"
-"x / 2 // Value = 1.86 (2 converted to 2.0 automatically)\n"
-"(int) x // Value = 1 (“casting to int”, converted to integer by truncating)\n"
+"x + 2. // Value = 5.72 (2. means 2.0)\n"
+"x + 2 // [!java]Value = 5.72 (2 automatically converted to 2.0)[/!][!scala]Type error (+ operator don't mix Double and Int); manual conversion mandatory[/!]\n"
+"x * 2. // Value = 7.44 \n"
+"x / 2. // Value = 1.86 \n"
+"[!java](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Value = 1 (“casting to int”, converted to integer by truncating)\n"
 "Math.round(x) // Value = 2 (1.86 rounded to nearest integer)\n"
 "Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)\n"
 "Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)\n"
 "Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)\n"
 "Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)\n"
-"(double) 17 // Value = 17.0 (“casted to double”, converted to double)\n"
+"[!java](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“casted to double”, converted to double)\n"
 msgstr ""
 "double x = 3.72;\n"
 "x + 1.234 // Valeur = 4.954\n"
-"x + 2 // Valeur = 5.72 (2 converti en 2.0 automatiquement)\n"
-"x * 2 // Valeur = 7.44 (2 converti en 2.0 automatiquement)\n"
-"x / 2 // Valeur = 1.86 (2 converti en 2.0 automatiquement)\n"
-"(int) x // Valeur = 1 (“transtypage en int”, converti en entier en tronquant)\n"
+"x + 2. // Valeur = 5.72 (2. signifie 2.0)\n"
+"x + 2 // [!java]Valeur = 5.72 (2 converti en 2.0 automatiquement)[/!][!scala]Erreur de typage (l'opérateur + operator ne mélange pas les Double avec les Int). Il faut convertir explicitement[/!]\n"
+"x * 2. // Valeur = 7.44\n"
+"x / 2. // Valeur = 1.86 (2 converti en 2.0 automatiquement)\n"
+"[!java](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Valeur = 1 (“transtypage en int”, converti en entier en tronquant)\n"
 "Math.round(x) // Valeur = 2 (1.86 arrondi à l'entier le plus proche)\n"
 "Math.floor(x) // Valeur = 1 (1.86 arrondi en direction de moins l'infini)\n"
 "Math.floor(-5.12) // Vale = -6 (Arrondi en direction de moins l'infini)\n"
 "Math.ceiling(x) // Value = 2 (1.86 arrondi en direction de plus l'infini)\n"
 "Math.ceiling(-5.12) // Value = -5 (Arrondi en direction de plus l'infini)\n"
-"(double) 17 // Value = 17.0 (“transtypage en double”, converti en double)\n"
+"[!java](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“transtypage en double”, converti en double)\n"
 
-#. type: Content of: <br><p><p><p><p><p><h2>
-#: src/lessons/recursion/square/Square.html:43
+#. type: Content of: <p><p><p><h2>
+#: src/lessons/recursion/square/FourSquare.html:47
 #: src/lessons/recursion/circle/Circle.html:14
 #: src/lessons/recursion/hanoi/HanoiBoard.html:20
-#: src/lessons/welcome/array/basics/Array.html:210
+#: src/lessons/welcome/array/basics/Array1.html:229
 msgid "Goal of this exercise"
 msgstr "Objectif de l'exercice"
 
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:44
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:48
 msgid ""
 "Even if this is the first exercise on the recursivity lesson, the code you "
 "have to write is not recursive. The goal is to get familiar with the turtle "
@@ -8837,33 +8622,18 @@ msgstr ""
 "que vous devez écrire n'est pas récursif. L'objectif est de se familiariser "
 "avec le monde des tortues avant d'attaquer les choses sérieuses."
 
-#. type: Content of: <p><p><p><p>
-#: src/lessons/recursion/square/Square.html:48
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:52
 msgid ""
 "You must reproduce a simple geometrical painting constituted of four 100 "
 "steps long squares (see the objective world for more details). It is "
 "obviously a good idea to write a method to draw a square, and then use it in "
-"your <code>run()</code> in charge of doing the work. You must absolutely "
-"write at least the run method, which prototype is the following:"
+"your code."
 msgstr ""
 "Vous devez reproduire une forme géométrique simple faite de quatre carrés de "
 "longueur 100 de coté (voir le monde objectif pour plus de détails). C'est "
 "sans doute une bonne idée d'écrire une méthode pour faire un carré, et de la "
-"réutiliser lors de l'écriture de la méthode <code>run()</code> qui fait le "
-"travail. Il est indispensable d'écrire au moins la méthode run, dont le "
-"prototype est le suivant:"
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/recursion/square/Square.html:54
-#, no-wrap
-msgid ""
-"public void run() {\n"
-"  // write here what your turtle is supposed to do\n"
-"}"
-msgstr ""
-"public void run() {\n"
-"  // ecrivez ici ce que doit faire votre tortue\n"
-"}"
+"réutiliser lors de l'écriture de votre code."
 
 #. type: Content of: <h2>
 #: src/lessons/recursion/polygonfractal/PolygonFractal.html:1
@@ -8883,14 +8653,14 @@ msgstr ""
 #. type: Content of: <pre>
 #: src/lessons/recursion/polygonfractal/PolygonFractal.html:5
 #, no-wrap
-msgid "void polygonFractal (int levels, int sides, double length, double shrink)"
-msgstr "void polygonFractal (int levels, int sides, double length, double shrink)"
+msgid "[!java]void [/!]polygonFractal ([!java]int [/!]levels[!scala]:Int[/!], [!java]int [/!]sides[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!], [!java]double [/!]shrink[!scala]:Double[/!])"
+msgstr "[!java]void [/!]polygonFractal ([!java]int [/!]niveaux[!scala]:Int[/!], [!java]int [/!]cotés[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!], [!java]double [/!]multiplicateur[!scala]:Double[/!])"
 
 #. type: Content of: <p>
 #: src/lessons/recursion/polygonfractal/PolygonFractal.html:7
 #: src/lessons/recursion/sierpinski/Sierpinski.html:8
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:27
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:50
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:25
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:44
 msgid ""
 "Have a look at each world's objective view to understand how to write the "
 "function."
@@ -8927,23 +8697,23 @@ msgstr ""
 #: src/lessons/recursion/koch/Koch.html:8
 #, no-wrap
 msgid ""
-"void snowFlake (int levels, double length) {\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"}"
-msgstr ""
-"void snowFlake (int levels, double length) {\n"
+"[!java]void [/!]snowFlake ([!java]int [/!]levels[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!])[!python]:[/!][!java|scala] {[/!]\n"
 "   snowSide(levels, length);\n"
-"   turnRight(120);\n"
+"   right(120);\n"
 "   snowSide(levels, length);\n"
-"   turnRight(120);\n"
+"   right(120);\n"
 "   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"}"
+"   right(120);\n"
+"[!java|scala]}[/!]"
+msgstr ""
+"[!java]void [/!]snowFlake ([!java]int [/!]niveaux[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!])[!python]:[/!][!java|scala] {[/!]\n"
+"   snowSide(niveaux, longueur);\n"
+"   right(120);\n"
+"   snowSide(niveaux, longueur);\n"
+"   right(120);\n"
+"   snowSide(niveaux, longueur);\n"
+"   right(120);\n"
+"[!java|scala]}[/!]"
 
 #. type: Content of: <p><p>
 #: src/lessons/recursion/koch/Koch.html:17
@@ -9021,29 +8791,30 @@ msgstr ""
 msgid ""
 "Differential calculus would even argue that a circle is the asymptotical "
 "limit of such construct when the size of each segment becomes infinitely "
-"small while their amount becomes infinitely large (but it is still possible "
-"to solve this exercise without understanding differential calculus)."
+"small while their amount becomes infinitely large, but you can definitely "
+"solve this exercise without understanding differential calculus :)"
 msgstr ""
 "Les amateurs de calcul différentiel diraient même sans doute qu'un cercle "
 "est la limite asymptotique d'une telle construction quand la taille des "
-"segments tend vers zéro alors que leur nombre tend vers l'infini (mais on "
-"peut tout de même réussir l'exercice sans maîtriser le calcul différentiel)."
+"segments tend vers zéro alors que leur nombre tend vers l'infini, mais il "
+"est tout à fait possible de réussir cet exercice sans maîtriser le calcul "
+"différentiel :)"
 
 #. type: Content of: outside any tag (error?)
 #: src/lessons/recursion/circle/Circle.html:16
 msgid ""
 "Write a function drawing a circle, taking the size of each of the 360 "
-"segments as parameter. Then use it in your <code>run()</code> method to draw "
-"the whole picture. The first circle is obtained with segments of size 0.5, "
-"the second with segments of size 1 and the last one with 1.5-long segments. "
-"Once again, this is a hand-on exercise, no recursion is needed."
+"segments as parameter. Then use it in your code to draw the whole picture.  "
+"The first circle is obtained with segments of size 0.5, the second with "
+"segments of size 1 and the last one with 1.5-long segments.  Once again, "
+"this is a warming exercise, no recursion is needed."
 msgstr ""
 "Écrivez une fonction dessinant un cercle, avec la taille de chacun des 360 "
-"pas passée en paramètre. Utilisez la ensuite dans votre méthode <code>run()</"
-"code> pour réaliser la figure dans son ensemble. Le premier cercle s'obtient "
-"avec des pas de 0.5, le second avec des pas de 1 et le troisième avec des "
-"pas de 1.5. Encore une fois, il s'agit d'un exercice de prise en main, et "
-"aucune récursion n'est nécessaire."
+"pas passée en paramètre. Utilisez la ensuite dans votre code pour réaliser "
+"la figure dans son ensemble. Le premier cercle s'obtient avec des pas de "
+"0.5, le second avec des pas de 1 et le troisième avec des pas de 1.5. Encore "
+"une fois, il s'agit d'un exercice de prise en main, et aucune récursion "
+"n'est nécessaire."
 
 #. type: Content of: <h2>
 #: src/lessons/recursion/tree/Tree.html:1
@@ -9062,8 +8833,8 @@ msgstr ""
 #. type: Content of: <pre>
 #: src/lessons/recursion/tree/Tree.html:5
 #, no-wrap
-msgid "void tree(int steps, double length, double angle, double shrink)"
-msgstr "void tree(int steps, double length, double angle, double shrink)"
+msgid "[!java]void [/!]tree([!java]int [/!]steps[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!], [!java]double [/!]angle[!scala]:Double[/!], [!java]double [/!]shrink[!scala]:Double[/!])"
+msgstr "[!java]void [/!]tree([!java]int [/!]nbPas[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!], [!java]double [/!]angle[!scala]:Double[/!], [!java]double [/!]multiplicateur[!scala]:Double[/!])"
 
 #. type: Content of: <p>
 #: src/lessons/recursion/tree/Tree.html:7
@@ -9092,7 +8863,7 @@ msgstr ""
 msgid "Sierpinski's Triangle"
 msgstr "Triangle de Sierpinski"
 
-#. type: Content of: outside any tag (error?)
+#. type: Content of: <p>
 #: src/lessons/recursion/sierpinski/Sierpinski.html:3
 msgid ""
 "The fractal we will now draw is formed of a big triangle inside which "
@@ -9106,8 +8877,8 @@ msgstr ""
 #. type: Content of: <pre>
 #: src/lessons/recursion/sierpinski/Sierpinski.html:6
 #, no-wrap
-msgid "void sierpinski(int level, double length)"
-msgstr "void sierpinski(int level, double length)"
+msgid "[!java]void [/!]sierpinski([!java]int [/!]level[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!])"
+msgstr "[!java]void [/!]sierpinski([!java]int [/!]niveau[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!])"
 
 #. type: Content of: <h2>
 #: src/lessons/recursion/spiral/Spiral.html:1
@@ -9128,8 +8899,8 @@ msgstr ""
 #. type: Content of: <pre>
 #: src/lessons/recursion/spiral/Spiral.html:6
 #, no-wrap
-msgid "void spiral(int steps, int angle, int length, int increment)"
-msgstr "void spiral(int steps, int angle, int length, int increment)"
+msgid "[!java]void [/!]spiral([!java]int [/!]steps[!scala]:Int[/!], [!java]int [/!]angle[!scala]:Int[/!], [!java]int [/!]length[!scala]:Int[/!], [!java]int [/!]increment[!scala]:Int[/!])"
+msgstr "[!java]void [/!]spiral([!java]int [/!]nbPas[!scala]:Int[/!], [!java]int [/!]angle[!scala]:Int[/!], [!java]int [/!]longueur[!scala]:Int[/!], [!java]int [/!]increment[!scala]:Int[/!])"
 
 #. type: Content of: outside any tag (error?)
 #: src/lessons/recursion/spiral/Spiral.html:8
@@ -9146,36 +8917,36 @@ msgstr ""
 msgid ""
 "spiral(5, 90, 0, 3);\n"
 "  forward(0);\n"
-"  turnLeft(90);\n"
+"  left(90);\n"
 "  spiral(4,90,3,3);\n"
 "    forward(3);\n"
-"    turnLeft(90);\n"
+"    left(90);\n"
 "    spiral(3,90,6,3);\n"
 "      forward(6);\n"
-"      turnLeft(90);\n"
+"      left(90);\n"
 "      spiral(2,90,9,3);\n"
 "        forward(9);\n"
-"        turnLeft(90);\n"
+"        left(90);\n"
 "        spiral(1,90,12,3);\n"
 "          forward(12);\n"
-"          turnLeft(90);\n"
+"          left(90);\n"
 "          spiral(0,90,12,3);\n"
 msgstr ""
 "spiral(5, 90, 0, 3);\n"
-"  forward(0);\n"
-"  turnLeft(90);\n"
+"  avance(0);\n"
+"  gauche(90);\n"
 "  spiral(4,90,3,3);\n"
-"    forward(3);\n"
-"    turnLeft(90);\n"
+"    avance(3);\n"
+"    gauche(90);\n"
 "    spiral(3,90,6,3);\n"
-"      forward(6);\n"
-"      turnLeft(90);\n"
+"      avance(6);\n"
+"      gauche(90);\n"
 "      spiral(2,90,9,3);\n"
-"        forward(9);\n"
-"        turnLeft(90);\n"
+"        avance(9);\n"
+"        gauche(90);\n"
 "        spiral(1,90,12,3);\n"
-"          forward(12);\n"
-"          turnLeft(90);\n"
+"          avance(12);\n"
+"          gauche(90);\n"
 "          spiral(0,90,12,3);\n"
 
 #. type: Content of: <h2>
@@ -9195,12 +8966,13 @@ msgstr ""
 #. type: Content of: <p>
 #: src/lessons/recursion/spiral/SpiralUse.html:6
 msgid ""
-"You must provide a method called <code>doit(int)</code> taking the number of "
-"the page to draw as parameter. Its code is as following, with A0, B0, etc "
-"being integers. The goal of this exercise is to find the good values for "
-"each page."
+"You must provide a method called <code>doit(page)</code> taking the page "
+"number to draw as parameter. Its code is as following, with A0, B0, etc "
+"being integers.  The goal of this exercise is to find the good values for "
+"each page, which requires to correctly understand how the spiral method "
+"works."
 msgstr ""
-"Vous devez écrire une méthode <code>doit(int)</code> qui prend en paramètre "
+"Vous devez écrire une méthode <code>doit(page)</code> qui prend en paramètre "
 "le numéro de la page à dessiner. Son code est de la forme suivante. A0, B0, "
 "etc sont des nombres entiers. L'objectif de l'exercice est de retrouver les "
 "valeurs convenables pour chaque page."
@@ -9209,48 +8981,48 @@ msgstr ""
 #: src/lessons/recursion/spiral/SpiralUse.html:12
 #, no-wrap
 msgid ""
-"void doit(int page) {\n"
-"  switch (page) {\n"
-"    case 0: /* Drawing of the first page, dubbed \"One\" */\n"
+"[!java]void [/!]doit([!java]int [/!]page[!scala]:Int[/!])[!python]:[/!][!java|scala] {[/!]\n"
+"  [!java]switch (page) {[/!][!scala]page match {[/!][!python]  # select on the value of page[/!]\n"
+"    [!java]case 0:[/!][!scala]case 0 =>[/!][!python]if page==0:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the first page, dubbed \"One\"</span>\n"
 "      spiral(A0,B0,C0,D0);\n"
-"      break;\n"
-"    case 1: /* Drawing of the second page, dubbed \"Two\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 1:[/!][!scala]case 1 =>[/!][!python]if page==1:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the second page, dubbed \"Two\"</span>\n"
 "      spiral(A1,B1,C1,D1);\n"
-"      break;\n"
-"    case 2: /* Drawing of the page dubbed \"Three\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 2:[/!][!scala]case 2 =>[/!][!python]if page==2:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed \"Three\"</span> \n"
 "      spiral(A2,B2,C2,D2);\n"
-"      break;\n"
-"    case 3: /* Drawing of the page dubbed \"Four\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 3:[/!][!scala]case 3 =>[/!][!python]if page==3:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed \"Four\"</span> \n"
 "      spiral(A3,B3,C3,D3);\n"
-"      break;\n"
-"    case 4: /* Drawing of the page dubbed \"Five\" */\n"
-"      spiral(A4,B4,C4,D4);\n"
-"      break;\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 4:[/!][!scala]case 4 =>[/!][!python]if page==4:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed \"Five\"</span>\n"
+"      spiral(A4,B4,C4,D4);[!java|scala]\n"
+"[!java]      break;[/!]\n"
 "  }\n"
-"}\n"
+"}[/!]"
 msgstr ""
-"void doit(int page) {\n"
-"  switch (page) {\n"
-"    case 0: /* Dessin de la première page, marquée \"One\" */\n"
+"[!java]void [/!]doit([!java]int [/!]page[!scala]:Int[/!])[!python]:[/!][!java|scala] {[/!]\n"
+"  [!java]switch (page) {[/!][!scala]page match {[/!][!python]  # Choix en fonction de la valeur de page[/!]\n"
+"    [!java]case 0:[/!][!scala]case 0 =>[/!][!python]if page==0:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Dessin sur la première page, nommée \"One\"</span>\n"
 "      spiral(A0,B0,C0,D0);\n"
-"      break;\n"
-"    case 1: /* Dessin de la seconde page, marquée \"Two\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 1:[/!][!scala]case 1 =>[/!][!python]if page==1:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Dessin sur la seconde page, nommée \"Two\"</span>\n"
 "      spiral(A1,B1,C1,D1);\n"
-"      break;\n"
-"    case 2: /* Dessin de la page marquée \"Three\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 2:[/!][!scala]case 2 =>[/!][!python]if page==2:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Dessin sur la troisième page, nommée \"Three\"</span> \n"
 "      spiral(A2,B2,C2,D2);\n"
-"      break;\n"
-"    case 3: /* Dessin de la page marquée \"Four\" */\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 3:[/!][!scala]case 3 =>[/!][!python]if page==3:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Dessin sur la quatrième page, nommée \"Four\"</span> \n"
 "      spiral(A3,B3,C3,D3);\n"
-"      break;\n"
-"    case 4: /* Dessin de la page marquée \"Five\" */\n"
-"      spiral(A4,B4,C4,D4);\n"
-"      break;\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 4:[/!][!scala]case 4 =>[/!][!python]if page==4:[/!] <span class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Dessin sur la cinquième page, nommée \"Five\"</span>\n"
+"      spiral(A4,B4,C4,D4);[!java|scala]\n"
+"[!java]      break;[/!]\n"
 "  }\n"
-"}\n"
+"}[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/spiral/SpiralUse.html:34
+#: src/lessons/recursion/spiral/SpiralUse.html:33
 msgid ""
 "No need to copy over the method of <code>spiral()</code>, the turtle of this "
 "exercise already knows it."
@@ -9296,9 +9068,9 @@ msgstr ""
 "si P et Q sont les points de coordonnées (x, y) et (z,t), les coordonnées "
 "(u, v) de R sont"
 
-#. type: Content of: <p><pre>
+#. type: Content of: <pre>
 #: src/lessons/recursion/dragoncurve/DragonCurve1.html:13
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:27
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:26
 #, no-wrap
 msgid ""
 "u = (x + z)/2 + (t - y)/2\n"
@@ -9308,26 +9080,26 @@ msgstr ""
 "v = (y + t)/2 - (z - x)/2\n"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:19
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:17
 msgid "The prototype of the method drawing the curve is the following:"
 msgstr "Le prototype de la méthode traçant la courbe est le suivant :"
 
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:20
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:18
 #: src/lessons/recursion/dragoncurve/DragonCurve2.html:22
 #, no-wrap
-msgid "void dragon(int ordre, double x, double y, double z, double t)"
-msgstr "void dragon(int ordre, double x, double y, double z, double t)"
+msgid "[!java]void [/!]dragon([!java]int [/!]order[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])"
+msgstr "[!java]void [/!]dragon([!java]int [/!]ordre[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:23
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:21
 msgid ""
 "You should use the method <code>setPos(x,y)</code> to put your turtle at "
 "coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line "
-"between the turtle position and the point (z,t)."
+"between the turtle position and the point(z,t)."
 msgstr ""
 "Vous utiliserez la méthode <code>setPos(x,y)</code> pour déplacer votre "
-"tortue aux coordonnées (x,y) et la méthode <code>moveTo(z,t)</code> pour "
+"tortue aux coordonnées (x,y) et la méthode <code>allerVers(z,t)</code> pour "
 "tracer un trait depuis le point où la tortue est positionnée vers le point "
 "de coordonnées (z,t)"
 
@@ -9396,19 +9168,19 @@ msgstr ""
 "<code>dragon()</code> seront :"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:33
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:30
 msgid "The prototype of the method <code>dragonReverse</code> is similar:"
 msgstr ""
 "Le prototype de la méthode <code>dragonInverse()</code> est identique : :"
 
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:34
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:31
 #, no-wrap
-msgid "void dragonReverse(int ordre, double x, double y, double z, double t)"
-msgstr "void dragonInverse(int ordre, double x, double y, double z, double t)"
+msgid "[!java]void [/!]dragonReverse([!java]int [/!]order[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])"
+msgstr "[!java]void [/!]dragonReverse([!java]int [/!]ordre[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:36
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:33
 msgid ""
 "The new point's coordinate (u, v) introduced by the <code>dragonReverse()</"
 "code> are:"
@@ -9416,8 +9188,8 @@ msgstr ""
 "Les coordonnées (u, v) du nouveau point introduit par la méthode "
 "<code>dragonInverse()</code> seront :"
 
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:39
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:35
 #, no-wrap
 msgid ""
 "u = (x + z)/2 - (t - y)/2\n"
@@ -9427,7 +9199,7 @@ msgstr ""
 "v = (y + t)/2 + (z - x)/2\n"
 
 #. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:45
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:39
 msgid ""
 "To make the work of each method recursiv more visible, the line painted by "
 "the <code>dragon()</code> must be red (<code>Color.red</code>) while the "
@@ -9518,10 +9290,11 @@ msgstr "Aucun disque ne peut être placé au dessus d'un disque plus petit."
 #. type: Content of: outside any tag (error?)
 #: src/lessons/recursion/hanoi/HanoiBoard.html:22
 msgid ""
-"Write the core of the method: <code>public void solve(int src, int dst, int "
-"height) throws HanoiInvalidMove</code> This method will recursively solve "
-"the presented problem. First parameter named <code>src</code> is the index "
-"of the initial tower, second parameter <code>dst</code> is the index of the "
+"Write the core of the method: <code>[!java]void [/!]solve([!java]int "
+"[/!]src[!scala]:Int[/!], [!java]int [/!]dst[!scala]:Int[/!], [!java]int "
+"[/!]height[!scala]:Int[/!])</code> This method will recursively solve the "
+"presented problem. First parameter named <code>src</code> is the index of "
+"the initial tower, second parameter <code>dst</code> is the index of the "
 "expected final tower, and the third parameter <code>height</code> is the "
 "height of the tower.  A key to solving this puzzle is to recognize that it "
 "can be solved by breaking the problem down into a collection of smaller "
@@ -9529,8 +9302,9 @@ msgid ""
 "until a solution is reached.  The following procedure demonstrates this "
 "approach:"
 msgstr ""
-"Ecrivez le coeur de la méthode <code>public void solve(int src, int dst, int "
-"height) throws HanoiInvalidMove</code>. Cette méthode résoudra de manière "
+"Écrivez le coeur de la méthode <code>[!java]void [/!]solve([!java]int "
+"[/!]src[!scala]:Int[/!], [!java]int [/!]dst[!scala]:Int[/!], [!java]int "
+"[/!]height[!scala]:Int[/!])</code>. Cette méthode résoudra de manière "
 "récursibe le problème. Le premier paramètre, nommé <code>src</code>, est "
 "l'index de la tour initiale, le second paramètre  <code>dst</code> est "
 "l'index de la tour final souhaitée, et le troisième paramètre <code>height</"
@@ -9566,20 +9340,21 @@ msgstr "Pour déplacer n disques du poteau A au poteau C : "
 
 #. type: Content of: <ul><li>
 #: src/lessons/recursion/hanoi/HanoiBoard.html:43
-msgid "move n−1 discs from A to B. This leaves disc #n alone on peg A"
+msgid "move n−1 discs from A to B. This leaves disc number n alone on peg A"
 msgstr ""
-"déplcacer n-1 disques de A vers B. Cela laisse le disque #n seul sur le "
+"déplacer n-1 disques de A vers B. Cela laisse le disque numéro n seul sur le "
 "poteau A"
 
 #. type: Content of: <ul><li>
 #: src/lessons/recursion/hanoi/HanoiBoard.html:44
-msgid "move disc #n from A to C"
-msgstr "déplacer le disque #n de A vers C"
+msgid "move disc number n from A to C"
+msgstr "déplacer le disque numéro n de A vers C"
 
 #. type: Content of: <ul><li>
 #: src/lessons/recursion/hanoi/HanoiBoard.html:45
-msgid "move n−1 discs from B to C so they sit on disc #n"
-msgstr "deplacer n-1 disques de B vers C afin qu'ils reposent sur le disque #n"
+msgid "move n−1 discs from B to C so they sit on disc number n"
+msgstr ""
+"deplacer n-1 disques de B vers C afin qu'ils reposent sur le disque numéro n"
 
 #. type: Content of: <h1>
 #: src/lessons/recursion/hanoi/universe/HanoiWorld.html:1
@@ -9610,17 +9385,11 @@ msgstr "Seules trois fonctions sont fournies :"
 #. type: Content of: <pre>
 #: src/lessons/recursion/hanoi/universe/HanoiWorld.html:13
 #, no-wrap
-msgid "void move(int src, int dst)"
-msgstr "void move(int src, int dst)"
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:14
-#, no-wrap
-msgid "move(src, dst) throws HanoiInvalidMove"
-msgstr "move(src, dst) throws HanoiInvalidMove"
+msgid "[!java]void [/!]move([!java]int [/!]src, [!java]int [/!]dst)"
+msgstr "[!java]void [/!]deplace([!java]int [/!]src, [!java]int [/!]dst)"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:16
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:15
 msgid ""
 "Moves one disk from the stick <code>src</code> onto the stick <code>dst</"
 "code>. If you try to do an invalid move (like laying a disk over a smaller "
@@ -9632,19 +9401,13 @@ msgstr ""
 "IllegalArgumentException est levée."
 
 #. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:20
-#, no-wrap
-msgid "int getSlotSize(int slot);"
-msgstr "int getSlotSize(int slot);"
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:21
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:19
 #, no-wrap
-msgid "getSlotSize(slot)"
-msgstr "getSlotSize(slot)"
+msgid "[!java]int [/!]getSlotSize([!java]int [/!]slot)[!scala]:Int[/!]"
+msgstr "[!java]int [/!]getTaillePiquet([!java]int [/!]slot)[!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:22
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:20
 msgid ""
 "Returns the amount of disks placed on the specified slot. This is mainly "
 "used to initialize the recursion and set the amount of recursive call to "
@@ -9678,8 +9441,8 @@ msgid ""
 "The day of your buggle starts badly. Out of luck, it got trapped into a "
 "maze. Help it finding its path out of there."
 msgstr ""
-"La journée de votre buggle commence mal. Il n'a pas eu de chance. Il est "
-"tombé dans un piège.  Aidez le à sortir de ce labyrinthe."
+"La journée de votre buggle commence mal. Elle n'a pas eu de chance. Elle est "
+"tombée dans un piège.  Aidez-la à sortir de ce labyrinthe."
 
 #. type: Content of: <p>
 #: src/lessons/maze/randommouse/RandomMouseMaze.html:8
@@ -9708,25 +9471,21 @@ msgid ""
 "<code>random3()</code> method and make one of the following actions: moving "
 "forward if possible, turn left or turn right."
 msgstr ""
-"Tant que notre buggle n'a pas trouvé la sortie, il doit progresser de la "
+"Tant que notre buggle n'a pas trouvé la sortie, elle doit progresser de la "
 "façon suivante : choisir un entier entre 0 et 2 au hasard à l'aide de "
 "la méthode <code>random3()</code> fournie et prendre l'une des décisions "
-"suivantes selon l'entier choisi : avancer si il le peut, tourner à "
+"suivantes selon l'entier choisi : avancer si elle le peut, tourner à "
 "droite ou bien tourner à gauche."
 
-#. type: Content of: <a><p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:27
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:24
 msgid ""
-"This exercise's objective is to write an algorithm allowing the buggle to "
-"find its path out of the maze."
+"You don't believe that it could work? Well, give it a try, you will see...  "
+"Don't forget to pick up the baggle once you've reached it."
 msgstr ""
-"L'objectif de cet exercice est d'écrire un algorithme permettant à votre "
-"buggle de sortir du labyrinthe."
-
-#. type: Content of: <a><p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:32
-msgid "Don't forget to pick up the baggle once you've reached it."
-msgstr "N'oubliez pas de ramasser le baggle quand vous l'avez trouvé."
+"Vous ne croyez pas qu'une méthode aussi stupide puisse fonctionner ? Et "
+"bien, essayez, vous verrez bien.\n"
+"N'oubliez pas de ramasser le biscuit quand vous l'avez trouvé."
 
 #. type: Content of: <h2>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:1
@@ -9756,8 +9515,8 @@ msgstr ""
 "sont connectés les uns aux autres. Pour sortir de ce genre de labyrinthe, il "
 "suffit à votre buggle de longer un mur (celui à sa droite, ou celui à sa "
 "gauche: c'est sans importance). Tout en gardant sa patte posée sur ce mur, "
-"votre buggle doit avancer jusqu'à ce qu'il trouve la sortie du labyrinthe et "
-"ce biscuit qu'il apprécie tant."
+"votre buggle doit avancer jusqu'à ce qu'elle trouve la sortie du labyrinthe "
+"et ce biscuit qu'il apprécie tant."
 
 #. type: Content of: <p>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:13
@@ -9799,12 +9558,12 @@ msgid ""
 "it won't crash into a wall. You can check the tip for more info on this, but "
 "only do so if you're stuck. Try to do it without the tip first."
 msgstr ""
-"Écrivez une méthode <code>keepHandOnSideWall()</code> qui fait avancer\n"
-"votre buggle d'une case tout en gardant la patte sur le mur du côté\n"
-"choisi. Vous devez vous assurer que votre buggle garde toujours la patte\n"
-"sur le mur et également qu'il ne risque pas de percuter un mur. Vous pouvez\n"
-"regarder l'indice (hint) si vous êtes coincés, mais vous devriez d'abord\n"
-"essayer de le faire par vous-même."
+"Écrivez une méthode <code>keepHandOnSideWall()</code> qui fait avancer votre "
+"buggle d'une case tout en gardant la patte sur le mur du côté choisi. Vous "
+"devez vous assurer que votre buggle garde toujours la patte sur le mur et "
+"également qu'elle ne risque pas de percuter un mur. Vous pouvez regarder "
+"l'indice (hint) si vous êtes coincé, mais vous devriez d'abord essayer de le "
+"faire par vous-même."
 
 #. type: Content of: <p>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:32
@@ -9814,8 +9573,7 @@ msgid ""
 "Don't forget to pick the baggle up once you've found it."
 msgstr ""
 "Enfin, écrivez l'algorithme complet qui parcourt le labyrinthe pas à pas "
-"jusqu'à\n"
-"trouver le biscuit et la sortie. N'oubliez pas de prendre le baggle."
+"jusqu'à trouver le biscuit et la sortie. N'oubliez pas de prendre le baggle."
 
 #. type: Attribute 'alt' of: <div>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:37
@@ -9831,24 +9589,24 @@ msgid ""
 "step."
 msgstr ""
 "Quand votre buggle a un mur à sa gauche, il faut considérer trois situations "
-"possible, qui dépendent des murs alentours. Le tableau suivant représente "
+"possibles, qui dépendent des murs alentours. Le tableau suivant représente "
 "graphiquement chaque situation initiale, et où vous devez placer votre "
 "buggle à la fin de l'étape."
 
 #. type: Content of: <div><table><tr><td>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:45
 msgid "Case 1"
-msgstr "Case 1"
+msgstr "Cas 1"
 
 #. type: Content of: <div><table><tr><td>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:46
 msgid "Case 2"
-msgstr "Case 2"
+msgstr "Cas 2"
 
 #. type: Content of: <div><table><tr><td>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:47
 msgid "Case 3"
-msgstr "Case 3"
+msgstr "Cas 3"
 
 #. type: Content of: <div><table><tr><td>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:49
@@ -9863,12 +9621,11 @@ msgstr "Étape suivante"
 #. type: Content of: <div><p>
 #: src/lessons/maze/wallfollower/WallFollowerMaze.html:60
 msgid ""
-"If you do a <code>turnRight()</code> in any case at the end of your "
-"function, it's possible to write it in 3 lines with a <code>while</code> "
-"loop."
+"If you do a <code>right()</code> in any case at the end of your function, "
+"it's possible to write it in 3 lines with a <code>while</code> loop."
 msgstr ""
-"Si vous faites un <code>turnRight()</code> dans tous les cas à la fin de "
-"votre fonction, il est possible de l'écrire en trois lignes avec une boucle "
+"Si vous faites un <code>right()</code> dans tous les cas à la fin de votre "
+"fonction, il est possible de l'écrire en trois lignes avec une boucle "
 "<code>while</code>."
 
 #. type: Content of: <h2>
@@ -9887,15 +9644,14 @@ msgid ""
 "point, it finds the north direction free, run into that direction, and falls "
 "again in the trap."
 msgstr ""
-"Une fois de plus, vous pensiez que votre algorithme vous permettait de vous\n"
+"Une fois de plus, vous pensiez que votre algorithme vous permettait de vous "
 "échapper des labyrinthes, et une fois de plus, votre buggle est prise dans "
-"un\n"
-"labyrinthe mettant votre algorithme en défaut. Vous essayer de copier votre "
-"code\n"
-"et de l'exécuter pour voir votre création échouer. Le piège a la forme d'un "
-"«G» majuscule : la buggle entre dans le piège, suit le bord interne. Au bout "
-"d'un moment, la direction nord est libre et votre buggle se met donc à "
-"courir dans cette direction. Pour retomber dans le piège..."
+"un labyrinthe mettant votre algorithme en défaut. Essayez de copier votre "
+"code et de l'exécuter pour voir : votre création précédente échoue "
+"lamentablement. Le piège a la forme d'un «G» majuscule : la buggle entre "
+"dans le piège, suit le bord interne. Au bout d'un moment, la direction nord "
+"est libre et votre buggle se met donc à courir dans cette direction. Pour "
+"retomber dans le piège..."
 
 #. type: Content of: <p>
 #: src/lessons/maze/pledge/PledgeMaze.html:13
@@ -9903,7 +9659,7 @@ msgid ""
 "The Pledge's algorithm (named after Jon Pledge of Exeter) can solve this "
 "maze."
 msgstr ""
-"L'algorithme de Pledge (nommé d'après Jon Pledge d'Exeter) peut résoudre ce "
+"L'algorithme de Pledge (nommé d'après Jon Pledge d'Exeter) peut sortir de ce "
 "labyrinthe."
 
 #. type: Content of: <p>
@@ -9918,11 +9674,11 @@ msgid ""
 msgstr ""
 "Cet algorithme est une version modifiée l'algorithme précédent conçu pour "
 "éviter les obstacles. Il nécessite de choisir de manière arbitraire une "
-"direction vers laquelle le buggle se dirigera. Quand un obstacle est "
+"direction vers laquelle la buggle se dirigera. Quand un obstacle est "
 "rencontré, une patte (disons la patte de gauche) est gardée le long des "
-"obstacles tandis que les virages sont comptabilisés. Quand le buggle est "
+"obstacles tandis que les virages sont comptabilisés. Quand la buggle est "
 "face à nouveau à la direction originale, et que la somme des virages est "
-"égale à 0, le buggle quitte l'obstacle et continue de se déplacer dans sa "
+"égale à 0, la buggle quitte l'obstacle et continue de se déplacer dans sa "
 "direction d'origine."
 
 # type: Content of: <p><p>
@@ -10022,11 +9778,9 @@ msgid ""
 "global never gets modified."
 msgstr ""
 "N'oubliez pas que si l'une de vos méthodes modifie une variable globale "
-"(telle\n"
-"que sommeAngles), vous devez vous assurer qu'elle définie cette globale\n"
-"correctement. Sinon, la méthode crée une nouvelle variable locale de même "
-"nom,\n"
-"et la globale n'est jamais modifiée."
+"(telle que sommeAngles), vous devez vous assurer qu'elle définie cette "
+"globale correctement. Sinon, la méthode crée une nouvelle variable locale de "
+"même nom, et la globale n'est jamais modifiée."
 
 #. type: Content of: <div><pre>
 #: src/lessons/maze/pledge/PledgeMaze.html:62
@@ -10058,8 +9812,7 @@ msgid ""
 "the favorite direction is not free. Do that until you find your baggle."
 msgstr ""
 "Vous devez changer votre cap vers votre direction favorite (probablement le "
-"nord\n"
-"-- NORTH). Il vous faut ensuite écrire la boucle principale de votre "
+"nord -- NORTH). Il vous faut ensuite écrire la boucle principale de votre "
 "algorithme. Tant que votre buggle n'a pas trouvé son biscuit, il faut "
 "avancer jusqu'à un obstacle dans la direction de prédilection. Quand un "
 "obstacle est rencontré, il faut garder la patte sur un mur (en utilisant "
@@ -10091,7 +9844,7 @@ msgid ""
 msgstr ""
 "L'algorithme de suivi de mur que nous avons utilisé jusqu'à présent "
 "fonctionne seulement si l'entrée et la sortie sont placées à côté de murs "
-"connectés à un mur externe. Mais si le buggle commence au milieu du "
+"connectés à un mur externe. Mais si la buggle commence au milieu du "
 "labyrinthe, il peut exister des pans de mur déconnectés du mur externe."
 
 #. type: Content of: <p><p>
@@ -10105,10 +9858,10 @@ msgid ""
 msgstr ""
 "Dans cette situation, notre précédente stratégie ferait notre buggle tourner "
 "en rond pour toujours sur l'un de ces îlots. En effet, le labyrinthe dont "
-"vous devez vous échapper maintenant contient des îles, et le buggle ne "
+"vous devez vous échapper maintenant contient des îles, et la buggle ne "
 "commence pas sur un des murs externes. Vous pouvez essayer si vous voulez : "
-"Copie/collez votre code et appuyez sur le bouton 'run' pour admirez votre "
-"solution précédente échouer lamentablement."
+"Copie/collez votre code et appuyez sur le bouton 'Exécuter' pour admirez "
+"votre solution précédente échouer lamentablement."
 
 #. type: Content of: <p><p>
 #: src/lessons/maze/island/IslandMaze.html:18
@@ -10122,7 +9875,7 @@ msgid ""
 msgstr ""
 "Cette méthode de suivre un mur est toujours efficace est permet d'échapper "
 "de manière assez efficace à certaines parties du labyrinthe, on ne va donc "
-"pas la supprimer entièrement. A la place, nous allons cesser de suivre le "
+"pas la supprimer entièrement. À la place, nous allons cesser de suivre le "
 "mur sous certaines conditions. Notez que le baggle repose près d'un mur "
 "externe du labyrinthe. Donc nous voulons atteindre un mur externe et ensuite "
 "le suivre. Nous avons par exemple de rechercher le mur nord avant de le "
@@ -10136,7 +9889,7 @@ msgid ""
 msgstr ""
 "Pour trouver le mur nord, vous avez tout simplement à foncez vers le nord "
 "tant que c'est possible, et quand vous faites face à un obstacle, vous "
-"l'évitez ( en utilisant la méthode précédente )."
+"l'évitez (en utilisant la méthode précédente)."
 
 #. type: Attribute 'alt' of: <p><p><div>
 #: src/lessons/maze/island/IslandMaze.html:30
@@ -10156,21 +9909,28 @@ msgid ""
 "is something like"
 msgstr ""
 "Notre nouvelle méthode run() va consister en deux états: notre buggle va "
-"alterner entre le mode \"north runner\" et le mode \"left follower\".\n"
-"Vous commencerz dans le mode \"north runner\", et vous passerez au mode "
-"\"left follower\" quand il y aura un mur au nord ( n'oubliez pas de vous "
-"assurez d'avoir un mur à votre gauche avant de changer de passer au mode "
-"\"left follower\").\n"
-"Vous repasserez au mode \"north runner\" dès que votre buggle fera face au "
-"nord et qu'elle n'est pas face à un mur.\n"
-"La manière la plus simple d'écrire une telle machine à état est quelque "
-"chose du type"
+"alterner entre le mode «coureur au nord» et le mode «suiveur à gauche». Vous "
+"commencerz dans le mode «coureur au nord», et vous passerez au mode «suiveur "
+"à gauche» quand il y aura un mur au nord (n'oubliez pas de vous assurez "
+"d'avoir un mur à votre gauche avant de changer de passer au mode «suiveur à "
+"gauche»). Vous repasserez au mode «coureur au nord» dès que votre buggle "
+"fera face au nord et qu'elle n'est pas face à un mur. La manière la plus "
+"simple d'écrire une telle machine à état est quelque chose de ce type:"
 
 #. type: Content of: <p><p><div><pre>
-#: src/lessons/maze/island/IslandMaze.html:40
+#: src/lessons/maze/island/IslandMaze.html:39
 #, no-wrap
 msgid ""
-"\t<code div=\"Java\">int state=0;\n"
+"[!scala]var state=0;\n"
+"state match  {\n"
+"  case 0 => // North runner\n"
+"     ...\n"
+"     state = 1;\n"
+"  case 1 => // Left follower\n"
+"     ...\n"
+"     state = 0;\n"
+"  case _ => println(\"This case should not happen. Please fix me\")\n"
+"}[/!][!java]int state=0;\n"
 "switch (state) {\n"
 "  case 0: // North runner\n"
 "     ...\n"
@@ -10180,47 +9940,59 @@ msgid ""
 "     ...\n"
 "     state = 0;\n"
 "     break;\n"
-"}\n"
-"</code>\n"
-"<code div=\"python\">northRunner = True\n"
+"}[/!][!python]northRunner = True\n"
 "if northRunner:\n"
 "     ...\n"
 "     northRunner = False\n"
 "else: # left follower\n"
 "     ...\n"
-"     northRunner = True\n"
-"</code>\n"
+"     northRunner = True[/!]"
 msgstr ""
-"\t<code div=\"Java\">int etat=0;\n"
+"[!scala]var etat=0;\n"
+"etat match  {\n"
+"  case 0 => // courir au nord\n"
+"     ...\n"
+"     etat = 1;\n"
+"  case 1 => // suivre à gauche\n"
+"     ...\n"
+"     etat = 0;\n"
+"  case _ => println(\"Ce cas ne devrait pas arriver. Corrigez ce problème svp.\")\n"
+"}[/!][!java]int etat=0;\n"
 "switch (etat) {\n"
 "  case 0: // courir au nord\n"
 "     ...\n"
 "     etat = 1;\n"
 "     break;\n"
-"  case 1: // suivre a gauche\n"
+"  case 1: // suivre à gauche\n"
 "     ...\n"
 "     etat = 0;\n"
 "     break;\n"
-"}\n"
-"</code>\n"
-"<code div=\"python\">courirNord = True\n"
-"if courirNord:\n"
+"}[/!][!python]coureurNord = True\n"
+"if coureurNord:\n"
 "     ...\n"
-"     courirNord = False\n"
-"else: # suivre a gauche\n"
+"     coureurNord = False\n"
+"else: # suiveur à gauche\n"
 "     ...\n"
-"     courirNord = True\n"
-"</code>\n"
+"     coureurNord = True[/!]"
+
+#. type: Content of: <p><p><div>
+#: src/lessons/maze/island/IslandMaze.html:66
+msgid ""
+"Don't forget the default case (matching _), or scala will issue an error "
+"since your matching would be incomplete.[/!]"
+msgstr ""
+"N'oubliez pas le cas par défaut (qui accepte _), ou scala vous donnera un "
+"message d'erreur en échange de votre filtrage incomplet."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/maze/island/IslandMaze.html:63
+#: src/lessons/maze/island/IslandMaze.html:69
 msgid "Don't forget to let the buggle pick the baggle at the end of your code."
 msgstr ""
 "N'oubliez pas de faire ramasser le baggle par votre buggle à la fin de votre "
 "code."
 
 #. type: Content of: <p><p><p>
-#: src/lessons/maze/island/IslandMaze.html:66
+#: src/lessons/maze/island/IslandMaze.html:72
 msgid ""
 "You're up. That should be enough for you to figure out how to escape this "
 "maze, but if not, you can always request for the tip. But you do not need "
@@ -10245,9 +10017,9 @@ msgid ""
 "to feel his environment."
 msgstr ""
 "Pour conclure avec cette leçon d'introduction aux algorithmes de sortie de "
-"labyrinthe, nous allons étudier un autre moyen de trouver la sortie. Le "
+"labyrinthe, nous allons étudier un autre moyen de trouver la sortie. La "
 "buggle de cette leçon est spécial : c'est un jedi. Il peut ressentir la "
-"Force. Cela signifie qu'il peut ressentir son environnement."
+"Force. Cela signifie qu'elle peut ressentir son environnement."
 
 #. type: Content of: <p>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:7
@@ -10255,18 +10027,18 @@ msgid ""
 "Without even leaving his position, he can retrieve information about the "
 "world he is leaving in, with the following functions:"
 msgstr ""
-"Sans même changer de place, il peut retrouver des informations sur le monde "
-"qui l'entoure, avec les instructions suivantes :"
+"Sans même changer de place, elle peut retrouver des informations sur le "
+"monde qui l'entoure, avec les instructions suivantes :"
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:9
 msgid "<code>getWorldWidth()</code> gives the width of its world."
-msgstr "<code>getWorldWidth()</code> pour connaitre la largeur du monde"
+msgstr "<code>getMondeLargueur()</code> pour connaitre la largeur du monde"
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:10
 msgid "<code>getWorldHeight()</code> gives the height of its world."
-msgstr "<code>getWorldHeight()</code> pour connaitre la hauteur du monde."
+msgstr "<code>getMondeHauteur()</code> pour connaitre la hauteur du monde."
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:11
@@ -10274,9 +10046,8 @@ msgid ""
 "<code>hasTopWall(x,y)</code> tells whether the cell (x,y) of this world has "
 "a wall on top."
 msgstr ""
-"<code>hasTopWall(x,y)</code> indique si la cellule (x,y) de ce monde est "
-"fermée\n"
-"par un mur en haut."
+"<code>aMurNord(x,y)</code> indique si la cellule (x,y) de ce monde est "
+"fermée par un mur en haut."
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:12
@@ -10284,9 +10055,8 @@ msgid ""
 "<code>hasLeftWall(x,y)</code> tells whether the cell (x,y) of this world has "
 "a wall on the left."
 msgstr ""
-"<code>hasLeftWall(x,y)</code> indique si la cellule (x,y) de ce monde est "
-"fermée\n"
-"par un mur à gauche."
+"<code>aMurOuest(x,y)</code> indique si la cellule (x,y) de ce monde est "
+"fermée par un mur à gauche."
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:13
@@ -10294,8 +10064,8 @@ msgid ""
 "<code>hasBaggle(x,y)</code> tells whether the cell (x,y) of this world has a "
 "baggle."
 msgstr ""
-"<code>hasBaggle(x,y)</code> indique si un baggle se trouve dans la cellule "
-"(x,y) de ce monde."
+"<code>aBiscuit(x,y)</code> indique si un baggle se trouve dans la cellule (x,"
+"y) de ce monde."
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:14
@@ -10304,8 +10074,7 @@ msgid ""
 "to the cell (x,y)."
 msgstr ""
 "<code>setIndication(x,y,i)</code> ajoute une indication entière <code>i</"
-"code>\n"
-"sur le sol de la cellule (x,y)."
+"code> sur le sol de la cellule (x,y)."
 
 #. type: Content of: <ul><li>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:15
@@ -10314,9 +10083,8 @@ msgid ""
 "cell (x,y) (or 9999 if there is no indication)."
 msgstr ""
 "<code>getIndication(x,y,i)</code> retourne l'indication entière qui se "
-"trouve\n"
-"dans la cellule (x,y) (ou bien la valeur 9999 s'il n'y a pas d'indication à\n"
-"l'endroit indiqué)."
+"trouve dans la cellule (x,y) (ou bien la valeur 9999 s'il n'y a pas "
+"d'indication à l'endroit indiqué)."
 
 #. type: Content of: <p>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:18
@@ -10328,10 +10096,10 @@ msgid ""
 "cell."
 msgstr ""
 "Il est bon de noter qu'il n'est pas possible de construire un mur sur la "
-"côté inférieur ou droit d'une case.Néanmoins, quand de tels murs existents, "
+"côté inférieur ou droit d'une case. Néanmoins, quand de tels murs existent, "
 "cela signifie qu'il a été construit sur une case voisine -- comme mur "
-"supérieur ( respectivement gauche ) sur la case qui est située en dessous "
-"( respectivement sur la droite ) de la case courante."
+"supérieur (respectivement gauche) sur la case qui est située en dessous "
+"(respectivement sur à droite) de la case courante."
 
 #. type: Content of: <p>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:24
@@ -10367,18 +10135,13 @@ msgid ""
 "EAST</code>."
 msgstr ""
 "Une fois que toutes les cases sont marquées, faites en sorte que votre "
-"buggle\n"
-"jedi trouve le plus court chemin en suivant les indications écrites au sol. "
-"Pour\n"
-"celà, il lui suffit à chaque pas d'aller sur la case de plus petite "
-"distance\n"
-"parmis celles accessibles. Vous pouvez utiliser la méthode <code>void\n"
-"setDirection(Direction d)</code> pour faire regarder votre buggle dans une\n"
-"direction spécifique comme <code>Direction.NORTH</code>,\n"
-"<code>Direction.SOUTH</code>, <code>Direction.EAST</code> ou\n"
-"<code>Direction.WEST</code>, qui correspondent respectivement au nord, sud, "
-"est\n"
-"et ouest."
+"buggle jedi trouve le plus court chemin en suivant les indications écrites "
+"au sol. Pour celà, il lui suffit à chaque pas d'aller sur la case de plus "
+"petite distance parmis celles accessibles. Vous pouvez utiliser la méthode "
+"<code>void setDirection(Direction d)</code> pour faire regarder votre buggle "
+"dans une direction spécifique comme <code>Direction.NORTH</code>, "
+"<code>Direction.SOUTH</code>, <code>Direction.EAST</code> ou <code>Direction."
+"WEST</code>, qui correspondent respectivement au nord, sud, est et ouest."
 
 #. type: Attribute 'alt' of: <div>
 #: src/lessons/maze/shortestpath/ShortestPathMaze.html:35
@@ -10402,8 +10165,8 @@ msgid ""
 "the same location. In particular, it does not have any wall to its left at "
 "the beginning."
 msgstr ""
-"C'est exactement le même labyrinthe que précédemment, mais le buggle ne "
-"commence plus au même emplacement. En particulier, il n'a plus de mur à sa "
+"C'est exactement le même labyrinthe que précédemment, mais la buggle ne "
+"commence plus au même emplacement. En particulier, elle n'a plus de mur à sa "
 "gauche dès le départ."
 
 #. type: Content of: <p>
@@ -10415,12 +10178,12 @@ msgid ""
 "(if that's not the case, well, you didn't really stick to the mission on "
 "previous exercise. Feel lucky and proceed to the next :)"
 msgstr ""
-"Ceci engendre que la méthode que vous avez écrite à l'exercice précédent ne "
-"fonctionne plus ici. Si vous l'utilisez ici sans modification, votre buggle "
-"va probablement commencer à tourner sur les quatres cases à côté de sa "
-"position de départ (si ça n'est pas le cas, et bien, vous n'avez pas "
-"réellement suivi la mission de l'exercice précédent. Sentez vous chanceux et "
-"passez à l'exercice suivant une fois que vous aurez lu ce texte)."
+"Ceci fait que la méthode écrite à l'exercice précédent ne fonctionne plus. "
+"Si vous l'utilisez ici sans modification, votre buggle va probablement "
+"commencer à tourner sur les quatres cases à côté de sa position de départ "
+"(si ça n'est pas le cas, et bien, vous n'avez pas réellement suivi la "
+"mission de l'exercice précédent. Sentez vous chanceux et passez à l'exercice "
+"suivant une fois que vous aurez lu ce texte)."
 
 #. type: Content of: <p>
 #: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:14
@@ -10433,7 +10196,7 @@ msgid ""
 "correctly."
 msgstr ""
 "C'est parce que votre méthode <code>keepHandOnSideWall()</code> a une <b>pré-"
-"condition</b> implicite : la méthode marche bien si et seulement si le "
+"condition</b> implicite : la méthode marche bien si et seulement si la "
 "buggle a un mur sur sa gauche quand vous appelez cette méthode. De telles "
 "pré-conditions sont très utilisées en programmation. Les spécifier "
 "explicitement aide à comprendre le code écrit par d'autres personnes, et "
@@ -10449,84 +10212,85 @@ msgid ""
 msgstr ""
 "Réparer le problème devrait être très facile. Assurez-vous simplement que la "
 "pré-condition de <code>keepHandOnSideWall()</code> est vérifiée avant de "
-"l'appeler Pour ce faire, mettez à jour votre code pour tout d'abord "
+"l'appeler. Pour ce faire, mettez à jour votre code pour tout d'abord "
 "rechercher à avoir un mur à sa gauche avant de rentrer dans la grande boucle "
 "<code>while</code>."
 
-#. type: Content of: <h1>
-#: src/jlm/universe/lightbot/LightBotWorld.html:1
-msgid "LightBotWorld"
-msgstr "LightBotWorld"
+#. type: Content of: <h3>
+#: src/plm/universe/lightbot/LightBotWorld.html:1
+#: src/lessons/lightbot/Main.html:1 src/lessons/lightbot/short_desc.html:1
+msgid "LightBot"
+msgstr "LightBot"
 
 #. type: Content of: outside any tag (error?)
-#: src/jlm/universe/lightbot/LightBotWorld.html:3
+#: src/plm/universe/lightbot/LightBotWorld.html:3
 msgid ""
-"This world introduces a little programming puzzle which can somehow be used "
-"to introduce programmation to non-reading kids since it is programmed "
+"This universe introduces a little programming puzzle which can somehow be "
+"used to introduce programmation to non-reading kids since it is programmed "
 "graphically.  The goal of each board is to light up all the lights. Your "
 "robot understands the following orders:"
 msgstr ""
-"Ce monde introduit un petit puzzle de programmation qui peut être utilisé "
+"Cet univers introduit un petit puzzle de programmation qui peut être utilisé "
 "pour introduire la programmation aux enfants ne sachant pas lire. En effet, "
 "il est programmé de manière graphique. L'objectif de chaque niveau est "
 "d'allumer toutes les lumières du plateau en utilisant le petit robot. Celui-"
 "ci comprend les ordres suivants :"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:7
+#: src/plm/universe/lightbot/LightBotWorld.html:7
 msgid "<b>Order</b>"
 msgstr "<b>Ordre</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:7
+#: src/plm/universe/lightbot/LightBotWorld.html:7
 msgid "<b>Meaning</b>"
 msgstr "<b>Signification</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:8
+#: src/plm/universe/lightbot/LightBotWorld.html:8
 msgid "<b>Move forward</b>"
 msgstr "<b>Avancer</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:8
+#: src/plm/universe/lightbot/LightBotWorld.html:8
 msgid ""
 "Cannot be done if the destination cell is of another height than source cell"
 msgstr ""
-"Ne peut être utilisé si la case d'arrivée n'est pas à la même altitude que "
-"la case de départ."
+"Ne peut être utilisé que si la case d'arrivée est à la même altitude que la "
+"case de départ."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:9
+#: src/plm/universe/lightbot/LightBotWorld.html:9
 msgid "<b>Jump forward</b>"
 msgstr "<b>Sauter en avant</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:9
+#: src/plm/universe/lightbot/LightBotWorld.html:9
 msgid ""
 "Can only be done if the destination cell is one step higher than source "
 "cell, or if destination is lower than source. Cannot be used for plain moves."
 msgstr ""
 "Ne peut être utilisé que si la case d'arrivée est un étage plus haute que la "
-"case de départ, ou si l'arrivée est plus basse que le départ. Ne peut être "
-"utilisée pour des déplacements à plat."
+"case de départ, ou si l'arrivée est plus basse que le départ. Il est "
+"impossible de sauter sur un terrain plat."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:10
+#: src/plm/universe/lightbot/LightBotWorld.html:10
 msgid "<b>Turn left</b>."
 msgstr "<b>Tourner à gauche</b>."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:11
+#: src/plm/universe/lightbot/LightBotWorld.html:11
 msgid "<b>Turn right</b>."
 msgstr "<b>Tourner à droite</b>."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:12
+#: src/plm/universe/lightbot/LightBotWorld.html:12
 msgid "<b>Switch the light</b>."
 msgstr "<b>Allumer ou éteindre</b>"
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:12
+#: src/plm/universe/lightbot/LightBotWorld.html:12
 msgid ""
 "Turn it on if it was off, and off if it was on. No effect if the cell does "
 "not contain any light."
@@ -10535,17 +10299,17 @@ msgstr ""
 "Sans effet s'il n'y a pas d'ampoule dans la case courante."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:13
+#: src/plm/universe/lightbot/LightBotWorld.html:13
 msgid "<b>Call function 1</b>."
 msgstr "<b>Appeller la fonction 1</b>."
 
 #. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:14
+#: src/plm/universe/lightbot/LightBotWorld.html:14
 msgid "<b>Call function 2</b>."
 msgstr "<b>Appeller la fonction 2</b>."
 
 #. type: Content of: <p>
-#: src/jlm/universe/lightbot/LightBotWorld.html:17
+#: src/plm/universe/lightbot/LightBotWorld.html:17
 msgid ""
 "Please note that this world is not completely suited to small kids since the "
 "main difficulty comes from the fact that your are highly limited in the "
@@ -10560,7 +10324,7 @@ msgstr ""
 "qui est souvent au delà des capacités des jeunes enfants."
 
 #. type: Content of: <p>
-#: src/jlm/universe/lightbot/LightBotWorld.html:19
+#: src/plm/universe/lightbot/LightBotWorld.html:19
 msgid ""
 "This game is heavily inspirated from a flash game of the same name, which "
 "can for example be played on kongregate.com. It was written by Danny "
@@ -10570,11 +10334,6 @@ msgstr ""
 "peut par exemple trouver sur kongregate.com. Il a été écrit par Danny "
 "Yaroslavski (Coolio-Niato), d'après une idée originale de Matt Chase."
 
-#. type: Content of: <h3>
-#: src/lessons/lightbot/Main.html:1 src/lessons/lightbot/short_desc.html:1
-msgid "LightBot"
-msgstr "LightBot"
-
 #. type: Content of: outside any tag (error?)
 #: src/lessons/lightbot/Main.html:2
 msgid ""
@@ -10806,75 +10565,68 @@ msgid "This one aint easy."
 msgstr "Celui-ci est loin d'être facile."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Close10.html:1
+#: src/lessons/welcome/bat/bool1/Close10.html:1
 msgid "Close to 10"
 msgstr "Proche de 10"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:2
-msgid ""
-"Given 2 int values, return whichever value is nearest to the value 10, or "
-"return 0 in the event of a tie. Note that Math.abs(n) returns the absolute "
-"value of a number."
-msgstr ""
-"Étant donné deux nombres entiers, retourner la valeur la plus proche de 10, "
-"ou 0 en cas de match nul. Remarquez que Math.abs(n) retourne la valeur "
-"absolue d'un nombre."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:5
+#: src/lessons/welcome/bat/bool1/Close10.html:2
 msgid ""
 "Given 2 int values, return whichever value is nearest to the value 10, or "
-"return 0 in the event of a tie. Note that math.fabs(n) returns the absolute "
-"value of a number. Note also that this function can only be used if you "
-"imported the math module."
+"return 0 in the event of a tie.  [!java|scala]Note that Math.abs(n) returns "
+"the absolute value of a number.[/!] [!python]Note that math.fabs(n) returns "
+"the absolute value of a number.  This function can only be used if you "
+"imported the math module.[/!]"
 msgstr ""
 "Étant donné deux nombres entiers, retourner la valeur la plus proche de 10, "
-"ou 0 en cas de match nul. Remarquez que math.fabs(n) retourne la valeur "
-"absolue d'un nombre. Remarquez également que vous ne pouvez utiliser cette "
-"fonction que si vous avez importé le module math."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:10
-#: src/lessons/welcome/bool1/Diff21.html:5
-#: src/lessons/welcome/bool1/HasTeen.html:6
-#: src/lessons/welcome/bool1/IcyHot.html:5
-#: src/lessons/welcome/bool1/In1020.html:5
-#: src/lessons/welcome/bool1/In3050.html:5
-#: src/lessons/welcome/bool1/LastDigit.html:9
-#: src/lessons/welcome/bool1/LoneTeen.html:6
-#: src/lessons/welcome/bool1/Main.html:11
-#: src/lessons/welcome/bool1/Makes10.html:5
-#: src/lessons/welcome/bool1/Max1020.html:8
-#: src/lessons/welcome/bool1/MonkeyTrouble.html:7
-#: src/lessons/welcome/bool1/NearHundred.html:5
-#: src/lessons/welcome/bool1/ParotTrouble.html:8
-#: src/lessons/welcome/bool1/PosNeg.html:5
-#: src/lessons/welcome/bool1/SleepIn.html:7
-#: src/lessons/welcome/bool1/SumDouble.html:5
-#: src/lessons/welcome/bool2/AlarmClock.html:11
-#: src/lessons/welcome/bool2/AnswerCell.html:8
-#: src/lessons/welcome/bool2/BlueTicket.html:10
-#: src/lessons/welcome/bool2/CaughtSpeeding.html:11
-#: src/lessons/welcome/bool2/CigarParty.html:9
-#: src/lessons/welcome/bool2/DateFashion.html:12
-#: src/lessons/welcome/bool2/GreenTicket.html:9
-#: src/lessons/welcome/bool2/In1To10.html:8
-#: src/lessons/welcome/bool2/InOrderEqual.html:9
-#: src/lessons/welcome/bool2/InOrder.html:8
-#: src/lessons/welcome/bool2/LastDigit2.html:8
-#: src/lessons/welcome/bool2/LessBy10.html:5
-#: src/lessons/welcome/bool2/Main.html:4
-#: src/lessons/welcome/bool2/MaxMod5.html:9
-#: src/lessons/welcome/bool2/NearTen.html:8
-#: src/lessons/welcome/bool2/RedTicket.html:9
-#: src/lessons/welcome/bool2/ShareDigit.html:9
-#: src/lessons/welcome/bool2/SortaSum.html:7
-#: src/lessons/welcome/bool2/SquirrelPlay.html:10
-#: src/lessons/welcome/bool2/TeaParty.html:11
-#: src/lessons/welcome/bool2/TeenSum.html:8
-#: src/lessons/welcome/bool2/TwoAsOne.html:5
-#: src/lessons/welcome/bool2/WithoutDoubles.html:8
+"ou 0 en cas de match nul.\n"
+"[!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un "
+"nombre.[/!] \n"
+"[!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un nombre. "
+"Remarquez également que vous ne pouvez utiliser cette fonction que si vous "
+"avez importé le module math.[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Close10.html:7
+#: src/lessons/welcome/bat/bool1/Diff21.html:5
+#: src/lessons/welcome/bat/bool1/HasTeen.html:6
+#: src/lessons/welcome/bat/bool1/IcyHot.html:5
+#: src/lessons/welcome/bat/bool1/In1020.html:5
+#: src/lessons/welcome/bat/bool1/In3050.html:5
+#: src/lessons/welcome/bat/bool1/LastDigit.html:9
+#: src/lessons/welcome/bat/bool1/LoneTeen.html:6
+#: src/lessons/welcome/bat/bool1/Main.html:11
+#: src/lessons/welcome/bat/bool1/Makes10.html:5
+#: src/lessons/welcome/bat/bool1/Max1020.html:7
+#: src/lessons/welcome/bat/bool1/MonkeyTrouble.html:7
+#: src/lessons/welcome/bat/bool1/NearHundred.html:7
+#: src/lessons/welcome/bat/bool1/ParotTrouble.html:8
+#: src/lessons/welcome/bat/bool1/PosNeg.html:5
+#: src/lessons/welcome/bat/bool1/SleepIn.html:7
+#: src/lessons/welcome/bat/bool1/SumDouble.html:5
+#: src/lessons/welcome/bat/bool2/AlarmClock.html:11
+#: src/lessons/welcome/bat/bool2/AnswerCell.html:8
+#: src/lessons/welcome/bat/bool2/BlueTicket.html:10
+#: src/lessons/welcome/bat/bool2/CaughtSpeeding.html:11
+#: src/lessons/welcome/bat/bool2/CigarParty.html:9
+#: src/lessons/welcome/bat/bool2/DateFashion.html:12
+#: src/lessons/welcome/bat/bool2/GreenTicket.html:9
+#: src/lessons/welcome/bat/bool2/In1To10.html:8
+#: src/lessons/welcome/bat/bool2/InOrderEqual.html:9
+#: src/lessons/welcome/bat/bool2/InOrder.html:8
+#: src/lessons/welcome/bat/bool2/LastDigit2.html:8
+#: src/lessons/welcome/bat/bool2/LessBy10.html:5
+#: src/lessons/welcome/bat/bool2/Main.html:4
+#: src/lessons/welcome/bat/bool2/MaxMod5.html:9
+#: src/lessons/welcome/bat/bool2/NearTen.html:8
+#: src/lessons/welcome/bat/bool2/RedTicket.html:9
+#: src/lessons/welcome/bat/bool2/ShareDigit.html:9
+#: src/lessons/welcome/bat/bool2/SortaSum.html:7
+#: src/lessons/welcome/bat/bool2/SquirrelPlay.html:10
+#: src/lessons/welcome/bat/bool2/TeaParty.html:11
+#: src/lessons/welcome/bat/bool2/TeenSum.html:8
+#: src/lessons/welcome/bat/bool2/TwoAsOne.html:5
+#: src/lessons/welcome/bat/bool2/WithoutDoubles.html:8
 #: src/lessons/bat/string1/Main.html:8 src/lessons/bat/string1/AltPairs.html:4
 #: src/lessons/bat/string1/FrontTimes.html:7
 #: src/lessons/bat/string1/Last2.html:8
@@ -10891,33 +10643,34 @@ msgstr ""
 #: src/lessons/welcome/array/notriples/NoTriples.html:7
 #: src/lessons/welcome/array/has271/Has271.html:8
 msgid ""
-"This exercise was converted to JLM from the excellent exercising site http://"
+"This exercise was converted to PLM from the excellent exercising site http://"
 "javabat.com/"
 msgstr ""
 "Cet exercice a été extrait de l'excellent site d'exercices http://javabat."
-"com/ pour JLM."
+"com/ pour PLM."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/CountTeen.html:1
+#: src/lessons/welcome/bat/bool1/CountTeen.html:1
 msgid "Count Teen"
 msgstr "Compter les ados"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool1/CountTeen.html:2
+#: src/lessons/welcome/bat/bool1/CountTeen.html:2
 msgid ""
 "We'll say that a number is \"teen\" if it is in the range 13..19 inclusive. "
 "Given 4 int values, return the amount of teen ones."
 msgstr ""
-"On dira qu'un nombre est \"ado\" s'il appartient à l'intervale [13;19]. "
-"Étant donné quatre nombres entiers, retournez combien d'entre eux sont ados."
+"On dira qu'un nombre est \"ado\" s'il appartient est entre 13 et 19 "
+"(inclus). Étant donné quatre nombres entiers, retournez combien d'entre eux "
+"sont ados."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Diff21.html:1
+#: src/lessons/welcome/bat/bool1/Diff21.html:1
 msgid "Diff 21"
 msgstr "Diff 21"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Diff21.html:2
+#: src/lessons/welcome/bat/bool1/Diff21.html:2
 msgid ""
 "Given an int n, return the absolute difference between n and 21, except "
 "return double the absolute difference if n is over 21."
@@ -10926,12 +10679,12 @@ msgstr ""
 "si n est plus grand que 21. Dans ce cas, doublez la différence absolue."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/HasTeen.html:1
+#: src/lessons/welcome/bat/bool1/HasTeen.html:1
 msgid "Has Teen"
 msgstr "A des ados"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/HasTeen.html:2
+#: src/lessons/welcome/bat/bool1/HasTeen.html:2
 msgid ""
 "We'll say that a number is \"teen\" if it is in the range 13..19 inclusive. "
 "Given 3 int values, return true if 1 or more of them are teen."
@@ -10941,12 +10694,12 @@ msgstr ""
 "d'entre eux sont ados."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/IcyHot.html:1
+#: src/lessons/welcome/bat/bool1/IcyHot.html:1
 msgid "Icy Hot"
 msgstr "Feu glacé"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/IcyHot.html:2
+#: src/lessons/welcome/bat/bool1/IcyHot.html:2
 msgid ""
 "Given two temperatures, return true if one is less than 0 and the other is "
 "greater than 100."
@@ -10955,12 +10708,12 @@ msgstr ""
 "et l'autre supérieure à 100."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/In1020.html:1
+#: src/lessons/welcome/bat/bool1/In1020.html:1
 msgid "In [10;20]"
 msgstr "Dans [10;20]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/In1020.html:2
+#: src/lessons/welcome/bat/bool1/In1020.html:2
 msgid ""
 "Given 2 int values, return true if either of them is in the range 10..20 "
 "inclusive."
@@ -10969,12 +10722,12 @@ msgstr ""
 "l'intervale [10;20]."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/In3050.html:1
+#: src/lessons/welcome/bat/bool1/In3050.html:1
 msgid "In [30;50]"
 msgstr "Dans [30;50]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/In3050.html:2
+#: src/lessons/welcome/bat/bool1/In3050.html:2
 msgid ""
 "Given 2 int values, return true if they are both in the range 30..40 "
 "inclusive, or they are both in the range 40..50 inclusive."
@@ -10984,12 +10737,12 @@ msgstr ""
 "[40;50]."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/LastDigit.html:1
+#: src/lessons/welcome/bat/bool1/LastDigit.html:1
 msgid "LastDigit"
 msgstr "Dernier chiffre"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/LastDigit.html:2
+#: src/lessons/welcome/bat/bool1/LastDigit.html:2
 msgid ""
 "Given two non-negative int values, return true if they have the same last "
 "digit, such as with 27 and 57. Note that the % \"mod\" operator computes "
@@ -11000,12 +10753,12 @@ msgstr ""
 "calcule le reste de la division entière (donc 17 % 10 vaut 7)."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/LoneTeen.html:1
+#: src/lessons/welcome/bat/bool1/LoneTeen.html:1
 msgid "Lone Teen"
 msgstr "Ado solitaire"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/LoneTeen.html:2
+#: src/lessons/welcome/bat/bool1/LoneTeen.html:2
 msgid ""
 "We'll say that a number is \"teen\" if it is in the range 13..19 inclusive. "
 "Given 2 int values, return true if one or the other is teen, but not both."
@@ -11015,12 +10768,12 @@ msgstr ""
 "ado, mais pas les deux."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Main.html:1
+#: src/lessons/welcome/bat/bool1/Main.html:1
 msgid "Boolean fun"
 msgstr "Jeux booléens"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool1/Main.html:3
+#: src/lessons/welcome/bat/bool1/Main.html:3
 msgid ""
 "Boolean operations are one of the very basic task in programming.  As long "
 "as you cannot write a not so simple boolean test under the minute, you "
@@ -11031,7 +10784,7 @@ msgstr ""
 "en moins d'une minute, il vous sera difficile d'écrire un vrai programme."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool1/Main.html:8
+#: src/lessons/welcome/bat/bool1/Main.html:8
 msgid ""
 "That is why this lesson provides you a bunch of such exercises, so that you "
 "can get trained in this."
@@ -11040,12 +10793,12 @@ msgstr ""
 "exercices pour vous permettre de vous entrainer."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Makes10.html:1
+#: src/lessons/welcome/bat/bool1/Makes10.html:1
 msgid "Makes 10"
 msgstr "Font 10"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Makes10.html:2
+#: src/lessons/welcome/bat/bool1/Makes10.html:2
 msgid ""
 "Given 2 ints, a and b, return true if one if them is 10 or if their sum is "
 "10."
@@ -11054,27 +10807,36 @@ msgstr ""
 "10, ou si leur somme vaut 10."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Max1020.html:1
+#: src/lessons/welcome/bat/bool1/Max1020.html:1
 msgid "Max1020"
 msgstr "Max1020"
 
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Max1020.html:2
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Max1020.html:2
 msgid ""
 "Given 2 positive int values, return the larger value that is in the range "
 "10..20 inclusive, or return 0 if neither is in that range."
 msgstr ""
 "Étant donné deux nombres entiers, retournez la plus grande valeur dans "
-"l'intervale [10;20], ou retournez 0 si aucun des nombres n'est dans cet "
-"intervale."
+"l'intervale 10..20 inclus, ou retournez 0 si aucun des nombres n'est dans "
+"cet intervale."
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Max1020.html:5
+msgid ""
+"Note that Math.max(Int,Int):Int and Math.min(Int,Int):Int return the maximum "
+"and minimum of two integers"
+msgstr ""
+"Notez que Math.max(Int,Int):Int et Math.min(Int,Int):Int retournent "
+"respectivement le maximum et le minimum de deux entiers."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/MonkeyTrouble.html:1
+#: src/lessons/welcome/bat/bool1/MonkeyTrouble.html:1
 msgid "MonkeyTrouble"
 msgstr "Problème de singe"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/MonkeyTrouble.html:3
+#: src/lessons/welcome/bat/bool1/MonkeyTrouble.html:3
 msgid ""
 "We have two monkeys, a and b, and the parameters aSmile and bSmile indicate "
 "if each is smiling.  We are in trouble if they are both smiling or if "
@@ -11086,26 +10848,33 @@ msgstr ""
 "problème."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/NearHundred.html:1
+#: src/lessons/welcome/bat/bool1/NearHundred.html:1
 msgid "Near Hundred"
 msgstr "Presque 100"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool1/NearHundred.html:2
+#: src/lessons/welcome/bat/bool1/NearHundred.html:2
 msgid ""
-"Given an int n, return true if it is within 10 of 100 or 200. Note Math."
-"abs(n) returns the absolute value of a number."
+"Given an int n, return true if it is within 10 of 100 or 200.  [!java|"
+"scala]Note that Math.abs(n) returns the absolute value of a number.[/!] [!"
+"python]Note that math.fabs(n) returns the absolute value of a number.  This "
+"function can only be used if you imported the math module.[/!]"
 msgstr ""
-"Étant donné un entier n, retournez vrai s'il est à 10 près de 100 ou de 200. "
-"Remarquez que Math.abs(n) retourne la valeur absolue d'un nombre."
+"Étant donné deux nombres entiers, retourner la valeur la plus proche de 10, "
+"ou 0 en cas de match nul.\n"
+"[!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un "
+"nombre.[/!] \n"
+"[!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un nombre. "
+"Remarquez également que vous ne pouvez utiliser cette fonction que si vous "
+"avez importé le module math.[/!]"
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/ParotTrouble.html:1
+#: src/lessons/welcome/bat/bool1/ParotTrouble.html:1
 msgid "Parot Trouble"
 msgstr "Problème de perroquet"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/ParotTrouble.html:3
+#: src/lessons/welcome/bat/bool1/ParotTrouble.html:3
 msgid ""
 "We have a loud talking parrot. The \"hour\" parameter is the current hour "
 "time in the range 0..23. We are in trouble if the parrot is talking and the "
@@ -11116,12 +10885,12 @@ msgstr ""
 "parle avant 7h ou après 20h. Retournez vrai si nous avons un problème."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/PosNeg.html:1
+#: src/lessons/welcome/bat/bool1/PosNeg.html:1
 msgid "Positive Negative"
 msgstr "Positif Negatif"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/PosNeg.html:2
+#: src/lessons/welcome/bat/bool1/PosNeg.html:2
 msgid ""
 "Given 2 int values, return true if one is negative and one is positive. "
 "Unless negative is true, then they both must be negative."
@@ -11131,12 +10900,12 @@ msgstr ""
 "que les deux nombres soient négatifs."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/SleepIn.html:1
+#: src/lessons/welcome/bat/bool1/SleepIn.html:1
 msgid "SleepDay"
 msgstr "Grasse matinée"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/SleepIn.html:3
+#: src/lessons/welcome/bat/bool1/SleepIn.html:3
 msgid ""
 "The parameter weekday is true if it is a weekday, and the parameter vacation "
 "is true if we are on vacation. We sleep in if it is not a weekday or we're "
@@ -11148,12 +10917,12 @@ msgstr ""
 "vacances. Retournez vrai si nous pouvons faire la grasse matinée."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool1/SumDouble.html:1
+#: src/lessons/welcome/bat/bool1/SumDouble.html:1
 msgid "Sum Double"
 msgstr "Somme doublée"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/SumDouble.html:2
+#: src/lessons/welcome/bat/bool1/SumDouble.html:2
 msgid ""
 "Given two int values, return their sum. Unless the two values are the same, "
 "then return double their sum."
@@ -11162,12 +10931,12 @@ msgstr ""
 "égales, auquel cas vous devez retourner le double de leur somme."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/AlarmClock.html:1
+#: src/lessons/welcome/bat/bool2/AlarmClock.html:1
 msgid "AlarmClock"
 msgstr "Radio réveil"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/AlarmClock.html:2
+#: src/lessons/welcome/bat/bool2/AlarmClock.html:2
 msgid ""
 "Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a "
 "boolean indicating if we are on vacation, return a string of the form "
@@ -11186,12 +10955,12 @@ msgstr ""
 "week-end."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/AnswerCell.html:1
+#: src/lessons/welcome/bat/bool2/AnswerCell.html:1
 msgid "AnswerCell"
 msgstr "Répondeur"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/AnswerCell.html:2
+#: src/lessons/welcome/bat/bool2/AnswerCell.html:2
 msgid ""
 "Your cell phone rings. Return true if you should answer it. Normally you "
 "answer, except in the morning you only answer if it is your mom calling. In "
@@ -11202,12 +10971,12 @@ msgstr ""
 "Dans tous les cas, vous ne répondez pas si vous dormez."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/BlueTicket.html:1
+#: src/lessons/welcome/bat/bool2/BlueTicket.html:1
 msgid "BlueTicket"
 msgstr "Ticket bleu"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/BlueTicket.html:2
+#: src/lessons/welcome/bat/bool2/BlueTicket.html:2
 msgid ""
 "You have a blue lottery ticket, with ints a, b, and c on it. This makes "
 "three pairs, which we'll call ab, bc, and ac. Consider the sum of the "
@@ -11222,12 +10991,12 @@ msgstr ""
 "de plus que les sommes bc ou ac, le résultat est 5. Sinon, le résultat est 0."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/CaughtSpeeding.html:1
+#: src/lessons/welcome/bat/bool2/CaughtSpeeding.html:1
 msgid "CaughtSpeeding"
 msgstr "Radar de vitesse"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/CaughtSpeeding.html:2
+#: src/lessons/welcome/bat/bool2/CaughtSpeeding.html:2
 msgid ""
 "You are driving a little too fast, and a police officer stops you. Write "
 "code to compute the result, encoded as an int value: 0=no ticket, 1=small "
@@ -11245,12 +11014,12 @@ msgstr ""
 "sinon, votre vitesse peut être supérieure de 5 dans tous les cas."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/CigarParty.html:1
+#: src/lessons/welcome/bat/bool2/CigarParty.html:1
 msgid "CigarParty"
 msgstr "Cigares de fête"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/CigarParty.html:2
+#: src/lessons/welcome/bat/bool2/CigarParty.html:2
 msgid ""
 "When squirrels get together for a party, they like to have cigars. A "
 "squirrel party is successful when the number of cigars is between 40 and 60, "
@@ -11263,12 +11032,12 @@ msgstr ""
 "nombre de cigares. Renvoyez vrai si la fête est réussie. "
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/DateFashion.html:1
+#: src/lessons/welcome/bat/bool2/DateFashion.html:1
 msgid "DateFashion"
 msgstr "Rendez-vous élégant"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/DateFashion.html:2
+#: src/lessons/welcome/bat/bool2/DateFashion.html:2
 msgid ""
 "You and your date are trying to get a table at a restaurant. The parameter "
 "\"you\" is the stylishness of your clothes, in the range 0..10, and \"date\" "
@@ -11288,12 +11057,12 @@ msgstr ""
 "résultat est 1 (peut-être)."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/GreenTicket.html:1
+#: src/lessons/welcome/bat/bool2/GreenTicket.html:1
 msgid "GreenTicket"
 msgstr "Ticket vert"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/GreenTicket.html:2
+#: src/lessons/welcome/bat/bool2/GreenTicket.html:2
 msgid ""
 "You have a green lottery ticket, with ints a, b, and c on it. If the numbers "
 "are all different from each other, the result is 0. If all of the numbers "
@@ -11306,12 +11075,12 @@ msgstr ""
 "nombres sont les mêmes, le résultat est 10."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/In1To10.html:1
+#: src/lessons/welcome/bat/bool2/In1To10.html:1
 msgid "In1To10"
 msgstr "De 1 à 10"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/In1To10.html:2
+#: src/lessons/welcome/bat/bool2/In1To10.html:2
 msgid ""
 "Given a number n, return true if n is in the range 1..10, inclusive. Unless "
 "\"outsideMode\" is true, in which case return true if the number is less or "
@@ -11322,12 +11091,12 @@ msgstr ""
 "petit ou égal à 1 ou bien s'il est plus grand ou égal à 10"
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/InOrderEqual.html:1
+#: src/lessons/welcome/bat/bool2/InOrderEqual.html:1
 msgid "InOrderEqual"
 msgstr "Dans l'ordre croissant"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/InOrderEqual.html:2
+#: src/lessons/welcome/bat/bool2/InOrderEqual.html:2
 msgid ""
 "Given three ints, a b c, return true if they are in strict increasing order, "
 "such as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the "
@@ -11340,12 +11109,12 @@ msgstr ""
 "5 5 7 ou 5 5 5."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/InOrder.html:1
+#: src/lessons/welcome/bat/bool2/InOrder.html:1
 msgid "InOrder"
 msgstr "Dans l'ordre"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/InOrder.html:2
+#: src/lessons/welcome/bat/bool2/InOrder.html:2
 msgid ""
 "Given three ints, a b c, return true if b is greater than a, and c is "
 "greater than b. However, with the exception that if \"bOk\" is true, b does "
@@ -11356,12 +11125,12 @@ msgstr ""
 "n'a pas besoin d'être plus grand que a."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/LastDigit2.html:1
+#: src/lessons/welcome/bat/bool2/LastDigit2.html:1
 msgid "LastDigit 2"
 msgstr "L'autre dernier chiffre"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/LastDigit2.html:2
+#: src/lessons/welcome/bat/bool2/LastDigit2.html:2
 msgid ""
 "Given three ints, a b c, return true if two or more of them have the same "
 "rightmost digit. The ints are non-negative. Note: the % \"mod\" operator "
@@ -11372,12 +11141,12 @@ msgstr ""
 "% \"mod\" calcule le reste, i.e. 17 % 10 vaut 7."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/LessBy10.html:1
+#: src/lessons/welcome/bat/bool2/LessBy10.html:1
 msgid "LessBy10"
 msgstr "Plus petit par 10"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/LessBy10.html:2
+#: src/lessons/welcome/bat/bool2/LessBy10.html:2
 msgid ""
 "Given three ints, a b c, return true if one of them is 10 or more less than "
 "one of the others."
@@ -11386,12 +11155,12 @@ msgstr ""
 "de 10 ou plus que l'un des autres."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/Main.html:1
+#: src/lessons/welcome/bat/bool2/Main.html:1
 msgid "Boolean (even more) fun"
 msgstr "Encore des jeux booléens"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/bool2/Main.html:3
+#: src/lessons/welcome/bat/bool2/Main.html:3
 msgid ""
 "A very good introduction to this type is available here: http://javabat.com/"
 "doc/ifboolean.html."
@@ -11400,12 +11169,12 @@ msgstr ""
 "com/doc/ifboolean.html."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/MaxMod5.html:1
+#: src/lessons/welcome/bat/bool2/MaxMod5.html:1
 msgid "MaxMod5"
 msgstr "Maximum Mod 5"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/MaxMod5.html:2
+#: src/lessons/welcome/bat/bool2/MaxMod5.html:2
 msgid ""
 "Given two int values, return whichever value is larger. However if the two "
 "values have the same remainder when divided by 5, then the return the "
@@ -11419,12 +11188,12 @@ msgstr ""
 "reste, i.e. 7 % 5 vaut 2."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/NearTen.html:1
+#: src/lessons/welcome/bat/bool2/NearTen.html:1
 msgid "NearTen"
 msgstr "Près de dix"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/NearTen.html:2
+#: src/lessons/welcome/bat/bool2/NearTen.html:2
 msgid ""
 "Given a non-negative number \"num\", return true if num is within 2 of a "
 "multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % "
@@ -11435,12 +11204,12 @@ msgstr ""
 "(7 % 5) vaut 2."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/RedTicket.html:1
+#: src/lessons/welcome/bat/bool2/RedTicket.html:1
 msgid "RedTicket"
 msgstr "Ticket rouge"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/RedTicket.html:2
+#: src/lessons/welcome/bat/bool2/RedTicket.html:2
 msgid ""
 "You have a red lottery ticket showing ints a, b, and c, each of which is 0, "
 "1, or 2. If they are all the value 2, the result is 10. Otherwise if they "
@@ -11454,12 +11223,12 @@ msgstr ""
 "0."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/ShareDigit.html:1
+#: src/lessons/welcome/bat/bool2/ShareDigit.html:1
 msgid "ShareDigit"
 msgstr "Chiffre partagé"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/ShareDigit.html:2
+#: src/lessons/welcome/bat/bool2/ShareDigit.html:2
 msgid ""
 "Given two ints, each in the range 10..99, return true if there is a digit "
 "that appears in both numbers, such as the 2 in 12 and 23. (Note: division, e."
@@ -11472,12 +11241,12 @@ msgstr ""
 "\" n%10 renvoye le bon chiffre.)"
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/SortaSum.html:1
+#: src/lessons/welcome/bat/bool2/SortaSum.html:1
 msgid "SortaSum"
 msgstr "Sommes d'entiers"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/SortaSum.html:2
+#: src/lessons/welcome/bat/bool2/SortaSum.html:2
 msgid ""
 "Given 2 ints, a and b, return their sum. However, sums in the range 10..19 "
 "inclusive, are forbidden, so in that case just return 20."
@@ -11486,12 +11255,12 @@ msgstr ""
 "10 et 19 inclus sont interdites, dans ce cas, renvoyez 20."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/SquirrelPlay.html:1
+#: src/lessons/welcome/bat/bool2/SquirrelPlay.html:1
 msgid "SquirrelPlay"
 msgstr "Jeu de l'écureuil"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/SquirrelPlay.html:2
+#: src/lessons/welcome/bat/bool2/SquirrelPlay.html:2
 msgid ""
 "The squirrels in Palo Alto spend most of the day playing. In particular, "
 "they play if the temperature is between 60 and 90 (inclusive). Unless it is "
@@ -11506,12 +11275,12 @@ msgstr ""
 "Renvoyez vrai si les écureuils jouent et faux sinon."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TeaParty.html:1
+#: src/lessons/welcome/bat/bool2/TeaParty.html:1
 msgid "TeaParty"
 msgstr "Goûter"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TeaParty.html:2
+#: src/lessons/welcome/bat/bool2/TeaParty.html:2
 msgid ""
 "We are having a party with amounts of tea and candy. Return the int outcome "
 "of the party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if "
@@ -11529,12 +11298,12 @@ msgstr ""
 "(0)."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TeenSum.html:1
+#: src/lessons/welcome/bat/bool2/TeenSum.html:1
 msgid "TeenSum"
 msgstr "Somme d'ados"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TeenSum.html:2
+#: src/lessons/welcome/bat/bool2/TeenSum.html:2
 msgid ""
 "Given 2 ints, a and b, return their sum. However, \"teen\" values in the "
 "range 13..19 inclusive, are extra lucky. So if either value is a teen, just "
@@ -11545,12 +11314,12 @@ msgstr ""
 "Donc, si l'un des nombres est ado, retournez simplement 19."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TwoAsOne.html:1
+#: src/lessons/welcome/bat/bool2/TwoAsOne.html:1
 msgid "TwoAsOne"
 msgstr "Deux pour un"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TwoAsOne.html:2
+#: src/lessons/welcome/bat/bool2/TwoAsOne.html:2
 msgid ""
 "Given three ints, a b c, return true if it is possible to add two of the "
 "ints to get the third."
@@ -11559,12 +11328,12 @@ msgstr ""
 "deux d'entre eux pour obtenir le troisième."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/bool2/WithoutDoubles.html:1
+#: src/lessons/welcome/bat/bool2/WithoutDoubles.html:1
 msgid "WithoutDoubles"
 msgstr "Sans double"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/WithoutDoubles.html:2
+#: src/lessons/welcome/bat/bool2/WithoutDoubles.html:2
 msgid ""
 "Return the sum of two 6-sided dice rolls, each in the range 1..6. However, "
 "if noDoubles is true, if the two dice show the same value, increment one die "
@@ -11575,12 +11344,12 @@ msgstr ""
 "la valeur suivante, en le mettant à 1 si sa valeur était 6."
 
 #. type: Content of: <h1>
-#: src/jlm/universe/bat/BatWorld.html:1
+#: src/plm/universe/bat/BatWorld.html:1
 msgid "BatWorld"
 msgstr "BatWorld"
 
 #. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:3
+#: src/plm/universe/bat/BatWorld.html:3
 msgid ""
 "This world is a simplistic testing environment largely inspired from the "
 "http://codingbat.com invented by Nick Parlente."
@@ -11589,7 +11358,7 @@ msgstr ""
 "http://codingbat.com inventé par Nick Parlente."
 
 #. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:6
+#: src/plm/universe/bat/BatWorld.html:6
 msgid ""
 "The typical exercises are very short ones, aiming at improving the tactical "
 "programming abilities of the students. That is to say that you will be "
@@ -11604,7 +11373,7 @@ msgstr ""
 "ces problèmes jusqu'à ce que cela devienne automatique."
 
 #. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:12
+#: src/plm/universe/bat/BatWorld.html:12
 msgid ""
 "In contrary to the other worlds, the BatWorld does not provide any fancy "
 "abstraction nor visualization. You have to fill a function, which gets "
@@ -11616,7 +11385,7 @@ msgstr ""
 "paramètres, et c'est tout."
 
 #. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:16
+#: src/plm/universe/bat/BatWorld.html:16
 msgid ""
 "For more information, you should refer to the CodingBat.com documentation, "
 "which contains for example a very useful documentation on boolean operators: "
@@ -11659,10 +11428,10 @@ msgstr "Petits exercices sur les chaînes"
 #: src/lessons/bat/string1/short_desc.html:3
 msgid ""
 "These are some training exercises around strings. But unfortunately, its "
-"integration within JLM is still ongoing."
+"integration within PLM is still ongoing."
 msgstr ""
 "Il s'agit d'exercices d'entraînement au sujet des chaînes de caractères. "
-"Mais malheureusement, leur intégration à JLM est encore en cours."
+"Mais malheureusement, leur intégration à PLM est encore en cours."
 
 #. type: Content of: <p>
 #: src/lessons/bat/string1/short_desc.html:6
@@ -11815,22 +11584,22 @@ msgstr ""
 "à la place du 'a'). Les différentes chaînes \"yak\" ne se chevauchent pas."
 
 #. type: Content of: <h1>
-#: src/lessons/welcome/array/basics/Array.html:1
-msgid "Knotting and sequences"
-msgstr "Tricots et séquences"
+#: src/lessons/welcome/array/basics/Array1.html:1
+msgid "[!java|scala]Arrays[/!][!python]Lists[/!] and Knotting"
+msgstr "[!java|scala]Tableaux[/!][!python]Listes[/!] et tricot"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/basics/Array.html:3
+#: src/lessons/welcome/array/basics/Array1.html:3
 msgid ""
 "The goal of this exercise is to reproduce the pattern of the first row in "
 "the other rows with a shift of one cell (see the Objective tab for details). "
-"The biggest difference between this exercise and the other we had on "
+"The biggest difference between this exercise and the others we had on "
 "patterns is that you have to read the pattern (on first row) before "
 "reproducing it. You cannot do otherwise because the same code will be "
-"executed on three different worlds, each of them having its specific pattern."
+"executed on three different worlds, each of them having a specific pattern."
 msgstr ""
 "L'objectif de cet exercice est de reproduire le motif de la première colonne "
-"en le décalant d'une case (voir l'onglet Objectives pour plus de détails). "
+"en le décalant d'une case (voir l'onglet «Objectif» pour plus de détails). "
 "La grande différence entre cet exercice et les précédents sur les motifs, "
 "c'est qu'il faut maintenant lire (sur la première colonne) le motif "
 "souhaité, puis le reproduire ensuite. Il est impossible de faire autrement "
@@ -11838,7 +11607,7 @@ msgstr ""
 "différents, chacune ayant un motif propre à reproduire."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:11
+#: src/lessons/welcome/array/basics/Array1.html:11
 msgid ""
 "One solution is to read the next cell, and go copy it in position before "
 "coming back to read the second cell. But since it is forbidden to use the "
@@ -11849,205 +11618,256 @@ msgstr ""
 "position, avant de revenir lire la case suivante, etc. Mais comme vous "
 "n'avez pas le droit d'utiliser les méthodes permettant de téléporter la "
 "buggle à une case particulière (<code>setPos()</code> et autres), cette "
-"façon de faire va être très pénible à mettre en place."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:16
-msgid ""
-"The simplest is to store the sequence of colors that constitute the whole "
-"pattern in an <b>array</b>."
-msgstr ""
-"Le plus simple est de stocker l'enchainement de couleurs constituant le "
-"motif dans un <b>tableau</b>."
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:19
-msgid ""
-"An array is a sequence of positions in which one can store values of the "
-"same kind (one value per cell). It is thus a sequence of values of the same "
-"kind:"
-msgstr ""
-"Un tableau est une séquence d'emplacements dans lesquels on peut mettre des "
-"valeurs de même type (une par emplacement). C'est donc une séquence de cases "
-"de même type :"
+"façon de faire va être très pénible à mettre en place."
 
 #. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:24
+#: src/lessons/welcome/array/basics/Array1.html:16
 msgid ""
-"The simplest is to store the sequence of colors that constitute the whole in "
-"a <b>list</b>."
+"The simplest is to store the sequence of colors that constitute the whole "
+"pattern in an [!java|scala]<b>array</b>[/!][!python]<b>list</b>[/!].  But "
+"before we can do so, we should learn a bit what [!java|scala]arrays[/!][!"
+"python]lists[/!] are."
 msgstr ""
 "Le plus simple est de stocker l'enchainement de couleurs constituant le "
-"motif dans une <b>liste</b>."
+"motif dans \n"
+"[!java|scala]un <b>tableau</b>[/!][!python]une <b>liste</b>[/!].  \n"
+"Mais avant de pouvoir faire cela, nous devons en apprendre un peu plus sur "
+"les [!java|scala]tableau[/!][!python]listes[/!]."
 
 #. type: Content of: <h2>
-#: src/lessons/welcome/array/basics/Array.html:26
-msgid "Lists"
-msgstr "Les listes"
+#: src/lessons/welcome/array/basics/Array1.html:20
+msgid "[!java|scala]Arrays[/!][!python]List[/!]"
+msgstr "[!java|scala]Les tableaux[/!][!python]Les listes[/!]"
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array1.html:22
+msgid ""
+"[!java|scala]An array[/!][!python]A list[/!] is an ordered sequence of "
+"variables that go together.  It is somehow similar to a shelve where each "
+"level can store a separate value. Each variable of the sequence is "
+"identified by its position, and can store a specific value. [!java|scala]All "
+"cells of the array must store values of the same type because arrays are "
+"homogeneous in [!thelang]. It is possible to trick this restriction by using "
+"the datatype <code>[!java]Object[/!][!scala]Any[/!]</code> that can contain "
+"[!java]almost[/!] any other datatype. [!java]Primitive types such as the "
+"ones we saw so far (int, boolean, double, char, etc) cannot be stored in an "
+"Object variable, but their objectified counter-part (Integer, Boolean, "
+"Double, Char, Boolean, etc) can.[/!] It is however a good practice to make "
+"the type of an array as specific as possible, i.e., if you plan to store "
+"some integers in your array, make it an array of integers, not of [!"
+"java]Object[/!][!scala]Any[/!].[/!] [!python]Lists can even mix values of "
+"differing types, such as integer values in some cells and colors in other "
+"cells.[/!]"
+msgstr ""
+"[!java|scala]Un tableau[/!][!python]Une liste[/!] est une séquence ordonnée "
+"de variables qui marchent ensemble. \n"
+"C'est un peu similaire à une commode dont les différents tiroirs peuvent "
+"stocker des valeurs différentes. \n"
+"Chaque variable de la séquence est identifiée par sa position et peut "
+"stocker une valeur spécifique.\n"
+"[!java|scala]Toutes les cellules d'un tableau doivent stocker des valeurs du "
+"même type de données parce que les tableaux sont homogènes en [!thelang]. \n"
+"Il est cependant possible de contourner cette restriction en utilisant le "
+"type de données <code>[!java]Object[/!][!scala]Any[/!]</code> qui peut "
+"contenir [!java]presque[/!] tous les autres type de données[!scala] («any» "
+"veut dire «n'importe» en anglais)[/!].\n"
+"[!java]Les types primitifs comme ceux que nous avons utilisé jusqu'à présent "
+"(int, boolean, double, char, etc) ne peuvent pas être stockés dans une "
+"variable Object, mais leurs variantes objectifiées (Integer, Boolean, "
+"Double, Char, Boolean, etc) peuvent l'être.[/!] \n"
+"Il est cependant raisonnable de rendre ses tableaux aussi spécifiques que "
+"possible. Si vous avez l'intention de stocker des entiers, faites en un "
+"tableau de [!java]integer[/!][!scala]Int[/!], pas de [!java]Object[/!][!"
+"scala]Any[/!].[/!] \n"
+"[!python]Les listes peuvent contenir des données de différents types, en "
+"mélangeant par exemple quelques valeurs entières dans certaines cellules "
+"avec des entiers dans d'autres cellules.[/!]"
 
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:27
-msgid ""
-"A list is an array of positions in which one can store values. Each cell is "
-"a variable on its own. A list is then a sequence of values. Lists can even "
-"mix values of differing types, such as integer values in some cells and "
-"colors in other cells.  At the end, a list is very similar to a storage "
-"shelve, where each level can store a separate value."
-msgstr ""
-"Une liste est une séquence d'emplacements dans lesquels on peut mettre des "
-"valeurs (une par emplacement). Chaque cellule est une variable à part "
-"entière. La liste est donc une séquence de valeurs. Il est même possible de "
-"stoquer des valeurs de type différentes dans une liste, avec par exemple des "
-"entiers dans certaines cases et des couleurs dans d'autres cases. En quelque "
-"sorte, une liste ressemble un peu à une étagère où chaque étage peut "
-"contenir une valeur donnée."
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:38
+msgid ""
+"T is the [!java|scala]array[/!][!python]list[/!]'s name, [!java|python]T[0]"
+"[/!][!scala]T(0)[/!] is the name of the first cell, [!java|python]T[1][/!][!"
+"scala]T(1)[/!] the name of the second cell, [!java|python]T[2][/!][!"
+"scala]T(2)[/!] the third one, etc. And yes, the first cell is numbered [!"
+"java|python]T[0][/!][!scala]T(0)[/!] while the last one of [!java|scala]an "
+"array[/!][!python]a list[/!] of size N is [!java|python]T[N-1][/!][!"
+"scala]T(N-1)[/!]. It may seem funny to count starting from 0 and not from 1 "
+"as usual, but some historical reasons make it unavoidable here."
+msgstr ""
+"T est le nom [!python]de la liste[/!][!scala|java]du tableau[/!], \n"
+"[!java|python]T[0][/!][!scala]T(0)[/!] est le nom de la première case, \n"
+"[!java|python]T[1][/!][!scala]T(1)[/!] de la deuxième case, \n"
+"[!java|python]T[2][/!][!scala]T(2)[/!] de la troisième case, etc... \n"
+"Et oui, la première case est [!java|python]T[0][/!][!scala]T(0)[/!] et la "
+"dernière case\n"
+"[!python]d'une liste[/!][!scala|java]d'un tableau[/!] de taille N est \n"
+"[!java|python]T[N-1][/!][!scala]T(N-1)[/!]. \n"
+"Cela peut sembler étrange de commencer à compter à partir de 0 et non de 1, "
+"mais c'est ainsi (et cela s'explique par des raisons historiques obscures)."
+
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:46
+msgid "Basic usage"
+msgstr "Usage de base"
 
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:38
-msgid ""
-"T is the array's name, T[0] is the name of the first cell, T[1] the name of "
-"the second cell, T[2] the third one, etc. And yes, the first cell in "
-"numbered T[0] and the last one of an array of size N is T[N-1]."
-msgstr ""
-"T est le nom du tableau, T[0] est le nom de la première case, T[1] de la "
-"deuxième case, T[2] de la troisième case, etc... Et oui, la première case "
-"est T[0] et la dernière case d'un tableau de dimension N est T[N - 1]."
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:48
+msgid ""
+"We can use an integer variable <i>i</i> to access with [!java|python]T[i][/!]"
+"[!scala]T(i)[/!] to the cells: when the value of <i>i</i> is 0, then [!java|"
+"python]T[i][/!][!scala]T(i)[/!] accesses [!java|python]T[0][/!][!scala]T(0)"
+"[/!]; when the value of <i>i</i> is 10, then [!java|python]T[i][/!][!"
+"scala]T(i)[/!] accesses [!java|python]T[10][/!][!scala]T(10)[/!].  <i>i</i> "
+"is said to be the <b>index</b> in T.  <code>[!java|python]T[i][/!][!"
+"scala]T(i)[/!]</code> can be used just like any variable. We can set a new "
+"value:"
+msgstr ""
+"On peut utiliser une variable entière <i>i</i> pour accéder avec [!java|"
+"python]T[i][/!][!scala]T(i)[/!] aux cases.\n"
+"Quand <i>i</i> vaut 0 alors [!java|python]T[i][/!][!scala]T(i)[/!] dénote la "
+"case [!java|python]T[0][/!][!scala]T(0)[/!]; \n"
+"lorsque <i>i</i> vaut 10,  [!java|python]T[i][/!][!scala]T(i)[/!] dénote  [!"
+"java|python]T[10][/!][!scala]T(10)[/!].\n"
+"On dit alors que <i>i</i> est un <b>indice</b> dans [!java|scala]le "
+"tableau[/!][!python]la liste[/!] T.\n"
+"<code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> peut être utilisé comme "
+"n'importe quelle variable.\n"
+"On peut lui affecter une nouvelle valeur:"
 
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:41
-msgid ""
-"T is the list's name, T[0] is the name of the first cell, T[1] the name of "
-"the second cell, T[2] the third one, etc. And yes, the first cell in "
-"numbered T[0] and the last one of a list of size N is T[N-1]. It may seem "
-"funny to count starting from 0 and not from 1 as usual, but some historical "
-"reasons make it unavoidable here."
-msgstr ""
-"T est le nom de la liste, T[0] est le nom de la première case, T[1] de la "
-"deuxième case, T[2] de la troisième case, etc... Et oui, la première case "
-"est T[0] et la dernière case d'une liste de taille N est T[N - 1]. Cela peut "
-"sembler étrange de commencer à compter à partir de 0 et non de 1, mais c'est "
-"ainsi (et cela s'explique par des raisons historiques obscures)."
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:56
+#, no-wrap
+msgid "[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]"
+msgstr "[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]"
 
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:47
-msgid ""
-"We can use an integer variable <i>i</i> to access with T[i] to the cells: "
-"when the value of <i>i</i> is 0, then T[i] accesses T[0], when the value of "
-"<i>i</i> is 10, then T[i] accesses T[10]. <i>i</i> is said to be the index "
-"in T."
-msgstr ""
-"On peut utiliser une variable entière <i>i</i> pour accéder avec T[i] aux "
-"cases : lorsque <i>i</i> vaut 0 alors T[i] dénote la case T[0], lorsque "
-"<i>i</i> vaut 10, T[i] dénote T[10]. On dit alors que <i>i</i> est un "
-"<b>indice</b> dans le tableau T ."
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:58
+msgid "We can retrieve and use its value:"
+msgstr "On peut réutiliser et tester cette valeur :"
 
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:52
-msgid "Initialization"
-msgstr "Initialisation"
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:59
+#, no-wrap
+msgid "x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]"
+msgstr "x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:53
-msgid ""
-"If <code>T</code> contains 10 elements, then each cell can be initialized "
-"with a simple loop:"
-msgstr ""
-"Si <code>T</code> contient 10 éléments, on peut alors initialiser son "
-"contenu\n"
-"avec une simple boucle :"
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:61
+msgid "We can test this value:"
+msgstr "On peut tester cette valeur :"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:56
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:62
 #, no-wrap
 msgid ""
-"for (int i = 0; i<10; i++) {\n"
-"   T[i] = 3;\n"
-"}\n"
+"if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) [!scala|java]{[/!][!python]:[/!]\n"
+"    [!java|scala]//[/!][!python]#[/!] instructions...\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"for (int i = 0; i<10; i++) {\n"
-"   T[i] = 3;\n"
-"}\n"
+"if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) [!scala|java]{[/!][!python]:[/!]\n"
+"    [!java|scala]//[/!][!python]#[/!] instructions...\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:61
-#, no-wrap
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:66
 msgid ""
-"for i in range(10):\n"
-"   T[i] = 3;\n"
+"It is very easy to traverse the whole [!scala|java]array[/!][!"
+"python]list[/!], for example to initialize each cells."
 msgstr ""
-"for i in range(10):\n"
-"   T[i] = 3;\n"
+"Il est également très simple de parcourir [!java|scala]tout le tableau[/!][!"
+"python]toute la liste[/!], par exemple pour initialiser chaque cellule."
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:65
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:69
+#, no-wrap
 msgid ""
-"Note that <code>range(max)</code> returns the list of all integers that are "
-"smaller than <code>max</code>, starting with 0. There is exactly max such "
-"values. For example, if <code>max</code> is 3, the returned values are 0, 1 "
-"and 2."
+"[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!]\n"
+"   [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"<code>range(max)</code> renvoie la liste de tous les entiers inférieurs à "
-"<code>max</code>, en commençant à 0. Il y a exactement <code>max</code> "
-"valeurs répondant à ces critères. Par exemple, si <code>max</code> est 3, "
-"les valeurs renvoyées seront 0, 1 et 2."
+"[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!]\n"
+"   [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!]\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:70
-msgid ""
-"<code>T[i]</code> can be used just like a variable. We can set a new value:"
-msgstr "<code>T[i]</code> s'utilise comme une variable. On peut l'affecter :"
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:71
-#, no-wrap
-msgid "T[i] = 78"
-msgstr "T[i] = 78"
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:73
-msgid "We can retrieve and use its value:"
-msgstr "On peut réutiliser et tester cette valeur :"
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:74
-#, no-wrap
-msgid "x = T[i]"
-msgstr "x = T[i]"
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:76
-msgid "We can test this value:"
-msgstr "On peut tester cette valeur :"
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:73
+msgid ""
+"[!java|scala]The notation <code>T.length</code> retrieves the length of the "
+"array T,[/!] [!python]The function <code>len()</code> retrieves the length "
+"of the list T,[/!] allowing to build a classical for loop easily.  [!"
+"python]Actually, the <code>len()</code> function is much more generic and "
+"can be used to retrieve the length of many objects.  Applied to strings for "
+"example, it returns the amount of chars in this string.[/!] [!scala]Don't "
+"forget to start at <code>0</code> and stop at <code>T.length-1</code> "
+"instead of <code>1 to T.length</code> however.[/!]"
+msgstr ""
+"[!java|scala]La notation <code>T.length</code> permet d'accéder à la taille "
+"(«length» en anglais) du tableau T,[/!]\n"
+"[!python]La fonction <code>len()</code> renvoie la longueur de la liste T,"
+"[/!] \n"
+"ce qui permet de construire facilement la boucle.\n"
+"[!python]En fait, la fonction <code>len()</code> est bien plus générique et "
+"peut être utilisée pour calculer la taille de nombreux objets. Appliquée à "
+"une chaîne de caractères par exemple, elle retourne le nombre de caractères "
+"composant cette chaîne.[/!]\n"
+"[!scala]N'oubliez pas de commencer à <code>0</code> pour terminer à <code>T."
+"length-1</code> au lieu de <code>1 to T.length</code>![/!]"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:78
-#, no-wrap
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:81
 msgid ""
-"if (T[i] > 0 ) {\n"
-"    // instructions...\n"
-"}\n"
+"If you just want to iterate over the values of T without keeping track of "
+"their index, you can simply write:"
 msgstr ""
-"if (T[i] > 0 ) {\n"
-"    // instructions...\n"
-"}\n"
+"Si vous souhaitez simplement parcourir les valeurs de T sans avoir besoin de "
+"l'index de chaque valeur, vous pouvez écrire simplement :"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:83
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:82
 #, no-wrap
 msgid ""
-"if T[i] > 0:\n"
-"    // instructions...\n"
+"[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in T:[/!]\n"
+"  action()[!java];[/!]\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"if T[i] > 0:\n"
-"    // instructions...\n"
+"[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in T:[/!]\n"
+"  action()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:85
+msgid ""
+"[!java]This construct is called an <i>extended loop</i> in Java. The "
+"variable <i>i</i> takes all values of the set located to the right of the "
+"colon (:), one after the other.[/!] [!python|scala]This is actually very "
+"similar to the previous construct.  Simply, <code>[!python]range(n)[/!][!"
+"scala]i to j[/!]</code> returns a set of integers over which the for "
+"construct iterates.  Actually, [!thelang] offers much more elegant ways to "
+"traverse [!python]lists[/!][!scala]arrays[/!] and other data collections, "
+"but this should be the topic of a specific set of exercises (that are still "
+"to be written in PLM).[/!]"
+msgstr ""
+"[!java]Cette construction s'appelle une boucle <code>for</code> étendue en "
+"Java. \n"
+"La variable <i>i</i> prend successivement toutes les valeurs de l'ensemble "
+"placé à droite des deux-points (:).[/!] \n"
+"[!python|scala]Cette écriture est finalement très semblable à la "
+"précédente. \n"
+"Simplement, <code>[!python]range(n)[/!][!scala]i to j[/!]</code> retourne un "
+"ensemble d'entiers sur lequel la boucle <code>for</code> itère.\n"
+"En fait, [!thelang] offre d'autres moyens très élégants de traverser des [!"
+"python]listes[/!][!scala]tableaux[/!] \n"
+"et d'autres collections de données. Mais cela devrait être le sujet "
+"d'exercices spécifiques (qui restent à écrire dans PLM).[/!]"
 
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:87
-msgid "Declaring an array"
-msgstr "Déclaration d'un tableau"
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:96
+msgid "Declaring [!python]a list[/!][!java|scala]an array[/!]"
+msgstr "Declarer [!python]une liste[/!][!java|scala]un tableau[/!]"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:88
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:99
 msgid ""
 "If you know beforehand the content of your list, you can affect these values "
 "all together.  Just put them between square braces and separated by commas "
@@ -12057,370 +11877,413 @@ msgstr ""
 "affecter ces valeurs directement. Placez-les simplement entre crochets et "
 "séparées par des virgules comme ceci :"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:91
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:102
 #, no-wrap
 msgid ""
 "L = [1, 3, 5, 7, 9] \n"
-"# L is now an array of 5 values, all of them being integers\n"
+"<span class=\"comment\"># L is now an array of 5 values, all of them being integers</span>"
 msgstr ""
 "L = [1, 3, 5, 7, 9] \n"
-"# L est maintenant une liste de 5 valeurs, toutes des entiers\n"
+"<span class=\"comment\"># L est maintenant une liste de 5 valeurs, toutes des entiers</span>"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:94
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:104
 msgid ""
 "Otherwise, you probably want to create an empty list and then append each "
-"values separately:"
+"values separately to the list:"
 msgstr ""
 "Dans le cas contraire, le plus simple est de créer une liste vide puis "
-"d'ajouter chaque valeur séparément :"
+"d'ajouter chaque valeur séparément à la liste :"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:96
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:106
 #, no-wrap
 msgid ""
 "L2 = [] \n"
-"# L2 is now an empty list\n"
+"<span class=\"comment\"># L2 is now an empty list</span>\n"
 "L2.append(1)\n"
 "L2.append(3)\n"
 "L2.append(5)\n"
 "L2.append(7)\n"
 "L2.append(9) \n"
-"# Its content is now the same as L previously\n"
+"<span class=\"comment\"># Its content is now the same as L previously</span>"
 msgstr ""
 "L2 = [] \n"
-"# L2 est maintenant une liste vide\n"
+"<span class=\"comment\"># L2 est maintenant une liste vide</span>\n"
 "L2.append(1)\n"
 "L2.append(3)\n"
 "L2.append(5)\n"
 "L2.append(7)\n"
 "L2.append(9) \n"
-"# Son contenu est maintenant le même que celui de L ci-dessus\n"
+"<span class=\"comment\"># Son contenu est maintenant le même que celui de L ci-dessus</span>"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:106
-msgid "An array can be declared the following way:"
-msgstr "Un tableau se déclare de la manière suivante :"
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:107
-#, no-wrap
-msgid "int[] T;"
-msgstr "int[] T;"
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:109
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:117
 msgid ""
-"<code>int</code> means that the elements of the array are of type integer; "
-"<code>T</code> is the name of the array and <code>[]</code> means that we "
-"are speaking of an array. It is also possible to declare the same array the "
-"following way. Both writings are equivalent, but the first one is often "
-"prefered in Java."
+"To declare a variable named <b>T</b> that can store arrays of integers, one "
+"should write:"
 msgstr ""
-"<code>int</code> indique que les éléments du tableau <code>T</code> sont de "
-"type entier est le nom du tableau, <code>[]</code> indique qu'il s'agit d'un "
-"tableau. On peut aussi écrire cette déclaration de la manière suivante. Les "
-"deux écritures sont syntaxiquement équivalente, mais la première est souvent "
-"préférée en Java."
+"Pour créer une variable nommée <b>T</b> pouvant contenir un tableau "
+"d'entiers, on écrira :"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:114
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:118
 #, no-wrap
-msgid "int T[];"
-msgstr "int T[];"
+msgid "[!java]int[] T;[/!][!scala]var T:Array[Int][/!]"
+msgstr "[!java]int[] T;[/!][!scala]var T:Array[Int][/!]"
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:120
+msgid ""
+"[!java]<code>int</code> means that the elements of the array are of type "
+"integer; <code>[]</code> means that we are speaking of an array and <code>T</"
+"code> is the name of the variable.  For historical reasons, this can also be "
+"written as <code>int T[]</code> (with the [] after the variable name), but "
+"this is less readable and should probably be avoided.[/!] [!scala]The "
+"<code>[Int]</code> notation specializes the Array type (that is generic), "
+"specifying that each cell of this array is an integer. An array of booleans "
+"would simply by written <code>Array[Boolean]</code>.[/!]"
+msgstr ""
+"[!java]<code>int</code> indique que les éléments du tableau sont de type "
+"entier;\n"
+"<code>[]</code> indique que nous parlons d'un tableau tandis que <code>T</"
+"code> est le nom de la variable. \n"
+"Pour des raisons historiques, cela peut également être écrit sous la forme "
+"<code>int T[]</code> (avec [] à droite du nom de la variable), \n"
+"mais cette forme est moins lisible et devrait probablement être évitée.[/!]\n"
+"[!scala]La notation <code>[Int]</code> spécialise le type <code>Array</code> "
+"(«tableau» en anglais), qui est générique. Cela spécifie que chaque case du "
+"tableau est un entier. Le type d'un tableau de booleens s'écrirait "
+"simplement <code>Array[Boolean]</code>.[/!]"
 
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:116
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:128
 msgid "Allocating an array"
 msgstr "Allocation d'un tableau"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:118
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:130
 msgid ""
 "Declaring a variable <code>T</code> that stores an array only reserve the "
-"name <code>T</code> for later use. But the array is not initialized yet: it "
-"does not have any value. What would <code>T[4]</code> mean if we didn't say "
-"that the array is at least 5 cells long?"
+"<b>name</b> <code>T</code> for later use, but not the memory area to store "
+"the cells. The array is not initialized yet: it does not have any value. "
+"What would <code>[!java]T[4][/!][!scala]T(4)[/!]</code> mean if we didn't "
+"say that the array is 5 cells long?"
 msgstr ""
 "Déclarer un tableau <code>T</code> nous réserve juste le nom <code>T</code> "
-"pour l'utiliser plus tard. Mais le tableau n'est pas initialisé : il n'a pas "
-"de valeur. Que voudrait dire <code>T[4]</code> si nous n'avons pas encore "
-"dit que <code>T</code> est un tableau d'au moins 5 éléments ?"
+"pour l'utiliser plus tard, mais pas la place en mémoire pour stocker les "
+"cases. Le tableau n'est pas initialisé : il n'a pas de valeur. Que voudrait "
+"dire <code>T[4]</code> si nous n'avons pas encore dit que <code>T</code> est "
+"un tableau de 5 éléments ?"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:123
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:135
 msgid "First and foremost, we have to give a value to <code>T</code>:"
 msgstr "Avant tout, il faut donc lui affecter une valeur à <code>T</code>:"
 
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:124
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:136
 #, no-wrap
-msgid "T = new int[10];"
-msgstr "T = new int[10];"
+msgid "[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]"
+msgstr "[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]"
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:126
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:138
 msgid ""
-"<code>new</code> means that we want to create something, and <code>int[10]</"
-"code> means that it is an array of 10 integer values. In return, an array of "
-"10 integer cells is created in memory, and the <code>T</code> variable "
-"reference this array."
+"<code>new</code> means that we want to create something, and <code>[!"
+"java]int[10][/!][!scala]Array[Int](10)[/!]</code> means that it is an array "
+"of 10 integer values.  In return, an array of 10 integer cells is created in "
+"memory, and the <code>T</code> variable <b>references</b> this array."
 msgstr ""
-"<code>new</code> indique qu'il faut créer quelque chose, et <code>int[10]</"
-"code> indique qu'il s'agit d'un tableau de 10 valeur entières. En réponse, "
-"un tableau d'entiers de longueur 10 est crée en mémoire, et la variable "
-"<code>T</code> référence ce tableau."
+"<code>new</code> indique qu'il faut créer quelque chose, et \n"
+"<code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> indique qu'il "
+"s'agit d'un tableau de 10 valeur entières. En réponse, un tableau d'entiers "
+"de longueur 10 est crée en mémoire, et la variable <code>T</code> "
+"<b>référence</b> ce tableau."
 
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:131
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:143
 msgid ""
 "The size of an array is fixed and cannot be changed after the creation of "
-"the array. To know the size of a <code>T</code> array, we can consult the "
-"value of the variable <code>T.length</code>."
+"the array. The size of a <code>T</code> array can be retrieve by consulting "
+"the variable <code>T.length</code>."
 msgstr ""
 "La taille d'un tableau est fixée et ne peut plus être changée après la "
-"création du tableau. Pour connapitre la taille d'un tableau <code>T</code>, "
-"on peut consulter la valeur de la variable <code>T.length</code>."
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:136
-msgid ""
-"It is forbidden to write something like <code>int T[10];</code> You are "
-"required to use the <code>new</code> instruction. On the other hand, you "
-"perfectly can specify the size with a variable <code>i</code>."
-msgstr ""
-"Il est interdit d'écrire quelque chose comme <code>int T[10]</code>.Il faut "
-"absolument utiliser l'instruction <code>new</code>. Par contre, on peut très "
-"bien donner la dimension par une variable <code>i</code>."
+"création du tableau. Pour connaître la taille d'un tableau <code>T</code>, "
+"on peut consulter la variable <code>T.length</code>."
 
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:140
-#, no-wrap
-msgid "T = new int[i];"
-msgstr "T = new int[i];"
-
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:141
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:147
 msgid ""
+"While allocating, you can specify the size with a variable: <code>[!"
+"java]int[] T = new int[i];[/!][!scala]var T = new Array[Int](i);[/!]</code> "
 "In this case, the array's size will be set to the value of <code>i</code> "
-"<b>when <code>new</code> gets called</b>. If the variable changes afterward, "
-"it won't change the array's size."
-msgstr ""
-"Dans ce cas, la taille du tableau sera la valeur de <code>i</code> <b>au "
-"moment où on a fait le</b> <code>new</code>. Si <code>i</code> change après "
-"coup, cela ne modifie pas la taille du tableau."
-
-#. type: Content of: <br><p><p><h4>
-#: src/lessons/welcome/array/basics/Array.html:145
-msgid "Declaration and allocation"
-msgstr "Déclaration et allocation"
-
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:146
-#, no-wrap
-msgid "int[] T = new int[10];"
-msgstr "int[] T = new int[10];"
-
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:148
-msgid "We declare and allocate the array on the same line."
-msgstr "On déclare et alloue le tableau en une seule ligne."
-
-#. type: Content of: <br><p><p><h4>
-#: src/lessons/welcome/array/basics/Array.html:150
+"<i>when <code>new</code> gets called</i>.  The size of the array still "
+"cannot be modified : even if the variable <code>i</code> changes afterward, "
+"the size remains to the value given when it was allocated.  [!java]Also, it "
+"is forbidden to write something like <code>int T[10];</code> when declaring "
+"the variable.  You are required to use the <code>new</code> instruction to "
+"allocate it, as in <code>int[] T = new int[10];</code> [/!]"
+msgstr ""
+"Lors de l'allocation, vous pouvez spécifier la taille à utiliser avec une "
+"variable: \n"
+"<code>[!java]int[] T = new int[i];[/!][!scala]var T = new Array[Int](i);"
+"[/!]</code> \n"
+"Dans ce cas, la taille du tableau est fixée à la valeur de <code>i</code> "
+"<i>quand <code>new</code> a été appelé</i>. \n"
+"La taille du tableau ne peut toujours pas être modifiée. Même si la valeur "
+"de <code>i</code> est modifiée ensuite, la taille reste la même.\n"
+"[!java]Enfin, il est interdit d'écrire quelque chose comme <code>int T[10];</"
+"code> pour déclarer la variable. Il faut absolument utiliser <code>new</"
+"code> pour l'allouer, comme dans <code>int[] T = new int[10];</code> [/!]"
+
+#. type: Content of: <p><p><p><h4>
+#: src/lessons/welcome/array/basics/Array1.html:155
 msgid "Declaration and initialization"
 msgstr "Déclaration et initialisation"
 
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:151
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:156
+msgid ""
+"If you know beforehand the content of your array, you can declare, allocate "
+"and initialize it in one shoot:"
+msgstr ""
+"Si vous connaissez le contenu de votre tableau à l'avance, vous pouvez le "
+"déclarer, l'allouer et l'initialiser en un coup:"
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:157
 #, no-wrap
-msgid "int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };"
-msgstr "int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };"
+msgid "[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]"
+msgstr "[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]"
 
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:153
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:159
 msgid ""
-"We declare, allocate and initialize the array on the same line. To know the "
-"size of the array to allocate, the compiler counts the provided values. This "
-"code is equivalent to:"
+"To know the size of the array to allocate, the compiler counts the provided "
+"values.  This code is equivalent to:"
 msgstr ""
-"On déclare, alloue et initialise le tableau en une seule ligne. Pour "
-"connaître la taille du tableau à allouer, le compilateur compte les valeurs "
-"données.  Ce code est équivalent à :"
+"Pour connaître la taille du tableau à allouer, le compilateur compte les "
+"valeurs données.  Ce code est équivalent à :"
 
-#. type: Content of: <br><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:157
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:161
 #, no-wrap
 msgid ""
-"int[] T = new int[10];\n"
+"[!java]int[] T = new int[10];\n"
 "T[0] = 1;\n"
 "T[1] = 2;\n"
 "...\n"
-"T[9] = 10;\n"
+"T[9] = 10;[/!][!scala]var T = new Array[Int](10);\n"
+"T(0) = 1\n"
+"T(1) = 2\n"
+"...\n"
+"T(9) = 10[/!]"
 msgstr ""
-"int[] T = new int[10];\n"
+"[!java]int[] T = new int[10];\n"
 "T[0] = 1;\n"
 "T[1] = 2;\n"
 "...\n"
-"T[9] = 10;\n"
+"T[9] = 10;[/!][!scala]var T = new Array[Int](10);\n"
+"T(0) = 1\n"
+"T(1) = 2\n"
+"...\n"
+"T(9) = 10[/!]"
 
-#. type: Content of: <br><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:164
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:171
 msgid "It is also equivalent to:"
 msgstr "C'est aussi équivalent au code :"
 
-#. type: Content of: <br><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:166
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:172
 #, no-wrap
 msgid ""
-"int[] T = new int[10];\n"
+"[!java]int[] T = new int[10];\n"
 "for (int i=0; i<T.length; i++) {\n"
 "  T[i] = i+1;\n"
-"}\n"
+"}[/!][!scala]var T = new Array[Int](10);\n"
+"for (i <- 0 to T.length-1) {\n"
+"  T(i) = i+1\n"
+"}[/!]"
 msgstr ""
-"int[] T = new int[10];\n"
+"[!java]int[] T = new int[10];\n"
 "for (int i=0; i<T.length; i++) {\n"
 "  T[i] = i+1;\n"
-"}\n"
-
-#. type: Content of: <br><p><p><p><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:176
-msgid "Lists and method parameters"
-msgstr "Listes et paramètres de méthode"
-
-#. type: Content of: <br><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:177
-msgid ""
-"It is perfectly ok to pass a list to a method as a parameter. This method "
-"can then use this parameter as if it were defined there. Methods can also "
-"return lists as result without any complication. As an example, here is a "
-"method doubling every values of the list received as a parameter:"
-msgstr ""
-"Il est parfaitement autorisé de passer une liste en paramètre à une méthode. "
-"Cette méthode peut ensuite utiliser cette liste comme si elle avait été "
-"définie localement. Les méthodes peuvent même renvoyer des listes en guise "
-"de résultats sans complication particulière. Par exemple, voici une méthode "
-"qui double la valeur de toutes les valeurs de la liste qu'elle reçoit en "
-"paramètre :"
+"}[/!][!scala]var T = new Array[Int](10);\n"
+"for (i <- 0 to T.length-1) {\n"
+"  T(i) = i+1\n"
+"}[/!]"
 
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:182
-#, no-wrap
-msgid ""
-"L = [1, 3, 5, 7, 9]\n"
-"def doubling(param):\n"
-"  for i in range( len(param) ):\n"
-"    param[i] *= 2\n"
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:183
+msgid "[!python]Lists[/!][!scala|java]Arrays[/!] and method parameters"
 msgstr ""
-"L = [1, 3, 5, 7, 9]\n"
-"def doubler(param):\n"
-"  for i in range( len(param) ):\n"
-"    param[i] *= 2\n"
-
-#. type: Content of: <br><p><p><p><p><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:189
-msgid "Arrays and method parameters"
-msgstr "Tableaux et paramètres de méthode"
+"Les [!python]listes[/!][!scala|java]tableaux[/!] et les paramètres de "
+"méthodes"
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:190
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:184
 msgid ""
-"It is perfectly ok to pass an array to a method as a parameter. The method "
-"must have a prototype similar to:"
+"It is perfectly OK to pass [!python]a list[/!][!java|scala]an array[/!] to a "
+"method as a parameter.  This method can then use this parameter as if it "
+"were defined locally:"
 msgstr ""
-"On peut tout à fait passer un tableau en paramètre d'une méthode. La méthode "
-"doit l'indiquer dans son prototype de la façon suivante:"
+"On peut tout à fait passer [!java|scala]un tableau[/!][!python]une liste[/!] "
+"en paramètre d'une méthode. La méthode peut alors l'utiliser comme si la "
+"variable avait été définie localement:"
 
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:192
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:186
 #, no-wrap
 msgid ""
-"void myMethod(int[] values) {\n"
-"  // do something\n"
-"}"
+"[!java]boolean has42First(int[] array) {\n"
+"    return array[0] == 42;\n"
+"}[/!][!python]def has42First(list):\n"
+"  return list[0] == 42[/!][!scala]def has42First(array:Array[Int]):Boolean = {\n"
+"  return array(0) == 42\n"
+"}[/!]"
 msgstr ""
-"void maMethode(int[] valeurs) {\n"
-"  // faire quelque chose\n"
-"}"
+"[!java]boolean a42Premier(int[] tableau) {\n"
+"    return tableau[0] == 42;\n"
+"}[/!][!python]def a42Premier(liste):\n"
+"  return liste[0] == 42[/!][!scala]def a42Premier(tableau:Array[Int]):Boolean = {\n"
+"  return tableau(0) == 42\n"
+"}[/!]"
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:196
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:193
 msgid "On the caller side, that also very simple:"
 msgstr "Coté appelant, c'est aussi simple :"
 
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:198
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:194
 #, no-wrap
 msgid ""
-"int[] tab = new int[10];\n"
-"// initalize the values\n"
-"myMethod(tab);\n"
+"[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]\n"
+"[!java|scala]<span class=\"comment\">// Values initialization omitted</span>\n"
+"[/!]if (has42First(tab))[!java|scala] {[/!][!python]:[/!]\n"
+"   <span class=\"comment\">[!java|scala]//[/!][!python]#[/!] do something</span>\n"
+"[!java|scala]}[/!]"
 msgstr ""
-"int[] tab = new int[10];\n"
-"// initialiser les valeurs\n"
-"maMethode(tab);\n"
+"[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]\n"
+"[!java|scala]<span class=\"comment\">// Initialisation des valeurs omise</span>\n"
+"[/!]if (a42Premier(tab))[!java|scala] {[/!][!python]:[/!]\n"
+"   <span class=\"comment\">[!java|scala]//[/!][!python]#[/!] faire des choses</span>\n"
+"[!java|scala]}[/!]"
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:203
-msgid "We can also have methods returns arrays as results:"
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:201
+msgid ""
+"If you want to allocate and initialize the array in one shoot, that's a bit "
+"more complicated as the compiler has to know the type of the parameter you "
+"are creating.  For that, use the following (ugly) construct:"
 msgstr ""
-"On peut également avoir des méthodes renvoyant des tableaux en résultat :"
+"Si vous voulez allouer et initialiser le tableau au vol lors du passage de "
+"paramètre, c'est un peu plus compliqué car il faut dire au compilateur le "
+"type du paramètre que vous construisez. Il faut alors utiliser la "
+"construction suivante, même si elle n'est pas très belle."
 
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:204
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:204
 #, no-wrap
 msgid ""
-"int[] otherMethod() {\n"
-"  int[] result = new int[10];\n"
-"  // do something\n"
-"  return result;\n"
+"if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {\n"
+"   <span class=\"comment\">// do something</span>\n"
 "}"
 msgstr ""
-"int[] autreMethode() {\n"
-"  int[] resultat = new int[10];\n"
-"  // faire quelque chose\n"
-"  return resultat;\n"
+"if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {\n"
+"   <span class=\"comment\">// faire des choses</span>\n"
 "}"
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:211
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:209
 msgid ""
-"Your code should save the color pattern observed on the first row into a "
-"list.  The easiest is to create an empty list, and then <code>append()</"
-"code> the colors one after the others."
+"Methods can also return [!java|scala]arrays[/!][!python]lists[/!] as result "
+"without any complication.  Here is a method that returns [!java|scala]an "
+"array[/!][!python]a list[/!] of the requested size, filled with 42s."
 msgstr ""
-"Votre code devrait sauvegarder dans une liste le motif de couleurs observées "
-"sur la première colonne. Le plus simple est de faire une liste vide, puis "
-"d'ajouter les couleurs les unes après les autres avec <code>append()</code>."
+"Les méthodes peuvent également retourner des [!java|scala]tableaux[/!][!"
+"python]listes[/!] comme résultat sans aucun problème.\n"
+"Voici une méthode retournant [!java|scala]un tableau[/!][!python]une "
+"liste[/!] de la taille demandée après avoir initialisé toutes les cases à la "
+"valeur 42."
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:215
-msgid ""
-"The <code>run()</code> method that you should write must declare an array of "
-"colors (<code>Color[]</code>) and allocate it. Beware, the first world is "
-"6x6, but this is not the case of the others. Use the <code>getWorldHeight()</"
-"code> method to retrieve the amount of lines in the current world."
-msgstr ""
-"La méthode <code>run()</code> que vous devez écrire doit commencer par "
-"déclarer un tableau de couleurs (<code>Color[]</code>) et l'allouer. "
-"Attention, le premier monde est de taille 6x6, mais ce n'est pas le cas des "
-"autres. Utilisez donc la méthode <code>getWorldHeight()</code> pour "
-"retrouver le nombre de lignes du monde actuel."
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:212
+#, no-wrap
+msgid ""
+"[!java]int[] fill42(int size) {\n"
+"    int[] res = new int[size];\n"
+"    for (int i=0; i<size; i++) \n"
+"        res[i] = 42;\n"
+"    return res;\n"
+"}[/!][!scala]def fill42(size:Int):Array[Int] = {\n"
+"    var res = new Array[int] (size)\n"
+"    for (i <- 0 to size -1) {\n"
+"        res(i) = 42;\n"
+"    }\n"
+"    return res;\n"
+"}[/!][!python]def fill42(size):\n"
+"    res = []\n"
+"    for i in range(size):\n"
+"        res.append(42)\n"
+"    return res[/!]"
+msgstr ""
+"[!java]int[] remplir42(int taille) {\n"
+"    int[] res = new int[taille];\n"
+"    for (int i=0; i<taille; i++) \n"
+"        res[i] = 42;\n"
+"    return res;\n"
+"}[/!][!scala]def remplir42(taille:Int):Array[Int] = {\n"
+"    var res = new Array[int] (taille)\n"
+"    for (i <- 0 to taille -1) {\n"
+"        res(i) = 42;\n"
+"    }\n"
+"    return res;\n"
+"}[/!][!python]def remplir42(taille):\n"
+"    res = []\n"
+"    for i in range(taille):\n"
+"        res.append(42)\n"
+"    return res[/!]"
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:221
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:231
 msgid ""
-"Once the array allocated, we have to fill it. For each cel of the row, read "
-"the ground color (with <code>getGroundColor()</code>), and store it in the "
-"right cell of the array."
+"At least! After this long explanation, we can come back to the exercise."
 msgstr ""
-"Une fois le tableau alloué, il faut le remplir. Pour chaque case de la "
-"colonne, lisez la couleur du sol (avec <code>getGroundColor()</code>), et "
-"stockez le résultat de cette méthode dans la bonne case du tableau."
+"Enfin ! Après toutes ces explications, nous pouvons revenir à l'exercice."
 
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:225
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:232
+msgid ""
+"Your mission is rather simple actually.  Your code should save the color "
+"pattern observed on the first row into [!java|scala]an array[/!][!python]a "
+"list[/!].  [!python]The easiest is to create an empty list, and then "
+"<code>append()</code> the colors one after the others as you read them (with "
+"<code>getGroundColor()</code>).[/!] [!java|scala]For that, you should "
+"declare and allocate an array of <code>Color</code>. Beware, there is "
+"several worlds, of differing size; use <code>getWorldHeight()</code> to "
+"retrieve the size of the current world.  Once the array allocated, fill it "
+"by reading the ground color in each locations (with <code>getGroundColor()</"
+"code>).[/!]"
+msgstr ""
+"Votre mission est plutôt simple au fond. Votre code doit sauvegarder le "
+"motif de couleurs observé sur la première colonne. Il faut bien entendu "
+"sauvegarder ces valeurs dans [!java|scala]un tableau[/!][!python]une "
+"liste[/!].  \n"
+"[!python]Le plus simple pour cela est de créer une liste vide puis d'y "
+"adjoindre (avec <code>append()</code> les différentes couleurs lues sur le "
+"sol de la première colonne (avec <code>getCouleurSol()</code>).[/!] \n"
+"[!java|scala]Pour cela, il faut déclarer et créer un tableau de <code>Color</"
+"code>s. Attention, les différents mondes ne sont pas tous de la même taille "
+"et il faut utiliser <code>getMondeHauteur()</code> pour trouver la taille du "
+"monde courant. Une fois créé, remplissez le tableau en lisant les couleurs "
+"au sol de la première colonne (avec <code>getCouleurSol()</code>).[/!]"
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:240
 msgid ""
 "Once you managed to read and save the pattern on the first row, you have to "
 "reapply the pattern on every rows, for example by executing "
@@ -12428,14 +12291,14 @@ msgid ""
 msgstr ""
 "Une fois le motif de la première colonne lu et sauvegardé, il faut le "
 "répliquer sur toutes les colonnes, par exemple en exécutant "
-"<code>getWorldWidth()</code> fois une méthode écrite tout exprès."
+"<code>getMondeLargeur()</code> fois une méthode écrite tout exprès."
 
 #. type: Content of: <h1>
 #: src/lessons/welcome/array/basics/Array2.html:1
-msgid "Knotting, sequences and modulo"
-msgstr "Tricots, séquences et modulos"
+msgid "[!java|scala]Arrays[/!][!python]Lists[/!], Knotting and Modulos"
+msgstr "[!java|scala]Tableaux[/!][!python]Listes[/!], tricot et modulo"
 
-#. type: Content of: outside any tag (error?)
+#. type: Content of: <p>
 #: src/lessons/welcome/array/basics/Array2.html:3
 msgid ""
 "This exercise is similar to the previous one: you have to reproduce the "
@@ -12470,42 +12333,29 @@ msgstr ""
 "n'est pas fixe, mais écrit sur la première case de chaque colonne. Pour "
 "obtenir l'information sous forme d'un entier, on peut utiliser:"
 
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/array/basics/Array2.html:15
+#. type: Content of: <pre>
+#: src/lessons/welcome/array/basics/Array2.html:16
 #, no-wrap
-msgid "int offset = Integer.parseInt(readMessage())"
-msgstr "int offset = Integer.parseInt(readMessage())"
+msgid "[!java]int offset = Integer.parseInt(readMessage())[/!][!python]offset = int( readMessage() )[/!][!scala]val offset = readMessage().toInt[/!]"
+msgstr "[!java]int decalage = Integer.parseInt(readMessage())[/!][!python]decalage = int( readMessage() )[/!][!scala]val decalage = readMessage().toInt[/!]"
 
 #. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array2.html:17
+#: src/lessons/welcome/array/basics/Array2.html:18
 msgid ""
-"<code>readMessage()</code> gets the message on the ground as a String, while "
-"<code>Integer.parseInt()</code> transforms a String into an integer by "
-"<i>reading</i> it."
+"<code>readMessage()</code> gets the message on the ground as a [!java|"
+"scala]String[/!][!python]string[/!], while <code>[!java]Integer.parseInt(str)"
+"[/!][!scala]str.toInt[/!][!python]int(str)[/!]</code> transforms the string "
+"<code>str</code> into an integer by <i>reading</i> it."
 msgstr ""
-"<code>readMessage()</code> lit l'indication au sol sous forme d'une chaine "
-"de caractères, tandis que <code>Integer.parseInt()</code> transforme une "
-"chaine de caractères en entiers en la <i>lisant</i>."
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/array/basics/Array2.html:21
-#, no-wrap
-msgid "offset = int( readMessage() )"
-msgstr "offset = int( readMessage() )"
+"<code>readMessage()</code> lit l'indication au sol sous forme d'une chaîne "
+"de caractères, \n"
+"tandis que <code>[!java]Integer.parseInt(ch)[/!][!scala]ch.toInt[/!][!"
+"python]int(ch)[/!]</code> \n"
+"transforme la chaîne <code>ch</code> en un entier en la <i>lisant</i>."
 
 #. type: Content of: <p>
 #: src/lessons/welcome/array/basics/Array2.html:22
 msgid ""
-"<code>readMessage()</code> gets the message on the ground as a String, while "
-"<code>int()</code> transforms it into an integer value by <i>reading</i> it."
-msgstr ""
-"<code>readMessage()</code> lit l'indication au sol sous forme d'une chaine "
-"de caractères, tandis que <code>int()</code> transforme le résultat en "
-"entier en <i>lisant</i> la chaîne de caractères."
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/array/basics/Array2.html:25
-msgid ""
 "Then, to pick the right color, the easier is to use the <code>%</code> "
 "(modulo) operator. For example, <code>(i + 5) % size</code> allows to "
 "retrieve the <code>i</code>th cell of an array of size <code>size</code> "
@@ -12517,6 +12367,11 @@ msgstr ""
 "taille <code>taille</code> quand on applique un décalage de <code>5</code> "
 "cases."
 
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:27
+msgid "You're up."
+msgstr "À vous de jouer."
+
 #. type: Content of: <h1>
 #: src/lessons/welcome/array/indexof/value/IndexOfValue.html:1
 msgid "Searching for a given value"
@@ -12880,17 +12735,11 @@ msgstr "Cet univers est très simple, avec seulement cinq fonctions fournies."
 #. type: Content of: <pre>
 #: src/lessons/sort/pancake/universe/PancakeWorld.html:5
 #, no-wrap
-msgid "int getStackSize()"
-msgstr "int getStackSize()"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:6
-#, no-wrap
-msgid "getStackSize()"
-msgstr "getStackSize()"
+msgid "[!java]int [/!]getStackSize()  [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getTaillePile()  [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:7
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:6
 msgid ""
 "Returns the size of the stack, that is the amount of pancakes it contains."
 msgstr ""
@@ -12898,19 +12747,13 @@ msgstr ""
 "compose."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:9
-#, no-wrap
-msgid "int getPancakeRadius(int rank)"
-msgstr "int getPancakeRadius(int rang)"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:10
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:8
 #, no-wrap
-msgid "getPancakeRadius(rank)"
-msgstr "getPancakeRadius(rang)"
+msgid "[!java]int [/!]getPancakeRadius([!java]int [/!]rank[!scala]:Int[/!])  [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getRayonCrepe([!java]int [/!]rang[!scala]:Int[/!])  [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:11
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:9
 msgid ""
 "Returns the radius of the pancake passed as argument, with the rank of the "
 "top-most pancake being 0."
@@ -12919,19 +12762,13 @@ msgstr ""
 "crêpe du haut est 0."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:13
-#, no-wrap
-msgid "boolean isPancakeUpsideDown(int rank)"
-msgstr "boolean isPancakeUpsideDown(int rang)"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:14
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:11
 #, no-wrap
-msgid "isPancakeUpsideDown(rank)"
-msgstr "isPancakeUpsideDown(rang)"
+msgid "[!java]boolean [/!]isPancakeUpsideDown([!java]int [/!]rank[!scala]:Int[/!])   [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estCrepeRetournee([!java]int [/!]rang[!scala]:Int[/!])   [!scala]:Boolean[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:15
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:12
 msgid ""
 "Returns whether the pancake passed as argument upside-down, that is, if its "
 "burned side is on top. As usual, the top-most pancake is of rank 0."
@@ -12940,19 +12777,13 @@ msgstr ""
 "est à l'envers, c'est-à-dire si sa face brulée est en haut."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:17
-#, no-wrap
-msgid "void flip(int amount)"
-msgstr "void flip(int quantité)"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:18
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:14
 #, no-wrap
-msgid "flip(amount)"
-msgstr "flip(quantité)"
+msgid "[!java]void [/!]flip([!java]int [/!]amount[!scala]:Int[/!])"
+msgstr "[!java]void [/!]retourne([!java]int [/!]quantité[!scala]:Int[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:19
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:15
 msgid ""
 "Flips the <code>amount</code> first pancakes composing the stack, from the "
 "top of it."
@@ -12961,24 +12792,22 @@ msgstr ""
 "du sommet de celle-ci."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:21
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:34
-#, no-wrap
-msgid "boolean isSorted()"
-msgstr "boolean isSorted()"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:22
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:35
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:17
 #, no-wrap
-msgid "isSorted()"
-msgstr "isSorted()"
+msgid "[!java]boolean [/!]isSorted()   [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estTrie()   [!scala]:Boolean[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:23
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:18
 msgid "Returns whether the pancake stack is correctly sorted."
 msgstr "Renvoie si la pile de crêpes est correctement triée."
 
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:20
+#, no-wrap
+msgid "[!java]boolean [/!]isSelected()   [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]"
+
 #. type: Content of: <h1>
 #: src/lessons/sort/pancake/Main.html:1
 #: src/lessons/sort/pancake/BasicPancake.html:1
@@ -13057,13 +12886,13 @@ msgid ""
 "This activity is also integrated to CSIRL (my repository of <i>free</i> "
 "unplugged activities to introduce computer science, available at http://www."
 "loria.fr/~quinson/Mediation/SMN/), and it may be interesting to run the "
-"unplugged activities before implementing these algorithms in JLM."
+"unplugged activities before implementing these algorithms in PLM."
 msgstr ""
 "Cette activité est également intégrée à SMN (mon dépot d'activités "
 "débranchées <i>libres</i> pour introduire la science informatique, "
 "disponible à l'adresse http://www.loria.fr/~quinson/Mediation/SMN/), et il "
 "peut être intéressant de faire les activités débranchées avant d'implémenter "
-"ces algorithmes dans JLM."
+"ces algorithmes dans PLM."
 
 #. type: Content of: <ul><li>
 #: src/lessons/sort/pancake/Main.html:33
@@ -13473,13 +13302,13 @@ msgid ""
 "Unplugged\" activities repository.  It was however heavily since then, first "
 "for the CSIRL (my repository of <i>free</i> unplugged activities to "
 "introduce computer science, available at http://www.loria.fr/~quinson/"
-"Mediation/SMN/) and now for JLM."
+"Mediation/SMN/) and now for PLM."
 msgstr ""
 "Cette activité est inspirée du jeu de l'orange dans le recueil d'activités "
 "«Computer Science Unplugged». Elle a cependant été profondément réarrangée "
 "depuis, d'abord pour SMN (mon recueil d'activités <i>libres</i> pour "
 "introduire la science informatique, disponible depuis http://www.loria.fr/"
-"~quinson/Mediation/SMN/), et maintenant pour JLM."
+"~quinson/Mediation/SMN/), et maintenant pour PLM."
 
 #. type: Content of: <p>
 #: src/lessons/sort/baseball/Main.html:7
@@ -13616,27 +13445,21 @@ msgstr ""
 #: src/lessons/sort/baseball/universe/BaseballWorld.html:8
 msgid ""
 "Once every players on the field are in their home base, the hole should be "
-"in the last base, that is of rank <code>getAmountOfBases()-1</code>."
+"in the last base, that is of rank <code>getBasesAmount()-1</code>."
 msgstr ""
 "Une fois que tous les joueurs du terrain sont chez eux, le trou se trouve "
-"dans la dernière base, celle de rang <code>getAmountOfBases()-1</code>."
+"dans la dernière base, celle de rang <code>getNombreBases()-1</code>."
 
 #. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:10
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:11
 msgid "Functions to retrieve the world's dimensions"
 msgstr "Fonctions pour découvrir les dimensions du monde"
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:12
-#, no-wrap
-msgid "int getBasesAmount()"
-msgstr "int getBasesAmount()"
-
-#. type: Content of: <pre>
 #: src/lessons/sort/baseball/universe/BaseballWorld.html:13
 #, no-wrap
-msgid "getBasesAmount()"
-msgstr "getBasesAmount()"
+msgid "[!java]int [/!]getBasesAmount() [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getNombreBases() [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
 #: src/lessons/sort/baseball/universe/BaseballWorld.html:14
@@ -13646,117 +13469,98 @@ msgstr "Retourne le nombre de bases dans le terrain."
 #. type: Content of: <pre>
 #: src/lessons/sort/baseball/universe/BaseballWorld.html:16
 #, no-wrap
-msgid "int getPositionsAmount()"
-msgstr "int getPositionsAmount()"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:17
-#, no-wrap
-msgid "getPositionsAmount()"
-msgstr "getPositionsAmount()"
+msgid "[!java]int [/!]getPositionsAmount() [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getNombrePositions() [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:18
-msgid "Returns the amount of player's positions per base on this field:"
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:17
+msgid "Returns the amount of player's positions per base on this field."
 msgstr "Retourne le nombre de positions disponibles par base."
 
 #. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:20
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:19
 msgid "Functions to retrieve the world's state"
 msgstr "Fonctions pour découvrir l'état du monde"
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:22
-#, no-wrap
-msgid "int getHoleBase()"
-msgstr "int getHoleBase()"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:23
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:21
 #, no-wrap
-msgid "getHoleBase()"
-msgstr "getHoleBase()"
+msgid "[!java]int [/!]getHoleBase() [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getTrouBase() [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:24
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:22
 msgid "Returns the base in which the hole is located."
 msgstr "Retourne l'index de la base où se trouve le trou."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:26
-#, no-wrap
-msgid " int getHolePosition()"
-msgstr " int getHolePosition()"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:27
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:24
 #, no-wrap
-msgid "getHolePosition()"
-msgstr "getHolePosition()"
+msgid "[!java]int [/!]getHolePosition() [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getTrouPosition() [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:28
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:25
 msgid "Returns the hole position within its base"
 msgstr "Retourne la position du trou dans sa base."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:30
-#, no-wrap
-msgid " int getPlayerColor(int base, int position)"
-msgstr " int getPlayerColor(int base, int position)"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:31
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:27
 #, no-wrap
-msgid "getPlayerColor(base, position)"
-msgstr "getPlayerColor(base, position)"
+msgid "[!java]int [/!]getPlayerColor([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]"
+msgstr "[!java]int [/!]getCouleurJoueur([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:32
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:28
 msgid "Returns the color of the player at a given location."
 msgstr "Retourne la couleur d'un joueur donné à partir de sa position."
 
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:30
+#, no-wrap
+msgid "[!java]boolean [/!]isSorted()  [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estTrie() [!scala]:Boolean[/!]"
+
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:36
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:31
 msgid "Returns whether all players of the field are at home."
 msgstr "Retourne si tous les joueurs présents sur le terrain sont chez eux."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:38
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:33
 #, no-wrap
-msgid "boolean isBaseSorted(int base)"
-msgstr "boolean isBaseSorted(int base)"
+msgid "[!java]boolean [/!]isBaseSorted([!java]int [/!]base)  [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estBaseTriee([!java]int [/!]base)  [!scala]:Boolean[/!]"
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:34
+msgid "Returns whether all players of a given base are at home."
+msgstr "Retourne si tous les joueurs d'une base donnée sont chez eux."
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:39
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:36
 #, no-wrap
-msgid "isBaseSorted(base)"
-msgstr "isBaseSorted(base)"
+msgid "[!java]boolean [/!]isSelected()  [!scala]:Boolean[/!]"
+msgstr "[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:40
-msgid "Returns whether all players of a given base are at home."
-msgstr "Retourne si tous les joueurs d'une base donnée sont chez eux."
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:37
+msgid "Returns whether the current world is selected in the interface."
+msgstr "Renvoi si le monde actuel est sélectionné dans l'interface graphique."
 
 #. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:42
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:38
 msgid "Functions to change the world"
 msgstr "Fonctions pour changer le monde"
 
 #. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:44
-#, no-wrap
-msgid "void move(int base, int position)"
-msgstr "void move(int base, int position)"
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:45
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:40
 #, no-wrap
-msgid "move(base, position)"
-msgstr "move(base, position)"
+msgid "[!java]void [/!]move([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])"
+msgstr "[!java]void [/!]deplace([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])"
 
 #. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:46
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:41
 msgid ""
 "Moves a given player into the hole. This throws an IllegalArgumentException "
 "if the specified player is not near the hole (at most one base away)."
@@ -13884,7 +13688,7 @@ msgstr ""
 "(modulo le nombre de bases). Ensuite, il faut calculer la distance que "
 "chacune des buggles de cette base doit encore parcourir (0 si elle est déjà "
 "chez elle). Une fois que vous avez sélectionné l'heureuse élue, utilisez la "
-"méthode <code>move</code> pour la faire bouger, avant de passer à "
+"méthode <code>deplace</code> pour la faire bouger, avant de passer à "
 "l'itération suivante."
 
 #. type: Content of: <p>
@@ -14216,7 +14020,7 @@ msgstr ""
 "sont très simples : «tant que ce n'est pas trier, déplacer le trou vers le "
 "bas puis vers le haut. À chaque pas, c'est le plus petit des deux joueurs de "
 "la base qui descend, et le plus grand des deux qui monte (en fonction du "
-"sens de déplacement).». Après un moment, <code>isSorted()</code> devient "
+"sens de déplacement).». Après un moment, <code>estTrie()</code> devient "
 "vrai, et votre algorithme s'arrête."
 
 #. type: Content of: <p>
@@ -14250,29 +14054,127 @@ msgstr ""
 "Il ne s'agit cependant pas d'une règle absolue, comme prouvé par "
 "l'algorithme simple et faux du premier exercice !"
 
-#~ msgid "Creating a new JLM world"
-#~ msgstr "Créer un nouveau monde JLM (\"World\")"
+#. type: Content of: <h3>
+#: src/lessons/turtleart/Main.html:1 src/lessons/turtleart/short_desc.html:1
+msgid "Turtle Art"
+msgstr "L'art de la tortue"
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:3
+msgid ""
+"Since its inception in the 60's, the LOGO turtle fascinates by its ability "
+"to draw nice figures on computer.  This lesson allows you to explore some of "
+"the classical figures, and draw your own."
+msgstr ""
+"Dès sa conception dans les années 60, la tortue LOGO s'est révélé être un "
+"outil fascinant pour dessiner sur ordinateur. Cette leçon vous permet "
+"d'explorer certaines des figures les plus classiques, et de dessiner les "
+"vôtres."
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:6
+msgid ""
+"The language's syntax is absolutely not presented, but if you know a bit of "
+"it or if someone tells you, you can take these exercises even if you are an "
+"absolute beginner in programming."
+msgstr ""
+"La syntaxe du langage n'est absolument pas présentée, mais si vous "
+"connaissez les bases (ou si quelqu'un peut répondre à vos questions), vous "
+"pouvez faire ces exercices même si vous êtes un débutant absolu en "
+"programmation."
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:9
+msgid ""
+"Please send us your best contributions so that they get added to this "
+"gallery to inspire the next ones."
+msgstr ""
+"Envoyez nous vos plus belles contributions pour que nous les ajoutions à "
+"cette galerie afin d'inspirer les futurs utilisateurs."
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:15
+msgid ""
+"When you don't want to follow the proposed exercises but draw your own "
+"stuff, the \"you failed\" message really gets annoying.  We should have a "
+"\"Creative mode\" in PLM, where the world is not checked against the "
+"answer.  Also, we should not clean the board automatically in this mode."
+msgstr ""
+"Lorsqu'on préfère faire son propre dessin plutôt que suivre l'exercice "
+"proposer, les messages «vous avez échoués» deviennent vite agaçant. Il "
+"faudrait un mode créatif dans PLM, où le monde ne serait plus comparé à la "
+"solution attendue, et où il ne serait pas remis à zéro automatiquement entre "
+"les exécutions."
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:18
+msgid ""
+"Other exercises should be added. A whole lot of exercises are available from "
+"http://neoparaiso.com/logo/#sect4."
+msgstr ""
+"D'autres exercices devraient être ajoutés. http://neoparaiso.com/logo/#sect4 "
+"constitue une source d'inspiration quasi inépuisable."
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:19
+msgid ""
+"Missing: the built-ins hide()/show(), that decide whether the turtle must be "
+"shown."
+msgstr ""
+"Il manque des primitives cache()/montre() pour décider si la tortue doit "
+"être affichée."
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:20
+msgid ""
+"Missing: the built-ins arc() and arcTo(), that draw an arc, either w/o "
+"moving or by moving to the end of the arc."
+msgstr ""
+"Il manque des primitives arc() et arcVers() pour dessiner un arc de cercle, "
+"en restant sur place ou en bougeant jusqu'à la fin de l'arc."
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/short_desc.html:2
+msgid ""
+"Draw beautiful figures with the Logo turtle, and learn programming while "
+"playing."
+msgstr ""
+"Dessinez de belles figures avec la tortue Logo, et apprenez la programmation "
+"en jouant."
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/short_desc.html:4
+msgid ""
+"You should know the basic syntax of the programming language you will "
+"choose, but no exhaustive programming practice is required to take this "
+"lesson."
+msgstr ""
+"Vous devez connaître la syntaxe de base du langage que vous allez choisir, "
+"mais aucune expérience n'est nécessaire pour entreprendre cette leçon."
+
+#~ msgid "Creating a new PLM world"
+#~ msgstr "Créer un nouveau monde PLM (\"World\")"
 
 #~ msgid ""
-#~ "Welcome to the JLM Meta-Lesson. Its goal is to teach you how to write new "
-#~ "universes in JLM. For that, we will reimplement the Hanoi world "
+#~ "Welcome to the PLM Meta-Lesson. Its goal is to teach you how to write new "
+#~ "universes in PLM. For that, we will reimplement the Hanoi world "
 #~ "(available in the recursion lesson) step-by-step. This lesson covers "
 #~ "quite advanced topics and suppose that you are fluent in Java and "
-#~ "confident with the use of the JLM framework already. If you are not used "
+#~ "confident with the use of the PLM framework already. If you are not used "
 #~ "to the framework already, you probably want to take another lesson "
 #~ "before, like the welcome one or (maybe more fun) the maze one."
 #~ msgstr ""
-#~ "Bienvenue dans la Meta-Leçon JLM. Son but est de vous apprendre comment "
-#~ "écrire de nouveaux univers dans la JLM. Pour ce faire, nous allons "
+#~ "Bienvenue dans la Meta-Leçon PLM. Son but est de vous apprendre comment "
+#~ "écrire de nouveaux univers dans la PLM. Pour ce faire, nous allons "
 #~ "réimplanter le monde des tours de Hanoï ( disponible dans la leçon "
 #~ "récursion ) pas à pas. Cette leçon couvre des sujets assez avancés et "
 #~ "supporse que vous êtes à l'aise en Java et que vous connaissez déjà bien "
-#~ "l'utilisation du framework de la JLM. Si vous n'êtes pas déjà habitué au "
+#~ "l'utilisation du framework de la PLM. Si vous n'êtes pas déjà habitué au "
 #~ "frameword, vous voudrez probablement suivre une autre leçon avant, comme "
 #~ "Welcome ou ( sans doute plus amusant ) Maze."
 
-#~ msgid "Every JLM universe is composed of 4 main components:"
-#~ msgstr "Chaque univers JLM est composé de quatre composants principaux"
+#~ msgid "Every PLM universe is composed of 4 main components:"
+#~ msgstr "Chaque univers PLM est composé de quatre composants principaux"
 
 #~ msgid "<b>The world</b>: it contains the state of the universe."
 #~ msgstr "<b>Le monde (\"world\")</b> : il contient l'état de l'univers."
@@ -14295,14 +14197,14 @@ msgstr ""
 
 #~ msgid ""
 #~ "<b>The entity interactive control panel</b>: this is the little panel "
-#~ "displayed under the world view in the JLM interface. It allows to "
+#~ "displayed under the world view in the PLM interface. It allows to "
 #~ "interactively control the selected entity. As you can see from the "
 #~ "existing universes, this is optional, and if you don't provide any, the "
 #~ "panel will remain blank, preventing the users from interactively "
 #~ "controlling the entities."
 #~ msgstr ""
 #~ "<b>Le panneau de contrôle interactif de l'entité</b> : c'est le petit "
-#~ "panneau affiché en dessous de la vue du monde dans l'interface de la JLM. "
+#~ "panneau affiché en dessous de la vue du monde dans l'interface de la PLM. "
 #~ "Il permet de contrôler interactivement l'entité sélectionnée. Comme vous "
 #~ "pouvez le voir avec les univers existants, c'est optionnel, et si vous "
 #~ "n'en fournissez pas, le panneau restera vide, empêchant l'utilisateur de "
@@ -14370,36 +14272,36 @@ msgstr ""
 #~ "cette meta-leçon."
 
 #~ msgid ""
-#~ "The very first element you want to write in a new JLM universe is a "
+#~ "The very first element you want to write in a new PLM universe is a "
 #~ "partial world implementation including the internal state. In subsequent "
 #~ "exercises, we will complete the World class to provide entities ways to "
 #~ "interact and modify their world, and we will also implement the other "
 #~ "elements of the universe."
 #~ msgstr ""
 #~ "Le premier élément que vous voulez écrire dans un nouvel univers de la "
-#~ "JLM est une implémentation partielle du monde incluant l'état interne. "
+#~ "PLM est une implémentation partielle du monde incluant l'état interne. "
 #~ "Dans des exercices ultérieurs, nous complèterons la classe World pour "
 #~ "fournir aux entités des moyens d'intéragir et de modifier leur monde, et "
 #~ "nous implémenterons aussi les autres éléments de l'univers."
 
 #~ msgid ""
 #~ "Before you jump in writing your World implementation, you should "
-#~ "understand the big JLM picture, and how worlds are used internally."
+#~ "understand the big PLM picture, and how worlds are used internally."
 #~ msgstr ""
 #~ "Avant que vous vous jetiez dans l'écriture de votre implémentation de "
-#~ "World, vous devez comprendre le schéma de la JLM, et comment les mondes "
+#~ "World, vous devez comprendre le schéma de la PLM, et comment les mondes "
 #~ "sont utilisés en interne."
 
-#~ msgid "JLM worlds big picture"
-#~ msgstr "Schéma des mondes de la JLM"
+#~ msgid "PLM worlds big picture"
+#~ msgstr "Schéma des mondes de la PLM"
 
 #~ msgid ""
-#~ "As you know, every JLM exercise can contain one or several worlds, each "
+#~ "As you know, every PLM exercise can contain one or several worlds, each "
 #~ "containing one or several entities. The code written by the student is "
 #~ "executed in the entities, which must interact with their world to change "
 #~ "it from its initial state to its goal state."
 #~ msgstr ""
-#~ "Comme vous le savez, chaque exercice de la JLM peut contenir un ou "
+#~ "Comme vous le savez, chaque exercice de la PLM peut contenir un ou "
 #~ "plusieurs mondes, chacun contenant une ou plusieures entitées. Le code "
 #~ "écrit par les étudiants est éxécutés dans les entitées, qui doivent "
 #~ "intéragir avec leur monde pour le faire passer de son état initial à "
@@ -14416,12 +14318,12 @@ msgstr ""
 
 #~ msgid ""
 #~ "Technically, in a given exercise, for every world accessible from the "
-#~ "relevant combobox, there is three World objects. They live in jlm.lesson."
+#~ "relevant combobox, there is three World objects. They live in plm.lesson."
 #~ "Exercise:"
 #~ msgstr ""
 #~ "Techniquement, dans un exercice donné, pour chaque monde accessible "
 #~ "depuis la liste déroulante, il y a trois objets World. Ils se trouvent "
-#~ "dans jlm.lesson.Exercise."
+#~ "dans plm.lesson.Exercise."
 
 #~ msgid ""
 #~ "protected World [] initialWorld; \n"
@@ -14472,11 +14374,11 @@ msgstr ""
 
 #~ msgid ""
 #~ "The internal use of Worlds hidden, but the important point is that every "
-#~ "World object has extend the jlm.universe.World class and define the "
+#~ "World object has extend the plm.universe.World class and define the "
 #~ "following methods and constructors:"
 #~ msgstr ""
 #~ "L'utilisation interne des mondes est cachée, mais le point important est "
-#~ "que chaque objet World hérite de la classe jlm.universe.World et définit "
+#~ "que chaque objet World hérite de la classe plm.universe.World et définit "
 #~ "les méthodes et constructeurs suivants :"
 
 #~ msgid ""
@@ -14566,16 +14468,16 @@ msgstr ""
 #~ msgstr "Permettre le rendu graphique des mondes"
 
 #~ msgid ""
-#~ "Some specific steps naturally must be taken so that JLM can graphically "
+#~ "Some specific steps naturally must be taken so that PLM can graphically "
 #~ "display your world. Usually, you must write a specific class extending "
-#~ "jlm.universe.WorldView, and provide some protected methods so that the "
+#~ "plm.universe.WorldView, and provide some protected methods so that the "
 #~ "View can retrieve the state to display. In this particular exercise, the "
 #~ "view is provided (you will write you own one in next exercise), so you "
 #~ "only have to implement the right accessor."
 #~ msgstr ""
 #~ "Certaines étapes spécifiques doivent naturellement être prise afin que la "
-#~ "JLM puisse afficher graphique votre monde. Usuellement, vous devez écrire "
-#~ "une classe spécifique héritant de jlm.universe.WorldView, et fournissant "
+#~ "PLM puisse afficher graphique votre monde. Usuellement, vous devez écrire "
+#~ "une classe spécifique héritant de plm.universe.WorldView, et fournissant "
 #~ "des méthodes \"protected\", afin que la vue puisse récupérer l'état à "
 #~ "afficher. Dans cet exercice particulier, la vue vous est fournie ( vous "
 #~ "en écrirez une dans le prochain exercice ), donc vous n'avez qu'à "
@@ -14636,19 +14538,19 @@ msgstr ""
 #~ "l'accesseur de rendu graphique (<code>Integer[] values(Integer i)</code>)."
 
 #~ msgid ""
-#~ "That seems quite a lot of code to write compared to the other JLM "
+#~ "That seems quite a lot of code to write compared to the other PLM "
 #~ "exercises, but at the end, my HanoiWorld implementation is less than 100 "
 #~ "lines long, which is not that much."
 #~ msgstr ""
 #~ "Cela semble être beaucoup de code à écrire comparé aux autres exercices "
-#~ "de la JLM, mais en fin de compte, mon implémentation de HanoiWorld fait "
+#~ "de la PLM, mais en fin de compte, mon implémentation de HanoiWorld fait "
 #~ "moints de cent lignes, ce qui n'est pas beaucoup."
 
 #~ msgid "Meta lesson"
 #~ msgstr "Meta leçon"
 
 #~ msgid ""
-#~ "The purpose of this lesson is to teach you how to write lessons for JLM."
+#~ "The purpose of this lesson is to teach you how to write lessons for PLM."
 #~ msgstr ""
 #~ "Le but de cette leçon est de vous apprendre comment écrire des leçons "
-#~ "pour la JLM."
+#~ "pour la PLM."
diff --git a/lib/l10n/jlm.pot b/lib/l10n/jlm.pot
deleted file mode 100644
index df0e1df..0000000
--- a/lib/l10n/jlm.pot
+++ /dev/null
@@ -1,10557 +0,0 @@
-# SOME DESCRIPTIVE TITLE
-# Copyright (C) YEAR Free Software Foundation, Inc.
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2013-08-04 11:27+0300\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#. type: Content of: <h2>
-#: lib/doc/MainWindow.html:1
-msgid "The JLM Main Window"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: lib/doc/MainWindow.html:3
-msgid ""
-"The JLM working environment should be self-explanatory, in particular with "
-"the tool tips appearing when your mouse is over the elements.  Here is a "
-"little explanation of the components in case you fail to understand "
-"something. The main window is made of 5 main components:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: lib/doc/MainWindow.html:10
-msgid ""
-"<b>The menu:</b> Placed on top of the window, it gives you access to some "
-"advanced commands such as exiting the program, and some other that we will "
-"detail later."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: lib/doc/MainWindow.html:14
-msgid ""
-"<b>The tool bar:</b> Placed just below the menu, it gives you access to the "
-"four main commands:"
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:19
-msgid ""
-"The <b>Start</b> button, which begins the compilation and execution of the "
-"code you may have typed in the editor. At the end of the execution, it "
-"verifies whether you reach the situation constituting the objective of the "
-"exercise or not. If yes, you gain access to the next exercise using the "
-"<b>Exercise</b> menu. If not, you need to rework your code."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:25
-msgid ""
-"The <b>Stop</b> button allows you to interupt the execution of your code, "
-"what may reveal useful if you encounter an <i>infinite loop</i>."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:28
-msgid ""
-"The <b>Reset</b> button can be used to reset the world into its initial "
-"state."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:31
-msgid ""
-"The <b>Demo</b> button shows you the execution of the expected "
-"solution. During its execution, you may want to swich the seen world to see "
-"the different expected solutions."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:34
-msgid ""
-"Please note that there is often several ways of achieving the awaited "
-"solution, and that the one presented during the demo is not more or less "
-"correct than the others. You are completely free to not follow strictly the "
-"process shown by the demo, as long as your final solution matches the "
-"exercise expectations."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:40
-msgid ""
-"The scrolling menu <b>Lessoon</b> allows you to choose the lesson you want "
-"to work on."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:43
-msgid ""
-"The scrolling menu <b>Exercise</b> allows you to switch to another exercise "
-"when you want. Some lessons require you to finish an exercise before "
-"starting the previous one."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: lib/doc/MainWindow.html:49
-msgid ""
-"<b>Mission and editor tabs:</b> this is were you read this very text. This "
-"area contains several tabs to which you can access by clicking on their name "
-"on the top left. The first tab (which is always named <b>Mission</b>)  "
-"contains a presentation of the current exercise. To solve an exercise, you "
-"need to write your code in the other tabs. For example, you can now clic on "
-"the <b>Source Code</b> tab to see the actual source. It is empty because "
-"there is no code to write for this introduction exercise."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: lib/doc/MainWindow.html:57
-msgid ""
-"<b>The console:</b> Placed under the tabs, this is where any messages of the "
-"application will appear. This area is initially empty and white."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: lib/doc/MainWindow.html:60
-msgid ""
-"<b>World view</b> Placed on the right of the tabs, it is constituted of five "
-"elements:"
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:65
-msgid ""
-"A scrolling menu allows to choose the world. Indeed, the program you write "
-"may be executed in several worlds to test it in differing conditions. This "
-"menu allows you to choose the world you want to see."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:69
-msgid ""
-"A slider placed underneath allows to choose the animation speed of the "
-"world. More precisely, it allows to choose the delay (in milliseconds) that "
-"the buggles must wait after each action to allow you to see what they are "
-"doing."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:74
-msgid ""
-"A tab <b>World</b> represents the view of the world currently selected (from "
-"the scrolling menu). This view is thus constitued of a grid forming the "
-"several cells of the world, as well as several <i>buggles</i> awaiting for "
-"your orders."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:79
-msgid ""
-"An <b>Objective</b> tab displaying the world as it must be by the end of the "
-"exercise."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li>
-#: lib/doc/MainWindow.html:83
-msgid ""
-"<b>The interactive controls</b>. Placed under the world view, these buttons "
-"allows you to interactively control the buggles. This way, you can try to "
-"<i>manually</i> bring your buggle to the scenario objective before writting "
-"the needed code in the editor."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:89
-msgid "A scrolling menu allows to select the buggle you want to control."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:91
-msgid "The <b>Forward</b> button let your buggle do one step forward."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:93
-msgid "The <b>Backward</b> button let it do one step backward."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:95
-msgid "The <b>Turn left</b> button ask your buggle to turn of 90° to its left."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:97
-msgid ""
-"The <b>Turn right</b> button asks the buggle to turn to the right (isn't "
-"this amazing?)."
-msgstr ""
-
-#. type: Content of: <ul><li><ul><li><ul><li>
-#: lib/doc/MainWindow.html:100
-msgid ""
-"The <b>Mark</b> button requests your buggle to leave a mark behind it when "
-"it goes."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/jlm/universe/sort/SortingWorld.html:1
-msgid "Sorting World"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/sort/SortingWorld.html:2
-msgid ""
-"This world provides tools to experiment with the sorting algorithms. It can "
-"be used in two different ways: the first one is naturally to write the "
-"required sorting algorithms. But it is also possible to simply use the demo "
-"mode of each exercise to observe the behavior of sorting algorithms. It "
-"helps understanding the differences between each of them."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/sort/SortingWorld.html:8
-msgid "Methods available to sorting algorithms"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
-msgid "<b>Method</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
-msgid "<b>Action</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:10
-msgid "<b>Cost</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:11
-msgid "int getValueCount()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:12
-msgid "getValueCount()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:13
-msgid "Returns the amount of values in the array"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:13 src/jlm/universe/sort/SortingWorld.html:38
-msgid "none"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:15
-msgid "boolean isSmaller(int i, int j)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:16
-msgid "isSmaller(i, j)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:17
-msgid ""
-"Returns true if the content of cell i is strictly smaller than the one of "
-"cell j"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:17
-msgid "two reads"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:18
-msgid "boolean isSmallerThan(int i, int val)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:19
-msgid "isSmallerThan(i, val)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:20
-msgid ""
-"Returns true if the content of cell i is strictly smaller than value "
-"<code>val</code>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:20 src/jlm/universe/sort/SortingWorld.html:31
-msgid "one read"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:22
-msgid "void swap(int i, int j)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:23
-msgid "swap(i, j)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:24
-msgid "Swaps the content of cell i and the one of cell j"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:24
-msgid "two reads, two writes"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:25
-msgid "void copy(int from, int to)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:26
-msgid "copy(from, to)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:27
-msgid "Copy the content of cell 'from' into the cell 'to'"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:27
-msgid "one read, one write"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:29
-msgid "int getValue(int idx)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:30
-msgid "getValue(idx)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:31
-msgid "Returns the value of cell idx"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:32
-msgid "void setValue(int idx, int val)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/sort/SortingWorld.html:33
-msgid "setValue(idx, val)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:34
-msgid "Sets cell 'idx' to the value 'val'"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/sort/SortingWorld.html:34
-msgid "one write"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/sort/SortingWorld.html:36 src/jlm/universe/turtles/TurtleWorld.html:72 src/jlm/universe/bugglequest/BuggleWorld.html:35 src/lessons/recursion/hanoi/universe/HanoiWorld.html:25 src/lessons/sort/pancake/universe/PancakeWorld.html:25
-#, no-wrap
-msgid "boolean isSelected()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/sort/SortingWorld.html:37 src/jlm/universe/turtles/TurtleWorld.html:73 src/jlm/universe/bugglequest/BuggleWorld.html:35 src/lessons/recursion/hanoi/universe/HanoiWorld.html:26 src/lessons/sort/pancake/universe/PancakeWorld.html:26
-#, no-wrap
-msgid "isSelected()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/sort/SortingWorld.html:38 src/lessons/recursion/hanoi/universe/HanoiWorld.html:27 src/lessons/sort/pancake/universe/PancakeWorld.html:27
-msgid "Returns whether the current world is selected in the graphical interface."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/sort/SortingWorld.html:42
-msgid "History view"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:43 src/lessons/sort/bubble/AlgBubbleSort1.html:7
-msgid ""
-"It is not enough to sort the array to pass the exercises. Your solution must "
-"strictly follow the expected behavior of each exercise. This is enforced by "
-"checking that your algorithm needs the same amount of read and write "
-"operations to sort the array. When they don't match, understanding the "
-"difference between your code and the expected solution can reveal very "
-"difficult."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:50
-msgid ""
-"To help in this process, it is possible to graphically explore the history "
-"of your sorting algorithm. Switch to the Objective view and use the "
-"contextual menu (right click) to switch from the the view of the current "
-"state to the view of its history."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:55 src/lessons/sort/bubble/AlgBubbleSort1.html:19
-msgid ""
-"The history view is a bit hairly at the first glance, but actually rather "
-"simple: The time flows from left to right on this graph, and each row is a "
-"cell of your array. The curved lines that go navigate between rows represent "
-"a given data value. When two lines cross, this means that two values were "
-"swapped at this time stamp; A line fork represent a value copy; When a value "
-"is magenta and followed by an interrogation mark (?), it was read using "
-"getValue(); If the value is red and followed with an exclamation point (!), "
-"it was written using setValue()."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/sort/SortingWorld.html:64
-msgid ""
-"This view, inspired from Aldo Cortesi, reveals very helpful understand the "
-"inner behavior of sorting algorithms."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/jlm/universe/turtles/TurtleWorld.html:1
-msgid "TurtleWorld"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/turtles/TurtleWorld.html:3
-msgid "This universe is an adaptation of LOGO for the Java Learning Machine."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/turtles/TurtleWorld.html:5
-msgid ""
-"It is directly inspired from the work of the mathematician Seymour Papert in "
-"the 60's. Inspired from the swiss psycholog Jean Piaget, he came up with a "
-"learning method called LOGO to teach programming to young childs. The world "
-"is full of turtles which leave a painting where they go and which respond to "
-"simple orders."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:11
-msgid "Functions to move the turtle"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:13
-#, no-wrap
-msgid ""
-"void forward(double steps)\n"
-"void backward(double steps)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:15
-#, no-wrap
-msgid ""
-"forward(steps)\n"
-"backward(steps)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:17
-msgid "Moves forward or backward of the requested amount of steps."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:19
-#, no-wrap
-msgid ""
-"void turnRight(double angle)\n"
-"void turnLeft(double angle)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:21
-#, no-wrap
-msgid ""
-"turnRight(angle)\n"
-"turnLeft(angle)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:23
-msgid "Turns left or right of the given angle (in degrees)."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:25
-#, no-wrap
-msgid ""
-"double getX()\n"
-"double getY()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:27
-#, no-wrap
-msgid ""
-"getX()\n"
-"getY()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:29
-msgid "Returns the current position of the turtle."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:31
-#, no-wrap
-msgid ""
-"void setX(double x)\n"
-"void setY(double y)\n"
-"void setPos(double x, double y)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:34
-#, no-wrap
-msgid ""
-"setX(x)\n"
-"setY(y)\n"
-"setPos(x,y)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:37
-msgid "Teleports the turtle to a new position."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:39
-#, no-wrap
-msgid "double getHeading()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:40
-#, no-wrap
-msgid "getHeading()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:41
-msgid "Returns the current heading of the turtle (in degrees)."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:43
-#, no-wrap
-msgid "void getHeading(double angle)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:44
-#, no-wrap
-msgid "getHeading(angle)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:45
-msgid "Sets a new heading to the turtle (in degrees)."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:47
-msgid "Functions about the pen"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:49
-#, no-wrap
-msgid "void penUp()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:50
-#, no-wrap
-msgid "penUp()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:51
-msgid ""
-"Moves the pen up (turtles have pens, not brushes as buggles). The turtle "
-"will not leave any trace during its subsequent moves."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:54
-#, no-wrap
-msgid "void penDown()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:55
-#, no-wrap
-msgid "penDown()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:56
-msgid ""
-"Moves the pen down. The turtle will leave a trace during its subsequent "
-"moves."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:58
-#, no-wrap
-msgid "boolean isPenDown()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:59
-#, no-wrap
-msgid "isPenDown()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:60
-msgid "Returns the current pen position as a boolean."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/turtles/TurtleWorld.html:62 src/jlm/universe/bugglequest/BuggleWorld.html:25 src/lessons/turmites/universe/TurmiteWorld.html:18
-#, no-wrap
-msgid "Color getColor()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/turtles/TurtleWorld.html:63 src/jlm/universe/bugglequest/BuggleWorld.html:25
-#, no-wrap
-msgid "getColor()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:64
-msgid "Returns the current pen color."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:66
-#, no-wrap
-msgid "void setColor(Color color)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/jlm/universe/turtles/TurtleWorld.html:67
-#, no-wrap
-msgid "getColor(color)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:68
-msgid "Changes the pen color."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/turtles/TurtleWorld.html:70
-msgid "Other functions"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/turtles/TurtleWorld.html:74
-msgid "Returns whether the current turtle is selected in the graphical interface."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:1 src/lessons/turmites/universe/TurmiteWorld.html:1
-msgid "BuggleWorld"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/bugglequest/BuggleWorld.html:2 src/lessons/turmites/universe/TurmiteWorld.html:2
-msgid ""
-"This world was invented by Lyn Turbak, at Wellesley College. It is full of "
-"Buggles, little animals understanding simple orders, and offers numerous "
-"possibilities of interaction with the world: taking or dropping objects, "
-"paint the ground, hit walls, etc."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:7 src/lessons/turmites/universe/TurmiteWorld.html:7
-msgid "Methods understood by buggles"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:9 src/lessons/turmites/universe/TurmiteWorld.html:9
-msgid "<b>Moving</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:9 src/lessons/turmites/universe/TurmiteWorld.html:9
-msgid "(See also the note on exceptions, below)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:10
-msgid "<b>Turn left"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:10
-msgid "Turn right"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:10
-msgid "Turn back"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:10
-msgid "Moving forward"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:10
-msgid "Moving back</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:11 src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnLeft()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:11
-msgid "turnLeft()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:12 src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnRight()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:12
-msgid "turnRight()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:13 src/lessons/turmites/universe/TurmiteWorld.html:11
-msgid "void turnBack()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:13
-msgid "turnBack()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:14
-msgid "void forward() or void forward(int steps)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:14
-msgid "forward() or forward(steps)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:15
-msgid "void backward() or void backward(int steps)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:15
-msgid "backward() or backward(steps)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16 src/lessons/turmites/universe/TurmiteWorld.html:13
-msgid "<b>Get X coordinate"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16 src/lessons/turmites/universe/TurmiteWorld.html:13
-msgid "Get Y coordinate"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16 src/lessons/turmites/universe/TurmiteWorld.html:13
-msgid "Set X coordinate"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16 src/lessons/turmites/universe/TurmiteWorld.html:13
-msgid "Set Y coordinate"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:16 src/lessons/turmites/universe/TurmiteWorld.html:13
-msgid "Set position</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:17 src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "int getX()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:17
-msgid "getX()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:18 src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "int getY()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:18
-msgid "getY()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:19
-msgid "void setX(int x)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:19
-msgid "setX(x)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:20
-msgid "void setY(int y)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:20
-msgid "setY(y)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:21
-msgid "void setPos(int x,int y)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:21
-msgid "setPos(x,y)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:23 src/lessons/turmites/universe/TurmiteWorld.html:16
-msgid "<b>Information on the buggle</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:24 src/lessons/turmites/universe/TurmiteWorld.html:17
-msgid "<b>Get the color"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:24 src/lessons/turmites/universe/TurmiteWorld.html:17
-msgid "Set the color</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:26
-msgid "void setColor(Color c)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:26
-msgid "setColor(color)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:27 src/lessons/turmites/universe/TurmiteWorld.html:19
-msgid "<b>Look for a wall forward"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:27 src/lessons/turmites/universe/TurmiteWorld.html:19
-msgid "Look for a wall backward</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:28 src/lessons/turmites/universe/TurmiteWorld.html:20
-msgid "boolean isFacingWall()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:28
-msgid "isFacingWall()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:29 src/lessons/turmites/universe/TurmiteWorld.html:20
-msgid "boolean isBackingWall()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:29
-msgid "isBackingWall()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30 src/lessons/turmites/universe/TurmiteWorld.html:21
-msgid "<b>Get heading"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30 src/lessons/turmites/universe/TurmiteWorld.html:21
-msgid "Set heading</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:30 src/lessons/turmites/universe/TurmiteWorld.html:21
-msgid "valid directions are:"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:31 src/lessons/turmites/universe/TurmiteWorld.html:22
-msgid "Direction getDirection()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:31
-msgid "getDirection()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:32
-msgid "void setDirection(Direction dir)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:32
-msgid "setDirection(direction)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:33 src/lessons/turmites/universe/TurmiteWorld.html:22
-msgid "Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:34
-msgid "Check whether the buggle is currently <b>selected in the interface</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:37 src/lessons/turmites/universe/TurmiteWorld.html:24
-msgid "<b>About the brush</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38 src/lessons/turmites/universe/TurmiteWorld.html:25
-msgid "<b>Brush down"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38 src/lessons/turmites/universe/TurmiteWorld.html:25
-msgid "Brush up"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:38 src/lessons/turmites/universe/TurmiteWorld.html:25
-msgid "Get brush position</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:39 src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "void brushUp()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:39
-msgid "brushUp()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:40 src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "void brushDown()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:40
-msgid "brushDown()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:41 src/lessons/turmites/universe/TurmiteWorld.html:26
-msgid "boolean isBrushDown()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:41
-msgid "isBrushDown()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:42 src/lessons/turmites/universe/TurmiteWorld.html:27
-msgid "<b>Change the brush color"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:42 src/lessons/turmites/universe/TurmiteWorld.html:27
-msgid "Get the color of the brush</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:43
-msgid "void setBrushColor(Color c)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:43
-msgid "setBrushColor(color)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:44 src/lessons/turmites/universe/TurmiteWorld.html:28
-msgid "Color getBrushColor()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:44
-msgid "getBrushColor()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:46 src/lessons/turmites/universe/TurmiteWorld.html:30
-msgid "<b>Interacting with the world</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:47 src/lessons/turmites/universe/TurmiteWorld.html:31
-msgid "<b>Get the color of the ground</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:48 src/lessons/turmites/universe/TurmiteWorld.html:31
-msgid "Color getGroundColor()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:48
-msgid "getGroundColor()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50 src/lessons/turmites/universe/TurmiteWorld.html:33
-msgid "<b>Look for a baggle on the ground"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50 src/lessons/turmites/universe/TurmiteWorld.html:33
-msgid "Look for a baggle in bag"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50 src/lessons/turmites/universe/TurmiteWorld.html:33
-msgid "Pickup a baggle"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:50 src/lessons/turmites/universe/TurmiteWorld.html:33
-msgid "Drop a baggle</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:51 src/lessons/turmites/universe/TurmiteWorld.html:34
-msgid "(see the note on exceptions)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:52 src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "boolean isOverBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:52
-msgid "isOverBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:53 src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "boolean isCarryingBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:53
-msgid "isCarryingBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:54 src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "void pickupBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:54
-msgid "pickupBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:55 src/lessons/turmites/universe/TurmiteWorld.html:35
-msgid "void dropBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:55
-msgid "dropBaggle()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57 src/lessons/turmites/universe/TurmiteWorld.html:37
-msgid "<b>Look for a message"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57 src/lessons/turmites/universe/TurmiteWorld.html:37
-msgid "Add a message"
-msgstr ""
-
-#. type: Content of: <table><tr><td><b>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57 src/lessons/turmites/universe/TurmiteWorld.html:37
-msgid "Read the message"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:57 src/lessons/turmites/universe/TurmiteWorld.html:37
-msgid "Erase the message</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:58 src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "boolean isOverMessage()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:58
-msgid "isOverMessage()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:59
-msgid "void writeMessage(String msg)"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:59
-msgid "writeMessage(msg)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:60 src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "String readMessage()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:60
-msgid "readMessage()"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:61 src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "void clearMessage()"
-msgstr ""
-
-#. type: Content of: <table><tr><td><div>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:61
-msgid "clearMessage()"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:64 src/lessons/turmites/universe/TurmiteWorld.html:41
-msgid "Note on exceptions"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/bugglequest/BuggleWorld.html:65 src/lessons/turmites/universe/TurmiteWorld.html:42
-msgid ""
-"Regular buggles throw a BuggleWallException exception if you ask them to "
-"traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you "
-"ask them to pickup a baggle from an empty cell, or a "
-"AlreadyHaveBaggleException exception if they already carry a baggle.  Trying "
-"to drop a baggle on a cell already containing one throws an "
-"AlreadyHaveBaggleException exception."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/bugglequest/BuggleWorld.html:71 src/lessons/turmites/universe/TurmiteWorld.html:48
-msgid ""
-"SimpleBuggles (ie, the one used in first exercises) display an error message "
-"on problem so that you don't need to know what an exception is."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/backtracking/Main.html:1
-msgid "Backtracking lesson"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:3
-msgid ""
-"This <b>experimental</b> lesson aims at teaching students about "
-"backtracking. It is not ready for consumtion yet, not even the first "
-"exercises. It will feature several exercices on the topic allowing to "
-"progressively build the relevant notions and mental representation in the "
-"students mind."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:9
-msgid ""
-"For now, it contains a Backtracking exercise which lacks a graphical "
-"representation to be usable. It is based on an entity KnapsackSolver which "
-"works on a KnapsackPartialSolution. This latter is not a World, but a "
-"passive world component. It is used by the solver to store the currently "
-"best solution and the working solution. This design should be rather generic "
-"and other backtracking problems, such as the ones used in my TOP teaching "
-"(pyramid, recipients) should be implmentable following this design. That is "
-"why Backtracking classes derive from generic ones: BacktrackingEntity and "
-"BacktrackingPartialSolution.  There is also a BacktrackingWorld, that "
-"specific universes should need to not override, and BacktrackingExercise, "
-"dealing with this specificity where the world does not only contain solving "
-"entities, but also two partial solutions (best know and current)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:23
-msgid ""
-"This exercise should be introduced by an interactive discovery activity such "
-"as the one used here: "
-"http://interstices.info/jcms/c_19213/le-probleme-du-sac-a-dos"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:27
-msgid ""
-"Although this exercise seems almost usable, there is a fundamental "
-"difficulty to solve in the visualization. It is envisionned that the call "
-"graph is used here, to help the students building their mental "
-"representation of recursion. The actual representation of the graph should "
-"be quite easy, thanks to the jung library. But I fail to see how to get the "
-"needed info so far. Adding sensors to the stepUI()  method is probably the "
-"best way to go, but I would need to inspect the complete call stack where "
-"Thread.currentThread().getStack() only give the static stack (method called, "
-"file location, etc). I think I need to inspect the parameters passed to each "
-"method call to rebuild the proper call tree."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:39
-msgid ""
-"The first thing that I tried to use was dtrace, but it seems non-portable "
-"and somehow linked to solaris so I didn't dig any further."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:43
-msgid ""
-"Then, I tried to use the debugging infrastructure (JPDA), but never managed "
-"to get it working. It seems to me that the original com.sun.jdi package is "
-"somehow deprecated since com.sun.jdi.BootStrap.virtualMachineManager() "
-"returns null while org.eclipse.jdi.Bootstrap.virtualMachineManager() does "
-"not. But when I'm using the eclipse version, it seem to take an endless "
-"amount of dependencies, which I'm not inclined to do. The root of my problem "
-"may be that I was using a jdi.jar comming from eclipse, but I didn' find any "
-"other. I just realised that the com.sun.jdi package is also implemented in "
-"/usr/lib/jvm/java-6-sun-1.6.0.26/lib/tools.jar on my disk. It seem to be "
-"functional, I should give it another spin."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:55
-msgid ""
-"Afterward, I tried to reuse the debugging infrastructure of DrJava. It looks "
-"like a good idea because they have several helper interfaces for debugging "
-"and compiling. Also, they have a good editor that we could reuse. Finally, "
-"they have a strong testing infrastructure with junit ensuring that their "
-"tool still work after modifications (that's something we are seriously "
-"missing in JLM). I'm really thinking that the two tools should converge to "
-"something stronger. The only argument for not doing so (beside the amount of "
-"work it'll take) is that each of us get the credit for each tool where "
-"things would be more fuzzy on a mixed tool. But I don't care, the mixed tool "
-"would be so much cooler that I'd like to find the time to ensure this "
-"convergence."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:67
-msgid ""
-"But the debugging feature of DrJava seems to suffer from an issue: "
-"http://sourceforge.net/tracker/index.php?func=detail&aid=3004294&group_id=44253&atid=438935 "
-"I was suspecting a permission error (something related to "
-"com.sun.jdi.JDIPermission), but even with a java.security.AllPermission as "
-"permission file, I still have the issue."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:73
-msgid ""
-"Another lead to get it working it to use lib ASM to modify the student code "
-"so that their recursive method gets traced. With the static backtrace and "
-"the tracing information, I guess I could rebuild the actual call tree. That "
-"seem to be possible: 2 sec of googling gave me something like "
-"http://rejeev.blogspot.com/2009/04/method-tracing.html"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/backtracking/Main.html:79
-msgid ""
-"So, here I am. The lesson would be very interesting to students, and quite "
-"easy to finish once I manage to get the information I need, but I didn't "
-"manage to do so so far, despite my efforts. If you have any hint (or "
-"patch!), please email martin.quinson#loria.fr."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/backtracking/Main.html:84
-msgid ""
-"This gives me the following todo actions: * Check whether tools.jar gives a "
-"working com.sun.jdi package * Find the DrJava bug around debugging to help "
-"them, and so that I can steal parts of their code about it for JLM (it's "
-"BSD'ed while JLM is mainly GPL'ed for now -- I'll have to ask them for an "
-"exception). That would be better since their helper interface seem to be "
-"able to deal with several debuggers (eclipse, sun or openjdk). That's quite "
-"a large amount of work I'd like to avoid duplicating.  * Check wheter I can "
-"get tracing info from ASM. It may be more robust to JVM variants than the "
-"debugging approach. On the other hand, debugging is a neat feature for JLM "
-"as is.  * Work on the convergence of JLM and DrJava. Beside of the licencing "
-"issue, it will also complicate the ongoing integration of JLM within Debian, "
-"since DrJava is composed of [[5 separated "
-"modules|http://drjava.org/docs/developer/ch02s03.html]] that can only be "
-"integrated as separated source packages. As every java package, no source "
-"archive is distributed, and they must be retrieved directly from the "
-"svn. Finally, they are quite huge, with sloccount reporting"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/chooser/LessonChooser.html:3 src/lessons/chooser/LessonChooser.html:3
-msgid "  "
-msgstr ""
-
-#. type: Content of: <table><tr><td><font>
-#: src/lessons/chooser/LessonChooser.html:3
-msgid "Welcome to the Java Learning Machine"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/chooser/LessonChooser.html:7
-msgid ""
-"The JLM is a Learning Management System (LMS) aiming at teaching the art of "
-"computer programming through interactive exercises. It offers an extensive "
-"set of varied exercises, allowing you to practice at your own pace."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/chooser/LessonChooser.html:11
-msgid "Pick a classical lesson"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:13
-msgid ""
-"<a href=\"jlm://lessons.welcome\">Welcome lesson</a> This lesson is intended "
-"to lead the first steps in programming of absolute beginners."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:16
-msgid ""
-"<a href=\"jlm://lessons.maze\">Escape the maze</a> Will you escape the "
-"mazes?"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:18
-msgid ""
-"<a href=\"jlm://lessons.bat.string1\">String lesson</a> A bunch of exercises "
-"on strings."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:20
-msgid ""
-"<a href=\"jlm://lessons.sort\">Sorting lesson</a> This short lesson proposes "
-"to discover the classical sorting algorithms by practice."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:23
-msgid ""
-"<a href=\"jlm://lessons.recursion\">Recursion lesson</a> Build some "
-"classical geometric figures through recursion."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:26
-msgid ""
-"<a href=\"jlm://lessons.lightbot\">LightBot</a> In this little game, you "
-"must program graphically a little robot to instruct it how to switch the "
-"lights off. It is a brain teaser for programmer."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/chooser/LessonChooser.html:30
-msgid ""
-"<a href=\"jlm://lessons.smn\">Digital Manual Science</a> Some activities "
-"developed for the Sciences Manuelles du Numérique (Digital Manual Science)"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/chooser/Main.html:1
-msgid "Lesson chooser"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/chooser/Main.html:3
-msgid ""
-"This isn't a real lesson, it's here that you can select a lesson among "
-"others."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/Main.html:1 src/lessons/welcome/short_desc.html:1
-msgid "First steps"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/Main.html:3
-msgid ""
-"This first lesson will lead your first steps in programming. It is intended "
-"for beginners. List of seen notions per exercise:"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:8 src/lessons/welcome/Main.html:91 src/lessons/welcome/Main.html:174 src/lessons/welcome/Main.html:254 src/lessons/welcome/Main.html:348 src/lessons/welcome/Main.html:428 src/lessons/welcome/Main.html:468
-msgid " "
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:9 src/lessons/welcome/Main.html:92 src/lessons/welcome/Main.html:175 src/lessons/welcome/Main.html:255 src/lessons/welcome/Main.html:349 src/lessons/welcome/Main.html:429 src/lessons/welcome/Main.html:469 src/lessons/welcome/basics/Basics.html:1
-msgid "Instructions"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:10 src/lessons/welcome/Main.html:93 src/lessons/welcome/Main.html:176 src/lessons/welcome/Main.html:256 src/lessons/welcome/Main.html:350 src/lessons/welcome/Main.html:430 src/lessons/welcome/Main.html:470
-msgid "Comments"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:11 src/lessons/welcome/Main.html:94 src/lessons/welcome/Main.html:177 src/lessons/welcome/Main.html:257 src/lessons/welcome/Main.html:351 src/lessons/welcome/Main.html:431 src/lessons/welcome/Main.html:471
-msgid "Conditionals/ Expressions"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:12 src/lessons/welcome/Main.html:78 src/lessons/welcome/Main.html:95 src/lessons/welcome/Main.html:178 src/lessons/welcome/Main.html:258 src/lessons/welcome/Main.html:352 src/lessons/welcome/Main.html:432 src/lessons/welcome/Main.html:472 src/lessons/welcome/loop/whileloop/LoopWhile.html:1
-msgid "While loops"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:13 src/lessons/welcome/Main.html:96 src/lessons/welcome/Main.html:179 src/lessons/welcome/Main.html:259 src/lessons/welcome/Main.html:353 src/lessons/welcome/Main.html:433 src/lessons/welcome/Main.html:473
-msgid "Variables"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:14 src/lessons/welcome/Main.html:97 src/lessons/welcome/Main.html:133 src/lessons/welcome/Main.html:180 src/lessons/welcome/Main.html:260 src/lessons/welcome/Main.html:354 src/lessons/welcome/Main.html:434 src/lessons/welcome/Main.html:474 src/lessons/welcome/loop/forloop/LoopFor.html:1
-msgid "For loops"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:15 src/lessons/welcome/Main.html:98 src/lessons/welcome/Main.html:181 src/lessons/welcome/Main.html:261 src/lessons/welcome/Main.html:355 src/lessons/welcome/Main.html:435 src/lessons/welcome/Main.html:475
-msgid "Do/While loops"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:16 src/lessons/welcome/Main.html:99 src/lessons/welcome/Main.html:161 src/lessons/welcome/Main.html:182 src/lessons/welcome/Main.html:262 src/lessons/welcome/Main.html:356 src/lessons/welcome/Main.html:436 src/lessons/welcome/Main.html:476 src/lessons/welcome/methods/basics/Methods.html:1
-msgid "Methods"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:17 src/lessons/welcome/Main.html:100 src/lessons/welcome/Main.html:183 src/lessons/welcome/Main.html:263 src/lessons/welcome/Main.html:357 src/lessons/welcome/Main.html:437 src/lessons/welcome/Main.html:477
-msgid "Switch"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:18 src/lessons/welcome/Main.html:101 src/lessons/welcome/Main.html:184 src/lessons/welcome/Main.html:264 src/lessons/welcome/Main.html:358 src/lessons/welcome/Main.html:438 src/lessons/welcome/Main.html:478 src/lessons/welcome/array/basics/Array.html:18
-msgid "Arrays"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:22 src/lessons/welcome/environment/Environment.html:1
-msgid "Welcome in the Buggles' World"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:36
-msgid "Java Instructions"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:50 src/lessons/welcome/basicsdrawg/BasicsDrawG.html:1
-msgid "Writing more complex programs"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:64 src/lessons/welcome/conditions/Conditions.html:1
-msgid "Conditional instructions"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:105 src/lessons/welcome/baggleseeker/BaggleSeeker.html:1
-msgid "Baggle Seeking"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:119 src/lessons/welcome/variables/Variables.html:1
-msgid "Storing and manipulating data"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:147 src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:1
-msgid "Do .. while loops"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:187 src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:1
-msgid "Building methodically"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:201 src/lessons/welcome/methods/returning/MethodsReturning.html:1
-msgid "Methods returning a result"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:214 src/lessons/welcome/methods/args/MethodsArgs.html:1
-msgid "Methods with parameters"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:228 src/lessons/welcome/methods/picture/MethodsPicture.html:1
-msgid "Methodically drawing"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:241 src/lessons/welcome/methods/picture2/MethodsPicture2.html:1
-msgid "Methodically drawing (only bigger)"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:267 src/lessons/welcome/methods/picture3/MethodsPicture3.html:1
-msgid "Drawing bigger and bigger"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:280 src/lessons/welcome/methods/picture4/MethodsPicture4.html:1
-msgid "Even more pattern to draw"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:294
-msgid "Buggle Dance Revolution"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:308
-msgid "Buggle Dance Revolution 2"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:322 src/lessons/welcome/slug/SlugHunting.html:1
-msgid "Slug Hunting"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:335 src/lessons/welcome/slug/SlugTracking.html:1
-msgid "Slug Tracking"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:361 src/lessons/welcome/snake/Snake.html:1
-msgid "Snake World"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:375
-msgid "Knitting and Arrays"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:389
-msgid "Knitting, Arrays and modulos"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:402 src/lessons/welcome/traversal/column/TraversalByColumn.html:1
-msgid "Traversal by column"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:415 src/lessons/welcome/traversal/line/TraversalByLine.html:1
-msgid "Traversal by line"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:441 src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:1
-msgid "Zig-zag traversal"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:454 src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:1
-msgid "Diagonal Traversal"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/Main.html:482
-msgid "Meaning of the symbols"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:485
-msgid "Introducing the concept"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:488
-msgid "Working on the concept"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:491
-msgid "Concept assumed mastered"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/Main.html:494
-msgid "Concept not mandated by the exercise"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/short_desc.html:2
-msgid ""
-"This first lesson will lead your first steps in programming. It is intended "
-"for beginners."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/short_desc.html:5
-msgid ""
-"If you are not sure, go for this lesson that will teach you the bases of "
-"programming."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/environment/Environment.html:3
-msgid ""
-"You just started the Java Learning Machine. This is a Learning Management "
-"System (LMS) aiming at teaching the art of computer programming through "
-"interactive exercises. It is constituted by a set of exercises grouped by "
-"lessons, allowing you to practice at your own pace. By default, the "
-"environment is configured to be programmed in the Java programming language, "
-"but you can change it from the Language menu if you want."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:9
-msgid "In this first lesson, the buggles will lead your first steps in programming."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/environment/Environment.html:11
-msgid "The <i>buggles</i>? What is this??"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:13
-msgid ""
-"The buggles are little animals obeying any order you may give them. In each "
-"exercise, you have to provide them with the right instructions so that the "
-"world turns into the objective of the exercise. For example in this "
-"exercise, you show instruct your buggle to move forward once. You can see "
-"that by checking the difference between the <i>World</i> view and the "
-"<i>Objective</i> one.  Depending on the lessons (and your settings in the "
-"Language menu), your code must be written in either Java, JavaScript, Python "
-"or Ruby (depending on the exercise)."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/environment/Environment.html:22
-msgid "Working environment"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:24
-msgid ""
-"Before going any further, get familiar with the working environment. Have a "
-"look at the several elements composing the main window, move your mouse over "
-"them to show the tooltip, and experiment with the elements to see what they "
-"do.  The white area below is the console: this is where errors and messages "
-"get displayed. If you have access to the net, try to open the forum in the "
-"help menu to check if other people are connected right now. Note that when "
-"you successfully solve an exercise, the good news is spread on twitter.  "
-"Keep posted to the progress of your friends by following @jlmlovers :)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/environment/Environment.html:33
-msgid ""
-"If your code contains errors (and code always do at some point), the "
-"computer will display error messages in the console. You obviously have to "
-"fix the errors to pass the exercises. The messages that get displayed may "
-"sound scary at first glance, but don't panic. The compiler is only somehow "
-"limited in its communication abilities, but he's not mean. If you look "
-"closer, the solution to solve your issue is written in the middle of those "
-"cryptic messages. You'll see, with a bit of habit, we get used to it."
-msgstr ""
-
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/environment/Environment.html:41
-msgid "What am I supposed to do?"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/environment/Environment.html:43
-msgid ""
-"It's time to write your first program. Simply ask your buggle to move one "
-"step forward using the Source Code pane. For that, simply write the "
-"following code (clicking on the interactive controls is not enough: You have "
-"to write the code after experimenting interactively)."
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/environment/Environment.html:47 src/lessons/welcome/basics/Basics.html:50
-#, no-wrap
-msgid "forward();"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/environment/Environment.html:48 src/lessons/welcome/basics/Basics.html:50
-#, no-wrap
-msgid "forward()"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/environment/Environment.html:49
-msgid ""
-"Do not forget the final <code>;</code> which tells the compiler that the "
-"instruction is over (yes, computers are so dumb that they cannot "
-"<i>guess</i> obvious stuff like this)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/environment/Environment.html:53
-msgid ""
-"Once done, clic on run, and proceed to next exercise using the File menu "
-"entry"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/environment/Environment.html:55
-msgid "(or keep around to experiment further if you feel so)."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/basics/Basics.html:3
-msgid ""
-"Congratulations! You just wrote your first program! You got the idea now: "
-"programming is nothing more than giving simple instructions to the computer "
-"that blindly apply them. The main difficulty is to explain stuff to someone "
-"as stupid as a computer..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basics/Basics.html:8
-msgid ""
-"Programs are mainly suites of method calls, which are no more than a list of "
-"simple order given to the machine. It is very similar to a recipe stating "
-"<i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>.  In "
-"your programs, such built instructions are called functions or methods, and "
-"you should add parenthesis to invoke them, as in"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:13
-#, no-wrap
-msgid "nameOfTheMethod()"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:16
-msgid ""
-"Java want to have the instructions separated by semi-columns (;).  The "
-"previous example would thus be written in a similar way:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:19
-#, no-wrap
-msgid ""
-"meltTheChocolatePieces();\n"
-"addSugar();\n"
-"coolMix();\n"
-"serve();\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:25
-msgid ""
-"Python want to have the instructions separated by either semi-columns (;) or "
-"by new lines. The previous example would thus be written the following way."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:29
-#, no-wrap
-msgid ""
-"meltTheChocolatePieces()\n"
-"addSugar()\n"
-"coolMix()\n"
-"serve()\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:35
-msgid ""
-"It could also be written in the following way, but it's generally considered "
-"as a bad practice to group several instructions on the same line since it "
-"greatly hinders the readability."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/basics/Basics.html:39
-#, no-wrap
-msgid "meltTheChocolatePieces(); addSugar(); coolMix(); serve()\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:42
-msgid ""
-"Of course, these specific methods do not exist in Java, but it may be "
-"possible to define them by yourself (we'll see later how to define your how "
-"methods)."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:44
-msgid ""
-"Of course, these specific methods do not exist in Python, but it may be "
-"possible to define them by yourself (we'll see later how to define your how "
-"methods)."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:46
-msgid ""
-"For now, we'll simply go for the buggle instructions. There is a method for "
-"each button of the interactive control panel. To achieve the same effect "
-"than the <b>forward</b> button (making the buggle moving one step forward), "
-"you need to write the following in the editor:"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:51
-msgid ""
-"Likewise, to achieve the same effect than the <b>backward</b>, <b>turn "
-"left</b> and <b>turn right</b> buttons, you need to use respectively:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:54
-#, no-wrap
-msgid ""
-"backward();\n"
-"turnLeft();\n"
-"turnRight();\n"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:59
-#, no-wrap
-msgid ""
-"backward()\n"
-"turnLeft()\n"
-"turnRight()\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/basics/Basics.html:63
-msgid ""
-"The <b>mark</b> button is a bit particular, since it correspond to two "
-"methods: the first one moves the pen up while the second moves it down."
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:66
-#, no-wrap
-msgid ""
-"brushUp();\n"
-"brushDown();\n"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/basics/Basics.html:70
-#, no-wrap
-msgid ""
-"brushUp()\n"
-"brushDown()\n"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/basics/Basics.html:73
-msgid ""
-"The buggle offers other methods, that are presented from the \"Help/about "
-"this world\" menu and will be introduced on need."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/basics/Basics.html:77 src/lessons/welcome/conditions/Conditions.html:147 src/lessons/welcome/baggleseeker/BaggleSeeker.html:8 src/lessons/welcome/variables/Variables.html:72 src/lessons/welcome/loop/forloop/LoopFor.html:73 src/lessons/welcome/loop/whileloop/LoopWhile.html:26 src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:26 src/lessons/welcome/methods/basics/Methods.html:59 src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:49 src/lessons/welcome/meth [...]
-msgid "Exercise goal"
-msgstr ""
-
-#. type: Content of: <p><p><a>
-#: src/lessons/welcome/basics/Basics.html:77
-msgid ""
-"<a name=\"Objectives\"> Our second program will be a bit more complicated, "
-"but not much. The goal for your buggle is simply to draw a house (a box), "
-"and hide inside. Check the objective world to see exactly what this means."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:2
-msgid ""
-"Now that we know how to draw things on the board, we'll enjoy this ability "
-"and draw a beautiful G on the board (check Objective panel for details on "
-"what's expected)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:6
-msgid ""
-"When you write a quite complex program, it is sometimes useful to <b>add "
-"comments</b> to simplify the code reviews afterward. Here for example, it's "
-"quite easy to get lost in the drawing process, and you may want to add "
-"comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to "
-"move back to initial position</i>. Commenting your code is almost mandatory "
-"if you (or someone else) want to read it afterward, although overcommenting "
-"(describing obvious stuff) is a bad idea as the important idea get lost in "
-"the noise."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:14
-msgid ""
-"There is three types of comments in Java, instructing the compiler to not "
-"read the text you add for humans:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:16
-msgid ""
-"There is two types of comments in Python, instructing the compiler to not "
-"read the text you add for humans:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:20
-msgid ""
-"<b>Comments on a single line</b>. When the compiler encounters the symbols "
-"//, it ignores the end of the line."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:22
-msgid ""
-"<b>Comments on several lines</b>. The compiler ignores anything placed "
-"between the symbols /* and */ even if they are placed on differing lines."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:27
-msgid ""
-"<b>Comments on a single line</b>. When the compiler encounters the symbol #, "
-"it ignores the end of the line."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:29
-msgid ""
-"<b>Comments on several lines</b>. The compiler ignores anything placed "
-"between a line beginning with ''' and the next line ending with '''."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:34
-#, no-wrap
-msgid ""
-"methodCallReadByTheCompiler(); <span class=\"comment\">// all this is "
-"ignored</span>\n"
-"otherCall(); <span class=\"comment\">/* This is</span>\n"
-"              "
-"<span class=\"comment\"> also ignored */</span>\n"
-"yetAnotherCall();\n"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:40
-#, no-wrap
-msgid ""
-"methodCallReadByTheCompiler() <span class=\"comment\"># all this is "
-"ignored</span>\n"
-"otherCall() \n"
-"<span class=\"comment\">''' This is</span>\n"
-"<span class=\"comment\">also ignored  '''</span>\n"
-"yetAnotherCall()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:47
-msgid ""
-"There is a third kind of comments in Java, between /** and */, which are "
-"read by a specific program called JavaDoc to generate automatically the "
-"documentation explaining how to use the code. These comments must follow a "
-"very precise formalism."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/basicsdrawg/BasicsDrawG.html:52
-msgid ""
-"The comments on several lines are often used to document how to use the "
-"code, while others are more used to describe how this code works."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/conditions/Conditions.html:3
-msgid ""
-"Programs made of simple suite of instructions similar to previous exercise "
-"are quite boring. They always do the same thing, and cannot react to "
-"external conditions. A <b>conditional</b> let the program adapt by doing "
-"something like <i>if it's raining, take an umbrella</i>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:8
-msgid "The Java syntax is the following:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:9
-msgid "The Python syntax is the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/conditions/Conditions.html:10
-#, no-wrap
-msgid ""
-"if (<b>condition</b>) {\n"
-"    <b>whatToDo();</b>\n"
-"}"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/conditions/Conditions.html:13
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:16
-msgid ""
-"If the condition is true, any code enclosed between the { and the "
-"corresponding } will be executed. If not, it will be ignored. Of course, it "
-"is possible to write more than one instruction between the curly brackets "
-"(even another test)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:20
-msgid ""
-"If the condition is true, any code in the block following the colon symbol "
-"will be executed. If not, it will be ignored. Of course, it is possible to "
-"write more than one instruction in the sub-block (even another test)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/conditions/Conditions.html:26
-msgid ""
-"Python uses indentation to define code blocks. The standard Python "
-"indentation is 4 spaces. Notice that code blocks do not need any "
-"termination. Indenting starts a block and unindenting ends it. In the "
-"following code the instructions <b>whatToDo()</b> and <b>whatToDoNext()</b> "
-"will be exectuded if the condition is true, then the instruction "
-"<b>whatToDoAnyway()</b> will be executed anyway."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:33
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>\n"
-"    <b>whatToDoNext()</b>\n"
-"<b>whatToDoAnyway()</b>\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:39
-msgid ""
-"Python functions have no explicit begin or end, and no curly braces to mark "
-"where the function code starts and stops. The only delimiter is a colon (:) "
-"and the indentation of the code itself."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:44
-msgid "Example 2.5. Indenting the buildConnectionString Function"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:48
-#, no-wrap
-msgid ""
-"def buildConnectionString(params):\n"
-"    \"\"\"Build a connection string from a dictionary of parameters.\n"
-"\n"
-"    Returns string.\"\"\"\n"
-"    return \";\".join([\"%s=%s\" % (k, v) for k, v in params.items()])\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:55
-msgid ""
-"Code blocks are defined by their indentation. By \"code block\", I mean "
-"functions, if statements, for loops, while loops, and so forth. Indenting "
-"starts a block and unindenting ends it. There are no explicit braces, "
-"brackets, or keywords. This means that whitespace is significant, and must "
-"be consistent. In this example, the function code (including the doc string) "
-"is indented four spaces.  It doesn't need to be four spaces, it just needs "
-"to be consistent. The first line that is not indented is outside the "
-"function."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:64
-msgid ""
-"It is important that the indentations of all the instructions of a block are "
-"consistent, and it is not possible to cut a block. The two following codes "
-"are incorrect and will raise errors."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:68
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>\n"
-"     <b>whatToDoNext()</b>\n"
-"<b>whatToDoAnyway()</b>\n"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:73
-#, no-wrap
-msgid ""
-"if <b>condition</b>:\n"
-"    <b>whatToDo()</b>\n"
-"<b>whatToDoAnyway()</b>\n"
-"    <b>whatToDoNext()</b>\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:79
-msgid ""
-"A condition can be a variable of type <tt>boolean</tt>. The code between "
-"curly braces will get executed if the variable is <tt>true</tt> and it will "
-"be ignored if it is <tt>false</tt>."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:83
-msgid ""
-"A condition can be a variable of type <tt>boolean</tt>. The code in the "
-"inner bloc will get executed if the variable is <tt>True</tt> and it will be "
-"ignored if it is <tt>False</tt>."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:88
-msgid ""
-"The condition can also be an arithmetic test, such as <tt>x</tt> <b>==</b> "
-"<tt>5</tt>, which checks whether the current value of <tt>x</tt> is 5, or "
-"such as <b>!=</b> (checking inequality), <b><</b> (smaller than), "
-"<b>></b> (larger than), <b><=</b> (smaller or equal to), <b>>=</b> "
-"(larger or equal to)."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/conditions/Conditions.html:94
-msgid ""
-"Beware of the classical trap, which consists in testing the equality of a "
-"variable using = instead of ==. Hopefully, the compiler detects this problem "
-"most of the time, but not always. If the variable is of type boolean, it can "
-"get trapped, so you have to be careful..."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:99
-msgid ""
-"The condition can also be a call to some perticular methods returning a "
-"boolean. For example, the <tt>isFacingWall()</tt> method of the buggle "
-"returns true if the buggle is facing a wall, and false in the other case."
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:103
-msgid ""
-"Finally, a condition can be composed of several sub-conditions connected by "
-"boolean operations."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:106
-msgid ""
-"<tt>cond1 && cond2</tt> is true when <tt>cond1</tt> <b>and</b> "
-"<tt>cond2</tt> are both true (if <tt>cond1</tt> is false, <tt>cond2</tt> is "
-"not even evaluated)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:109
-msgid ""
-"<tt>cond1 || cond2</tt> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt> "
-"are true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:111
-msgid "<tt>!cond</tt> is true if <tt>cond</tt> is false."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:112 src/lessons/welcome/conditions/Conditions.html:125
-msgid ""
-"It is possible to force the order of evaluation by adding parenthesis. In "
-"ambigous cases, do not hesitate to add more parenthesis to remove any "
-"ambiguities on evaluation order."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:118
-msgid ""
-"<tt>cond1 and cond2</tt> is true when <tt>cond1</tt> <b>and</b> "
-"<tt>cond2</tt> are both true (if <tt>cond1</tt> is false, <tt>cond2</tt> is "
-"not even evaluated)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:121
-msgid ""
-"<tt>cond1 or cond2</tt> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt> "
-"are true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><ul><li>
-#: src/lessons/welcome/conditions/Conditions.html:124
-msgid "<tt>not cond</tt> is true if <tt>cond</tt> is false."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:130
-msgid ""
-"Finally, it is possible to specify what to do when the condition is false "
-"using the following syntax:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:132
-#, no-wrap
-msgid ""
-"if (<b>condition</b>) {\n"
-"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
-"} else {\n"
-"    <b>whatToDoIfItsFalse();</b>\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/conditions/Conditions.html:138
-#, no-wrap
-msgid ""
-"if (<b>condition</b>):\n"
-"    <b>whatToDoIfTheConditionIsTrue()</b>\n"
-"else:\n"
-"    <b>whatToDoIfItsFalse()</b>\n"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/conditions/Conditions.html:144
-msgid ""
-"Don't forget the colon (:) after the else, it is indicating that a new block "
-"is beginning."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><a>
-#: src/lessons/welcome/conditions/Conditions.html:147
-msgid ""
-"<a name=\"Objectives\">If the buggle is facing a wall (predicate "
-"<tt>isFacingWall()</tt>), you must move one step back. If not, you must move "
-"one step forward."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><a><p>
-#: src/lessons/welcome/conditions/Conditions.html:151
-msgid ""
-"This exercise is a bit different: your code has to work for several buggles, "
-"each of them being in a specific initial condition. The same code will be "
-"executed for each of them."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/conditions/Conditions.html:155 src/lessons/welcome/loop/whileloop/LoopWhile.html:32
-msgid "When your program works, move forward to the next exercise."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:2
-msgid ""
-"The buggle world can sometimes contain some <i>baggles</i>, which are little "
-"biscuits that buggles can carry from one point to another. For that, they "
-"have to use specific methods such as <code>isOverBaggle(), "
-"isCarryingBaggle(), pickupBaggle()</code> or "
-"<code>dropBaggle()</code>. Check their documentation in \"Help/About this "
-"world\" for more details."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/baggleseeker/BaggleSeeker.html:10
-msgid ""
-"Let each buggle find its baggle by adapting the code you wrote in previous "
-"exercise (copy/paste what you've done before to save time)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/Variables.html:2
-msgid ""
-"The programs we wrote so far are missing a fundamental point in computing.  "
-"Actually, it is all about processing <b>data</b> through specific "
-"<b>instructions</b>. In the buggle world, the main data are a bit hidden "
-"behind the graphical representation, but that's no reason to never "
-"manipulate some data explicitly."
-msgstr ""
-
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/variables/Variables.html:8
-msgid "Data in Java"
-msgstr ""
-
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/variables/Variables.html:9
-msgid "Data in Python"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/Variables.html:10
-msgid ""
-"In a program, you can use several <i>types</i> of data, such as integers or "
-"strings of chars. If you want to use a data several times, you need to store "
-"it within a <i>variable</i>, which is a memory cell containing a value. It's "
-"not very different from a shelve containing a book: you put your data (say "
-"'5') in the variable (say 'length'), and you can retrieve it latter when you "
-"need it."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:16
-msgid ""
-"Java is said to be a <i>typed</i> language, which means that it is only "
-"possible to store a value in a variable of the right type. Don't think about "
-"storing the letters of your name into an integer variable. In other "
-"languages (such as Python)  allow you to store any kind of data in any "
-"variable without such restriction, but not in Java."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:20
-msgid ""
-"The Python language is said to <i>not typed</i>, which means you can store "
-"any type of data into a given variable. Other languages (such as Java) "
-"mandate that each variable store only data of a given type, but there is no "
-"such difficulties here."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:25
-msgid ""
-"To <i>declare</i> (ie, create) a variable, you just need to write its type, "
-"a space, and the variable name. From the existing types, we can speak of "
-"<b>int</b> (for integers), <b>double</b> for dot numbers, <b>boolean</b> for "
-"booleans (ie, values being either true or false) and <b>String</b> for char "
-"strings. If you want, you can specify the initial value of the variable by "
-"adding a equal sign (=) followed by the value after the declaration."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:31
-msgid ""
-"So, to create a variable named <b>x</b> intended to contain integers, one "
-"can write:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:32
-#, no-wrap
-msgid "int x;"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/variables/Variables.html:33
-msgid "If you want that the variable contains 5 as initial value, you should type:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:33
-#, no-wrap
-msgid "int x = 5;"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:34 src/lessons/welcome/variables/Variables.html:48
-msgid ""
-"Later in the program, if you want to <i>affect</i> a new value to the "
-"variable, that's really easy:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:35
-#, no-wrap
-msgid "x = 3;"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:36
-msgid ""
-"The syntax to create an integer variable <code>x</code> with 4 as initial "
-"value is the following:"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:38
-#, no-wrap
-msgid "int x = 4;"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:39 src/lessons/welcome/variables/Variables.html:50
-msgid ""
-"This quite the same story for strings, floating point numbers and boolean "
-"values."
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:41
-#, no-wrap
-msgid ""
-"String name = \"Martin Quinson\";\n"
-"double height=1.77; <span class=\"comment\">// in meters</span>\n"
-"boolean married=true;"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:45
-msgid ""
-"<i>Declaring</i> (ie, creating) a variable in Python is dead simple: you "
-"just need to give it an initial value by writing its name, the equal sign "
-"and the value."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/variables/Variables.html:47
-msgid ""
-"So, to create a variable named <b>x</b> which initial value should be 5, you "
-"should type:"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:47
-#, no-wrap
-msgid "x = 5"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:49
-#, no-wrap
-msgid "x = 3"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:52
-#, no-wrap
-msgid ""
-"firstName = \"Martin\"\n"
-"lastName = 'Quinson' <span class=\"comment\"># both single and double quote "
-"work here</span>\n"
-"motto = \"I never finish anyth' (but I keep trying)\" <span "
-"class=\"comment\"># having single quote within double quote is fine</span> "
-"\n"
-"height=1.77 <span class=\"comment\"># in meters</span>\n"
-"married=True <span class=\"comment\"># the contrary would be written "
-"False</span>"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:59
-msgid ""
-"To the right of the equal symbol, you can put an expression containing "
-"constants, variables and operations:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:62
-#, no-wrap
-msgid ""
-"x = 3 + 2;\n"
-"x = 3 * x;\n"
-"greeting = \"Hello \"+name;\n"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/variables/Variables.html:66
-#, no-wrap
-msgid ""
-"x = 3 + 2\n"
-"x = 3 * x\n"
-"greeting = \"Hello \"+name\n"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:73
-msgid ""
-"It is now time to do more challenging exercises, don't you think? The "
-"objective is now to move forward until you find a baggle, pick it up, and "
-"then move back to your initial location before dropping the baggle."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><h3>
-#: src/lessons/welcome/variables/Variables.html:78
-msgid "How to do this?"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:79
-msgid ""
-"To solve this problem, you have to decompose it in easier sub-parts. For "
-"example, you may want to do the following steps:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:82
-msgid "Move forward until located over a baggle"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:83
-msgid "Pickup the baggle"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:84
-msgid "Move backward of the same amount of steps than done in first step"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ol><li>
-#: src/lessons/welcome/variables/Variables.html:85
-msgid "Drop back the baggle"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:88
-msgid ""
-"Naturally, it is impossible to do the right amount of steps backward at step "
-"3 if you didn't count the amount of steps done in the first phase. You can "
-"use a variable for that, which can be named <code>stepAmount</code>."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:92
-msgid ""
-"Create a variable (of type <code>int</code>) before phase 1, initialize it "
-"to 0, and each time you move one step forward, increment its value by one "
-"(<code>stepAmount = stepAmount + 1;</code> or <code>stepAmount++;</code>, "
-"both syntaxes being equivalent)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:96
-msgid ""
-"Create a variable before phase 1, initialize it to 0, and each time you move "
-"one step forward, increment its value by one (<code>stepAmount = stepAmount "
-"+ 1</code>)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:100
-msgid ""
-"Then, phase 3 consists in simply creating a new integer variable "
-"<code>doneSteps</code> initialized to 0, and do one step backward until "
-"<code>doneSteps</code> equals <code>stepAmount</code>, incrementing "
-"<code>doneSteps</code> each time."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:105
-msgid ""
-"Please note that it is forbidden to use spaces in variable names. So you can "
-"name you variable <code>stepAmount</code>, but <code>step Amount</code> is "
-"not a valid name."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/variables/Variables.html:109
-msgid "It's your turn now!"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/variables/RunFour.html:1
-msgid "Run Four bases"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/RunFour.html:3
-msgid ""
-"Today is a great day for the buggles: the Big Buggles' Race begun. It's a "
-"traditional competition in which young buggles prove their value to the "
-"tribe. Both force and intelligence is exercised: you have to rush forward, "
-"but stop as soon as you reach your fourth baggle.  Please help the buggles "
-"to move forward while counting the baggles and to determine when to stop."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/variables/RunHalf.html:1
-msgid "The Four Halves run"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/RunHalf.html:3
-msgid ""
-"Here is the second day of the Big Buggles' Race.  As previously, you have to "
-"run forward until you reach the right cell to stop on.  But this time, you "
-"have to reach the cell where you saw as much baggles as orange cells plus "
-"1.  In other word, the following condition must become true <code>2 * "
-"baggles = orangeCells + 1</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/variables/RunHalf.html:8
-msgid ""
-"You can determine whether you are over a orange cell with the "
-"<code>isOverOrange()</code> method."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:3
-msgid ""
-"While loops are well adapted to situations where you want to achieve an "
-"action while a condition stays true, but it is less adapted to achieve a "
-"given action a predetermined amount of time. For example, when we wanted to "
-"move <code>stepAmount</code> steps backward in previous exercise, you had to "
-"create a new variable, initialize it, and move backward until the new "
-"variable became equal to <code>stepAmount</code>, incrementing the new "
-"variable manually at the end of the loop."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:11
-msgid ""
-"In such situations, <code>for</code> loops become handy. Their syntax is the "
-"following:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:13
-#, no-wrap
-msgid ""
-"for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {\n"
-"   <b>action</b>();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:17
-#, no-wrap
-msgid ""
-"for <b>variable</b> in <b>sequence of values</b>:\n"
-"   <b>action</b>()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:21
-msgid "This code is perfectly equivalent to the following:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:22
-#, no-wrap
-msgid ""
-"<b>initializing</b>;\n"
-"while (<b>condition</b>) {\n"
-"   <b>action</b>();\n"
-"   <b>incrementing</b>;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:28
-#, no-wrap
-msgid ""
-"while <b>there is a value in the sequence</b>: \n"
-"   <b>set variable to the next unseen value of the "
-"sequence</b>\n"
-"   <b>action</b>()\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:33
-msgid ""
-"Please note that in Python the instruction <code>range(n)</code> allows to "
-"get a sequence n integer value from 0 to n-1."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:36
-msgid ""
-"For example, both following codes are equivalent. The latter is easier to "
-"read, don't you think?"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:39
-#, no-wrap
-msgid ""
-"int done = 0;\n"
-"while (done < stepAmount) {\n"
-"   backward();\n"
-"   done++;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:44
-#, no-wrap
-msgid ""
-"for (int done = 0; done < stepAmount; done++) {\n"
-"   backward();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:48
-#, no-wrap
-msgid ""
-"done = 0\n"
-"while done < stepAmount:\n"
-"   backward()\n"
-"   done = done + 1\n"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:53
-#, no-wrap
-msgid ""
-"for done in range(stepAmount):\n"
-"   backward()\n"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:59
-msgid ""
-"It is possible to build more advanced <tt>for</tt> loops since any valid "
-"instruction can be used as initialization, condition and incrementation. The "
-"following example is a bit extreme since it compute the gcd (greatest common "
-"divisor) of two numbers without loop body and initialization (everything is "
-"in the condition and incrementation)."
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:65
-#, no-wrap
-msgid ""
-"int x=20, y=3, tmp;\n"
-"for (; y!=0 ; tmp=x, x=y, y=tmp%y) { }\n"
-" <span class=\"comment\">/* the gcd is stored in x */</span>"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:69
-msgid ""
-"If you don't understand every details of this example, don't panic. That's "
-"quite logic since it uses some syntax details that we did not introduce yet."
-msgstr ""
-
-#. type: Content of: <p><p><p><a>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:73
-msgid ""
-"<a name=\"Objectives\"> You now have to redo the same exercise than "
-"previously (move forward until being over a baggle, pick it up, move back to "
-"your original location, drop the baggle), but using a <tt>for</tt> loop "
-"instead of a <tt>while</tt> loop to move back to the initial location."
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/loop/forloop/LoopFor.html:78
-msgid "Once done, proceed to next exercise."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:1
-msgid "Stairway to Heaven"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:3
-msgid ""
-"Your buggle feels a bit depressed today, but it's currently facing a magic "
-"stair: It leads directly to heaven, and each time you walk on it, joyful "
-"colors spur all around."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:6
-msgid ""
-"Your goal is to take this stair, one step after the other.  First devise the "
-"four instructions you have to give you buggle to take one stair step, and "
-"then put them in a loop to take the whole stair."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopStairs.html:10
-msgid ""
-"And before that, walk a bit forward to reach that stair, and ensure that you "
-"are in the right situation for your loop content to run properly. And once "
-"you reach the heaven, take some steps in your new home."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:1
-msgid "Training Buggle"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:3
-msgid ""
-"Today, your buggle wants to get some serious exercise: It wants to run 'till "
-"the track burns! Its super-shoes are just perfect to run like hell, but "
-"unfortunately, they can actually damage the track on the long run..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourse.html:6
-msgid ""
-"Your goal is to run the track 10 times, no matter what happens.  Even if the "
-"track suffers, you <b>really HAVE</b> to take that run.  Remember, the track "
-"has four sides, that take eight steps each to run along.  Now go, and show "
-"them what these super shoes can do."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:1
-msgid "Outdoor Training Buggle"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:3
-msgid ""
-"Well, our last training didn't went that well. The track actually burned, "
-"and we are now banned from there.  This time, our buggle decided to practice "
-"outdoor, in the middle of the forest, with its good old shoes instead.  The "
-"problem is that you have to be careful to not fall into water. The track on "
-"which you can run is rather narrow: One side is now 4 steps forward, 2 steps "
-"to the left, 4 steps to the right, 2 steps to the right, 4 steps to the "
-"left, and you want to run 7 around."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/forloop/LoopCourseForest.html:9
-msgid ""
-"Oh crap, running on the grass seems to destroy it too! So just take your 7 "
-"loops around the garden, and move along to the next exercise before anyone "
-"notices the damage you made..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:3
-msgid ""
-"In addition to conditionals, another handy construction is the ability to "
-"repeat an action while a specific condition does not appear. A while loop is "
-"used for that, with the following syntax:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:6
-#, no-wrap
-msgid ""
-"while (<b>condition</b>) {\n"
-"  <b>action()</b>;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:9
-#, no-wrap
-msgid ""
-"while <b>condition</b>:\n"
-"  <b>action()</b>"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:12
-msgid ""
-"Naturally, if the chosen action does not modify the value of the condition, "
-"the buggle will do the action endlessly. The <b>stop</b> button of the "
-"interface becomes then handy. To test this, you can try to type the "
-"following code in the editor:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:17
-#, no-wrap
-msgid ""
-"while (true) {\n"
-"  turnLeft();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:20
-#, no-wrap
-msgid ""
-"while True:\n"
-"  turnLeft()"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:23
-msgid ""
-"The buggle will turn left while true is true (ie, endlessly), or until you "
-"stop it manually using the stop button."
-msgstr ""
-
-#. type: Content of: <p><a>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:26
-msgid ""
-"<a name=\"Objective\">You now have to write some code so that your buggles "
-"move forward until they encounter a wall. The idea is thus to do something "
-"like:"
-msgstr ""
-
-#. type: Content of: <p><a><pre>
-#: src/lessons/welcome/loop/whileloop/LoopWhile.html:29
-#, no-wrap
-msgid ""
-"while we are not facing a wall, do:\n"
-"  moveForward()"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:1
-msgid "Lost in the Moria"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:3
-msgid ""
-"You buggle got stuck in a mine! Some rocks are blocking the exit, and you "
-"will have to clear your way to the exit. Well of course these are only "
-"baggles and you could simply walk away, but it will be easier to program "
-"your buggle so that it moves those \"rocks\" than convincing your buggle "
-"that it could easily walk away without solving the problem..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:9
-msgid ""
-"So, you have to find the first baggle blocking the exit (simply walk to the "
-"east until you are over a baggle), take it and move it back to the other "
-"side of the tunnel (walk to the west while you are not over a baggle, and "
-"then move back one step to the east and drop your baggle), and iterate until "
-"you find the exit (that is, the wall to the east side). Afterward, move out "
-"as in the objective world."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/whileloop/WhileMoria.html:16
-msgid "Once you manage to escape this trap, move forward to the next exercise."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:3
-msgid ""
-"Here is another little exercise about loops. It is slightly more complex as "
-"we want the action to be executed in any case, even if the condition is "
-"false right away. Some languages have specific constructs for that, but not "
-"the Python language. No problem, I'm sure you can do it without them, can't "
-"you?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:7
-msgid ""
-"A bad solution would be to duplicate the loop content before the loop, but "
-"code duplication is a <b>very</b> bad habit, and you should always avoid "
-"it. A better solution is to have a dedicated variable indicating whether we "
-"are taking the loop for the first time, as follows:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:10
-#, no-wrap
-msgid ""
-"firstTime = True\n"
-"while firstTime or (other conditions):\n"
-"  firstTime = False\n"
-"  (loop body)\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:16
-msgid ""
-"In a <tt>while</tt> loop, the condition is evaluated before anything else, "
-"and if it's false, the loop body is never evaluated. Sometimes (although not "
-"that often), you would prefer the loop body to get evaluated at least once, "
-"even if the condition is initially false. For that, a variation of the "
-"<tt>while</tt> loop gets used, using the following syntax in Java:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:22
-#, no-wrap
-msgid ""
-"do {\n"
-"  <b>action()</b>;\n"
-"} while (<b>condition</b>);"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:27
-msgid ""
-"Some cells of the world are yellow, but your buggle cannot stand being in "
-"such cells. Write the necessary code to move forward until the ground gets "
-"white. For that, use the provided method <code>isGroundWhite()</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:31
-msgid ""
-"The trick is that most buggles of this world are currently on this yellow "
-"ground that they dislike so much. That is why they are in panic, and every "
-"buggle rushes one cell forward, even the buggle that was not on a yellow "
-"cell at first. In other worlds, even if the ground is white on the first "
-"cell, you still want to move forward to the next cell."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:36
-msgid "The general idea is to do something like:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:37
-#, no-wrap
-msgid "move forward until located in a white cell"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html:39
-msgid ""
-"<i>Remark:</i> it is also possible to solve this exercise with a classical "
-"<tt>while</tt> loop, but it's not the goal."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:1
-msgid "Tracks of buggles"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:3
-msgid ""
-"Your buggle got lost in a strange maze, and you must help it finding the "
-"exit that is represented in orange.  You cannot simply explain the path to "
-"the exit in something like "
-"<code>turnRight();forward;forward();forward()</code> because you have to "
-"save two buggles at the same time, that are lost in similar but not "
-"identical worlds.  You can switch to the other world by using the combobox "
-"above the world representation (where it's written 'Deep Forest' right now), "
-"and selecting the other entry (that should read 'Deeper Forest')."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:9
-msgid ""
-"The good news is that the path to the exit is written on the ground. As you "
-"can see, the world is made of several corridors, with baggles on the "
-"ground. After each corridor, you should turn left if the corridor contains "
-"three baggels or more, and you have to turn right if there is only 2 baggles "
-"or less."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:13
-msgid ""
-"So, the general form of your code must be something like \"while I did not "
-"find the exit, take the next corridor to decide whether I should turn left "
-"or right at the next intersection\". You can determine whether you are on "
-"the exit cell (that is orange) with the provided <code>exitReached()</code> "
-"method."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:17
-msgid ""
-"To take one corridor, you simply have to run from one intersection to "
-"another while counting the baggles you see on your path. The method "
-"<code>crossing()</code> tells you whether your buggle currently stands on an "
-"intersection.  The extra complexity is that at the beginning of a corridor, "
-"you obviously stand on an intersection, but you still want to move on."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:22
-msgid ""
-"For that, the easiest is to use a <code>do / while</code> loop instead of a "
-"regular <code>while</code> loop to move until the next intersection."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:25
-msgid ""
-"For that, use an extra variable indicating whether you already entered the "
-"corridor, as follows. This will ensure that you execute the loop body at "
-"least once (when <code>firstTime</code> is true)  before we actually use the "
-"value returned by <code>crossing()</code> to determine to continue or not."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:28
-#, no-wrap
-msgid ""
-"firstTime = True\n"
-"while firstTime or not crossing():\n"
-"  firstTime = False\n"
-"  <your body>  \n"
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:34
-msgid "I cannot imagine how to count the baggles I see."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:35
-msgid ""
-"You need a variable that is initialized to 0, and incremented each time you "
-"see a baggle on the ground. A variable used this way is often called "
-"<i>accumulator</i>."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:37
-msgid ""
-"Don't forget to reset your accumulator to 0 at the beginning of each "
-"corridor!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/loop/dowhileloop/Poucet.html:40
-msgid ""
-"Oh, and when you reach the exit, don't forget to take an extra step to "
-"actually exit the maze!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/basics/Methods.html:4
-msgid ""
-"We will now write our own methods. It somehow comes down to extending the "
-"buggle vocabulary by learning it new tricks."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/basics/Methods.html:7
-msgid ""
-"For example, we saw in previous exercise how to ask the buggle to go get the "
-"baggle in front of it, and bring it back. If there is several baggles on the "
-"board, and if we want to bring all of them on the bottom line, you have to "
-"repeate this code several times, or include it in a loop. In any case, the "
-"result may reveal unpleasant to read, and it would be better if the buggle "
-"could obey an <code>goAndGet()</code> order just like it understands a "
-"<code>forward()</code> one."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:16 src/lessons/welcome/methods/basics/Methods.html:22
-msgid ""
-"The syntax to write a simple method called <code>goAndGet</code> is the "
-"following:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:18
-#, no-wrap
-msgid ""
-"def goAndGet():\n"
-"  actions();\n"
-"  to();\n"
-"  do();"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:24
-#, no-wrap
-msgid ""
-"public void goAndGet() {\n"
-"  actions();\n"
-"  to();\n"
-"  do();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:30
-msgid ""
-"The method body (between curly braces) can contain as many instructions as "
-"you want, and any construction we saw so far (for, while, if, etc)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:32
-msgid ""
-"The method body (the code that is indended) can contain as many instructions "
-"as you want, and any construction we saw so far (for, while, if, etc)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:35
-msgid ""
-"We will come back later on the exact signification of the "
-"<code>public</code> keyword. Let's say for now that it means that everybody "
-"can use this method."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:39
-msgid ""
-"<code>void</code> means that the method does not return any result. We said "
-"previously that the <code>isOverBaggle()</code> method returns a boolean and "
-"can thus be used as a condition in a if or a while. This means that it is "
-"declared the following way:"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:43
-#, no-wrap
-msgid "public boolean isOverBaggle() { ... }"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:45
-msgid ""
-"We will introduce in next exercise how to do this kind of tricks. For now, "
-"let's just write <code>void</code> at this location."
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/basics/Methods.html:48
-msgid ""
-"In Java, the convention is to use lower case for the first letter of a "
-"method name and concatenate every word describing the method using a upper "
-"case for each first letter. It is forbidden to use spaces or accentuated "
-"letters in a method name. That is why we write \"go and get\" as goAndGet()."
-msgstr ""
-
-#. type: Content of: <p><p><p><a>
-#: src/lessons/welcome/methods/basics/Methods.html:59
-msgid ""
-"<a name=\"Objectives\"> The goal of this exercise is to write a method "
-"called <code>goAndGet()</code> which does the same than in previous "
-"exercises (move forward until over a baggle, pick it up, move back to "
-"initial position, drop baggle)."
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:64
-msgid ""
-"One particularity of this exercise is that all your code should be written "
-"in this function, with nothing out of it. The code that calls your function "
-"will be automagically added when you click on <b>Start</b>."
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:68
-msgid ""
-"One particularity of this exercise is that you shouldn't write directly the "
-"code that the buggle should execute, but a method it should use. Actually, "
-"in any previous exercise, you wrote the body of a specific method called "
-"<code>run()</code> which gets invoked by the environment when you click on "
-"<b>Start</b>."
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:74
-msgid ""
-"Don't try to define this method here, since the buggle already knows "
-"it. This would cause trouble to the compiler, which would give you an error "
-"message in exchange. For your information, here is the <code>run()</code> "
-"method of this exercise:"
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:79
-#, no-wrap
-msgid ""
-"public void run() {\n"
-"  for (int i=0; i<7; i++) { \n"
-"    goAndGet();\n"
-"    turnRight();\n"
-"    forward();\n"
-"    turnLeft();\n"
-"  }\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p><pre>
-#: src/lessons/welcome/methods/basics/Methods.html:87
-#, no-wrap
-msgid ""
-"def run():\n"
-"  for i in range(7): \n"
-"    goAndGet()\n"
-"    turnRight()\n"
-"    forward()\n"
-"    turnLeft()\n"
-"  \n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:98
-msgid ""
-"Your buggle will repeat 7 times (which matches the world's dimension)  "
-"sequence constituted of a call to the <code>goAndGet()</code> method that "
-"you should write, plus a move to get to the next row (turn right, move "
-"forward, turn left). As you can see, the buggle will do one step right from "
-"the right border of the world. It will bring it back to the left side since "
-"its world is a torus."
-msgstr ""
-
-#. type: Content of: <p><p><p><a><p>
-#: src/lessons/welcome/methods/basics/Methods.html:105
-msgid "You should now write this goAndGet() method."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:3
-msgid ""
-"We now would like to learn the buggle to build a doghouse. The seamingly "
-"simpler approach consists in directly writing the needed code as follows (it "
-"works because the buggle of this exercise leaves a red path as it moves)."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:8
-#, no-wrap
-msgid ""
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-"forward();\n"
-"forward();\n"
-"turnLeft(); \n"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:23
-#, no-wrap
-msgid ""
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-"forward()\n"
-"forward()\n"
-"turnLeft() \n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:37
-msgid ""
-"It becomes harder when we want to draw two doghouses: we have to rewrite the "
-"same code twice, which is not really handy. Even worse: it's definitively "
-"not good form to duplicate code this way. Indeed, if you realize that an "
-"error sneaked into a code that you copied at several locations, you will "
-"have to fix it several times. And mind your back if you forget one of these "
-"locations."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:44
-msgid ""
-"It is good form to <b>factorize your code</b>, ie to write it only once, for "
-"example in a method. This is what you will do now. It is even possible to go "
-"further by factorizing the method body with a <code>for</code> loop, as seen "
-"previously."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:49
-msgid ""
-"The goal of this exercise is to write a method called <code>dogHouse</code> "
-"achieving the same result than the code above. The buggle will call your "
-"creation to create several dog houses around its world. Remind to factorize "
-"your method with a for loop."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/doghouse/MethodsDogHouse.html:54 src/lessons/welcome/array/basics/Array.html:229 src/lessons/welcome/array/basics/Array2.html:30
-msgid "You're up."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:3
-msgid ""
-"Writing a method returning a result is not really more work than writing a "
-"method without any result. <span class=\"Java\">You simply have to specify "
-"the data type of expected results before the method name</span>. And, then "
-"write a <code>return</code> instruction in your method body to specify the "
-"actual value to return."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:9
-#, no-wrap
-msgid ""
-"double pi() {\n"
-"    return 3.14159;\n"
-"}\n"
-"boolean isNumberTwoEven() {\n"
-"    return true;\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:16
-#, no-wrap
-msgid ""
-"def pi():\n"
-"    return 3.14159\n"
-"\n"
-"def isNumberTwoEven():\n"
-"    return True\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:23
-msgid ""
-"It is possible to have several <code>return</code> instructions in several "
-"branches of a conditional. It is even forbidden to have one execution path "
-"of your body without any <code>return</code>, or to write some code after "
-"the <code>return</code> instruction."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:28
-msgid ""
-"Indeed, if the machine reaches the end of the method without finding any "
-"<code>return</code>, it cannot know what actual value to give back to the "
-"method caller. Moreover, <code>return</code> interrupts immediately the "
-"method execution (why bother looking further when you know the method "
-"result?). So, if there is some code after a <code>return</code>, it must be "
-"an error and the compiler warns you."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:35
-#, no-wrap
-msgid ""
-"boolean negation(boolean cond) {\n"
-"    if (cond == true) {\n"
-"        return true;\n"
-"        <span class=\"comment\">/* "
-"no code allowed here */</span>\n"
-"    } else {\n"
-"        return false;\n"
-"        <span class=\"comment\">/* "
-"here neither */</span>\n"
-"    }\n"
-"    <span class=\"comment\">/* even here, forget it "
-"*/</span>\n"
-"}"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:45
-#, no-wrap
-msgid ""
-"def negation(cond):\n"
-"    if cond == True:\n"
-"        return True\n"
-"        <span class=\"comment\"># no "
-"code allowed here</span>\n"
-"    else:\n"
-"        return False\n"
-"        <span class=\"comment\"># "
-"here neither</span>\n"
-"    \n"
-"    <span class=\"comment\"># even here, forget "
-"it</span>\n"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:56
-msgid ""
-"You will once again write a method that the buggle will use. Its name must "
-"be <code>haveBaggle</code>, and it returns a boolean value indicating "
-"whether the row in front of the buggle contains a baggle or not. The buggle "
-"will use it to search the first row containing a baggle, and stop here."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:61
-msgid ""
-"The easier for this method is to use a boolean variable called "
-"<code>seenBaggle</code> indicating whether or not we saw a baggle so far. It "
-"initial value is 'false'."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:65
-msgid ""
-"Then, move 6 steps forward (the world contains 7 cells and we already are "
-"one one of them). For each cell, if it contains a baggle, we store true in "
-"<code>sawBaggle</code> (and we don't do anything but moving forward if not)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:69
-msgid ""
-"At the end, we move back by 6 steps, and we return the value of "
-"<code>seenBaggle</code> to the caller."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:73
-msgid ""
-"This exercise is a bit different since there is two initial worlds, each "
-"with a specific objective. Your code must work for each of them. Observe "
-"that the world selection scrolling menu (right below the speed slider)  "
-"allows to switch the observed world."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/returning/MethodsReturning.html:78
-msgid "When your method <code>haveBaggle</code> works, proceed to next exercise."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/args/MethodsArgs.html:3
-msgid ""
-"Don't you get tired of writing again and again the code to move by a fixed "
-"amount of steps? On the other hand, writing <tt>forward2()</tt>, "
-"<tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>, "
-"<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:8
-msgid ""
-"Luckily, it is possible to pass <b>parameters</b> to your methods. You have "
-"to specify their type and name between the parenthesis after the method "
-"name. Then, you can use them in the method body as if it were variables "
-"defined in there, and which initial value is what the caller specified."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:13
-#, no-wrap
-msgid ""
-"double divideByTwo(double x) {\n"
-"  return x / 2;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:17
-#, no-wrap
-msgid ""
-"def divideByTwo(x):\n"
-"  return x / 2\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:21
-msgid ""
-"As caller, you have to specify the initial value of this \"variables\" "
-"between the call's parenthesis."
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:23
-#, no-wrap
-msgid "double y = divideByTwo(3.14);"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:25
-#, no-wrap
-msgid "y = divideByTwo(3.14)"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:28
-msgid ""
-"If you want several parameters, you need to separate them with comas (,)  "
-"both in the declaration and calls."
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:31
-#, no-wrap
-msgid ""
-"double divide(double x, double y) {\n"
-"  return x / y;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:34
-#, no-wrap
-msgid "double y = divide(3.14 , 1.5);"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:36
-#, no-wrap
-msgid ""
-"def divide(double x, double y):\n"
-"  return x / y\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:39
-#, no-wrap
-msgid "y = divide(3.14 , 1.5)"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:42
-msgid ""
-"In Java, you can declare several methods of the same name as long as they "
-"don't have the same parameter types and number (they are said to have "
-"different <b>signature</b>)."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:45
-#, no-wrap
-msgid ""
-"int max(int x, int y) {\n"
-"  if (x > y) {\n"
-"    return x;\n"
-"  }\n"
-"  return y;\n"
-"}\n"
-"int max(int x, int y, int z) {\n"
-"  if (x > y && x > z) {\n"
-"    return x;\n"
-"  }\n"
-"  if (y > z) {\n"
-"    return y;\n"
-"  }\n"
-"  return z;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:63
-msgid ""
-"Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It "
-"works anyway because a <tt>return</tt> interrupts the method execution. If "
-"we arrive to the last line of <code>max(int,int)</code>, we know that "
-"<code>x<=y</code> because on the other case, the <tt>return</tt> of line "
-"2 would have stopped the execution."
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:69
-msgid ""
-"This time, you have to write a <code>move(int stepCount,boolean "
-"forward)</code> method which move forward of <code>stepCount</code> if "
-"<code>forward</code> is true, and move back of that amount of steps if the "
-"boolean is false. The buggle will use some methods we did not introduce yet "
-"to guess its position and orientation in order to determine the amount of "
-"steps to do and their direction, but it is not relevant here."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:76
-msgid ""
-"This time, there is only one world, and seven buggles. But it does not "
-"change anything for you, since the same code is used for any buggles."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:79
-msgid "The code of the method to write should not be really problematic for you."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><h2>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:81
-msgid "What's coming next?"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:82
-msgid ""
-"You now know the very basics of programming. At least, we introduced all the "
-"important concepts, and you should be able to read most code by now. If you "
-"want to play safe, you should proceed to the next exercises of this lesson "
-"to solidify your knowledge by reusing these concepts in various simple "
-"situations. After taking them, you'll master what's called \"Tactical "
-"programming\", meaning that you will master the syntax enough to not have "
-"any issue with it, allowing you to focus on the fundamental problems of what "
-"you want to solve instead of struggling with syntaxic difficulties. Some of "
-"these exercises are even fun to do ;)"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/methods/args/MethodsArgs.html:90
-msgid ""
-"If you are in a hurry and want more, you can skip these exercises and "
-"proceed directly to more interesting challenges. For example, the "
-"<i>Labyrinths</i> lesson will teach you about maze escaping algorithms, "
-"which are not rocket science but require several improvements to work for "
-"any kind of maze. The <i>Lightbot</i> lesson is a little programming game "
-"where you control a little robot wanting to light the world. Since it is not "
-"programmed in a language but graphically, the first exercises can be used as "
-"an introduction activity to what programming means for real beginners, but "
-"the last exercises constitute challenges and brain teaser even to "
-"professional programmers."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:3
-msgid ""
-"In this exercise, we will reproduce the geometric drawing that you can see "
-"in the \"Objective\" tab."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:6
-msgid ""
-"Your goal (here and in any well written program) is to write the simplest "
-"possible <code>run()</code>. For that, you have to decompose your work in "
-"sub-steps, and write a specific method for each sub-step."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:10
-msgid ""
-"Your goal (here and in any well written program) is to write the simplest "
-"possible main code. For that, you have to decompose your work in sub-steps, "
-"and write a specific method for each sub-step."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:14
-msgid ""
-"If you observe carefully the picture to draw, it is constituted of four "
-"parts depicting a sort of V using a different color. A possible "
-"decomposition is to write a method in charge of drawing a V of the specified "
-"color from the current position. Its prototype can be:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:18
-#, no-wrap
-msgid "void makeV(Color c)"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:19
-#, no-wrap
-msgid "makeV(c)"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:21
-msgid ""
-"The <code>Color</code> data type naturally describes a particular "
-"color. Your <code>run()</code> method should probably call "
-"<code>makeV</code> with the following arguments (a different color for each "
-"call):"
-msgstr ""
-
-#. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:26
-msgid "Color.yellow"
-msgstr ""
-
-#. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:27
-msgid "Color.red"
-msgstr ""
-
-#. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:28
-msgid "Color.blue"
-msgstr ""
-
-#. type: Content of: <p><p><ul><li>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:29
-msgid "Color.green"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:32
-msgid ""
-"In <code>makeV()</code>, you should use the <code>setBrushColor()</code> "
-"method (predefined in the buggle) to change the color of the buggle's brush, "
-"as well as <code>brushUp()</code> and <code>brushDown()</code> to change the "
-"brush position."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:37
-msgid ""
-"It may be wise to write the <code>makeV()</code> so that it places directly "
-"the buggle in position for the next V."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/methods/picture/MethodsPicture.html:40
-msgid ""
-"Your turn. The <code>run()</code> method should not be longer than 4 "
-"lines..."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:3
-msgid ""
-"We will now reproduce an even bigger geometrical drawing. Once again, you "
-"can see the model by clicking on the \"Objective\" tab."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:6
-msgid ""
-"You can naturally reuse all the code you typed in previous exercise (select "
-"the other exercise, do Ctrl-C, come back to the code of this exercise, do "
-"Ctrl-V)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:10
-msgid ""
-"But you want to keep your main<code>run()</code> as simple as possible. For "
-"that, define new methods to deal simply with the repetitions in the "
-"pattern. For example, a method <code>makePattern()</code> achieving the "
-"pattern of previous example seems to be a good idea (but this may not be "
-"enough)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:16
-msgid ""
-"But you want to keep your main code as simple as possible. For that, define "
-"new methods to deal simply with the repetitions in the pattern. For example, "
-"a method <code>makePattern()</code> achieving the pattern of previous "
-"example seems to be a good idea (but this may not be enough)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:22
-msgid ""
-"Why don't you give it a shot? The <code>run()</code> method shouldn't take "
-"more than 2 lines (included in a for loop)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture2/MethodsPicture2.html:25
-msgid ""
-"Why don't you give it a shot? The main code method shouldn't take more than "
-"2 lines (included in a for loop)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:3
-msgid ""
-"As you can imagine, you have to reproduce the geometric drawing depicted in "
-"the \"Objectives\" tab. As you can see, it is even bigger than the previous "
-"one."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:7
-msgid ""
-"You thus have to declare even more methods to use the repetitions of the "
-"pattern and factorize your code. Another solution is to <i>parametrize</i> "
-"your functions to reuse the code you wrote previously by changing the size."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture3/MethodsPicture3.html:11 src/lessons/welcome/snake/Snake.html:46 src/lessons/welcome/traversal/column/TraversalByColumn.html:52 src/lessons/welcome/traversal/line/TraversalByLine.html:10 src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:10 src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:6
-msgid "Your turn..."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:2
-msgid "(and methods to write)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:4
-msgid ""
-"Here is yet another exercise where you have to reproduce the pattern "
-"provided in the \"Objective\" tab."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:7
-msgid ""
-"This one is a bit more difficult than the one seen previously. Look for "
-"repeating patterns, even if the color changes, and write a method drawing "
-"each of them."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/methods/picture4/MethodsPicture4.html:11
-msgid "Good luck!"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/bdr/BDR.html:1
-msgid "Buggle Dance Revolution (BDR)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:3
-msgid ""
-"Today is a great day: we will learn the buggles to play Dance Revolution, "
-"this game beloved of some students where the player has to move its feet on "
-"the carpet according to the instructions presented on the screen, and "
-"following the music. But before that, we have some details to study first."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/bdr/BDR.html:8
-msgid "Conditionals without curly braces"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:10
-msgid ""
-"There is one detail we omitted about the conditional syntax: if a branch "
-"contains only one instruction, then the curly braces become optional. So, "
-"the two chunk of code are equivalent:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:14
-#, no-wrap
-msgid ""
-"if (<b>condition</b>) {\n"
-"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
-"} else {\n"
-"    <b>whatToDoElse();</b>\n"
-"}"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:19
-#, no-wrap
-msgid ""
-"if (<b>condition</b>) \n"
-"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
-"else\n"
-"    <b>whatToDoElse();</b>"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:24
-msgid ""
-"But beware, this becomes dangerous if you chain the <tt>if</tt> instructions "
-"like this:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:26
-#, no-wrap
-msgid ""
-"if (isOverBaggle())    \n"
-"     if (x == 5)\n"
-"          turnLeft();\n"
-"else\n"
-"     turnRight();\n"
-"forward();"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:33
-msgid ""
-"In fact, it does not turn right when there is no baggle on the ground AND x "
-"equals 5, but when the buggle found a baggle on the ground and x equals "
-"anything but 5. Putting this otherwise, the buggle understands the previous "
-"code as if it were written the following way (note that the <tt>else</tt> "
-"were moved to the right):"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:38
-#, no-wrap
-msgid ""
-"if (isOverBaggle())    \n"
-"        if (x == 5)\n"
-"            turnLeft();\n"
-"        else\n"
-"            turnRight();\n"
-"forward();"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:45
-msgid ""
-"The first lesson of this is that the indentation is very helpful to help "
-"humans understanding, but it's of no importance for the actual meaning of "
-"the code. We could have written the following code and obtain the same "
-"result. But beware, if you want a human to read and review your code, you "
-"really want to indent it correctly. That's for example the case if you want "
-"a professor to read it (to grade it or to answer a question about it), or if "
-"you want to reuse your code later."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:53
-#, no-wrap
-msgid "if (isOverBaggle()) if (x == 5) turnLeft(); else turnRight(); forward();"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:55
-msgid ""
-"The second lesson is that a <tt>else</tt> branch always connects to the "
-"closest <tt>if</tt>. This may be a bit troublesome in some case, and it may "
-"be easier to add more braces than strictly needed to remove any ambiguity."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/welcome/bdr/BDR.html:59
-msgid "Chaining conditionals"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:61
-msgid "You sometimes want to ask the buggle something similar to:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:62
-#, no-wrap
-msgid ""
-"if it's raining, take an umbrella;\n"
-"if not, and if it's a hot day, take a bottle of water;\n"
-"if not and if it's July 4th, take an american flag"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:66
-msgid ""
-"The trap is that we want at most one of these actions to be taken. That is "
-"to say, if it's raining a very hot July 4th, we don't want the buggle to get "
-"outside with an umbrella, some water and a flag, but simply with an "
-"umbrella. The following code is thus WRONG."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:71
-#, no-wrap
-msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
-"}\n"
-"if (hot()) {\n"
-"    takeWater();\n"
-"} \n"
-"if (todayIsJuly4th()) {\n"
-"    takeFlag();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:81
-#, no-wrap
-msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
-"if hot():\n"
-"    takeWater()\n"
-"if todayIsJuly4th():\n"
-"    takeFlag()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:90
-msgid ""
-"Indeed, since the conditions are evaluated one after the other, there is a "
-"risk that you go to the July 4th march on a rainy day. Instead, we should "
-"use something like this:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:94
-#, no-wrap
-msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
-"} else {\n"
-"    if (hotDay()) {\n"
-"        takeWater();\n"
-"    } else {\n"
-"        if (todayIsJuly4th()) {\n"
-"            takeFlag();\n"
-"        }\n"
-"    }\n"
-"}"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:106
-#, no-wrap
-msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
-"else:\n"
-"    if hotDay():\n"
-"        takeWater()\n"
-"    else:\n"
-"        if todayIsJuly4th():\n"
-"            takeFlag()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:117
-msgid ""
-"Such a cascade of conditionals are quite difficult to read, and it is better "
-"to omit the curly braces for the <tt>else</tt> statements. Some languages "
-"even introduce a specific construct for these <tt>else if</tt> (but Java "
-"doesn't)."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/bdr/BDR.html:121
-#, no-wrap
-msgid ""
-"if (rainy()) {\n"
-"    takeUmbrella();\n"
-"} else if (hotDay()) {\n"
-"    takeWater();\n"
-"} else if (todayIsJuly4th()) {\n"
-"    takeFlag();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:129
-msgid ""
-"Such a cascade of conditionals are quite difficult to read, and it is better "
-"to omit extra indentation for the <tt>else</tt> statements. In Python, there "
-"is a specific construct for this: <tt>elif</tt>."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/bdr/BDR.html:132
-#, no-wrap
-msgid ""
-"if rainy():\n"
-"    takeUmbrella()\n"
-"elif hotDay():\n"
-"    takeWater()\n"
-"elif todayIsJuly4th():\n"
-"    takeFlag()\n"
-msgstr ""
-
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/bdr/BDR.html:140
-msgid "Graffitis in the Buggle World"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR.html:142
-msgid ""
-"Buggles can write graffitis on the ground of their world. For that, they use "
-"the four following methods:"
-msgstr ""
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:146
-msgid ""
-"<code>boolean isOverMessage()</code>: returns <code>true</code> if and only "
-"if there is a message on the ground."
-msgstr ""
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:148
-msgid ""
-"<code>boolean isOverMessage()</code>: returns <code>True</code> if and only "
-"if there is a message on the ground."
-msgstr ""
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:150
-msgid ""
-"<code>String readMessage()</code>: returns the message written on the ground "
-"(or an empty string if nothing is written)."
-msgstr ""
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:152
-msgid ""
-"<code>void writeMessage(String msg)</code>: writes the specified message "
-"down on the ground. If there is already a message on the ground, the new "
-"content is added at the end of the existing message."
-msgstr ""
-
-#. type: Content of: <p><ul><li>
-#: src/lessons/welcome/bdr/BDR.html:155
-msgid "<code>void clearMessage()</code>: clears what is written on the ground."
-msgstr ""
-
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:159
-msgid ""
-"<a name=\"Objectives\">The goal is then to organize a BDR game between the "
-"buggles by learning them to move according to the instructions written on "
-"the ground. These instructions are messages written on the ground, with the "
-"following signification:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:127
-msgid "Message"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:166 src/lessons/welcome/bdr/BDR2.html:128
-msgid "What to do"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:167
-msgid "Mnemonic"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:130 src/lessons/turmites/turmitecreator/TurmiteCreator.html:30 src/lessons/turmites/turmitecreator/TurmiteCreator.html:33
-msgid "R"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:130
-msgid "Turn right and move one step forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:169
-msgid "Right"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:131
-msgid "L"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:131
-msgid "Turn left and move one step forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:170
-msgid "Left"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171 src/lessons/welcome/bdr/BDR2.html:132
-msgid "I"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171
-msgid "Turn back (U-turn) and move one step forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:171
-msgid "Inverse"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173 src/lessons/welcome/bdr/BDR2.html:134
-msgid "A"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173 src/lessons/welcome/bdr/BDR2.html:134
-msgid "Move one step forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:173
-msgid "First letter of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174 src/lessons/welcome/bdr/BDR2.html:135
-msgid "B"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174 src/lessons/welcome/bdr/BDR2.html:135
-msgid "Move two steps forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:174
-msgid "Second letter of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175 src/lessons/welcome/bdr/BDR2.html:136
-msgid "C"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175 src/lessons/welcome/bdr/BDR2.html:136
-msgid "Move three steps forward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:175
-msgid "Third letter of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177 src/lessons/welcome/bdr/BDR2.html:141
-msgid "Z"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177 src/lessons/welcome/bdr/BDR2.html:141
-msgid "Move one step backward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:177
-msgid "One letter before the end of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178 src/lessons/welcome/bdr/BDR2.html:142
-msgid "Y"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178 src/lessons/welcome/bdr/BDR2.html:142
-msgid "Move two steps backward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:178
-msgid "Two letters before the end of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179 src/lessons/welcome/bdr/BDR2.html:143
-msgid "X"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179 src/lessons/welcome/bdr/BDR2.html:143
-msgid "Move three steps backward"
-msgstr ""
-
-#. type: Content of: <p><a><table><tr><td>
-#: src/lessons/welcome/bdr/BDR.html:179
-msgid "Three letters before the end of the alphabet"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><p>
-#: src/lessons/welcome/bdr/BDR.html:182 src/lessons/welcome/bdr/BDR2.html:149
-msgid "In any other case, you should stop"
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:184
-msgid ""
-"Write the code of the dance in the <code>run()</code> method which prototype "
-"is already in the editor."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:187
-msgid "Write the code of the dance directly in the editor, out of any function."
-msgstr ""
-
-#. type: Content of: <p><a><h3>
-#: src/lessons/welcome/bdr/BDR.html:190
-msgid "Indications"
-msgstr ""
-
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:192
-msgid ""
-"This exercise may seem a bit complex at the first glance, but it comes down "
-"to summarizing the information above in a sequence of conditionals."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:197
-msgid ""
-"The first subtlety is that we use the <code>char getIndication()</code> "
-"instead of <code>String readMessage()</code>. This method, only known by the "
-"buggles of this exercise, return the first char of the message written on "
-"the ground (or ' ' if nothing is written down)."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:202
-msgid ""
-"The other subtlety is to keep working as long as there is some work to do, "
-"i.e., as long as we did not find a cell which content is not described in "
-"the table. The easier for that is to use a boolean variable "
-"(<code>finished</code>)  that is initialized to <code>false</code> as "
-"termination condition for the loop.  As soon as the buggle find a cell with "
-"a value not described in the table, the boolean variable is set to "
-"<code>false</code>.  Thus the loop, will stop and the program will "
-"terminate."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:209
-msgid ""
-"The other subtlety is to keep working as long as there is some work to do, "
-"i.e., as long as we did not find a cell which content is not described in "
-"the table. The easier for that is to use a boolean variable "
-"(<code>finished</code>)  that is initialized to <code>False</code> as "
-"termination condition for the loop.  As soon as the buggle find a cell with "
-"a value not described in the table, the boolean variable is set to "
-"<code>False</code>.  Thus the loop, will stop and the program will "
-"terminate."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:217
-msgid ""
-"The functions having <code>void</code> as return type can contain some "
-"<tt>return</tt> without any associated value. It interrupts immediately "
-"their execution."
-msgstr ""
-
-#. type: Content of: <p><a><h3>
-#: src/lessons/welcome/bdr/BDR.html:221
-msgid "Tips and Hints"
-msgstr ""
-
-#. type: Content of: <p><a>
-#: src/lessons/welcome/bdr/BDR.html:223
-msgid ""
-"If you fail understanding why the buggle does not execute the expected "
-"steps, try adding <code>brushDown()</code> in your method. This asks the "
-"buggle to put down a brush leaving a trail when it moves. It should help you "
-"understanding its trajectory, but do not forget to remove this call when you "
-"want to test whether your code is a valid solution to the exercise: you are "
-"asked to let the buggle dance, not to vandalize the dance floor."
-msgstr ""
-
-#. type: Content of: <p><a><p>
-#: src/lessons/welcome/bdr/BDR.html:230
-msgid "When your program finally works, move on to the next exercise."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/bdr/BDR2.html:1
-msgid "Buggle Dance Revolution 2 (BDR2)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bdr/BDR2.html:3
-msgid ""
-"BDR is cool, but it's a bit chaotic. First, the buggles giggle in any "
-"directions, and then the code you had to write to let them move is rather "
-"difficult to read. Here is a new BDR world where the buggle will dance a "
-"gentle circle. We will benefit this tranquillity to clean up a bit our code "
-"thanks to the new constructs we will introduce."
-msgstr ""
-
-#. type: Content of: <p><h3>
-#: src/lessons/welcome/bdr/BDR2.html:9
-msgid "<tt>switch</tt> conditionals"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/bdr/BDR2.html:12
-msgid ""
-"The hardest part of previous code is certainly the conditional "
-"cascading. Somewhere in your code, you certainly had something similar to:"
-msgstr ""
-
-#. type: Content of: <p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:15
-#, no-wrap
-msgid ""
-"if (getIndication() == 'R') {\n"
-"  turnRight();\n"
-"  forward();\n"
-"} else if (getIndication() == 'L') {\n"
-"  turnLeft();\n"
-"  forward();\n"
-"} else if (getIndication() == 'I') {\n"
-"  turnBack();\n"
-"  forward();\n"
-"/* other else if */\n"
-"} else {\n"
-"  return;\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:31
-msgid ""
-"When you review this code, it may not be clear at the first glance that it "
-"is simply a choice with 4 branches depending on the value of "
-"getIndication(). To improve this, we will use a <code>switch</code> "
-"construct, which Java syntax is the following:"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:37
-#, no-wrap
-msgid ""
-"switch (<b>expression</b>) {\n"
-"  case <b>firstValue</b>: \n"
-"    <b>whatToDoIfExpressionEqualsFirstValue();</b>\n"
-"    break;\n"
-"  case <b>secondValue</b>: \n"
-"    <b>whatToDoIfExpressionEqualsSecondValue();</b>\n"
-"    break;\n"
-"  case <b>thirdValue</b>: \n"
-"    <b>whatToDoIfExpressionEqualsThirdValue();</b>\n"
-"    break;\n"
-"    /* as much similar cases as you want */\n"
-"  default: \n"
-"    <b>whatToDoIfExpressionDoesNotEqualsAnySeenValues();</b>\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:53
-msgid ""
-"Observe that each branch of a <tt>switch</tt> must be ended by a "
-"<code>break</code>. If you forget this, the machine keeps going and execute "
-"the next branch in the list after the branch it jumped to. There is even "
-"some <b>rare</b> cases where this behavior reveals helpful."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:58
-msgid ""
-"It is then possible to rewrite previous BDR code in a cleaner way using the "
-"<tt>switch</tt> construct:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:61
-#, no-wrap
-msgid ""
-"switch (getIndication()) {\n"
-"  case 'R':\n"
-"    turnRight(); \n"
-"    forward(); \n"
-"    break;\n"
-"  case 'L':\n"
-"    turnLeft();\n"
-"    forward(); \n"
-"    break;\n"
-"  case 'U':\n"
-"    turnBack();\n"
-"    forward();\n"
-"    break;\n"
-"  default: \n"
-"    return;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><h2>
-#: src/lessons/welcome/bdr/BDR2.html:79
-msgid "Variables shared between methods"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:82
-msgid ""
-"Another issue in your code is that it begins to be a bit long to be written "
-"as a single method. We would like to split it up in two methods:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ul><li>
-#: src/lessons/welcome/bdr/BDR2.html:85
-msgid "<code>danceOneStep()</code> would take care of achieving a single dance step"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><ul><li>
-#: src/lessons/welcome/bdr/BDR2.html:86
-msgid ""
-"<code>run()</code> would take care of the dance as a whole. It would do the "
-"steps while we didn't encounter a cell not asking any further move."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:90
-msgid ""
-"The difficulty is to make sure that <tt>danceOneStep()</tt> keeps "
-"<tt>run()</tt> informed that there is no further dance step to achieve. The "
-"simpler solution is to have a boolean function visible from both methods "
-"indicating whether there is more steps to do or if we're done. For that, we "
-"have to write out the following of any method:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:95
-#, no-wrap
-msgid "boolean moreMusic = true;"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:97
-msgid ""
-"Note that it is possible to write variable declarations out of any methods, "
-"but that instructions must be in a method. In Java such <i>global</i> "
-"variables are called <b>fields</b>."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:101
-msgid ""
-"Then, the <tt>danceOneStep()</tt> must be changed to update this variable to "
-"<tt>false</tt> when there is nothing more to do. For that, simply add "
-"<code>moreMusic = false;</code> before any <tt>return</tt>."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:105
-msgid "It is then possible to use the following <tt>run()</tt> method:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><pre>
-#: src/lessons/welcome/bdr/BDR2.html:106
-#, no-wrap
-msgid ""
-"public void run() {\n"
-"  while (moreMusic)\n"
-"    danseOneStep();\n"
-"}"
-msgstr ""
-
-#. type: Content of: <a>
-#: src/lessons/welcome/bdr/BDR2.html:111 src/lessons/maze/randommouse/RandomMouseMaze.html:24
-msgid "<a name=\"Objectives\">"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:112
-msgid "Apply the improvement we just saw to rewrite your buggle code."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:114
-msgid ""
-"You don't have to write the <tt>run()</tt> method since the buggle already "
-"know it. If you put it anyway, the compiler will complain about this "
-"multiple definition without noticing that both declarations match. Simply "
-"declare the variable <tt>moreMusic</tt> and the <tt>danceOneStep()</tt> "
-"method."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:120
-msgid ""
-"This dance step is slightly more complex but actually better looking. Beside "
-"of that, that's the same old story."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p>
-#: src/lessons/welcome/bdr/BDR2.html:123
-msgid ""
-"Here are the ground indications to use for BDR2. Note that we can now move a "
-"buggle up to 6 cells in one dance step."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:132
-msgid "Turn back and move one step forward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:137
-msgid "D"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:137
-msgid "Move four cells forward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:138
-msgid "E"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:138
-msgid "Move five cells forward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:139
-msgid "F"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:139
-msgid "Move six cells forward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:144
-msgid "W"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:144
-msgid "Move four cells backward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:145
-msgid "V"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:145
-msgid "Move five cells backward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:146
-msgid "U"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><table><tr><td>
-#: src/lessons/welcome/bdr/BDR2.html:146
-msgid "Move six cells backward"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p><p><p><a><p><p>
-#: src/lessons/welcome/bdr/BDR2.html:151
-msgid "When you program works again, proceed to next exercise."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:3
-msgid ""
-"Now that your <code>isFacingTrail()</code> method is working, it's time to "
-"write the code to organize the hunting party. Copy/paste your code from the "
-"previous exercise, and complete the <code>hunt()</code> method."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:7
-msgid ""
-"Following a track is not very difficult: move forward as long as you have "
-"the track in front of you.  If there is not track in front of you anymore, "
-"check if the rest of the track is on your left or on your right, and follow "
-"it further."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:11
-msgid ""
-"To ensure that you don't mix the track you come from with the one in front "
-"of you, the easier is to erase the track when you follow it. Use the method "
-"<code>brushDown()</code> to put your brush down and mark the ground, and "
-"<code>brushUp()</code> to move it up again."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugHunting.html:15
-msgid ""
-"Finally, do not forget to capture your prey once you found it (using "
-"<code>pickupBaggle()</code>)."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/slug/SlugHunting.html:19
-msgid ""
-"<a name=\"Objectives\"> Complete the <code>hunt()</code> method. You "
-"probably want to copy over the <code>isFacingTrail()</code> method that you "
-"wrote in previous exercise.  </a>"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:3
-msgid ""
-"Your buggle is super happy! It just found the green dribbling trail, "
-"certainly left by a big yummy slug.  At its end, the buggle is certain to "
-"entertain itself with this appetizing slug (represented as a baggle)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:7
-msgid ""
-"To reach that goal, you had to write a boolean method "
-"<tt>isFacingTrail</tt>, which determines whether we are facing a green cell "
-"or not. Of course, if we are facing a wall, it should return false without "
-"bumping into it. You should make sure that this method has no <b>side "
-"effect</b>, i.e. that it does not change the state of the calling buggle nor "
-"of its world."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:12
-msgid ""
-"Your tool to that end is the <code>getGroundColor()</code> that returns the "
-"color of the current cell. Just go to the cell you want to test and run that "
-"function. You cannot test whether this color is equal to "
-"<code>Color.green</code> with an <code>==</code> sign but instead you have "
-"to write something like "
-"<code>getGroundColor().equals(Color.green)</code>. This is because green is "
-"an <i>object</i> in Java, and <code>.equals()</code> is the way to go to "
-"test equality between Java objects."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:18
-msgid ""
-"Your tool to that end is the <code>getGroundColor()</code> that returns the "
-"color of the current cell. Just go to the cell you want to test and run that "
-"function."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugTracking.html:22
-msgid ""
-"Complete the <code>isFacingTrail()</code> method (which gets called "
-"automatically)."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/slug/SlugSnail.html:1
-msgid "Slugs and Snails"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugSnail.html:3
-msgid ""
-"Yuhu! This time, your buggle found the tracks of much more preys! In the "
-"first world, that's a yummy Kitty Slug (leaving a pink trail) while on the "
-"second world, that's a big fat snail that awaits your buggle at the end of "
-"the orange trail."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/slug/SlugSnail.html:7
-msgid ""
-"You have to copy/paste your code again, and change it so that your methods "
-"take the color of the trail to follow as a parameter. Beside of this, your "
-"code should work as earlier."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:3
-msgid ""
-"We will now teach the buggle to explore its world. Its initial position is "
-"the bottom left corner, and it should visit any cells up to the top "
-"(coloring the ground on its path. The main loop of the <code>run()</code> "
-"method (that you should write) is something like:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:8
-#, no-wrap
-msgid ""
-" move brush down\n"
-" while we did not reach the final position\n"
-"   move like a snake\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:13
-msgid "The prototype of this method (its first line) must be:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:14
-#, no-wrap
-msgid "public void run()"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:15
-msgid ""
-"(we will come back later on the meaning of <code>public</code>). We thus "
-"have to write two methods in addition to <code>run()</code>. The former "
-"returns a boolean indicating whether we are on a final position while the "
-"latter does not return any result and move one snake step forward."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:20
-msgid "We reached the final position if and only if both conditions are true:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:22
-msgid "We are facing a wall"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:23
-msgid ""
-"There is a wall on the north of the buggle. So, if the buggle is facing "
-"east, you should check whether there is a wall on the left, and if the "
-"buggle is facing west, you should check on the right side."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:26
-msgid ""
-"We can get the current heading of the buggle using the "
-"<code>getDirection()</code>, and we know whether it looks east using "
-"<code>getDirection() == Direction.EAST</code> (WEST for west)."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/welcome/snake/Snake.html:29
-msgid ""
-"For the checking itself, nothing magical: you have to turn the buggle and "
-"check whether it is facing a wall afterward."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:33
-msgid ""
-"Then, a snake step can be achieved by moving one step forward if we are not "
-"facing a wall, and moving to the upper line else (ie, if you look to the "
-"west facing a wall, you have to turn right, forward and turn right)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:37
-msgid ""
-"Hint: the main loop of the <code>run()</code> method must continue while the "
-"testing function returns false. Their is thus two way of writing it:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:39
-#, no-wrap
-msgid "while (testingFunction() == false)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:40
-#, no-wrap
-msgid "while testingFunction() == False:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:41
-msgid "or"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:42
-#, no-wrap
-msgid "while (! testingFunction())"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/welcome/snake/Snake.html:43
-#, no-wrap
-msgid "while not testingFunction():"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/snake/Snake.html:44
-msgid "It works because the exclamation mark (!) means in Java a boolean negation."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:3
-msgid ""
-"The goal of this serie of exercises is to let the buggle traverse its "
-"world. It must number the cells it walks on to show its traversal order."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:6
-msgid ""
-"The main loop of the <code>run()</code> method (that you must write) is "
-"something like:"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:8
-msgid "The main loop of your code should be something like:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><pre>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:10
-#, no-wrap
-msgid ""
-" while we are not on the final position\n"
-"   go to the next position\n"
-"   label the cell with its number\n"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:15
-msgid ""
-"In contrary to the exercises we saw so far, we won't use the "
-"<code>forward()</code>, <code>backward()</code> and similar "
-"methods. Instead, we will compute the coordinate of the next buggle position "
-"and use the <code>setPos(x, y)</code> method to <i>teleport</i> the buggle "
-"directly to this position. For example, <code>setPos(3, 5)</code> teleports "
-"the buggle to the cell where x=3 and y=5."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:22
-msgid ""
-"Your first task is thus to write a boolean function indicating whether the "
-"buggle the final position or not, ie if it reached the bottom right corner "
-"of the world. For this, you can use <code>getWorldWidth()</code> and "
-"<code>getWorldHeight()</code> which return respectively the world's width "
-"and height. Your test is about comparing the buggle's current position (that "
-"you can access with <code>getX()</code> and <code>getY()</code>) to the "
-"world dimensions."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:29
-msgid "Beware, the first line and column are numbered 0 and not 1..."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:31
-msgid ""
-"Then, you have to write the code to reach the next position. In this "
-"exercise, you have to traverse the world row after row. So, if you are at "
-"the bottom of a row, you have to move to the top of next row, and you have "
-"to move to the cell below else."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:36
-msgid ""
-"At this point, you can launch your program to check that the buggle "
-"correctly traverse the world in the expected order, and that it stops when "
-"it has to. Use the <b>stop</b> button if the buggle does not stop correctly."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:40
-msgid ""
-"It is now time to write done the cell numbers. For that, you will need a "
-"counter initialiser to zero at the begining of your <code>run()</code> "
-"method, and incremented by one at each step (for example with <code>counter "
-"+= 1;</code>). Then, you have to write the value on the ground, for example "
-"with <code>writeMessage(counter);</code>."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:46
-msgid ""
-"You probably need to write the first or last value out of the main loop, "
-"depending on whether you prefer to use a <code>while {}</code> or a <code>do "
-"{} while</code>..."
-msgstr ""
-
-#. type: Content of: <p><p><p><p><p><p>
-#: src/lessons/welcome/traversal/column/TraversalByColumn.html:50
-msgid ""
-"You may want to write the first value out of the main <code>while "
-"...:</code> loop."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/traversal/line/TraversalByLine.html:3
-msgid ""
-"You once again have to let the buggle traverse the world numbering the cells "
-"on its way, but the goal of this exercise is to write a line traversal. Most "
-"of the code you wrote for previous exercise remains usable here. Simply, the "
-"method computing the coordinates of the next buggle position has to be "
-"correctly updated: if you are at the right of a line, you have to go to the "
-"begining of the next one. If not, you have to go to the right cell."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:3
-msgid ""
-"This time, you are asked to traverse the world one diagonal after the "
-"other. Have a look at the objective world for more details on the requested "
-"traversal order."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:7
-msgid ""
-"You may find useful to use an integer variable <code>diag</code> storing the "
-"number of the diagonal you are traversing."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:3
-msgid ""
-"This time, you have to zigzag on the way up. Have a look at the objective "
-"world for more details on the requested traversal order."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/turmites/Main.html:1 src/lessons/turmites/short_desc.html:1
-msgid "The turmites"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/Main.html:3
-msgid ""
-"This set of activities lets you play with Langton's ants, that are 2D turing "
-"machines. They constitute very simple application problems, achievable by "
-"beginners, and open the door to an amazing world."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/Main.html:7
-msgid ""
-"This mechanism were invented in 1986 by Chris Langton, and later generalized "
-"in several ways (as we shall see in the next exercises). It was proven in "
-"2000 that the ant's trajectory can be used to compute any boolean circuit, "
-"and thus that the ant is capable of universal computation (ie, any possible "
-"computation can be achieved using the ant as a computing device). Yet "
-"another subject of fascination..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/Main.html:13
-msgid ""
-"Multicolor Langton's ants were discovered in 1995 by Propp et Al. Another "
-"funny fact is that the ants which name is a list of consecutive pair of "
-"identical letters (LL and RR) produce symmetric patterns. This fact was even "
-"formally proved."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/Main.html:18
-msgid ""
-"Check the corresponding wikipedia web page, of which this exercise is "
-"inspired, for further details."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/turmites/Main.html:21 src/lessons/sort/pancake/Main.html:29 src/lessons/sort/baseball/Main.html:27
-msgid "What can I do to improve this JLM universe?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/Main.html:23 src/lessons/sort/pancake/Main.html:31 src/lessons/sort/baseball/Main.html:29
-msgid ""
-"As usual, there are several things that could be done in the code of this "
-"universe to improve it:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/Main.html:25
-msgid ""
-"We are probably missing some good exercises. The turmite creator exercise is "
-"a bit harsh: we could introduce the patterns in a more friendly manner."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/Main.html:27
-msgid "We may want to write an exercise on the busy beaver, maybe?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/short_desc.html:2
-msgid "Discover the Langton's ants, that are 2D turing machines."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/short_desc.html:4
-msgid ""
-"These activities are very simple application problems, achievable by "
-"beginners, and open the door to an amazing world."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/langton/Langton.html:1
-msgid "Langton's ant"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:3
-msgid ""
-"In this exercise, you will turn your buggle into a <i>Langton's "
-"ant</i>. These artificial little animals are very interesting because they "
-"are given simple rules that depend only on their local environment, and "
-"after a period of apparent chaotic behavior, a general pattern "
-"<i>emerges</i>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:8
-msgid ""
-"The rules are absolutely trivial: to compute what the next step should be, "
-"you should check the current color of the ground (using "
-"<code>getGroundColor()</code>). If it's white, change it to black, turn "
-"right and move forward by one cell. If the ground is currently black, change "
-"it to white, turn left and move forward by one cell."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:14
-msgid ""
-"It's hard to come up with simpler rules isn't it? Well, let's go and code it "
-"now. You have to complete the <code>step()</code> method, which encodes the "
-"behavior of the ant at each step. You will probably use the "
-"<code>getGroundColor()</code> method to retrieve the color of the cell on "
-"which the ant is currently.  Colors of interest are simply named "
-"<code>Color.black</code> and <code>Color.white</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:20
-msgid ""
-"To compare colors, you cannot use the equal sign (=), because these things "
-"are not scalar values but objects. Instead, you need to write something like "
-"the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/langton/Langton.html:24
-#, no-wrap
-msgid ""
-"Color c /* = some initialization */;\n"
-"if (c.equals(Color.black)) {\n"
-"  /* that's equal */\n"
-"} else {\n"
-"  /* that was not equal */\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:32
-msgid ""
-"Changing the ground color is not difficult, but a bit long: you have to "
-"change the brush color of your buggle, set the brush down (to mark the "
-"current cell -- with <code>brushDown()</code>), and set the brush back up "
-"(with <code>brushUp()</code>) to avoid further issues when the buggle will "
-"move. You are naturally free of organizing your code the way you want, but "
-"you may want to write a <code>setGroundColor(color)</code> method to "
-"factorize things a bit."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langton/Langton.html:39
-msgid ""
-"As you can see from the execution of this exercise, the interest in this "
-"algorithm is that after about 10000 steps of relative chaotic behavior, the "
-"ant start building a regular pattern. This emergence of a regular pattern "
-"from the chaos is rather fascinating, isn't it? Move on to the next exercise "
-"to see more of them."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:1
-msgid "Multicolor Langton's ant"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:3
-msgid ""
-"There is several ways to extend the concept of Langton's ant. In this "
-"exercise, we explore first one, using more than two colors. It remains very "
-"similar to the base case: the behavior at each step still depends on the "
-"ground color, but you have more than 2 possibilities. It allows to have more "
-"than one kind of ant, depending on what you decide to do for each color. For "
-"example, the ant LRL takes 3 colors. It turns left on the first color, right "
-"on the second one and left on the third color. According to this definition, "
-"the basic ant is a RL (since it turns right on white cells and left on black "
-"ones)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:12
-msgid ""
-"Some of these ants draw fascinating patterns (switch the world to see them): "
-"LLRR build a symmetric figure resembling loosely to a ball, LRRRRRLLR draws "
-"a square, LLRRRLRLRLLR draws a convoluted regular pattern after a period of "
-"seemingly chaotic behavior, and RRLLLRLLLRRR seems to fill a hour glass..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:17
-msgid ""
-"Changing your buggle into a generic Langton's ant is not very complicated, "
-"although it is not completely trivial. As previously, you have to write a "
-"<code>step</code> function. But this time, it receives two arrays as "
-"parameters.  The first one defines the rules to follow depending on the "
-"ground color while the second one gives the sequence of colors to use. For "
-"example, the basic ant would have <code>{'R', 'L'}</code> and "
-"<code>{Color.white, Color.black}</code> as arguments."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:24
-msgid ""
-"Changing your buggle into a generic Langton's ant is not very complicated, "
-"although it is not completely trivial. As previously, you have to write a "
-"<code>step</code> function. But this time, it receives two arrays as "
-"parameters.  The first one defines the rules to follow depending on the "
-"ground color while the second one gives the sequence of colors to use. For "
-"example, the basic ant would have <code>['R', 'L']</code> and "
-"<code>[Color.white, Color.black]</code> as arguments."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:31
-msgid "At each step, you thus have to apply the following pseudo-code:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:33
-msgid "Find the position of the ground color in the color sequence;"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:34
-msgid ""
-"Turn left or right depending on the content of the rule array at that "
-"position;"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:35
-msgid ""
-"Mark the current ground with the next color in the sequence (the last color "
-"being followed by the first one);"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:36
-msgid "Move forward by one step."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/langtoncolors/LangtonColors.html:39 src/lessons/turmites/helloturmite/HelloTurmite.html:70
-msgid "You now should have enough information to succeed."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:1
-msgid "Turmites"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:3
-msgid ""
-"This exercise explores a new way to extend the concept of Langton's "
-"ant. Now, the behavior of the ant not only depends on the color on the "
-"ground, but also on its internal state (represented by an integer "
-"value). The idea of changing the ant into such an automata naturally comes "
-"from the Turing machine concept. This explains the name of these new "
-"animals, which is a portemanteau of <i>Turing</i> and <i>Termite</i> (if you "
-"don't know what a Turing machine is, you should run to wikipedia, because it "
-"is simply impossible to be a real computer scientist before that)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:12
-msgid ""
-"Once again, you just have to write the <code>step()</code> method, in charge "
-"of doing one turmite's step. Once again, you should first find the rank of "
-"the current's cell ground color in the color sequence. But this time, the "
-"<code>rule</code> data depends both on the current color and the current "
-"state.  <code>rule</code> actually contains 3 information in each situation: "
-"the color to write, the move to do, and the next state value. For example, "
-"rule[1][0] contains the informations to use when <code>state==1</code> and "
-"<code>color==0</code>. In other worlds, you can retrieve the information "
-"relative to your current situation by using "
-"<code>rule[state][currentColor]</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:22
-msgid ""
-"Each such information set contains 3 values. The first one is the rank of "
-"the color to write on the ground. The second is the move to do, with the "
-"following notation: 0=stop, 1=noturn, 2=right, 4=u-turn, 8=left. Note that "
-"if the command is stop, you shouldn't even move forward on that step (but "
-"you shouldn't stop your program either: the next steps can do something else "
-"in a future state). Finally, the third integer is the next "
-"<code>state</code> value to go into after this iteration."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:29
-msgid ""
-"Since these arbitrary notations are somehow difficult to remember, the "
-"template code defines a set of constants that you should use instead of the "
-"direct numerical values. Their names are NOTURN, LEFT, RIGHT and so on. The "
-"modifiers <code>final static</code> before their type is the way to mark "
-"variables as constant in Java (sorry if the notation seems complex). Using "
-"such constants greatly help making the code easier to read. This allows to "
-"write things this way:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:35
-msgid ""
-"Since these arbitrary notations are somehow difficult to remember, the "
-"template code defines a set of constants that you should use instead of the "
-"direct numerical values. Their names are NOTURN, LEFT, RIGHT and so on. By "
-"convention, such constant variables are written in upper case in "
-"python. Technically, you can still modify them, but that would be a very bad "
-"idea. Using such constants greatly help making the code easier to read, as "
-"it allows to write things this way:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:42
-#, no-wrap
-msgid ""
-"  if (rule[state][currentColor][NEXT_MOVE] == LEFT) {\n"
-"    turnLeft();\n"
-"  }\n"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:47
-#, no-wrap
-msgid ""
-"  if rule[state][currentColor][NEXT_MOVE] == LEFT:\n"
-"    turnLeft()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:50
-msgid "This is much more easier to read than the following way:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:52
-#, no-wrap
-msgid ""
-"  if (rule[x][y][1] == 2) {\n"
-"    turnLeft();\n"
-"  }\n"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:57
-#, no-wrap
-msgid ""
-"  if rule[x][y][1] == 2:\n"
-"    turnLeft()\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:61
-msgid ""
-"Finally, you probably want to write a <code>elif</code> branch for the "
-"<code>STOP</code> condition too. Having a <code>else</code> branch "
-"displaying an error message such as \"unknown case\" is a good practice: it "
-"makes your assumptions about your code more explicit, and you will get an "
-"error message if they fall short. When doing so, the next problem is that "
-"you have nothing to do in the <code>STOP</code> case, but python do not "
-"allows you to write empty <code>elif</code> branches. You should use the "
-"<code>pass</code> instruction as a placeholder: it says python that you have "
-"a branch here, and that it does not contain anything."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:72
-msgid "Bibliographical notes"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/helloturmite/HelloTurmite.html:73
-msgid ""
-"According to wikipedia, turmites were invented independently by the end of "
-"the eighties. It has been shown that turmites in general are exactly "
-"equivalent in power to one-dimensional Turing machines with an infinite "
-"tape, as either can simulate the other. This means that absolutely any "
-"program that you can think of could theoretically be computed on this "
-"device..."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:1
-msgid "Creating Turmites"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:3
-msgid ""
-"This exercise allows you to build your own turmites. To pass the exercise, "
-"you should simply write a <code>init()</code> method which initializes the "
-"<code>rule</code> to use the following transitions table (from wikipedia), "
-"set the buggle initial position at (8;33), and ask for 8342 steps."
-msgstr ""
-
-#. type: Content of: <table><tr><th>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:10
-msgid "Current color"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:13 src/lessons/turmites/turmitecreator/TurmiteCreator.html:28 src/lessons/turmites/turmitecreator/TurmiteCreator.html:31 src/lessons/turmites/turmitecreator/TurmiteCreator.html:39 src/lessons/turmites/turmitecreator/TurmiteCreator.html:41 src/lessons/turmites/turmitecreator/TurmiteCreator.html:42
-msgid "0"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:14 src/lessons/turmites/turmitecreator/TurmiteCreator.html:29 src/lessons/turmites/turmitecreator/TurmiteCreator.html:32 src/lessons/turmites/turmitecreator/TurmiteCreator.html:34 src/lessons/turmites/turmitecreator/TurmiteCreator.html:37 src/lessons/turmites/turmitecreator/TurmiteCreator.html:44
-msgid "1"
-msgstr ""
-
-#. type: Content of: <table><tr><th>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:18 src/lessons/turmites/turmitecreator/TurmiteCreator.html:21
-msgid "Write color"
-msgstr ""
-
-#. type: Content of: <table><tr><th>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:19 src/lessons/turmites/turmitecreator/TurmiteCreator.html:22
-msgid "Turn"
-msgstr ""
-
-#. type: Content of: <table><tr><th>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:20 src/lessons/turmites/turmitecreator/TurmiteCreator.html:23
-msgid "Next state"
-msgstr ""
-
-#. type: Content of: <table><tr><th>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:26
-msgid "Current state"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:40 src/lessons/turmites/turmitecreator/TurmiteCreator.html:43
-msgid "N"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:48
-msgid ""
-"where the direction to turn is one of <b>L</b> (90° left), <b>R</b> (90° "
-"right), <b>N</b> (no turn) and <b>U</b> (180° U-turn)."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:50
-msgid "Going further"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:51
-msgid ""
-"This exercise is naturally an excuse to let you experiment with your own "
-"turmites.  Feel free to change the transition table and the amount of steps "
-"to experiment by yourself. To that extend, you may find the Ed Pegg Jr's "
-"library useful. If you find new interesting patterns, send them per email so "
-"that we can integrate them to this list!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:57
-msgid ""
-"In addition, wikipedia is desperately missing some good looking colorful "
-"turmites: only black and white ones are depicted.  You should consider "
-"submitting your creations directly to the free encyclopedia."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:62
-msgid ""
-"Here are some 2-color turmites, extracted from "
-"http://demonstrations.wolfram.com/Turmites/ They are not written using the "
-"python syntax, but converting them should be easy."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:64
-msgid ""
-"Here are some 2-color turmites, extracted from "
-"http://demonstrations.wolfram.com/Turmites/"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:67
-#, no-wrap
-msgid ""
-"{{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant\n"
-"{{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: binary counter\n"
-"{{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: "
-"(filled triangle)\n"
-"{{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: "
-"spiral in a box\n"
-"{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: "
-"stripe-filled spiral\n"
-"{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: "
-"stepped pyramid\n"
-"{{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: "
-"contoured island\n"
-"{{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: "
-"woven placemat\n"
-"{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: "
-"snowflake-ish\n"
-"{{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: "
-"slow city builder\n"
-"{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: "
-"framed computer art\n"
-"{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: "
-"balloon bursting (makes a spreading highway)\n"
-"{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: "
-"makes a horizontal highway\n"
-"{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: "
-"makes a 45 degree highway\n"
-"{{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: "
-"makes a 45 degree highway\n"
-"{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: "
-"spiral in a filled box\n"
-"{{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: "
-"glaciers\n"
-"{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: "
-"golden rectangle!\n"
-"{{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: "
-"fizzy spill\n"
-"{{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: "
-"nested cabinets\n"
-"{{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: "
-"(cross)\n"
-"{{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: "
-"saw-tipped growth\n"
-"{{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: "
-"curves in blocks growth\n"
-"{{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: "
-"textured growth\n"
-"{{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: "
-"(diamond growth)\n"
-"{{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: "
-"coiled rope\n"
-"{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: "
-"(growth)\n"
-"{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: "
-"(square spiral)\n"
-"{{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: "
-"loopy growth with holes\n"
-"{{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: "
-"Lanton's Ant drawn with squares\n"
-"{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: "
-"growth with curves and blocks\n"
-"{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: "
-"distracted spiral builder\n"
-"{{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: "
-"cauliflower stalk (45 deg highway)\n"
-"{{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: "
-"worm trails (eventually turns cyclic!)\n"
-"{{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: "
-"eventually makes a two-way highway!\n"
-"{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: "
-"almost symmetric mould bloom\n"
-"{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: "
-"makes a 1 in 2 gradient highway\n"
-"{{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: "
-"immediately makes a 1 in 3 highway\n"
-"{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, "
-"RIGHT , 2}, {1, LEFT  , 0}}} # 39: squares and diagonals growth\n"
-"{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, "
-"RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient\n"
-"{{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, "
-"RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient\n"
-"{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, "
-"LEFT  , 1}, {1, NOTURN, 1}}} # 42: maze-like growth\n"
-"{{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, "
-"LEFT  , 0}, {0, LEFT  , 1}}} # 43: growth by cornices \n"
-"{{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, "
-"NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway\n"
-"{{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, "
-"LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:114
-msgid ""
-"Langton's ants may not share the expressiveness power of the turmites, but "
-"they remain fascinating too. You can experiment with them using the "
-"initLangton() method, provided in your template, that allows to build a "
-"Turmite transition table from a Langton's ant name. Tiny changes in the ant "
-"may result huge changes. For example, \"RRL\" does not seem to lead to any "
-"constructed pattern, even after a million steps, but \"RLL\" starts building "
-"a very simple highway pattern after less than 100 steps!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:121
-msgid ""
-"Quite a lot of Langton's ants build highways: RL, of course, but also "
-"RLRLRLLRLR (about 2500 steps).  The chaotic behavior of ants before the "
-"highway can be very short (as with RLL that only need 100 steps to converge) "
-"or very long, as with LLLLLLRRLRRR which seems chaotic for more than 500,000 "
-"steps before build the highway or even RRLLLRRRLRRR which needs 1170000 to "
-"start converging. Some are narrow, and others are very large, such as "
-"RRLRLLRLRR (200,000 steps). This ant is also notable since it is somehow "
-"squarish even before the highway start where most others do not show "
-"anything notable before their highway."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:129
-msgid ""
-"Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), "
-"RRLLLRLLLRRR (30,000 steps), RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR "
-"(20,000 steps). Some even fill the whole space (RRLRR after 3000 "
-"steps). Some of my personal favorite ones are the ones where the ant seem to "
-"be bouncing within a box that gets bigger on each bump, such as LRRRRRLLR "
-"(30,000 steps). LRRRRLLLRRR is even more impressing since the bounces within "
-"the box are regular and since it converges more rapidly to its stable "
-"behavior (15,000 steps are enough)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:136
-msgid ""
-"Finally, some ants are just build artistic patterns. You should check this "
-"video for some beautiful ones: "
-"http://www.youtube.com/watch?v=1X-gtr4pEBU. If you want to convert them into "
-"your code, you have to shift them by one: For example, the one depicted at "
-"3:42 is not RRLRLRLLRL, but RLRLRLLRLR (the first visible move should be "
-"read as last one)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:141
-msgid ""
-"As you can see by exploring the above set of turmites, they are usually not "
-"as colorful as the ants, but this may be because very few colors suffice to "
-"exhibit complex behaviors. For example, there is a specific class of "
-"turmites called <i>busy beavers</i> which are turmites that write a lot of "
-"things before stopping (busy beavers are usually classical turing machines, "
-"but the idea fits perfectly to turmites too). There is a sort of "
-"international competition where people strive to find the turmite that "
-"covers the biggest area before stopping. The web page is here: "
-"http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:12
-msgid "void forward() or void forward(int)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:12
-msgid "void backward() or void backward(int)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setX(int)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setY(int)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:14
-msgid "void setPos(int,int)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:18
-msgid "void setColor(Color)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:22
-msgid "void setDirection(Direction)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:28
-msgid "void setBrushColor(Color)"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/lessons/turmites/universe/TurmiteWorld.html:38
-msgid "void writeMessage(String)"
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/sort/Main.html:1 src/lessons/sort/short_desc.html:1
-msgid "Sorting Algorithms"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/Main.html:3
-msgid ""
-"This lesson allows to experiment with some classical sorting algorithms (and "
-"some less common variant of them). The goal is two fold: you can first "
-"better understand the idea of these algorithms by writing them yourself. But "
-"even if you don't code the algorithms, you can use the demo mode to organize "
-"\"races\" between these algorithms to experiment in practice what the "
-"different asymptotical complexity mean."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/Main.html:10
-msgid ""
-"More exercises are planned for the future, on recursive sorting algorithms "
-"(such as QuickSort and MergeSort) or using other microworlds to apply these "
-"algorithms to other contexts."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/short_desc.html:3
-msgid ""
-"This lesson allows to experiment with some classical sorting algorithms (and "
-"some less common variant of them :)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/short_desc.html:6 src/lessons/recursion/short_desc.html:5 src/lessons/maze/short_desc.html:5
-msgid "You are supposed to master the bases of programming to take this lesson."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:1
-msgid "BubbleSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:3
-msgid ""
-"Welcome to the sorting world. It allows you to experiment with the existing "
-"sorting algorithms. The list of buildins that you can use in your algorithms "
-"is available in the world reference documentation (\"Help\"->\"About this "
-"world\")."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:14
-msgid ""
-"To help in this process, it is posible to graphically explore the history of "
-"your sorting algorithm. Switch to the Objective view and use the contextual "
-"menu (right click) to switch from the the view of the current state to the "
-"view of its history."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:28
-msgid "First attempt at BubbleSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:30
-msgid ""
-"This first sorting algorithm is the most simple one: Bubble sort consists in "
-"progressively moving up the smaller elements of the array, as if they were "
-"air bubbles moving up to the surface of a liquid. The algorithm traverse the "
-"array, and compare any pair of adjacent elements. If two adjacent elements "
-"are wrongly sorted, they are swapped. Once the array was completely "
-"traversed, the operation starts again from the beginning. When no elements "
-"were sorted after a full traversal, it means that the array is completely "
-"sorted: the algorithm can stop.  Bubble sort is studied because of its "
-"simplicity, but it is almost never used in practice because of its bad "
-"performance (O(n^2) on average)."
-msgstr ""
-
-#. type: Attribute 'alt' of: <div>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:40 src/lessons/sort/bubble/AlgBubbleSort2.html:11
-msgid "Show Tip (Pseudo-code)"
-msgstr ""
-
-#. type: Content of: <div><p>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:41
-msgid "The pseudo-code of the BubbleSort algorithm is the following:"
-msgstr ""
-
-#. type: Content of: <div><pre>
-#: src/lessons/sort/bubble/AlgBubbleSort1.html:42
-#, no-wrap
-msgid ""
-"do: \n"
-"        For each i in [0,len-2]\n"
-"          If cells i and i+1 must be swapped, do it\n"
-"while we swapped something during last traversal\n"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:1
-msgid "BubbleSort (take 2)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:3
-msgid ""
-"If you look carefully at the behavior of BubbleSort, a first easy "
-"optimization appears: after one traversal, the last element of the array "
-"must be the biggest of all since the traversal moved it up like a bubble to "
-"its position. More generally, after N traversal, we know that the N last "
-"elements of the array are already sorted. It is thus not necessary to "
-"compare them again during the subsequent traversals. For now, we will have "
-"as many traversal as there is in the array."
-msgstr ""
-
-#. type: Content of: <div><p>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:12
-msgid "The pseudo-code of the BubbleSort2 algorithm is the following:"
-msgstr ""
-
-#. type: Content of: <div><pre>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:13
-#, no-wrap
-msgid ""
-"For all i in [len-2,0] (traversing from biggest to smallest)\n"
-"       For all j in [0, i]\n"
-"          If cells j and j+1 must be swapped, do it\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:19
-msgid ""
-"When we run this algorithm, it is quite disappointing to see that it runs "
-"approximately at the same speed than the basic version of BubbleSort. This "
-"is a graphical effect only since only value changes are graphically "
-"represented. Since this variation avoids some useless comparisons, it does "
-"exactly the same amount of swaps that the basic version. It is thus quite "
-"logical that the graphical interface draws this version at the same pace "
-"than the base version. But the statistics on the amount of reads show that "
-"we saved about the fourth of the amount of reads, which is not bad."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort2.html:28
-msgid ""
-"From the asymptotic complexity point of view, there is absolutely no "
-"difference: this variation is still in O(n^2) on average (our gain is only "
-"on the constant term, ignored when computing the asymptotic complexity)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:1
-msgid "BubbleSort (take 3)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:3
-msgid ""
-"Let's now reintroduce the little optimization we removed at previous step: "
-"if a traversal does not swap any element, it means that the array is already "
-"sorted. In that case, we want to stop the whole sorting process."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:7
-msgid ""
-"For that, simply use the <code>break</code> keyword, which breaks the "
-"current loop.  Beware, if you have several embedded loops, this will apply "
-"to the internal one."
-msgstr ""
-
-#. type: Attribute 'alt' of: <div>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:10
-msgid "If you want, this tip shows the pseudo-code."
-msgstr ""
-
-#. type: Content of: <div><pre>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:12
-#, no-wrap
-msgid ""
-"For all i in [len-2,0] (traversing from biggest to smallest)\n"
-"       For all j in [0, i]\n"
-"          If cells j and j+1 must be swapped, do it\n"
-"       If traversal on j did not swap anything, break the for loop\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/bubble/AlgBubbleSort3.html:19
-msgid ""
-"This optimization is even more disappointing: it only provide a gain of a "
-"few percents on the amount of reads over BubbleSort2."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/cocktail/AlgCocktailSort1.html:1
-msgid "CocktailSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/cocktail/AlgCocktailSort1.html:3
-msgid ""
-"To improve further the BubbleSort algorithm, we need to look closer its "
-"behavior. One can notice that big elements are moved very quickly in "
-"position while small ones move very slowly to their destination. They are "
-"thus traditionally referred to as \"rabbits\" and \"turtles\" respectively "
-"for big fast values and small slow ones."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/cocktail/AlgCocktailSort1.html:9
-msgid ""
-"To help the turtles moving faster, the cocktail sort traverse alternatively "
-"the array from right to left and from left to right. Here is the "
-"pseudo-code:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/cocktail/AlgCocktailSort1.html:14
-#, no-wrap
-msgid ""
-"Do\n"
-"  For all i in [0,len-2], do:\n"
-"    if i and i+1 must be swapped, do it\n"
-"  For all i in [len-2,0] (downward), do:\n"
-"    if i and i+1 must be swapped, do it\n"
-"while at least one of the traversal swapped an element\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/cocktail/AlgCocktailSort1.html:22
-msgid ""
-"One can see that cocktail sort achieves exactly the same amount of swaps "
-"than the bubble sort, but improves slightly on read amount. It is however "
-"still worse than BubbleSort2 to that extend."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/cocktail/AlgCocktailSort2.html:1
-msgid "CocktailSort (take 2)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/cocktail/AlgCocktailSort2.html:3
-msgid ""
-"We will now apply to CocktailSort the same optimization than BubbleSort2 did "
-"to BubbleSort. We must remember the limits of the array part not being "
-"sorted yet, and traverse it alternatively from left to right and from right "
-"to left:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/cocktail/AlgCocktailSort2.html:8
-#, no-wrap
-msgid ""
-"beg=0; end=len-2\n"
-"do\n"
-"  For all Pour i in [beg,end], do:\n"
-"      If cells i and i+1 must be swapped, do it    \n"
-"  end--\n"
-"  For all Pour i in [beg,end] (downwards), do:\n"
-"      If cells i and i+1 must be swapped, do it    \n"
-"  beg++\n"
-"while at least one of the traversal swapped an element\n"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/cocktail/AlgCocktailSort3.html:1
-msgid "CocktailSort (take 3)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/cocktail/AlgCocktailSort3.html:3
-msgid ""
-"Even if the asymptotic complexity of CocktailSort2 is the same than the one "
-"of BubbleSort, it seem to perform better in practice. It is even possible to "
-"improve a bit further by stopping it if the first traversal didn't found "
-"anything to swap, without achieving the downwards traversal. Likewise, we "
-"can stop if the upward traversal found something to swap, but not the "
-"downwards one."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:1
-msgid "InsertionSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:4
-msgid ""
-"This sorting algorithm is quite simple to understand and write, even if it "
-"is not as efficient as possible. Its asymptotic complexity is in O(n2), but "
-"it is more efficient in practice (linear in best case, ie when the array is "
-"already sorted, and N2/4 on average)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:9
-msgid ""
-"The idea is to traverse all elements of the array, and to insert each of "
-"them into its proper position in the already sorted part of the array. When "
-"we look at an element x, the situation is the following: any elements to the "
-"left of the array are already sorted, and we have to insert x at its "
-"position in the array."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:17
-msgid "Once this is done, the situation is the following:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:21
-msgid "The pseudo-code of this algorithm is thus the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:22
-#, no-wrap
-msgid ""
-"For each i in [1,len]\n"
-"  store the value of i in a variable val\n"
-"  copy the cell i-1 into i if i-1 contains a value bigger than val\n"
-"  copy the cell i-2 into i-1 if i-2 contains a value bigger than val\n"
-"  copy the cell i-3 into i-2 if i-3 contains a value bigger than val\n"
-"  copy the cell i-4 into i-3 if i-4 contains a value bigger than val\n"
-"  ...\n"
-"  copy val into the last cell copied above\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:32
-msgid ""
-"Naturally, you should use a loop to write the big permutation within the "
-"given loop. Writing it this way would be really ... counter-productive."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:35
-msgid ""
-"If you've always wondered what computer science researchers do nowadays, "
-"here is part of the answer: They improve fundamental algorithms so that "
-"others can write efficient programs."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:39
-msgid "Other variation of insertion sort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:41
-msgid ""
-"TreeSort builds a binary search tree to sort them. It leads to a O(n log(n))  "
-"on average, but O(n^2) in worst cases. We won't study this algorithm here "
-"since unterstanding its behavior requires to know what a binary tree is, "
-"what is beyond our present goals."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:46
-msgid ""
-"There is other variations over the insertion sort, such as PatienceSort "
-"which builds piles of values and sort each pile afterward. This algorithm "
-"presents a 0(n log(n)) timing worst case and a 0(n) space "
-"complexity. LibrarySort (proposed in 2004) also trades a bit space in "
-"exchange for time since it provide a time complexity of O(n log(n)) but "
-"needs to store some more data."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/insertion/AlgInsertionSort.html:53
-msgid ""
-"Wikipedia provides a detailled description of all these algorithms we cannot "
-"present here because of time constraints."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/shell/AlgShellSort.html:1
-msgid "ShellSort"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/shell/AlgShellSort.html:3
-msgid ""
-"This algorithm is named after its author, Donald Shell, who published it in "
-"1959. It can be seen as an application of the CombSort idea (let elements "
-"having a long path to travel take shortcuts) to the insertion sort (CombSort "
-"is a variation of BubbleSort). Instead of comparing adjacent values during "
-"the insertion sort, it compares values separated by a bigger gap. The bigger "
-"the gap, the faster the elements are moved to their final destination, but "
-"also the less precise is this move. It is thus mandatory to apply the "
-"algorithm with a serie of decreasing gaps. At the last step, when the gap is "
-"1, InsertionSort is used, but onto an array which is almost already sorted "
-"by previous steps."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/shell/AlgShellSort.html:14
-msgid ""
-"Donald Shell propose <code>len/2</code> as initial value of the gap, and "
-"then to divide it by 2 at each step. The pseudo-code is thus the following:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/sort/shell/AlgShellSort.html:17
-#, no-wrap
-msgid ""
-"gap=len/2\n"
-"while gap>0:\n"
-"  apply InsertionSort, comparing i-gap and i, then i-2gap and i-gap, then "
-"i-3gap and i-2gap, etc.\n"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/sort/shell/AlgShellSort.html:22
-msgid ""
-"Just like in CombSort, the sequence of values taken by the gap is crucial "
-"for Shell sort performance. In some rare pathological cases, the sequence we "
-"used above can lead to a O(n^2) performance. Other sequences were proposed: "
-"the Hibbard's increments of 2k − 1 lead to a complexity of O(n^(3/2)) in "
-"worst cases. Pratt's increments 2^i3^j lead to a O(nlog(n)log(n) performance "
-"in worst cases. The existance of a sequence leading to a O(n log(n)) was "
-"precluded by Poonen, Plaxton, and Suel. Thanks to this performance, "
-"ShellSort is a valid candidate for array of several hundred thousands when "
-"correctly implemented."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/sort/shell/AlgShellSort.html:32
-msgid ""
-"In our case, the array are ways too small to benefit of these "
-"optimizations. If you ever need to do so, take as initial gap the biggest "
-"value of the targeted serie still smaller than the array size, and then use "
-"decreasing values of the serie."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/sort/shell/AlgShellSort.html:37
-msgid ""
-"Interesingly enough, determining the best gap sequence for shell sort turns "
-"into a contemporary research issue in computer science. For example, an "
-"article of 2001 introduces the following sequence, which seems to be optimal "
-"in practice for arrays of size up to 10^5: {1, 4, 10, 23, 57, 132, 301, 701, "
-"1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th "
-"International Symposium on Fundamentals of Computation Theory, LNCS 2001; "
-"Vol. 2138)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/selection/AlgSelectionSort.html:1
-msgid "Selection Sort"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/selection/AlgSelectionSort.html:3
-msgid ""
-"In this exercise we will implement another classical algorithm: selection "
-"sort."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/selection/AlgSelectionSort.html:6
-msgid ""
-"The idea is simply to select for each cell of the array the smallest value "
-"from the part not already sorted. Thus for the first cell, it takes the "
-"smallest value over the whole array. For the second one, it takes the second "
-"smallest value, which is the smallest value from the cell not already "
-"sorted."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/sort/selection/AlgSelectionSort.html:12
-msgid ""
-"More generally, for the cell N, it looks the cell M in [n;len] containing "
-"the smallest possible value of the interval. Then, it swaps the content of "
-"cell N with the one of cell M."
-msgstr ""
-
-#. type: Content of: <p><p><h2>
-#: src/lessons/sort/selection/AlgSelectionSort.html:16
-msgid "Existing variations"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/sort/selection/AlgSelectionSort.html:17
-msgid ""
-"Another classical algorithm which idea is based on the selection of good "
-"elements is HeapSort, but it uses a heap data structure which we did not see "
-"yet. Simply remember that HeapSort provides a O(n log n) performance in "
-"worst case, which is why it is a very interesting algorithm in practice."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/comb/AlgCombSort.html:1
-msgid "CombSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/comb/AlgCombSort.html:3
-msgid ""
-"We saw that CocktailSort improve a bit for turtles (i.e. small values near "
-"to the end of the array), but it is still possible to achieve "
-"better. ComboSort comes down to providing them a short cut: instead of "
-"comparing adjacent values, we compare values separated by a gap bigger than "
-"1. That way, turtles we traverse <i>gap</i> cells at each "
-"traversal. Naturally, we have to apply the algorithm with decreasing gaps, "
-"and finish with <i>gap=1</i> to ensure that the array is correctly sorted "
-"afterward. Choosing the right gap and how to decrease it is a difficult "
-"question, but in practice, dividing it by 1.3 after each traversal leads to "
-"good performance. Here is the corresponding pseudo-code:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/comb/AlgCombSort.html:15
-#, no-wrap
-msgid ""
-"gap = len;\n"
-"do\n"
-"   if gap>1 then\n"
-"     gap = gap / 1.3\n"
-"   i = O\n"
-"   while i+gap < len do:\n"
-"     if i and i+gap must be swapped, do it\n"
-"     increase i by the gap\n"
-"while the gap is bigger than 1 or the last traversal swapped at least one "
-"pair\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/comb/AlgCombSort.html:26
-msgid ""
-"This algorithm was invented by Wlodek Dobosiewicz in 1980, and later "
-"rediscovered and popularized by Stephen Lacey and Richard Box, who described "
-"it in Byte Magazine in April 1991."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/comb/AlgCombSort11.html:1
-msgid "CombSort11"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/comb/AlgCombSort11.html:3
-msgid ""
-"The authors of this algorithm observed that the performance is increased if "
-"we make sure that the last values of the gap are (11, 8, 6, 4, 3, 2, 1)  "
-"rather than (9, 6, 4, 3, 2, 1) or (10, 7, 5, 3, 2, 1). Rework the code of "
-"CombSort to ensure just after the gap update that if it is 9 or 10, we "
-"should use 11 instead."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/gnome/AlgGnomeSort.html:1
-msgid "GnomeSort"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/gnome/AlgGnomeSort.html:3
-msgid ""
-"The Gnome sort is similar to insertion sort, but the elements are moved in "
-"position by a serie of swaps just like in bubble sort. It is named after the "
-"supposed behavior of garden gnomes when they sort flower pots. Here is a "
-"description of the algorithm by its author:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/gnome/AlgGnomeSort.html:8
-msgid ""
-"Gnome Sort is based on the technique used by the standard Dutch Garden Gnome "
-"(Du.: tuinkabouter). Here is how a garden gnome sorts a line of flower "
-"pots. Basically, he looks at the flower pot next to him and the previous "
-"one; if they are in the right order he steps one pot forward, otherwise he "
-"swaps them and steps one pot backwards. Boundary conditions: if there is no "
-"previous pot, he steps forwards; if there is no pot next to him, he is "
-"done.  <i>—Dick Grune</i>"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/recursion/Main.html:1
-msgid "Recursive algorithms"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/Main.html:2
-msgid "This lesson allows to experiment with recursive algorithms."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/Main.html:4
-msgid ""
-"If you need more recursive algorithms, an exercise on recursive sorting "
-"algorithms (in particular QuickSort and MergeSort) is planned in the future "
-"within the sorting lesson."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/recursion/short_desc.html:1
-msgid "Bases of recursion"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/short_desc.html:2
-msgid ""
-"Discover the recursive way of thinking by drawing trees and other figures "
-"with the Logo turtle."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/square/Square.html:1
-msgid "The small cousines of Buggles"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/square/Square.html:3
-msgid ""
-"Today, we will meet the small cousines of the buggles: the turtles. In fact, "
-"turtles are much olders than the buggles. They were invented in the 70's by "
-"a scientific from MIT called Seymour Papert to help teaching programming, "
-"and the buggles are a variation on the idea invented by Lyn Turbak from "
-"Wellesley College later."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/square/Square.html:9
-msgid ""
-"Turtles are thus a bit like buggles, but smaller. Just like buggles, you can "
-"order them to move forward, to turn, to move backward, etc. Just like "
-"buggles, they leave a line on their path when they move (but the line is "
-"much smaller)."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/recursion/square/Square.html:14
-msgid ""
-"The main difference is that where buggles can only move of right angles, "
-"turtles can move of any arbitrary angles specified by a real number (a "
-"double). This gives them much more liberty in their movings. The buggles can "
-"do several other tricks, like reading and writting messages, picking or "
-"dropping objects, and there is sometimes walls in their worlds (but all this "
-"is completely above the capacities of turtles)."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:21
-msgid ""
-"From a practical point of view, most of the methods you knew about buggles "
-"still work with turtles, with some minor adaptations. In particular, the "
-"<code>forward()</code> method takes the amount of steps to do as a double "
-"(see \"About this world\" for more details)."
-msgstr ""
-
-#. type: Content of: <p><p><p><h3>
-#: src/lessons/recursion/square/Square.html:26
-msgid "Doubles? But what is it?"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:27
-msgid "It's simply a point number. Example:"
-msgstr ""
-
-#. type: Content of: <p><p><p><pre>
-#: src/lessons/recursion/square/Square.html:29
-#, no-wrap
-msgid ""
-"double x = 3.72;\n"
-"x + 1.234 // Value = 4.954\n"
-"x + 2 // Value = 5.72 (2 converted to 2.0 automatically)\n"
-"x * 2 // Value = 7.44 (2 converted to 2.0 automatically)\n"
-"x / 2 // Value = 1.86 (2 converted to 2.0 automatically)\n"
-"(int) x // Value = 1 (“casting to int”, converted to integer by "
-"truncating)\n"
-"Math.round(x) // Value = 2 (1.86 rounded to nearest integer)\n"
-"Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)\n"
-"Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)\n"
-"Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)\n"
-"Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)\n"
-"(double) 17 // Value = 17.0 (“casted to double”, converted to double)\n"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><h2>
-#: src/lessons/recursion/square/Square.html:43 src/lessons/recursion/circle/Circle.html:14 src/lessons/recursion/hanoi/HanoiBoard.html:20 src/lessons/welcome/array/basics/Array.html:210
-msgid "Goal of this exercise"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/recursion/square/Square.html:44
-msgid ""
-"Even if this is the first exercise on the recursivity lesson, the code you "
-"have to write is not recursive. The goal is to get familiar with the turtle "
-"world before getting on serious matter."
-msgstr ""
-
-#. type: Content of: <p><p><p><p>
-#: src/lessons/recursion/square/Square.html:48
-msgid ""
-"You must reproduce a simple geometrical painting constituted of four 100 "
-"steps long squares (see the objective world for more details). It is "
-"obviously a good idea to write a method to draw a square, and then use it in "
-"your <code>run()</code> in charge of doing the work. You must absolutely "
-"write at least the run method, which prototype is the following:"
-msgstr ""
-
-#. type: Content of: <p><p><p><p><pre>
-#: src/lessons/recursion/square/Square.html:54
-#, no-wrap
-msgid ""
-"public void run() {\n"
-"  // write here what your turtle is supposed to do\n"
-"}"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/polygonfractal/PolygonFractal.html:1
-msgid "Fractal of polygons"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/polygonfractal/PolygonFractal.html:3
-msgid ""
-"The fractal we will now draw is formed of a polygon, with little polygons on "
-"each corner. The prototype of the method drawing it is the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/polygonfractal/PolygonFractal.html:5
-#, no-wrap
-msgid "void polygonFractal (int levels, int sides, double length, double shrink)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/polygonfractal/PolygonFractal.html:7 src/lessons/recursion/sierpinski/Sierpinski.html:8 src/lessons/recursion/dragoncurve/DragonCurve1.html:27 src/lessons/recursion/dragoncurve/DragonCurve2.html:50
-msgid ""
-"Have a look at each world's objective view to understand how to write the "
-"function."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/koch/Koch.html:1
-msgid "Snow flake"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/koch/Koch.html:3
-msgid ""
-"We will now draw snow flakes using the Koch fractal. A fractal is a "
-"geometrical pattern repeated at every scale."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/koch/Koch.html:6
-msgid ""
-"The general form is a triangle, with each side given by a serie of recursive "
-"calls. The general form is given by something like this:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/koch/Koch.html:8
-#, no-wrap
-msgid ""
-"void snowFlake (int levels, double length) {\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"   snowSide(levels, length);\n"
-"   turnRight(120);\n"
-"}"
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/recursion/koch/Koch.html:17
-msgid ""
-"Observe the drawing in each world's objective to understand the pattern's "
-"logic, and then reproduce it. You must write the <code>snowSide()</code> "
-"method, which is recursive."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/star/Star.html:1
-msgid "Turtles in the stars"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/star/Star.html:3
-msgid ""
-"This is the last hand-on turtles exercise before recursion. The goal is to "
-"draw three 5-branches stars. Like any regular stars with N branches, the "
-"angle at each external corners are 360/N degrees while the angles between "
-"branches are of 2*360/N degrees."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/star/Star.html:8
-msgid ""
-"The first star to draw is black (<code>Color.black</code>) and its branches "
-"are 100 steps long. The second is blue (<code>Color.blue</code>) and its "
-"branches are 80 steps long. It's shifted of 45 degrees from the first "
-"one. The last star is red (<code>Color.red</code>), its branches are 60 "
-"steps long and it's shifted of 45 degrees from the previous one."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/star/Star.html:14
-msgid "Observe the world's objective to visualize the picture to draw."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/circle/Circle.html:1
-msgid "Three little circles"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/circle/Circle.html:3
-msgid ""
-"As we saw (and as you can check in the documentation of this world under "
-"\"About this world\"), turtles can only draw straight lines. Despite of "
-"this, the goal of this world is to draw circles... This can be achived "
-"simply by realizing that a circle can be seen as a concatenation of very "
-"little segments."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/circle/Circle.html:9
-msgid ""
-"Differential calculus would even argue that a circle is the asymptotical "
-"limit of such construct when the size of each segment becomes infinitely "
-"small while their amount becomes infinitely large (but it is still possible "
-"to solve this exercise without understanding differential calculus)."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/circle/Circle.html:16
-msgid ""
-"Write a function drawing a circle, taking the size of each of the 360 "
-"segments as parameter. Then use it in your <code>run()</code> method to draw "
-"the whole picture. The first circle is obtained with segments of size 0.5, "
-"the second with segments of size 1 and the last one with 1.5-long "
-"segments. Once again, this is a hand-on exercise, no recursion is needed."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/tree/Tree.html:1
-msgid "Trees"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/tree/Tree.html:3
-msgid ""
-"We will now draw trees. For that, we will write a method using double "
-"recursion following this prototype"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/tree/Tree.html:5
-#, no-wrap
-msgid "void tree(int steps, double length, double angle, double shrink)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/tree/Tree.html:7
-msgid ""
-"To draw a tree of four levels, you have to draw a trunk of the given length, "
-"turn right of the given angle, draw a tree of level 3, turn left twice of "
-"the given angle, draw another tree of level 3, and come back to your initial "
-"location."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/recursion/tree/Tree.html:12
-msgid ""
-"If a tree's trunk is of length 'len', the trunk of the next level tree will "
-"be of length 'len*shrink'."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/sierpinski/Sierpinski.html:1
-msgid "Sierpinski's Triangle"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/sierpinski/Sierpinski.html:3
-msgid ""
-"The fractal we will now draw is formed of a big triangle inside which "
-"several smaller triangles are embeeded. The prototype of the fuction to draw "
-"it is the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/sierpinski/Sierpinski.html:6
-#, no-wrap
-msgid "void sierpinski(int level, double length)"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/spiral/Spiral.html:1
-msgid "Spirals"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/spiral/Spiral.html:3
-msgid ""
-"We will now draw our first recursive function with the turtle. The goal is "
-"to draw different kind of spirals with the same function, which prototype is "
-"the following:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/spiral/Spiral.html:6
-#, no-wrap
-msgid "void spiral(int steps, int angle, int length, int increment)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/spiral/Spiral.html:8
-msgid ""
-"To help you understanding how to write it, here is an example of how the "
-"parameters change during one specific call:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/spiral/Spiral.html:11
-#, no-wrap
-msgid ""
-"spiral(5, 90, 0, 3);\n"
-"  forward(0);\n"
-"  turnLeft(90);\n"
-"  spiral(4,90,3,3);\n"
-"    forward(3);\n"
-"    turnLeft(90);\n"
-"    spiral(3,90,6,3);\n"
-"      forward(6);\n"
-"      turnLeft(90);\n"
-"      spiral(2,90,9,3);\n"
-"        forward(9);\n"
-"        turnLeft(90);\n"
-"        spiral(1,90,12,3);\n"
-"          forward(12);\n"
-"          turnLeft(90);\n"
-"          spiral(0,90,12,3);\n"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/spiral/SpiralUse.html:1
-msgid "Drawing spirals"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/spiral/SpiralUse.html:3
-msgid ""
-"Can you reproduce the provided patterns of this exercise using the "
-"<code>spiral()</code> method?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/spiral/SpiralUse.html:6
-msgid ""
-"You must provide a method called <code>doit(int)</code> taking the number of "
-"the page to draw as parameter. Its code is as following, with A0, B0, etc "
-"being integers. The goal of this exercise is to find the good values for "
-"each page."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/spiral/SpiralUse.html:12
-#, no-wrap
-msgid ""
-"void doit(int page) {\n"
-"  switch (page) {\n"
-"    case 0: /* Drawing of the first page, dubbed \"One\" */\n"
-"      spiral(A0,B0,C0,D0);\n"
-"      break;\n"
-"    case 1: /* Drawing of the second page, dubbed \"Two\" */\n"
-"      spiral(A1,B1,C1,D1);\n"
-"      break;\n"
-"    case 2: /* Drawing of the page dubbed \"Three\" */\n"
-"      spiral(A2,B2,C2,D2);\n"
-"      break;\n"
-"    case 3: /* Drawing of the page dubbed \"Four\" */\n"
-"      spiral(A3,B3,C3,D3);\n"
-"      break;\n"
-"    case 4: /* Drawing of the page dubbed \"Five\" */\n"
-"      spiral(A4,B4,C4,D4);\n"
-"      break;\n"
-"  }\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/spiral/SpiralUse.html:34
-msgid ""
-"No need to copy over the method of <code>spiral()</code>, the turtle of this "
-"exercise already knows it."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:1
-msgid "Dragon curve (1)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:3
-msgid "The dragon curve is a classical example of recursive method."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:5
-msgid "The definition of this curve is the following:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:6
-msgid "the dragon curve of order 1 is a vector between to arbitrary points P and Q,"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:7
-msgid ""
-"the dragon curve of order n is the dragon curve of order n-1 between P and "
-"R, followed by the same curve of order n-1 between R and Q (reverse side), "
-"where PRQ is an isoscele triangle with angle R being a right angle, and R "
-"being at the right of the PQ vector. Thus, if P and Q coordinates are (x, y)  "
-"and (z, t), the coordinate (u, v) of R are given by:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:13 src/lessons/recursion/dragoncurve/DragonCurve2.html:27
-#, no-wrap
-msgid ""
-"u = (x + z)/2 + (t - y)/2\n"
-"v = (y + t)/2 - (z - x)/2\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:19
-msgid "The prototype of the method drawing the curve is the following:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:20 src/lessons/recursion/dragoncurve/DragonCurve2.html:22
-#, no-wrap
-msgid "void dragon(int ordre, double x, double y, double z, double t)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve1.html:23
-msgid ""
-"You should use the method <code>setPos(x,y)</code> to put your turtle at "
-"coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line "
-"between the turtle position and the point (z,t)."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:1
-msgid "The dragon curve (2)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:3
-msgid ""
-"Previous solution induce that the turtle teleports to other location, or at "
-"the very least, that it moves its pen up during the drawing. Indeed, the end "
-"of the drawing of the first recursive call does not match the begining of "
-"the second recursive call. That is why we had to use the method "
-"<code>setPos()</code>"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:9
-msgid ""
-"In this lesson, you will write a recursive method allowing to draw the "
-"dragon curve without taking the pen up. For that, we need another recursive "
-"method drawing the mirror side of the curve."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:13
-msgid ""
-"The method <code>dragon()</code> is then recursively defined using itself "
-"and <code>dragonReverse()</code>. Likewise, the method "
-"<code>dragonReverse()</code> is defined recursively using itself and "
-"<code>dragon()</code>. This is thus an example of <i>mutual recursion</i>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:20
-msgid ""
-"The prototype of the <code>dragon()</code> method remains unchanged from "
-"previous exercise:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:24
-msgid ""
-"The new point's coordinate (u, v) introduced by the <code>dragon()</code> "
-"are:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:33
-msgid "The prototype of the method <code>dragonReverse</code> is similar:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:34
-#, no-wrap
-msgid "void dragonReverse(int ordre, double x, double y, double z, double t)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:36
-msgid ""
-"The new point's coordinate (u, v) introduced by the "
-"<code>dragonReverse()</code> are:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:39
-#, no-wrap
-msgid ""
-"u = (x + z)/2 - (t - y)/2\n"
-"v = (y + t)/2 + (z - x)/2\n"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/dragoncurve/DragonCurve2.html:45
-msgid ""
-"To make the work of each method recursiv more visible, the line painted by "
-"the <code>dragon()</code> must be red (<code>Color.red</code>) while the "
-"line painted by the <code>dragonReverse()</code> must be blue "
-"(<code>Color.blue</code>)."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/recursion/hanoi/Main.html:1 src/lessons/recursion/hanoi/short_desc.html:1
-msgid "Hanoi towers"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/hanoi/Main.html:2
-msgid ""
-"Here comes the super classical exercise on recursion. It's not very "
-"developped here, I'm not sure of what I could add to this lesson. If you "
-"have any idea, please submit them."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/hanoi/short_desc.html:2
-msgid "Here comes the super classical exercise on recursion."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/hanoi/short_desc.html:4
-msgid ""
-"This is an application exercise of recursion, that you should master to take "
-"this lesson."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:1
-msgid "Tower of Hanoi"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/HanoiBoard.html:3
-msgid ""
-"The Tower of Hanoi or Towers of Hanoi , also called the Tower of Brahma or "
-"Towers of Brahma, is a mathematical game or puzzle. It consists of three "
-"rods, and a number of disks of different sizes which can slide onto any "
-"rod. The puzzle starts with the disks in a neat stack in ascending order of "
-"size on one rod, the smallest at the top, thus forming a pyramid.  The "
-"objective of the puzzle is to move the entire stack to another rod, obeying "
-"the following rules:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:11
-msgid "Only one disk may be moved at a time."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:13
-msgid ""
-"Each move consists of taking the upper disk from one of the rods and sliding "
-"it onto another rod, on top of the other disks that may already be present "
-"on that rod."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:17
-msgid "No disk may be placed on top of a smaller disk."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/HanoiBoard.html:22
-msgid ""
-"Write the core of the method: <code>public void solve(int src, int dst, int "
-"height) throws HanoiInvalidMove</code> This method will recursively solve "
-"the presented problem. First parameter named <code>src</code> is the index "
-"of the initial tower, second parameter <code>dst</code> is the index of the "
-"expected final tower, and the third parameter <code>height</code> is the "
-"height of the tower.  A key to solving this puzzle is to recognize that it "
-"can be solved by breaking the problem down into a collection of smaller "
-"problems and further breaking those problems down into even smaller problems "
-"until a solution is reached.  The following procedure demonstrates this "
-"approach:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:36
-msgid "label the pegs A, B, C (these labels may move at different steps)"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:37
-msgid "let n be the total number of discs (the height of the initial tower)"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:38
-msgid "number the discs from 1 (smallest, topmost) to n (largest, bottommost)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/HanoiBoard.html:41
-msgid "To move n discs from peg A to peg C:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:43
-msgid "move n−1 discs from A to B. This leaves disc #n alone on peg A"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:44
-msgid "move disc #n from A to C"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/recursion/hanoi/HanoiBoard.html:45
-msgid "move n−1 discs from B to C so they sit on disc #n"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:1
-msgid "HanoiWorld"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:4
-msgid ""
-"This world implements the ultra-classical Hanoi problem. You are asked to "
-"move the disk pile from the stick where they are to the target stick (given "
-"as second parameter in the world's name -- number 1 for the default "
-"world). There is some extra constraint: you can only move one disk at a "
-"time, and you cannot move a big disk over a smaller one."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:11
-msgid "Only 3 functions are provided:"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:13
-#, no-wrap
-msgid "void move(int src, int dst)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:14
-#, no-wrap
-msgid "move(src, dst) throws HanoiInvalidMove"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:16
-msgid ""
-"Moves one disk from the stick <code>src</code> onto the stick "
-"<code>dst</code>. If you try to do an invalid move (like laying a disk over "
-"a smaller one), an IllegalArgumentException is thrown."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:20
-#, no-wrap
-msgid "int getSlotSize(int slot);"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:21
-#, no-wrap
-msgid "getSlotSize(slot)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:22
-msgid ""
-"Returns the amount of disks placed on the specified slot. This is mainly "
-"used to initialize the recursion and set the amount of recursive call to "
-"execute."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/maze/Main.html:1 src/lessons/maze/short_desc.html:1
-msgid "Labyrinths"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/Main.html:3 src/lessons/maze/short_desc.html:3
-msgid "This lesson proposes several exercises about labyrinths in the buggle world."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:1
-msgid "The crazy mouse"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:3
-msgid ""
-"The day of your buggle starts badly. Out of luck, it got trapped into a "
-"maze. Help it finding its path out of there."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:8
-msgid ""
-"The exit is represented by a baggle and you need to pick this baggle in "
-"order to exit the maze."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:13
-msgid ""
-"Since the maze is so small, we can write the dumbest possible algorithm to "
-"do so. It relies on randomness and proves quite inefficient."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:18
-msgid ""
-"While the buggle didn't find the path to the escape, it must proceed the "
-"following way: pick a random integer between 0 and 2 by using the provided "
-"<code>random3()</code> method and make one of the following actions: moving "
-"forward if possible, turn left or turn right."
-msgstr ""
-
-#. type: Content of: <a><p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:27
-msgid ""
-"This exercise's objective is to write an algorithm allowing the buggle to "
-"find its path out of the maze."
-msgstr ""
-
-#. type: Content of: <a><p>
-#: src/lessons/maze/randommouse/RandomMouseMaze.html:32
-msgid "Don't forget to pick up the baggle once you've reached it."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:1
-msgid "Following the walls"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:3
-msgid ""
-"This time, the maze is a bit more complicated. Random won't be enough, we "
-"ough to be smart!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:6
-msgid ""
-"The good news is that this maze is simpler that it seems at the first "
-"glance: every wall are connected to each other. To get out of this kind of "
-"maze, the buggle only have to follow a wall (the one on its left or the one "
-"on its right, it doesn't matter).  While keeping a paw on the wall, the "
-"buggle must move forward until it finds the maze exit and this biscuit it "
-"loves so much."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:13
-msgid ""
-"This works here because there is no island of isolated walls, so our buggle "
-"cannot loop around for ever without encountering its baggle."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:17
-msgid ""
-"The goal of this exercise is to write an algorithm allowing the buggle to "
-"get out of this maze."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:20
-msgid ""
-"As said earlier, it does not matter whether you decide to follow the left "
-"wall or the right one. Simply, the demo follows the left one, so you should "
-"do the same in your solution to ease the comparison of your solution and the "
-"demo."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:25
-msgid ""
-"Write a method <code>keepHandOnSideWall()</code> which lets the buggle move "
-"one step forward while keeping the paw on the wall of the selected side. You "
-"must ensure that the buggle always keep the paw on the wall, but also that "
-"it won't crash into a wall. You can check the tip for more info on this, but "
-"only do so if you're stuck. Try to do it without the tip first."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:32
-msgid ""
-"Then, write the whole algorithm to traverse the maze step by step (using "
-"<code>keepHandOnSideWall()</code>) until it finds the biscuit and the "
-"exit. Don't forget to pick the baggle up once you've found it."
-msgstr ""
-
-#. type: Attribute 'alt' of: <div>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:37
-msgid "I'm lost, please give me some extra indications"
-msgstr ""
-
-#. type: Content of: <div><p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:38
-msgid ""
-"When your buggle has a wall on the left, there is three situations to "
-"consider, depending on the surrounding walls. The following table depicts "
-"each initial situation, and where you should let your buggle end after one "
-"step."
-msgstr ""
-
-#. type: Content of: <div><table><tr><td>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:45
-msgid "Case 1"
-msgstr ""
-
-#. type: Content of: <div><table><tr><td>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:46
-msgid "Case 2"
-msgstr ""
-
-#. type: Content of: <div><table><tr><td>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:47
-msgid "Case 3"
-msgstr ""
-
-#. type: Content of: <div><table><tr><td>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:49
-msgid "Initial situation"
-msgstr ""
-
-#. type: Content of: <div><table><tr><td>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:54
-msgid "Where is the next step"
-msgstr ""
-
-#. type: Content of: <div><p>
-#: src/lessons/maze/wallfollower/WallFollowerMaze.html:60
-msgid ""
-"If you do a <code>turnRight()</code> in any case at the end of your "
-"function, it's possible to write it in 3 lines with a <code>while</code> "
-"loop."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/pledge/PledgeMaze.html:1
-msgid "Pledge algorithm"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:3
-msgid ""
-"Once again, you thought that your algorithm were good enough to escape the "
-"maze, and once again, you buggle is now in a maze where your previous "
-"algorithm fails. Just give it a try: copy/paste your code and hit the "
-"\"Run\" button and see your creation fail. The trap is shaped like an upper "
-"case \"G\". The buggle enters the trap and follows the inner border. At some "
-"point, it finds the north direction free, run into that direction, and falls "
-"again in the trap."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:13
-msgid ""
-"The Pledge's algorithm (named after Jon Pledge of Exeter) can solve this "
-"maze."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:16
-msgid ""
-"This algorithm is a modification of the previous one thought to avoid "
-"obstacles. It randomly picks a heading and let the buggle move in that "
-"direction. When it encounters an obstacle, a paw (for example the left one)  "
-"is kept on the wall following the obstacle while counting the turns. When "
-"the buggle is back to its original heading and when the sum of the turns is "
-"0, the buggle leaves the obstacle and continues keeping its original "
-"heading."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:24
-msgid ""
-"Note that the use of \"total turning\" rather than just the \"current "
-"direction\" allows the algorithm to avoid G-shapped traps. If one proceeds "
-"left into the trap, one gets turned around a full 360 degrees by the "
-"walls. As we said before, the naive \"current direction\" algorithm gets "
-"into a limit cycle as it leaves the lower rightmost wall heading left and "
-"runs into the curved section on the left again."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:31
-msgid ""
-"The Pledge's algorithm does not leave the rightmost wall due to the total "
-"turning not being zero at that point. It follows the wall all the way "
-"around, finally leaving it heading left on the bottom outside"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:38
-msgid ""
-"<a name=\"Objective\"/>You now have to modify your solution to implement the "
-"Pledge algorithm to escape this maze."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:41
-msgid ""
-"Change your <code>keepHandOnSideWall()</code> method to count the amount of "
-"turns done by the buggle (+1 when it turns left, and -1 when it turns "
-"right). This counting may require the addition of an <code>angleSum</code> "
-"integer value in your program."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:46
-msgid ""
-"Write a boolean method <code>isDirectionFree(dir)</code> indicating if the "
-"provided direction is free, ie, if you can move in that direction (Note that "
-"the demo uses the NORTH direction for that).  You can retrieve the current "
-"direction of the buggle using the method <code>getDirection()</code>. You "
-"can change your direction (without moving) using "
-"<code>setDirection(dir)</code>. Don't forget to store the previous direction "
-"of your buggle (in a dedicated variable) before checking if your favorite "
-"direction is free in order to restore your state afterward."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:55
-msgid ""
-"You may have to change the rest of your code also, but these changes should "
-"remain limited."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/pledge/PledgeMaze.html:58
-msgid ""
-"Don't forget that if you have a method modifying a global variable (such as "
-"angleSum), you should ensure that it declares this variable as "
-"global. Without it, the method creates a new variable of the same name, and "
-"the global never gets modified."
-msgstr ""
-
-#. type: Content of: <div><pre>
-#: src/lessons/maze/pledge/PledgeMaze.html:62
-#, no-wrap
-msgid ""
-"def myMethod():\n"
-"  global angleSum\n"
-"  ...\n"
-"  angleSum = angleSum + 1\n"
-msgstr ""
-
-#. type: Attribute 'alt' of: <div>
-#: src/lessons/maze/pledge/PledgeMaze.html:68
-msgid "Show an additional tip"
-msgstr ""
-
-#. type: Content of: <div>
-#: src/lessons/maze/pledge/PledgeMaze.html:69
-msgid ""
-"You should set your direction to your favorite one (NORTH is advised). Then, "
-"you should write the algorithm main loop. In other words, while your buggle "
-"did not find its biscuit, you have to move forward until next obstacle in "
-"the favorite direction. Then, put a paw on a wall (using "
-"(<code>keepHandOnSideWall()</code>) while the sum of turns is not null and "
-"the favorite direction is not free. Do that until you find your baggle."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/island/IslandMaze.html:1
-msgid "Lost between islands"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/island/IslandMaze.html:3
-msgid ""
-"You thought that your algorithm was enough to escape mazes? Well, not every "
-"mazes..."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/island/IslandMaze.html:7
-msgid ""
-"The <i>wall follower algorithm</i> we used so far only works if the entry "
-"and the exit are placed near to walls connected to the external wall. But if "
-"the buggle begins in the middle of the maze, it may exist wall sections "
-"disconnected from the external wall."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/maze/island/IslandMaze.html:12
-msgid ""
-"That is why the previous strategy would let the buggle round around for "
-"ever. Indeed, the maze you should now escape from contains islands, and the "
-"buggle does not start along one of the external walls. Just give it a try if "
-"you want: copy your code over, push the run button and see your previous "
-"solution failing miserabily."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/maze/island/IslandMaze.html:18
-msgid ""
-"The method of following a wall is still good and allow to escape very "
-"efficiently some sections of the maze, so we do not want to remove it "
-"entierely. Instead, we want to stop following the wall under some "
-"conditions. Notice that the baggle lays near to the external border of the "
-"maze. So, we want to reach the border and then follow that wall. We need for "
-"example to search for the north wall before following it to the baggle."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/maze/island/IslandMaze.html:26
-msgid ""
-"To find the north wall, you simply run to the north as long as it's "
-"possible, and when facing an obstacle, you avoid it (using previous method)."
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><p><div>
-#: src/lessons/maze/island/IslandMaze.html:30
-msgid "I'm lost now, please give me some extra indications"
-msgstr ""
-
-#. type: Content of: <p><p><div>
-#: src/lessons/maze/island/IslandMaze.html:31
-msgid ""
-"Our new run() method will consist in two modes: our buggle will alternate "
-"between the \"north runner mode\" and the \"left follower mode\". You begin "
-"in \"north runner mode\", and switch to \"left follower\" when you have a "
-"wall at the north (do not forget to make sure you have a wall at your left "
-"before switching to \"left follower\" mode). You switch to \"north runner\" "
-"as soon as your buggle is facing north and is not in front of a wall during "
-"its trip around its left wall. The easiest way to write such a state machine "
-"is something like"
-msgstr ""
-
-#. type: Content of: <p><p><div><pre>
-#: src/lessons/maze/island/IslandMaze.html:40
-#, no-wrap
-msgid ""
-"\t<code div=\"Java\">int state=0;\n"
-"switch (state) {\n"
-"  case 0: // North runner\n"
-"     ...\n"
-"     state = 1;\n"
-"     break;\n"
-"  case 1: // Left follower\n"
-"     ...\n"
-"     state = 0;\n"
-"     break;\n"
-"}\n"
-"</code>\n"
-"<code div=\"python\">northRunner = True\n"
-"if northRunner:\n"
-"     ...\n"
-"     northRunner = False\n"
-"else: # left follower\n"
-"     ...\n"
-"     northRunner = True\n"
-"</code>\n"
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/maze/island/IslandMaze.html:63
-msgid "Don't forget to let the buggle pick the baggle at the end of your code."
-msgstr ""
-
-#. type: Content of: <p><p><p>
-#: src/lessons/maze/island/IslandMaze.html:66
-msgid ""
-"You're up. That should be enough for you to figure out how to escape this "
-"maze, but if not, you can always request for the tip. But you do not need "
-"any more help, do you?"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:1
-msgid "Basic Shortest Path algorithm"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:3
-msgid ""
-"To conclude with this introductory lesson to maze solving algorithms, we "
-"will investigate another way to find the exit. The buggle in this lesson is "
-"a special buggle: he is a jedi. He can feel the Force. This means he is able "
-"to feel his environment."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:7
-msgid ""
-"Without even leaving his position, he can retrieve information about the "
-"world he is leaving in, with the following functions:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:9
-msgid "<code>getWorldWidth()</code> gives the width of its world."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:10
-msgid "<code>getWorldHeight()</code> gives the height of its world."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:11
-msgid ""
-"<code>hasTopWall(x,y)</code> tells whether the cell (x,y) of this world has "
-"a wall on top."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:12
-msgid ""
-"<code>hasLeftWall(x,y)</code> tells whether the cell (x,y) of this world has "
-"a wall on the left."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:13
-msgid ""
-"<code>hasBaggle(x,y)</code> tells whether the cell (x,y) of this world has a "
-"baggle."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:14
-msgid ""
-"<code>setIndication(x,y,i)</code> adds the integer indication <code>i</code> "
-"to the cell (x,y)."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:15
-msgid ""
-"<code>getIndication(x,y,i)</code> retrieves the integer indication of the "
-"cell (x,y) (or 9999 if there is no indication)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:18
-msgid ""
-"It has to be noted that it is not possible to build a wall on the bottom "
-"edge or on the right edge of a cell.  Therefore when such wall exists, it "
-"means it was built on a sibling cells -- as a top (respectively left) wall "
-"on the cell that is located below (respectively at the right of) the current "
-"cell."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:24
-msgid ""
-"Your buggle should first write the distance to the exit on each cell (or at "
-"least the useful ones)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:25
-msgid ""
-"For that, find the exit and write 0 there.  Then, write 1 on every "
-"neighboring cells that is not separated from the exit with a wall.  And then "
-"mark every cells from which you can reach the exit in 2 steps, and iterate "
-"for all cells until you mark the cell where the buggle is located."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:30
-msgid ""
-"Once the cells are marked, get your jedi buggle to follow the shortest "
-"path.  Basically the buggle has only to walk on each case with the lesser "
-"distance from the exit. You can use the method "
-"<code>setDirection(direction)</code> to make your buggle look at the "
-"specific direction such as <code>Direction.NORTH</code> or "
-"<code>Direction.EAST</code>."
-msgstr ""
-
-#. type: Attribute 'alt' of: <div>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:35
-msgid "I'm lost now. Please give me some extra indications."
-msgstr ""
-
-#. type: Content of: <div>
-#: src/lessons/maze/shortestpath/ShortestPathMaze.html:36
-msgid "Use the Force, Luke!"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:1
-msgid "Finding the walls to follow"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:3
-msgid ""
-"This is exactly the same maze than before, but the buggle does not start at "
-"the same location. In particular, it does not have any wall to its left at "
-"the beginning."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:7
-msgid ""
-"As a result, the method you wrote for the previous exercise probably don't "
-"work for this one. If you use it here with no modification, your buggle "
-"probably start looping over the four free cells around its start position "
-"(if that's not the case, well, you didn't really stick to the mission on "
-"previous exercise. Feel lucky and proceed to the next :)"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:14
-msgid ""
-"This is because your <code>keepHandOnSideWall()</code> method has an "
-"implicit <b>pre-condition</b>: it works well if and only if the buggle has a "
-"wall to its left when you call it. Such pre-condition are very heavily used "
-"when programming. Specifying them explicitly helps understanding the code "
-"written by other, and they even allow sometimes to prove that the code works "
-"correctly."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:24
-msgid ""
-"Fixing the problem should be very easy. Simply make sure that the "
-"pre-condition of <code>keepHandOnSideWall()</code> is verified before "
-"calling it. For that, update your code to first look for a wall on its left "
-"before the big <code>while</code> loop."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/jlm/universe/lightbot/LightBotWorld.html:1
-msgid "LightBotWorld"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/jlm/universe/lightbot/LightBotWorld.html:3
-msgid ""
-"This world introduces a little programming puzzle which can somehow be used "
-"to introduce programmation to non-reading kids since it is programmed "
-"graphically.  The goal of each board is to light up all the lights. Your "
-"robot understands the following orders:"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:7
-msgid "<b>Order</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:7
-msgid "<b>Meaning</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:8
-msgid "<b>Move forward</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:8
-msgid "Cannot be done if the destination cell is of another height than source cell"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:9
-msgid "<b>Jump forward</b>"
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:9
-msgid ""
-"Can only be done if the destination cell is one step higher than source "
-"cell, or if destination is lower than source. Cannot be used for plain "
-"moves."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:10
-msgid "<b>Turn left</b>."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:11
-msgid "<b>Turn right</b>."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:12
-msgid "<b>Switch the light</b>."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:12
-msgid ""
-"Turn it on if it was off, and off if it was on. No effect if the cell does "
-"not contain any light."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:13
-msgid "<b>Call function 1</b>."
-msgstr ""
-
-#. type: Content of: <table><tr><td>
-#: src/jlm/universe/lightbot/LightBotWorld.html:14
-msgid "<b>Call function 2</b>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/lightbot/LightBotWorld.html:17
-msgid ""
-"Please note that this world is not completely suited to small kids since the "
-"main difficulty comes from the fact that your are highly limited in the "
-"amount of instructions you can give to your robot. Advanced levels thus "
-"require to write sound functions, and are often above the capacities of "
-"small kids."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/lightbot/LightBotWorld.html:19
-msgid ""
-"This game is heavily inspirated from a flash game of the same name, which "
-"can for example be played on kongregate.com. It was written by Danny "
-"Yaroslavski (Coolio-Niato), the original idea being of Matt Chase."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/lightbot/Main.html:1 src/lessons/lightbot/short_desc.html:1
-msgid "LightBot"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/lightbot/Main.html:2
-msgid ""
-"This lesson introduces a little programming puzzle inspired from a flash "
-"game."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Main.html:4
-msgid "See the <i>About this world</i> dialog for more details."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/short_desc.html:3
-msgid ""
-"This lesson constitutes a little brain teaser for programmers. You have to "
-"instruct your robot to turn off all lights. The trick is that you program "
-"your robot graphically, and that you are limited in the amount of "
-"instructions."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/short_desc.html:8
-msgid "No previous experience is expected to take this lesson."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board01TwoSteps.html:1
-msgid "Welcome"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board01TwoSteps.html:3
-msgid ""
-"Welcome to the lightbot world. This is merely a programmer puzzle rather "
-"than a real lesson (although some use it to teach programming).  The robot "
-"is not programmed in Java, but rather graphically. You can see the existing "
-"orders in the documentation using the <i>About this world</i> menu."
-msgstr ""
-
-#. type: Content of: <p><</p><p>
-#: src/lessons/lightbot/Board01TwoSteps.html:6
-msgid ""
-"The goal of each board is simply to switch on every lights of the board "
-"using your little robot."
-msgstr ""
-
-#. type: Content of: <p><</p><p>
-#: src/lessons/lightbot/Board01TwoSteps.html:8
-msgid ""
-"This is a introduction exercise, which should be solvable by only moving "
-"forward and switching the light, using respectively"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board01TwoSteps.html:10 src/lessons/lightbot/Board02Turn.html:4 src/lessons/lightbot/Board06Func.html:3
-msgid "and"
-msgstr ""
-
-#. type: Content of: <p><</p><p>
-#: src/lessons/lightbot/Board01TwoSteps.html:10
-msgid "."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board02Turn.html:1
-msgid "Turn around"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board02Turn.html:3
-msgid "Now, you probably need to turn in addition (using"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board02Turn.html:4
-msgid ")."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board03Jump.html:1
-msgid "Jump"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board03Jump.html:3
-msgid "You can also jump using"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board03Jump.html:3
-msgid ""
-"to pass obstacles. You can either jump one level up or any amount of levels "
-"down, but you cannot jump to go on a cell of the same height."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board04Stairs.html:1
-msgid "Stairs"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board04Stairs.html:3
-msgid "Can you pass these stairs?"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board05Higher.html:1
-msgid "Higher"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board05Higher.html:3
-msgid "Let's go higher"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board06Func.html:1
-msgid "Functions"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board06Func.html:3
-msgid "You can use"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board06Func.html:3
-msgid ""
-"to call respectively the first and second functions. Define their code in "
-"their own tab."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/lightbot/Board06Func.html:5
-msgid "This is great if you get out of space in your main function"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board07Repeat.html:1
-msgid "Repetitive tasks"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board07Repeat.html:3
-msgid "Functions are also of great use for repetitive tasks"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board08Rec.html:1
-msgid "Calling functions from functions"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board08Rec.html:3
-msgid "It is perfectly okay to call a function from within a function!"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board09Castle.html:1
-msgid "Castle"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board09Castle.html:3
-msgid "You're getting good at this..."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board10Wall.html:1
-msgid "Wall"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board10Wall.html:3
-msgid "Ready to climb the wall?"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board11Sea.html:1
-msgid "Sea"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board11Sea.html:3
-msgid "You now have to surf these waves of lamps."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/lightbot/Board12Escher.html:1
-msgid "Escher Castle"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/lightbot/Board12Escher.html:3
-msgid "This one aint easy."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Close10.html:1
-msgid "Close to 10"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:2
-msgid ""
-"Given 2 int values, return whichever value is nearest to the value 10, or "
-"return 0 in the event of a tie. Note that Math.abs(n) returns the absolute "
-"value of a number."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:5
-msgid ""
-"Given 2 int values, return whichever value is nearest to the value 10, or "
-"return 0 in the event of a tie. Note that math.fabs(n) returns the absolute "
-"value of a number. Note also that this function can only be used if you "
-"imported the math module."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Close10.html:10 src/lessons/welcome/bool1/Diff21.html:5 src/lessons/welcome/bool1/HasTeen.html:6 src/lessons/welcome/bool1/IcyHot.html:5 src/lessons/welcome/bool1/In1020.html:5 src/lessons/welcome/bool1/In3050.html:5 src/lessons/welcome/bool1/LastDigit.html:9 src/lessons/welcome/bool1/LoneTeen.html:6 src/lessons/welcome/bool1/Main.html:11 src/lessons/welcome/bool1/Makes10.html:5 src/lessons/welcome/bool1/Max1020.html:8 src/lessons/welcome/bool1/MonkeyTrouble. [...]
-msgid ""
-"This exercise was converted to JLM from the excellent exercising site "
-"http://javabat.com/"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/CountTeen.html:1
-msgid "Count Teen"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/CountTeen.html:2
-msgid ""
-"We'll say that a number is \"teen\" if it is in the range 13..19 "
-"inclusive. Given 4 int values, return the amount of teen ones."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Diff21.html:1
-msgid "Diff 21"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Diff21.html:2
-msgid ""
-"Given an int n, return the absolute difference between n and 21, except "
-"return double the absolute difference if n is over 21."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/HasTeen.html:1
-msgid "Has Teen"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/HasTeen.html:2
-msgid ""
-"We'll say that a number is \"teen\" if it is in the range 13..19 "
-"inclusive. Given 3 int values, return true if 1 or more of them are teen."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/IcyHot.html:1
-msgid "Icy Hot"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/IcyHot.html:2
-msgid ""
-"Given two temperatures, return true if one is less than 0 and the other is "
-"greater than 100."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/In1020.html:1
-msgid "In [10;20]"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/In1020.html:2
-msgid ""
-"Given 2 int values, return true if either of them is in the range 10..20 "
-"inclusive."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/In3050.html:1
-msgid "In [30;50]"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/In3050.html:2
-msgid ""
-"Given 2 int values, return true if they are both in the range 30..40 "
-"inclusive, or they are both in the range 40..50 inclusive."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/LastDigit.html:1
-msgid "LastDigit"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/LastDigit.html:2
-msgid ""
-"Given two non-negative int values, return true if they have the same last "
-"digit, such as with 27 and 57. Note that the % \"mod\" operator computes "
-"remainders, so 17 % 10 is 7."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/LoneTeen.html:1
-msgid "Lone Teen"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/LoneTeen.html:2
-msgid ""
-"We'll say that a number is \"teen\" if it is in the range 13..19 "
-"inclusive. Given 2 int values, return true if one or the other is teen, but "
-"not both."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Main.html:1
-msgid "Boolean fun"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Main.html:3
-msgid ""
-"Boolean operations are one of the very basic task in programming.  As long "
-"as you cannot write a not so simple boolean test under the minute, you "
-"probably will have a very bad time writing a real program."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/Main.html:8
-msgid ""
-"That is why this lesson provides you a bunch of such exercises, so that you "
-"can get trained in this."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Makes10.html:1
-msgid "Makes 10"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Makes10.html:2
-msgid ""
-"Given 2 ints, a and b, return true if one if them is 10 or if their sum is "
-"10."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/Max1020.html:1
-msgid "Max1020"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/Max1020.html:2
-msgid ""
-"Given 2 positive int values, return the larger value that is in the range "
-"10..20 inclusive, or return 0 if neither is in that range."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/MonkeyTrouble.html:1
-msgid "MonkeyTrouble"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/MonkeyTrouble.html:3
-msgid ""
-"We have two monkeys, a and b, and the parameters aSmile and bSmile indicate "
-"if each is smiling.  We are in trouble if they are both smiling or if "
-"neither of them is smiling.  Return true if we are in trouble."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/NearHundred.html:1
-msgid "Near Hundred"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool1/NearHundred.html:2
-msgid ""
-"Given an int n, return true if it is within 10 of 100 or 200. Note "
-"Math.abs(n) returns the absolute value of a number."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/ParotTrouble.html:1
-msgid "Parot Trouble"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/ParotTrouble.html:3
-msgid ""
-"We have a loud talking parrot. The \"hour\" parameter is the current hour "
-"time in the range 0..23. We are in trouble if the parrot is talking and the "
-"hour is before 7 or after 20. Return true if we are in trouble."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/PosNeg.html:1
-msgid "Positive Negative"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/PosNeg.html:2
-msgid ""
-"Given 2 int values, return true if one is negative and one is "
-"positive. Unless negative is true, then they both must be negative."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/SleepIn.html:1
-msgid "SleepDay"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/SleepIn.html:3
-msgid ""
-"The parameter weekday is true if it is a weekday, and the parameter vacation "
-"is true if we are on vacation. We sleep in if it is not a weekday or we're "
-"on vacation. Return true if we sleep in."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool1/SumDouble.html:1
-msgid "Sum Double"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool1/SumDouble.html:2
-msgid ""
-"Given two int values, return their sum. Unless the two values are the same, "
-"then return double their sum."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/AlarmClock.html:1
-msgid "AlarmClock"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/AlarmClock.html:2
-msgid ""
-"Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a "
-"boolean indicating if we are on vacation, return a string of the form "
-"\"7:00\" indicating when the alarm clock should ring. Weekdays, the alarm "
-"should be \"7:00\" and on the weekend it should be \"10:00\". Unless we are "
-"on vacation -- then on weekdays it should be \"10:00\" and weekends it "
-"should be \"off\"."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/AnswerCell.html:1
-msgid "AnswerCell"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/AnswerCell.html:2
-msgid ""
-"Your cell phone rings. Return true if you should answer it. Normally you "
-"answer, except in the morning you only answer if it is your mom calling. In "
-"all cases, if you are asleep, you do not answer."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/BlueTicket.html:1
-msgid "BlueTicket"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/BlueTicket.html:2
-msgid ""
-"You have a blue lottery ticket, with ints a, b, and c on it. This makes "
-"three pairs, which we'll call ab, bc, and ac. Consider the sum of the "
-"numbers in each pair. If any pair sums to exactly 10, the result is 10.  "
-"Otherwise if the ab sum is exactly 10 more than either bc or ac sums, the "
-"result is 5. Otherwise the result is 0."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/CaughtSpeeding.html:1
-msgid "CaughtSpeeding"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/CaughtSpeeding.html:2
-msgid ""
-"You are driving a little too fast, and a police officer stops you. Write "
-"code to compute the result, encoded as an int value: 0=no ticket, 1=small "
-"ticket, 2=big ticket. If speed is 60 or less, the result is 0. If speed is "
-"between 61 and 80 inclusive, the result is 1. If speed is 81 or more, the "
-"result is 2. Unless it is your birthday -- on that day, your speed can be 5 "
-"higher in all cases."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/CigarParty.html:1
-msgid "CigarParty"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/CigarParty.html:2
-msgid ""
-"When squirrels get together for a party, they like to have cigars. A "
-"squirrel party is successful when the number of cigars is between 40 and 60, "
-"inclusive. Unless it is the weekend, in which case there is no upper bound "
-"on the number of cigars. Return true if the party with the"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/DateFashion.html:1
-msgid "DateFashion"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/DateFashion.html:2
-msgid ""
-"You and your date are trying to get a table at a restaurant. The parameter "
-"\"you\" is the stylishness of your clothes, in the range 0..10, and \"date\" "
-"is the stylishness of your date's clothes. The result getting the table is "
-"encoded as an int value with 0=no, 1=maybe, 2=yes. If either of you is very "
-"stylish, 8 or more, then the result is 2 (yes). With the exception that if "
-"either of you has style of 2 or less, then the result is 0 (no). Otherwise "
-"the result is 1 (maybe)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/GreenTicket.html:1
-msgid "GreenTicket"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/GreenTicket.html:2
-msgid ""
-"You have a green lottery ticket, with ints a, b, and c on it. If the numbers "
-"are all different from each other, the result is 0. If all of the numbers "
-"are the same, the result is 20. If two of the numbers are the same, the "
-"result is 10."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/In1To10.html:1
-msgid "In1To10"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/In1To10.html:2
-msgid ""
-"Given a number n, return true if n is in the range 1..10, inclusive. Unless "
-"\"outsideMode\" is true, in which case return true if the number is less or "
-"equal to 1, or greater or equal to 10."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/InOrderEqual.html:1
-msgid "InOrderEqual"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/InOrderEqual.html:2
-msgid ""
-"Given three ints, a b c, return true if they are in strict increasing order, "
-"such as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the "
-"exception that if \"equalOk\" is true, equality is allowed, such as 5 5 7 or "
-"5 5 5."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/InOrder.html:1
-msgid "InOrder"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/InOrder.html:2
-msgid ""
-"Given three ints, a b c, return true if b is greater than a, and c is "
-"greater than b. However, with the exception that if \"bOk\" is true, b does "
-"not need to be greater than a."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/LastDigit2.html:1
-msgid "LastDigit 2"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/LastDigit2.html:2
-msgid ""
-"Given three ints, a b c, return true if two or more of them have the same "
-"rightmost digit. The ints are non-negative. Note: the % \"mod\" operator "
-"computes the remainder, e.g. 17 % 10 is 7."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/LessBy10.html:1
-msgid "LessBy10"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/LessBy10.html:2
-msgid ""
-"Given three ints, a b c, return true if one of them is 10 or more less than "
-"one of the others."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/Main.html:1
-msgid "Boolean (even more) fun"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/bool2/Main.html:3
-msgid ""
-"A very good introduction to this type is available here: "
-"http://javabat.com/doc/ifboolean.html."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/MaxMod5.html:1
-msgid "MaxMod5"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/MaxMod5.html:2
-msgid ""
-"Given two int values, return whichever value is larger. However if the two "
-"values have the same remainder when divided by 5, then the return the "
-"smaller value. However, in all cases, if the two values are the same, return "
-"0.  Note: the % \"mod\" operator computes the remainder, e.g. 7 % 5 is 2."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/NearTen.html:1
-msgid "NearTen"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/NearTen.html:2
-msgid ""
-"Given a non-negative number \"num\", return true if num is within 2 of a "
-"multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % "
-"5) is 2."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/RedTicket.html:1
-msgid "RedTicket"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/RedTicket.html:2
-msgid ""
-"You have a red lottery ticket showing ints a, b, and c, each of which is 0, "
-"1, or 2. If they are all the value 2, the result is 10. Otherwise if they "
-"are all the same, the result is 5. Otherwise so long as both b and c are "
-"different from a, the result is 1. Otherwise the result is 0."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/ShareDigit.html:1
-msgid "ShareDigit"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/ShareDigit.html:2
-msgid ""
-"Given two ints, each in the range 10..99, return true if there is a digit "
-"that appears in both numbers, such as the 2 in 12 and 23. (Note: division, "
-"e.g. n/10, gives the left digit while the % \"mod\" n%10 gives the right "
-"digit.)"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/SortaSum.html:1
-msgid "SortaSum"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/SortaSum.html:2
-msgid ""
-"Given 2 ints, a and b, return their sum. However, sums in the range 10..19 "
-"inclusive, are forbidden, so in that case just return 20."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/SquirrelPlay.html:1
-msgid "SquirrelPlay"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/SquirrelPlay.html:2
-msgid ""
-"The squirrels in Palo Alto spend most of the day playing. In particular, "
-"they play if the temperature is between 60 and 90 (inclusive). Unless it is "
-"summer, then the upper limit is 100 instead of 90. Given an int temperature "
-"and a boolean isSummer, return true if the squirrels play and false "
-"otherwise."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TeaParty.html:1
-msgid "TeaParty"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TeaParty.html:2
-msgid ""
-"We are having a party with amounts of tea and candy. Return the int outcome "
-"of the party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if "
-"both tea and candy are at least 5. However, if either tea or candy is at "
-"least double the amount of the other one, the party is great (2).  However, "
-"in all cases, if either tea or candy is less than 5, the party is always bad "
-"(0)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TeenSum.html:1
-msgid "TeenSum"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TeenSum.html:2
-msgid ""
-"Given 2 ints, a and b, return their sum. However, \"teen\" values in the "
-"range 13..19 inclusive, are extra lucky. So if either value is a teen, just "
-"return 19."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/TwoAsOne.html:1
-msgid "TwoAsOne"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/TwoAsOne.html:2
-msgid ""
-"Given three ints, a b c, return true if it is possible to add two of the "
-"ints to get the third."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/bool2/WithoutDoubles.html:1
-msgid "WithoutDoubles"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/bool2/WithoutDoubles.html:2
-msgid ""
-"Return the sum of two 6-sided dice rolls, each in the range 1..6. However, "
-"if noDoubles is true, if the two dice show the same value, increment one die "
-"to the next value, wrapping around to 1 if its value was 6."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/jlm/universe/bat/BatWorld.html:1
-msgid "BatWorld"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:3
-msgid ""
-"This world is a simplistic testing environment largely inspired from the "
-"http://codingbat.com invented by Nick Parlente."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:6
-msgid ""
-"The typical exercises are very short ones, aiming at improving the tactical "
-"programming abilities of the students. That is to say that you will be "
-"presented a quite long list of very little exercises about rather simple "
-"things. The idea is to train you on these issues until they become automatic "
-"to you."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:12
-msgid ""
-"In contrary to the other worlds, the BatWorld does not provide any fancy "
-"abstraction nor visualization. You have to fill a function, which gets "
-"called for a bunch of parameter sets, and that's it."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/jlm/universe/bat/BatWorld.html:16
-msgid ""
-"For more information, you should refer to the CodingBat.com documentation, "
-"which contains for example a very useful documentation on boolean operators: "
-"http://codingbat.com/doc/ifboolean.html"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/Main.html:1
-msgid "String fun"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/bat/string1/Main.html:3
-msgid ""
-"Strings are the simplest of the complex data types :) They provide several "
-"operations, such as getting the length of the string, or a substring of it.."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/bat/string1/Main.html:7
-msgid ""
-"A very good introduction to this type is available here: "
-"http://javabat.com/doc/string.html."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/bat/string1/short_desc.html:1
-msgid "Small exercises about strings"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/bat/string1/short_desc.html:3
-msgid ""
-"These are some training exercises around strings. But unfortunately, its "
-"integration within JLM is still ongoing."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/bat/string1/short_desc.html:6
-msgid "Please be patient with us."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/AltPairs.html:1
-msgid "AltPairs"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/AltPairs.html:2
-msgid ""
-"Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 "
-"... so \"kittens\" yields \"kien\"."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/FrontTimes.html:1
-msgid "FrontTimes"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/FrontTimes.html:2
-msgid ""
-"Given a string and a non-negative int n, we'll say that the front of the "
-"string is the first 3 chars, or whatever is there if the string is less than "
-"length 3. Return n copies of the front;"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/Last2.html:1
-msgid "Last2"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/bat/string1/Last2.html:3
-msgid ""
-"Given a string, return the amount of times that the two last letters appear "
-"as a substring of the string. So \"hixxxhi\" yields 1 (we won't count the "
-"end substring) while \"aaaNaa\" yields 2 (substrings may overlap)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringBits.html:1
-msgid "StringBits"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringBits.html:2
-msgid ""
-"Given a string, return a new string made of every other char starting with "
-"the first, so \"Hello\" yields \"Hlo\"."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringMatch.html:1
-msgid "StringMatch"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringMatch.html:2
-msgid ""
-"Given 2 strings, a and b, return the number of the positions where they "
-"contain the same length 2 substring. So \"xxcaazz\" and \"xxbaaz\" yields 3, "
-"since the \"xx\", \"aa\", and \"az\" substrings appear in the same place in "
-"both strings."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringSplosion.html:1
-msgid "StringSplosion"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringSplosion.html:2
-msgid "Given a non-empty string like \"Code\" return a string like \"CCoCodCode\"."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringTimes.html:1
-msgid "StringTimes"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringTimes.html:2
-msgid ""
-"Given a string and a non-negative int n, return a larger string that is n "
-"copies of the original string."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringX.html:1
-msgid "StringX"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringX.html:2
-msgid ""
-"Given a string, return a version where all the \"x\" have been "
-"removed. Except an \"x\" at the very start or end should not be removed."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/bat/string1/StringYak.html:1
-msgid "StringYak"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/bat/string1/StringYak.html:2
-msgid ""
-"Suppose the string \"yak\" is unlucky. Given a string, return a version "
-"where all the \"yak\" are removed, but the \"a\" can be any char. The "
-"\"yak\" strings will not overlap."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/basics/Array.html:1
-msgid "Knotting and sequences"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/basics/Array.html:3
-msgid ""
-"The goal of this exercise is to reproduce the pattern of the first row in "
-"the other rows with a shift of one cell (see the Objective tab for "
-"details). The biggest difference between this exercise and the other we had "
-"on patterns is that you have to read the pattern (on first row) before "
-"reproducing it. You cannot do otherwise because the same code will be "
-"executed on three different worlds, each of them having its specific "
-"pattern."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:11
-msgid ""
-"One solution is to read the next cell, and go copy it in position before "
-"coming back to read the second cell. But since it is forbidden to use the "
-"methods to teleport the buggle to a specific position (<code>setPos()</code> "
-"and similar), this approach will be a pain to implement."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:16
-msgid ""
-"The simplest is to store the sequence of colors that constitute the whole "
-"pattern in an <b>array</b>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:19
-msgid ""
-"An array is a sequence of positions in which one can store values of the "
-"same kind (one value per cell). It is thus a sequence of values of the same "
-"kind:"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:24
-msgid ""
-"The simplest is to store the sequence of colors that constitute the whole in "
-"a <b>list</b>."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/welcome/array/basics/Array.html:26
-msgid "Lists"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array.html:27
-msgid ""
-"A list is an array of positions in which one can store values. Each cell is "
-"a variable on its own. A list is then a sequence of values. Lists can even "
-"mix values of differing types, such as integer values in some cells and "
-"colors in other cells.  At the end, a list is very similar to a storage "
-"shelve, where each level can store a separate value."
-msgstr ""
-
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:38
-msgid ""
-"T is the array's name, T[0] is the name of the first cell, T[1] the name of "
-"the second cell, T[2] the third one, etc. And yes, the first cell in "
-"numbered T[0] and the last one of an array of size N is T[N-1]."
-msgstr ""
-
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:41
-msgid ""
-"T is the list's name, T[0] is the name of the first cell, T[1] the name of "
-"the second cell, T[2] the third one, etc. And yes, the first cell in "
-"numbered T[0] and the last one of a list of size N is T[N-1]. It may seem "
-"funny to count starting from 0 and not from 1 as usual, but some historical "
-"reasons make it unavoidable here."
-msgstr ""
-
-#. type: Content of: <br><p>
-#: src/lessons/welcome/array/basics/Array.html:47
-msgid ""
-"We can use an integer variable <i>i</i> to access with T[i] to the cells: "
-"when the value of <i>i</i> is 0, then T[i] accesses T[0], when the value of "
-"<i>i</i> is 10, then T[i] accesses T[10]. <i>i</i> is said to be the index "
-"in T."
-msgstr ""
-
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:52
-msgid "Initialization"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:53
-msgid ""
-"If <code>T</code> contains 10 elements, then each cell can be initialized "
-"with a simple loop:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:56
-#, no-wrap
-msgid ""
-"for (int i = 0; i<10; i++) {\n"
-"   T[i] = 3;\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:61
-#, no-wrap
-msgid ""
-"for i in range(10):\n"
-"   T[i] = 3;\n"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:65
-msgid ""
-"Note that <code>range(max)</code> returns the list of all integers that are "
-"smaller than <code>max</code>, starting with 0. There is exactly max such "
-"values. For example, if <code>max</code> is 3, the returned values are 0, 1 "
-"and 2."
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:70
-msgid "<code>T[i]</code> can be used just like a variable. We can set a new value:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:71
-#, no-wrap
-msgid "T[i] = 78"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:73
-msgid "We can retrieve and use its value:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:74
-#, no-wrap
-msgid "x = T[i]"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:76
-msgid "We can test this value:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:78
-#, no-wrap
-msgid ""
-"if (T[i] > 0 ) {\n"
-"    // instructions...\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:83
-#, no-wrap
-msgid ""
-"if T[i] > 0:\n"
-"    // instructions...\n"
-msgstr ""
-
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:87
-msgid "Declaring an array"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:88
-msgid ""
-"If you know beforehand the content of your list, you can affect these values "
-"all together.  Just put them between square braces and separated by commas "
-"as follows:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:91
-#, no-wrap
-msgid ""
-"L = [1, 3, 5, 7, 9] \n"
-"# L is now an array of 5 values, all of them being integers\n"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:94
-msgid ""
-"Otherwise, you probably want to create an empty list and then append each "
-"values separately:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:96
-#, no-wrap
-msgid ""
-"L2 = [] \n"
-"# L2 is now an empty list\n"
-"L2.append(1)\n"
-"L2.append(3)\n"
-"L2.append(5)\n"
-"L2.append(7)\n"
-"L2.append(9) \n"
-"# Its content is now the same as L previously\n"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:106
-msgid "An array can be declared the following way:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:107
-#, no-wrap
-msgid "int[] T;"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:109
-msgid ""
-"<code>int</code> means that the elements of the array are of type integer; "
-"<code>T</code> is the name of the array and <code>[]</code> means that we "
-"are speaking of an array. It is also possible to declare the same array the "
-"following way. Both writings are equivalent, but the first one is often "
-"prefered in Java."
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:114
-#, no-wrap
-msgid "int T[];"
-msgstr ""
-
-#. type: Content of: <br><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:116
-msgid "Allocating an array"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:118
-msgid ""
-"Declaring a variable <code>T</code> that stores an array only reserve the "
-"name <code>T</code> for later use. But the array is not initialized yet: it "
-"does not have any value. What would <code>T[4]</code> mean if we didn't say "
-"that the array is at least 5 cells long?"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:123
-msgid "First and foremost, we have to give a value to <code>T</code>:"
-msgstr ""
-
-#. type: Content of: <br><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:124
-#, no-wrap
-msgid "T = new int[10];"
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:126
-msgid ""
-"<code>new</code> means that we want to create something, and "
-"<code>int[10]</code> means that it is an array of 10 integer values. In "
-"return, an array of 10 integer cells is created in memory, and the "
-"<code>T</code> variable reference this array."
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:131
-msgid ""
-"The size of an array is fixed and cannot be changed after the creation of "
-"the array. To know the size of a <code>T</code> array, we can consult the "
-"value of the variable <code>T.length</code>."
-msgstr ""
-
-#. type: Content of: <br><p><p>
-#: src/lessons/welcome/array/basics/Array.html:136
-msgid ""
-"It is forbidden to write something like <code>int T[10];</code> You are "
-"required to use the <code>new</code> instruction. On the other hand, you "
-"perfectly can specify the size with a variable <code>i</code>."
-msgstr ""
-
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:140
-#, no-wrap
-msgid "T = new int[i];"
-msgstr ""
-
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:141
-msgid ""
-"In this case, the array's size will be set to the value of <code>i</code> "
-"<b>when <code>new</code> gets called</b>. If the variable changes afterward, "
-"it won't change the array's size."
-msgstr ""
-
-#. type: Content of: <br><p><p><h4>
-#: src/lessons/welcome/array/basics/Array.html:145
-msgid "Declaration and allocation"
-msgstr ""
-
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:146
-#, no-wrap
-msgid "int[] T = new int[10];"
-msgstr ""
-
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:148
-msgid "We declare and allocate the array on the same line."
-msgstr ""
-
-#. type: Content of: <br><p><p><h4>
-#: src/lessons/welcome/array/basics/Array.html:150
-msgid "Declaration and initialization"
-msgstr ""
-
-#. type: Content of: <br><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:151
-#, no-wrap
-msgid "int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };"
-msgstr ""
-
-#. type: Content of: <br><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:153
-msgid ""
-"We declare, allocate and initialize the array on the same line. To know the "
-"size of the array to allocate, the compiler counts the provided values. This "
-"code is equivalent to:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:157
-#, no-wrap
-msgid ""
-"int[] T = new int[10];\n"
-"T[0] = 1;\n"
-"T[1] = 2;\n"
-"...\n"
-"T[9] = 10;\n"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:164
-msgid "It is also equivalent to:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:166
-#, no-wrap
-msgid ""
-"int[] T = new int[10];\n"
-"for (int i=0; i<T.length; i++) {\n"
-"  T[i] = i+1;\n"
-"}\n"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:176
-msgid "Lists and method parameters"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:177
-msgid ""
-"It is perfectly ok to pass a list to a method as a parameter. This method "
-"can then use this parameter as if it were defined there. Methods can also "
-"return lists as result without any complication. As an example, here is a "
-"method doubling every values of the list received as a parameter:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:182
-#, no-wrap
-msgid ""
-"L = [1, 3, 5, 7, 9]\n"
-"def doubling(param):\n"
-"  for i in range( len(param) ):\n"
-"    param[i] *= 2\n"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><h3>
-#: src/lessons/welcome/array/basics/Array.html:189
-msgid "Arrays and method parameters"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:190
-msgid ""
-"It is perfectly ok to pass an array to a method as a parameter. The method "
-"must have a prototype similar to:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:192
-#, no-wrap
-msgid ""
-"void myMethod(int[] values) {\n"
-"  // do something\n"
-"}"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:196
-msgid "On the caller side, that also very simple:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:198
-#, no-wrap
-msgid ""
-"int[] tab = new int[10];\n"
-"// initalize the values\n"
-"myMethod(tab);\n"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:203
-msgid "We can also have methods returns arrays as results:"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><pre>
-#: src/lessons/welcome/array/basics/Array.html:204
-#, no-wrap
-msgid ""
-"int[] otherMethod() {\n"
-"  int[] result = new int[10];\n"
-"  // do something\n"
-"  return result;\n"
-"}"
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:211
-msgid ""
-"Your code should save the color pattern observed on the first row into a "
-"list.  The easiest is to create an empty list, and then "
-"<code>append()</code> the colors one after the others."
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:215
-msgid ""
-"The <code>run()</code> method that you should write must declare an array of "
-"colors (<code>Color[]</code>) and allocate it. Beware, the first world is "
-"6x6, but this is not the case of the others. Use the "
-"<code>getWorldHeight()</code> method to retrieve the amount of lines in the "
-"current world."
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:221
-msgid ""
-"Once the array allocated, we have to fill it. For each cel of the row, read "
-"the ground color (with <code>getGroundColor()</code>), and store it in the "
-"right cell of the array."
-msgstr ""
-
-#. type: Content of: <br><p><p><p><p><p><p>
-#: src/lessons/welcome/array/basics/Array.html:225
-msgid ""
-"Once you managed to read and save the pattern on the first row, you have to "
-"reapply the pattern on every rows, for example by executing "
-"<code>getWorldHeight()</code> times a method written specifically for this."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/basics/Array2.html:1
-msgid "Knotting, sequences and modulo"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/basics/Array2.html:3
-msgid ""
-"This exercise is similar to the previous one: you have to reproduce the "
-"color pattern of the first cell into the other ones."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array2.html:6
-msgid ""
-"The first difference is that the world is bordered of walls: you thus have "
-"to slightly modify your trajectory to ensure that the buggle does not crash "
-"into a wall. The simpler for that is to handle the first cell out of the "
-"<code>for</code> loop and do only <code>getWorldHeight()-1</code> steps in "
-"the loop."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array2.html:12
-msgid ""
-"The other difference is that the offset to apply between columns is not "
-"fixed, but written on the first cell of each column. To get the info as an "
-"integer, we can use:"
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/array/basics/Array2.html:15
-#, no-wrap
-msgid "int offset = Integer.parseInt(readMessage())"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array2.html:17
-msgid ""
-"<code>readMessage()</code> gets the message on the ground as a String, while "
-"<code>Integer.parseInt()</code> transforms a String into an integer by "
-"<i>reading</i> it."
-msgstr ""
-
-#. type: Content of: <p><pre>
-#: src/lessons/welcome/array/basics/Array2.html:21
-#, no-wrap
-msgid "offset = int( readMessage() )"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/basics/Array2.html:22
-msgid ""
-"<code>readMessage()</code> gets the message on the ground as a String, while "
-"<code>int()</code> transforms it into an integer value by <i>reading</i> it."
-msgstr ""
-
-#. type: Content of: <p><p>
-#: src/lessons/welcome/array/basics/Array2.html:25
-msgid ""
-"Then, to pick the right color, the easier is to use the <code>%</code> "
-"(modulo) operator. For example, <code>(i + 5) % size</code> allows to "
-"retrieve the <code>i</code>th cell of an array of size <code>size</code> "
-"with an offset of <code>5</code>."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:1
-msgid "Searching for a given value"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:3
-msgid ""
-"The goal of this exercise is to search the cell of a given value, and return "
-"its position."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:5
-msgid ""
-"To that extend, you should fill the method <code>indexOf()</code>, which "
-"parameters are the array to explore, and the value to search. If the value "
-"<code>lookingFor</code> is not in the array <code>tab</code>, the method "
-"should return -1."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:9
-msgid ""
-"The idea of the algorithm is to sweep over the whole array, checking the "
-"value of each cell. If it's the searched value, you should return the index "
-"of the cell currently checked."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:13
-msgid ""
-"Remember that indices begin at 0 and not at 1. So, if there is 3 cells, "
-"their indices will be 0, 1 and 2. There would not be any cell numbered 3."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:16
-msgid ""
-"Remember also that the amount of cells in an array can be retrieved using "
-"the <code>length</code> attribute. So, if your array is called "
-"<code>tab</code>, its size can be retrieved as <code>tab.length</code>.  "
-"Note that there is no () after <code>length</code>. An attribute is a sort "
-"of variable embedded in another object (here, the array)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:21
-msgid "So, the last value of an array is given by <code>tab[tab.length - 1]</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:23
-msgid ""
-"Remember also that the amount of cells in an array can be retrieved with the "
-"<code>len()</code> function. So, if your array is called <code>tab</code>, "
-"its size can be retrieved as <code>len(tab)</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:27
-msgid "So, the last value of an array is given by <code>tab[ len(tab) - 1]</code>."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:1
-msgid "Index of the maximum value"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:3
-msgid ""
-"In this exercise, you must compute the index of the tab cell containing the "
-"biggest value."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:5
-msgid ""
-"For that, fill the <code>indexOfMaximum()</code> method. Its parameter is "
-"the array to explore. Should the array contain the searched value several "
-"times, you should return the index of the first occurrence."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:9
-msgid ""
-"To solve this exercise, you should sweep over the whole array. For each "
-"value, if it's bigger than the biggest value you saw so far, you must save "
-"this new champion and its position.  You will thus need 2 extra variables; "
-"the initial value of the champion could be the value of the first cell."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:1
-msgid "Average value"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:4
-msgid ""
-"The objective of this exercise is to compute the average value of the "
-"integer values stored in an array."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:6
-msgid ""
-"You have to fill the body of the method <code>average()</code> which takes "
-"as parameter the array of integers of which it computes and returns the "
-"average value. Please note that this method must return an integer."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:8
-msgid ""
-"To compute the average value of an integer, it is necessary to traverse the "
-"whole array and to compute the sum of all its values (so you will need a "
-"variable to store this temporary result), then you have to divide this sum "
-"by the size of the array."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:10
-msgid ""
-"In Java, you can get the size of an array <code>myarray</code> by consulting "
-"its <code>length</code> attribute (in other words, "
-"<code>myarray.length</code>). Notice that there is no parenthesis after "
-"<code>length</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/averagevalue/AverageValue.html:15
-msgid ""
-"In python, retrieving the size of an array <code>myarray</code> is as easy "
-"as calling <code>len(myarray)</code>."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/maxvalue/MaxValue.html:1
-msgid "Maximal value"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/maxvalue/MaxValue.html:3
-msgid ""
-"In this exercise, you must compute the maximal value contained in an array.  "
-"For that, fill the <code>maximum()</code> method, which parameter is the "
-"array to explore."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/maxvalue/MaxValue.html:7
-msgid ""
-"To compute this value, sweep over the whole parameter. For each value, if "
-"it's bigger than the biggest value you saw so far, you must save this value "
-"somewhere to remember it afterward. You thus need an extra variable, which "
-"can be initialized to the value of the first array cell."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:1
-msgid "Occurrence of a value"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:3
-msgid ""
-"In this exercise, you must compute the amount of occurrences of a given "
-"value in an array (that is, the amount of time that this value appears in "
-"the array). For that, fill the <code>occurrences()</code> method, which "
-"returns the number of occurrence of <code>lookingFor</code> in "
-"<code>tab</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:8
-msgid ""
-"To compute this value, simply sweep over the array counting for the amount "
-"of cells containing the searched value. You thus need an extra variable for "
-"that."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/array123/Array123.html:1
-msgid "Array123"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/array123/Array123.html:2
-msgid ""
-"Given an array of integers, return true if .. 1, 2, 3, .. appears in the "
-"array somewhere."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/array667/Array667.html:1
-msgid "Array667"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/array667/Array667.html:2
-msgid ""
-"Given an array of integers, return the number of times that two 6's are next "
-"to each other in the array. Also count instances where the second \"6\" is "
-"actually a 7."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/arraycount9/ArrayCount9.html:1
-msgid "ArrayCount9"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/arraycount9/ArrayCount9.html:2
-msgid "Given an array of integers, return the number of 9's in the array."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/arrayfront9/ArrayFront9.html:1
-msgid "ArrayFront9"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/arrayfront9/ArrayFront9.html:2
-msgid ""
-"Given an array of integers, return true if one of the first 4 elements in "
-"the array is a 9. The array length may be less than 4."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/notriples/NoTriples.html:1
-msgid "NoTriples"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/notriples/NoTriples.html:2
-msgid ""
-"Given an array of integers, we'll say that a triple is a value appearing 3 "
-"times in a row in the array. Return true if the array does not contain any "
-"triples."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/welcome/array/has271/Has271.html:1
-msgid "Has271"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/welcome/array/has271/Has271.html:2
-msgid ""
-"Given an array of integers, return true if it contains a 2, 7, 1 pattern -- "
-"a value, followed by the value plus 5, followed by the value minus 1.  "
-"Additionally the 271 counts even if the \"1\" differs by 2 or less from the "
-"correct value."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:1
-msgid "PancakeWorld"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:3
-msgid "This universe is very simple, with only five functions provided."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:5
-#, no-wrap
-msgid "int getStackSize()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:6
-#, no-wrap
-msgid "getStackSize()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:7
-msgid "Returns the size of the stack, that is the amount of pancakes it contains."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:9
-#, no-wrap
-msgid "int getPancakeRadius(int rank)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:10
-#, no-wrap
-msgid "getPancakeRadius(rank)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:11
-msgid ""
-"Returns the radius of the pancake passed as argument, with the rank of the "
-"top-most pancake being 0."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:13
-#, no-wrap
-msgid "boolean isPancakeUpsideDown(int rank)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:14
-#, no-wrap
-msgid "isPancakeUpsideDown(rank)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:15
-msgid ""
-"Returns whether the pancake passed as argument upside-down, that is, if its "
-"burned side is on top. As usual, the top-most pancake is of rank 0."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:17
-#, no-wrap
-msgid "void flip(int amount)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:18
-#, no-wrap
-msgid "flip(amount)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:19
-msgid ""
-"Flips the <code>amount</code> first pancakes composing the stack, from the "
-"top of it."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:21 src/lessons/sort/baseball/universe/BaseballWorld.html:34
-#, no-wrap
-msgid "boolean isSorted()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:22 src/lessons/sort/baseball/universe/BaseballWorld.html:35
-#, no-wrap
-msgid "isSorted()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/pancake/universe/PancakeWorld.html:23
-msgid "Returns whether the pancake stack is correctly sorted."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/pancake/Main.html:1 src/lessons/sort/pancake/BasicPancake.html:1
-msgid "Pancake Sorting"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:3
-msgid ""
-"This activity is inspired by a problem first introduced in 1975 by Harry "
-"Dweighter in the American Mathematical Monthly. The question is not only to "
-"sort the pancakes, but to determine <code>f(n)</code> the <i>minimal</i> "
-"amount of flips mandated to sort any stack of size <code>n</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:7
-msgid ""
-"This problem is now famous because Bill Gates authored (with "
-"C. Papadimitriou) his only scientific publication in 1979 on this topic, "
-"providing a faster algorithm and proving that <code>17n/16 ≤ f(n) ≤ "
-"(5n+5)/3</code>.  This was the only publication of Bill Gates before he "
-"invented Windows and became rich."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:11
-msgid ""
-"Then, David X. Cohen, the inventor of the Futurama comics with many "
-"mathematical references, introduced the variant with burnt pancakes and "
-"studied its complexity with Manuel Blum in 1993."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:14
-msgid ""
-"An article of 2012 (by L. Bulteau, G. Fertin and I. Rusu) proved that "
-"determining the minimal amount of flips to sort the stack is a NP-complete "
-"problem. Naturally, the stack sorting problem is not NP-complete since it "
-"can be solved in 2n-3 steps with the naive algorithm and (5n+5)/3 steps with "
-"the Gates algorithm.  That's determining the minimal amount of steps that is "
-"NP."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:19
-msgid "Further information can be found on the wikipedia page, as usual."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/Main.html:22
-msgid ""
-"This activity is also integrated to CSIRL (my repository of <i>free</i> "
-"unplugged activities to introduce computer science, available at "
-"http://www.loria.fr/~quinson/Mediation/SMN/), and it may be interesting to "
-"run the unplugged activities before implementing these algorithms in JLM."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/Main.html:33
-msgid "A temporal view similar to the sorting universe could be helpful"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/Main.html:34
-msgid "Other exercises, for example on the Cohen's algorithm, or on the other ones."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/sort/pancake/short_desc.html:1
-msgid "The pancake problem"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/short_desc.html:3
-msgid "Help the poor psychorigid pancakes' chef to sort its pancake stack!"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/short_desc.html:5
-msgid ""
-"This funny problem leads to algorithms that are somewhat more challenging to "
-"implement. You are supposed to master the bases of programming and some "
-"sorting algorithms to take this lesson."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/BasicPancake.html:3
-msgid ""
-"The pancake sorting problem this is a simple puzzle where you have a set of "
-"pancakes, each of differing size. The chef cooking the pancake is a bit "
-"psychorigid: he hates when the pancakes are not correctly sorted on the "
-"plate. He loves when they are correctly ordered, with the small ones over "
-"the larger ones. As every pancake maker, he masters the pancake flipping "
-"with his spatula. He can flip the pancake on top of the stack, or even "
-"several pancakes at once. The thing is that he has only one plate and the "
-"table is too dirty to place pancakes on it, even temporary. The only allowed "
-"operation is to flip some pancakes that are on top of the stack."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/BasicPancake.html:12
-msgid ""
-"Your work is to help this poor guy sorting his stack by flipping the "
-"pancakes. Each pancake is defined by its radius and rank within the stack, "
-"where the bottom pancake is at rank 0, and the one above at rank 1."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/BasicPancake.html:16
-msgid ""
-"Note that you can play physically with pieces of paper or wood at first to "
-"get the grasp on this problem. This is even one of the activities that I use "
-"in my CS-IRL (computer science in real life) project to introduce the "
-"concept of algorithm to absolute beginners that wonder about our "
-"science. More information at http://www.loria.fr/~quinson/Mediation/SMN/ (in "
-"French)."
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:22
-msgid "I don't get it. I need some help."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:23
-msgid ""
-"You should try to first move the largest pancake to the bottom, and then the "
-"largest but one pancake on top of it, and then the one just smaller on top, "
-"and so on."
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:27
-msgid "The first tip was not enough. I need another one."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:28
-msgid "So first, you need to move the largest pancake at the bottom of the stack."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:29
-msgid ""
-"Can you imagine a situation in which you can easily bring this damn large "
-"pancake to the bottom?"
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/BasicPancake.html:30
-msgid "How could you reach this situation from the current one?"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/pancake/BurnedPancake.html:1
-msgid "Burned Pancakes"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/BurnedPancake.html:3
-msgid ""
-"Hard blow for the chef! The pancakes got burnt on one side! There is no way "
-"he can deliver a stack of pancakes with visibly burnt pancakes! You've got "
-"to help him ensuring that no pancake is upside-down while sorting his stack."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/pancake/GatesPancake.html:1
-msgid "Faster Pancake Sorting"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/GatesPancake.html:3
-msgid ""
-"Unlike others sorting problem, the expensive operation is not the comparison "
-"of values, but the flipping of pancakes. In this exercise, we will explore "
-"another algorithm that attempt to reduce the amount of stack flipping. The "
-"funny side is that this algorithm was first introduced by Bill Gates, before "
-"invented Windows."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/GatesPancake.html:8
-msgid ""
-"The basic idea is to grow sequences of sorted pancakes, not necessarily "
-"starting from the bottom.  We say that a sequence of ordered pancakes "
-"constitute a <b>bloc</b> while a pancake that is not part of a bloc is said "
-"to be <b>free</b>. The algorithm then considers the topmost pancake (of "
-"radius <code>t</code>) and search for the <code>t+1</code> or "
-"<code>t-1</code> pancakes (the considered neighbor is noted "
-"<code>t+o</code>). Eight cases may happen:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:15
-msgid ""
-"<b>Case a</b>: Both <code>t</code> and <code>t+o</code> are free. They are "
-"then merged in one flip."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:19
-msgid ""
-"<b>Case b</b>: <code>t</code> is free, and <code>t+o</code> is the first of "
-"a block. They are merged in one flip."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:24
-msgid ""
-"<b>Case c</b>: <code>t</code> is free but both <code>t-1</code> and "
-"<code>t+1</code> are the last elements of blocks.  Both blocs and "
-"<code>t</code> are merged all together in 4 flips.  Beware, if either "
-"<code>t-1</code> or <code>t+1</code> does not exist (because <code>t</code> "
-"is 0 or max), only two flips are mandated."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:32
-msgid ""
-"<b>Case d</b>: <code>t</code> is in a block but <code>t+o</code> is "
-"free. They are merged in one flip."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:37
-msgid ""
-"<b>Case e</b>: <code>t</code> is in a block and <code>t+o</code> is the "
-"first element of a block. They are merged in one flip."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:41
-msgid ""
-"<b>Case f</b>: <code>t</code> is in a block and <code>t+o</code> is the last "
-"element of another block.  They are merged in 3 flips as follows."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:45
-msgid ""
-"<b>Case g</b>: <code>t</code> is in a block of length k+1 (the last element "
-"is <code>t+ko</code>), <code>t+(k+1)o</code> is either free or the last "
-"element of another block. Both blocks are merged in 2 flips:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:48
-msgid ""
-"<b>Case h</b>: <code>t</code> is in a block of length k+1 (the last element "
-"is <code>t+ko</code>), <code>t+(k+1)o</code> is the first element of another "
-"block (the difference with case g is that <code>t+(k+1)o</code> is now the "
-"<i>first</i> element of its block). Both blocks are merged in 2 flips:"
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/pancake/GatesPancake.html:54
-msgid ""
-"<b>Case i</b>: <code>t</code> is in a block of length <code>n</code> (this "
-"block contains all pancakes).  If <code>t</code> is not 1, the whole stack "
-"is fliped. The algorithm then stops."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/GatesPancake.html:57
-msgid ""
-"Each iteration increases the size of the blocks, so the algorithm eventually "
-"halts in all cases. A finer analysis would show that it takes at most "
-"<code>(5n+5)/3</code> steps to sort the stack. That's better than the naïve "
-"algorithm, that requires 2n-3 steps."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/pancake/GatesPancake.html:60
-msgid "Your turn"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/GatesPancake.html:61
-msgid ""
-"You now have almost enough information to implement this algorithm on your "
-"own. We just have to remove the last remaining ambiguities to ensure that "
-"you implement exactly the same algorithm that the correction. If several "
-"cases apply to your situation, then you should use the first given one. For "
-"example, if both cases a and b apply (e.g., with <code>t-1</code> on case "
-"<b>a</b> and <code>t+1</code> on case <b>b</b>), then you should apply the "
-"flips of case <b>a</b>. If a given case applies for both <code>t+1</code> "
-"and <code>t-1</code>, then you should apply it to <code>t+1</code>."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/pancake/GatesPancake.html:67
-msgid ""
-"Note that it is somehow harder than the other exercises we did so far, so "
-"don't be surprised if you need more time to achieve this.  But do not give "
-"hope, you can do it!"
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><div>
-#: src/lessons/sort/pancake/GatesPancake.html:70
-msgid "Well, I need some help to start."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/GatesPancake.html:71
-msgid ""
-"First write some helper functions such as <code>isFirst()</code> or "
-"<code>isFree()</code>. This will simplify your main algorithm afterward, "
-"that can be written very similarly to the explication above with a bunch of "
-"if conditions. Factorizing code this way often helps making your code more "
-"readable."
-msgstr ""
-
-#. type: Attribute 'alt' of: <p><div>
-#: src/lessons/sort/pancake/GatesPancake.html:78
-msgid "My code keeps failing and I don't know how to debug it."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/GatesPancake.html:79
-msgid ""
-"To debug one world after the other and avoid that the messages of all worlds "
-"get intermixed, you can write your debug function only if the method "
-"<code>isSelected()</code> returns true. It will be so only for the entity "
-"that is currently selected in the graphical interface, that is probably the "
-"world you are currently debugging. This will help breaking the difficulty in "
-"parts by debugging the situation on after the other."
-msgstr ""
-
-#. type: Content of: <p><div>
-#: src/lessons/sort/pancake/GatesPancake.html:85
-msgid ""
-"In particular, it may help to print textually the state of the world each "
-"time you enter the main loop."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/Main.html:1
-msgid "The Rainbow Baseball Game"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/Main.html:3
-msgid ""
-"This activity is inspired from the orange game, from the \"Computer Science "
-"Unplugged\" activities repository.  It was however heavily since then, first "
-"for the CSIRL (my repository of <i>free</i> unplugged activities to "
-"introduce computer science, available at "
-"http://www.loria.fr/~quinson/Mediation/SMN/) and now for JLM."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/Main.html:7
-msgid ""
-"In the literature, the generalized form of this problem is known as the "
-"pebble motion problem (the bases can be connected by any kind of graph, and "
-"the affinity of pebbles with bases may be different). Another variant of "
-"this problem is the well known 15-puzzle, with one player per base, and a "
-"two dimensional square grid. Much more information about these problems can "
-"be found on wikipedia, as usual."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/sort/baseball/Main.html:12
-msgid ""
-"How do you know that the naive algorithm won't loop on that initial "
-"situation?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/Main.html:14
-msgid ""
-"Well, we simply tested all possible situations to see when this algorithm "
-"loops and when it finds the correct solution. We found that it works for all "
-"situations where no player is at home (there is 84 such situations for 4 "
-"bases, once you take the symmetries into account). It obviously works for "
-"some situations that do not respect this criteria (such as all situations it "
-"encounters from one of those 84 boards to the final state), but that's "
-"another story. Having such a criteria allows us to generate pseudo-random "
-"initial situations for the first exercise for which the algorithm we propose "
-"is guarenteed to work."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/Main.html:21
-msgid ""
-"We also explored bigger instances of the problem, and unfortunately, we have "
-"no such criteria for them.  With 5 bases, the algorithm wrongly loops for 24 "
-"of the 1824 possible boards where no player is home (that's 1.31%).  With 6 "
-"bases, it fails on 1251 of the 58860 such boards (2.12%). With 7 bases, it "
-"fails for 84444 out of 2633940 (that's 3.2%). I am still looking for a "
-"criteria ensuring that the algorithm won't loop. If you discover one, please "
-"report it. Ideally, it would be simple to enforce manually so that we can "
-"use it during our unplugged activities."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/baseball/Main.html:31
-msgid ""
-"Other graphical representations could be proposed, such as a linear one (for "
-"the existing exercises) or other ones (such as a grid or a tree, if an "
-"exercise on this kind of graph proves interesting)."
-msgstr ""
-
-#. type: Content of: <ul><li>
-#: src/lessons/sort/baseball/Main.html:33
-msgid ""
-"Other exercises on other algorithms on this variant, or on other variants "
-"such as the 15-puzzle."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/sort/baseball/short_desc.html:1
-msgid "Rainbow baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/short_desc.html:3
-msgid ""
-"This is another funny variation on the sorting problem, adapting the main "
-"sorting algorithms on an unusual context."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:1
-msgid "Rainbow Baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:2
-msgid ""
-"The colors are represented by integers, between <code>0</code> and "
-"<code>amount of bases -1</code>.  The hole is represented by the special "
-"value <code>-1</code>.  The color of each base is its rank. So base "
-"<code>1</code> is of color <code>1</code>.  In the graphical interface, the "
-"base <code>0</code> is the dark blue one while the base <code>1</code> is "
-"the fuscia one."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:8
-msgid ""
-"Once every players on the field are in their home base, the hole should be "
-"in the last base, that is of rank <code>getAmountOfBases()-1</code>."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:10
-msgid "Functions to retrieve the world's dimensions"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:12
-#, no-wrap
-msgid "int getBasesAmount()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:13
-#, no-wrap
-msgid "getBasesAmount()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:14
-msgid "Returns the amount of bases on this field."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:16
-#, no-wrap
-msgid "int getPositionsAmount()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:17
-#, no-wrap
-msgid "getPositionsAmount()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:18
-msgid "Returns the amount of player's positions per base on this field:"
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:20
-msgid "Functions to retrieve the world's state"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:22
-#, no-wrap
-msgid "int getHoleBase()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:23
-#, no-wrap
-msgid "getHoleBase()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:24
-msgid "Returns the base in which the hole is located."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:26
-#, no-wrap
-msgid " int getHolePosition()"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:27
-#, no-wrap
-msgid "getHolePosition()"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:28
-msgid "Returns the hole position within its base"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:30
-#, no-wrap
-msgid " int getPlayerColor(int base, int position)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:31
-#, no-wrap
-msgid "getPlayerColor(base, position)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:32
-msgid "Returns the color of the player at a given location."
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:36
-msgid "Returns whether all players of the field are at home."
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:38
-#, no-wrap
-msgid "boolean isBaseSorted(int base)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:39
-#, no-wrap
-msgid "isBaseSorted(base)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:40
-msgid "Returns whether all players of a given base are at home."
-msgstr ""
-
-#. type: Content of: <h2>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:42
-msgid "Functions to change the world"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:44
-#, no-wrap
-msgid "void move(int base, int position)"
-msgstr ""
-
-#. type: Content of: <pre>
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:45
-#, no-wrap
-msgid "move(base, position)"
-msgstr ""
-
-#. type: Content of: outside any tag (error?)
-#: src/lessons/sort/baseball/universe/BaseballWorld.html:46
-msgid ""
-"Moves a given player into the hole. This throws an IllegalArgumentException "
-"if the specified player is not near the hole (at most one base away)."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/NaiveBaseball.html:1
-msgid "Naive Rainbow Baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:3
-msgid ""
-"Today, the buggles decided to play a baseball game, but they are rather out "
-"of luck, actually.  First, kinda forgot the rules, and ... well ... they "
-"cannot find the ball and bats again.  So they decided to \"adapt a bit\" the "
-"rules. As the are no ball, the buggles can only running around the field, "
-"what they do happily: for a while, all attending buggle run at full speed in "
-"all directions around the field."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:9
-msgid ""
-"But after a few collisions, they decide to invent new rules to organize a "
-"bit the game: They make one team per base and two players per team. One of "
-"the teams has only one player so that its base has an empty location. Then, "
-"the players are dispatched randomly around the bases, and the game for them "
-"is to reach their home base. The whole game stops when all players are "
-"home.  There is no winning team: either all players win, or they all "
-"lose. Actually, this game is very different from the original baseball. The "
-"only rule that remains is that you can only run around the field, from one "
-"base to the next one, without crossing middle of the field."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:17
-msgid ""
-"Now, they are asking you to help them deciding who and when should move so "
-"that each player returns to its base. Only one buggle can move at each "
-"round, from its position to the empty spot.  The maximal distance that a "
-"buggle can cover in one round is of one base."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:21
-msgid ""
-"So, at each round, the empty spot is on one base (say <code>B</code>), and "
-"you should decide which buggle enters that empty spot. There is four "
-"candidates (two from base <code>B-1</code> and two from base "
-"<code>B+1</code>). Actually, there is a fifth candidate since the buggle "
-"that is on the same base than the empty spot can change its position, but "
-"that's not really helping."
-msgstr ""
-
-#. type: Content of: <h3>
-#: src/lessons/sort/baseball/NaiveBaseball.html:26
-msgid "The Naïve algorithm"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:28
-msgid ""
-"In this exercise, we will first explore a very simple algorithm. To decide "
-"which of the four candidate buggles should enter the empty spot, we first "
-"restrict ourselves and decide that buggles can only turn clockwise. Then, "
-"from the two remaining candidates, we pick the one that has the largest "
-"distance to cover to reach its base (turning clockwise). Click on the demo "
-"button: this works rather well in practice."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:34
-msgid ""
-"It's hard to find a simpler algorithm for this problem: While it's not "
-"sorted, search for the base containing the candidate buggles: if the hole is "
-"in base <code>B</code>, it's the base <code>B+1</code>, modulo the amount of "
-"bases. Then, compute the distance that each buggle of that base still has to "
-"run to reach its base (0 if it's already home). Once you found the buggle "
-"that should enter the empty spot, just use the <code>move</code> method on "
-"it, and iterate."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/NaiveBaseball.html:40
-msgid ""
-"The main difficulty should be to get the few equations right: determining "
-"the base next to the hole should be easy, but determining the distance that "
-"a player has to cover may reveal a bit more challenging. Don't hesitate to "
-"draw pictures on a paper to cover all possible cases. It should not be that "
-"difficult either: there is not that many cases after all."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/SelectBaseball.html:1
-msgid "Selection Baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:3
-msgid ""
-"The previous algorithm is very pleasant: it's rather simple and rather fast "
-"to implement, but unfortunately, it is also rather wrong! In some cases, it "
-"never stops, which is obviously bad. If you don't believe it, just copy "
-"paste your previous code, and hit the run button. The first world of this "
-"exercise is one of these unfortunate situations that drives our previous "
-"algorithm crazy."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:9
-msgid ""
-"So we have to find another algorithm, preferably one that works in all "
-"cases."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:11
-msgid ""
-"For that, the best solution is to start from a well known algorithm instead "
-"of trying to invent a new one from scratch as we just did. When you think a "
-"bit about this problem, this can is very similar to a sorting problem: Just "
-"make sure that the players are sorted by their colors and you're set. And "
-"while we are at it, let's generalize the game to allow more that 4 bases."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:17
-msgid ""
-"Let's adapt the selection sort to our situation. The big lines of the "
-"algorithm is then \"for each base, select the players that should occupy "
-"this base and make sure that they come to their position\". This way, we "
-"will grow an sorted area where all players are already sorted (and never "
-"changed) while the unsorted area shrinks."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:23
-msgid ""
-"Selecting the player should be no problem; Do not hesitate to define some "
-"methods such as <code>findPlayer()</code> or "
-"<code>findPlayerBase()</code>. This will ensure that your code remains "
-"understandable."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:27
-msgid ""
-"The most problematic aspect is to move the selected players into "
-"position. For that, you have to move the hole to the position where the "
-"player is, and then move both the player and the hole to the base that is "
-"next to the player's goal (probably in a loop), and finally put the player "
-"in the right position of its target base."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/SelectBaseball.html:32
-msgid ""
-"As often in programming, the devil is in the details: there is a bunch of "
-"corner cases that you should detect and deal with correctly, such as the "
-"cases where the player is already in the base (but not in the position that "
-"you would like), or when the hole is on the right of the player (probably "
-"when you sort the first base). But you will find and hunt these while "
-"debugging your code."
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/InsertBaseball.html:1
-msgid "Insertion Baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:3
-msgid ""
-"The good point of adapting the selection sort to the baseball problem is "
-"that we know that it works (provided that our adaptation is correct). That's "
-"much better than the first naive algorithm, that was unable to converge to "
-"the solution in some situations. But actually, the selection sort is not "
-"perfect either as it requires a lot of swaps: we have to bring the hole to "
-"the selected player and then both the player and hole in position, and "
-"more. We can do better."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:9
-msgid ""
-"For example, each player can run quite a long way from its initial position "
-"to its target solution.  Instead, it may be more interesting to split the "
-"field in two parts: one on the left where all players are sorted relatively "
-"to each others, and one on the right where the players are still at their "
-"initial positions. Then, at each iteration, we take the player at the border "
-"between the sorted and unsorted areas (that is, the left-most player of the "
-"unsorted area) and move it to the left (within the sorted area) until it "
-"reaches its position (that is, until the position where it's bigger that its "
-"left neighbor). This would at least reduce the travel of players to the "
-"sorted area as we use the first one on the border."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:18
-msgid ""
-"Actually, that's exactly what an insertion sort would do: maintain a sorted "
-"area on the left, and put iteratively the player on the border to its "
-"position within the sorted area. This is good, as we know that our algorithm "
-"is not inherently flawed since we adapt a well known one."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:22
-msgid ""
-"The easiest to adapt the insertion sort to the baseball problem is to "
-"consider all positions as adjacent and forget about bases. For that, we "
-"define the methods <code>getColor(pos)</code>, <code>move(pos)</code> and "
-"<code>getHole()</code> that all use a unique integer to designate a given "
-"position. These functions simply convert between the way to specify a "
-"position and then call the usual functions to interact with the world. If "
-"you have an <code>index</code> and want to convert it into a "
-"<code>base,pos</code>, then <code>base=index/2</code> and "
-"<code>pos=index%2</code>. To compute the reverse, "
-"<code>index=base*2+pos</code> (this works because "
-"<code>getPositionsAmount()</code> always returns 2)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:31
-msgid ""
-"For the algorithm itself, you should first move the hole to the position "
-"1. The position 0 is considered to be the sorted area (of size 1 for now) "
-"while the area above 2 is the unsorted area.  Then comes an iteration to "
-"sort each element of the unsorted area. Since this iteration is a bit "
-"complex, you should think of its loop invariant, that is, the condition that "
-"is true before and after the loop and which explains that the loop fulfills "
-"its goal. Here, the loop invariant is twofold: First, the hole is between "
-"the sorted area and the unsorted area, and then, the every elements of the "
-"sorted area are ... well sorted relatively to their neighbors."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:39
-msgid ""
-"Then, the loop body to sort an element should first descend the hole and the "
-"elements within the sorted area until the element is larger than the element "
-"before in the sorted area (2 moves per position to travel), and then move "
-"the hole back to its position between the sorted and unsorted areas (1 move "
-"per position)."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/InsertBaseball.html:43
-msgid ""
-"Once you insert the last element within the sorted area, your whole set is "
-"sorted and you're done.  I preserve the surprise of the border cases that "
-"will require some little adjustments to your algorithm to make it work "
-"properly :)"
-msgstr ""
-
-#. type: Content of: <h1>
-#: src/lessons/sort/baseball/BubbleBaseball.html:1
-msgid "Bubble Baseball"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/BubbleBaseball.html:3
-msgid ""
-"Crap, we adapted the insertion sort because our selection sort required too "
-"much moves to get the selected players to their position, but the insertion "
-"sort requires an inordinate amount of changes to get the border elements to "
-"their position within the sorted area without mixing the already sorted "
-"elements. At the end of the day, our selection variant was more efficient "
-"with at most <code>3*amountOfBase</code> moves to sort one element (1 to get "
-"the hole alongside with the player, and 2 to get the hole+player in "
-"position) while our insertion variant requires at most "
-"<code>3*amountOfPlayers</code> to sort one element (2 to descend the hole "
-"and player in position, 1 to get the hole back to its position). That's "
-"twice as bad as there is two players per base. It may be possible to improve "
-"the insertion sort by moving by more than one element when descending, but "
-"it seems uneasy (at least, while not mixing the already sorted elements) and "
-"it would probably only ensure that our insertion variant becomes as "
-"efficient as our selection variant, not dramatically better."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/BubbleBaseball.html:15
-msgid ""
-"If we cannot make the sort faster, we can make it easier. If you think about "
-"it, it seems rather natural to adapt the bubble sort to this problem: the "
-"hole becomes the bubble that moves up and down, sorting a bit the array "
-"during each traversal. The big lines are simply: \"while it's not sorted, "
-"move the hole down to base 0 (moving the biggest player of each base at each "
-"step) and then back to the maximal base (moving the smallest player of each "
-"base)\". After a while, <code>isSorted()</code> will return true and your "
-"algorithm will stop."
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/BubbleBaseball.html:21
-msgid ""
-"This is so easy that we introduce another variant of the problem, with more "
-"than two players per base.  But actually, that shouldn't block you very "
-"long, should it?"
-msgstr ""
-
-#. type: Content of: <p>
-#: src/lessons/sort/baseball/BubbleBaseball.html:24
-msgid ""
-"Surprisingly, the bubble sort variant requires ways less moves than the "
-"other variants. This is astonishing because usually, the bubble sort "
-"performs much worse than the others sorts, but it comes from the very good "
-"match between its big lines and the baseball universe. It actually happens "
-"rather often that a pleasantly written algorithm performs very decently. But "
-"this is not an universal rule either, as demonstrated by the naive algorithm "
-"of the first exercise, that was nice, simple and wrong ;)"
-msgstr ""
diff --git a/lib/l10n/plm.pot b/lib/l10n/plm.pot
new file mode 100644
index 0000000..597118f
--- /dev/null
+++ b/lib/l10n/plm.pot
@@ -0,0 +1,10346 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2013-08-28 21:02+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Content of: <h2>
+#: lib/doc/MainWindow.html:1
+msgid "The PLM Main Window"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: lib/doc/MainWindow.html:3
+msgid ""
+"The PLM working environment should be self-explanatory, in particular with "
+"the tool tips appearing when your mouse is over the elements.  Here is a "
+"little explanation of the components in case you fail to understand "
+"something. The main window is made of 5 main components:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: lib/doc/MainWindow.html:10
+msgid ""
+"<b>The menu:</b> Placed on top of the window, it gives you access to some "
+"advanced commands such as exiting the program, and some other that we will "
+"detail later."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: lib/doc/MainWindow.html:14
+msgid ""
+"<b>The tool bar:</b> Placed just below the menu, it gives you access to the "
+"four main commands:"
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:19
+msgid ""
+"The <b>Start</b> button, which begins the compilation and execution of the "
+"code you may have typed in the editor. At the end of the execution, it "
+"verifies whether you reach the situation constituting the objective of the "
+"exercise or not. If yes, you gain access to the next exercise using the "
+"<b>Exercise</b> menu. If not, you need to rework your code."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:25
+msgid ""
+"The <b>Stop</b> button allows you to interupt the execution of your code, "
+"what may reveal useful if you encounter an <i>infinite loop</i>."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:28
+msgid ""
+"The <b>Reset</b> button can be used to reset the world into its initial "
+"state."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:31
+msgid ""
+"The <b>Demo</b> button shows you the execution of the expected "
+"solution. During its execution, you may want to swich the seen world to see "
+"the different expected solutions."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:34
+msgid ""
+"Please note that there is often several ways of achieving the awaited "
+"solution, and that the one presented during the demo is not more or less "
+"correct than the others. You are completely free to not follow strictly the "
+"process shown by the demo, as long as your final solution matches the "
+"exercise expectations."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:40
+msgid ""
+"The scrolling menu <b>Lessoon</b> allows you to choose the lesson you want "
+"to work on."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:43
+msgid ""
+"The scrolling menu <b>Exercise</b> allows you to switch to another exercise "
+"when you want. Some lessons require you to finish an exercise before "
+"starting the previous one."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: lib/doc/MainWindow.html:49
+msgid ""
+"<b>Mission and editor tabs:</b> this is were you read this very text. This "
+"area contains several tabs to which you can access by clicking on their name "
+"on the top left. The first tab (which is always named <b>Mission</b>)  "
+"contains a presentation of the current exercise. To solve an exercise, you "
+"need to write your code in the other tabs. For example, you can now clic on "
+"the <b>Source Code</b> tab to see the actual source. It is empty because "
+"there is no code to write for this introduction exercise."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: lib/doc/MainWindow.html:57
+msgid ""
+"<b>The console:</b> Placed under the tabs, this is where any messages of the "
+"application will appear. This area is initially empty and white."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: lib/doc/MainWindow.html:60
+msgid ""
+"<b>World view</b> Placed on the right of the tabs, it is constituted of five "
+"elements:"
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:65
+msgid ""
+"A scrolling menu allows to choose the world. Indeed, the program you write "
+"may be executed in several worlds to test it in differing conditions. This "
+"menu allows you to choose the world you want to see."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:69
+msgid ""
+"A slider placed underneath allows to choose the animation speed of the "
+"world. More precisely, it allows to choose the delay (in milliseconds) that "
+"the buggles must wait after each action to allow you to see what they are "
+"doing."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:74
+msgid ""
+"A tab <b>World</b> represents the view of the world currently selected (from "
+"the scrolling menu). This view is thus constitued of a grid forming the "
+"several cells of the world, as well as several <i>buggles</i> awaiting for "
+"your orders."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:79
+msgid ""
+"An <b>Objective</b> tab displaying the world as it must be by the end of the "
+"exercise."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li>
+#: lib/doc/MainWindow.html:83
+msgid ""
+"<b>The interactive controls</b>. Placed under the world view, these buttons "
+"allows you to interactively control the buggles. This way, you can try to "
+"<i>manually</i> bring your buggle to the scenario objective before writting "
+"the needed code in the editor."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:89
+msgid "A scrolling menu allows to select the buggle you want to control."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:91
+msgid "The <b>Forward</b> button let your buggle do one step forward."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:93
+msgid "The <b>Backward</b> button let it do one step backward."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:95
+msgid "The <b>Turn left</b> button ask your buggle to turn of 90° to its left."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:97
+msgid ""
+"The <b>Turn right</b> button asks the buggle to turn to the right (isn't "
+"this amazing?)."
+msgstr ""
+
+#. type: Content of: <ul><li><ul><li><ul><li>
+#: lib/doc/MainWindow.html:100
+msgid ""
+"The <b>Mark</b> button requests your buggle to leave a mark behind it when "
+"it goes."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/plm/universe/sort/SortingWorld.html:1
+msgid "Sorting World"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/sort/SortingWorld.html:2
+msgid ""
+"This world provides tools to experiment with the sorting algorithms. It can "
+"be used in two different ways: the first one is naturally to write the "
+"required sorting algorithms. But it is also possible to simply use the demo "
+"mode of each exercise to observe the behavior of sorting algorithms. It "
+"helps understanding the differences between each of them."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/sort/SortingWorld.html:8
+msgid "Methods available to sorting algorithms"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:10
+msgid "<b>Method</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:10
+msgid "<b>Action</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:10
+msgid "<b>Cost</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:11
+msgid "[!java]int [/!]getValueCount() [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:12
+msgid "Returns the amount of values in the array"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:12 src/plm/universe/sort/SortingWorld.html:30
+msgid "none"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:14
+msgid ""
+"[!java]boolean [/!]isSmaller([!java]int [/!]i[!scala]:Int[/!], [!java]int "
+"[/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:15
+msgid ""
+"Returns true if the content of cell i is strictly smaller than the one of "
+"cell j"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:15
+msgid "two reads"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:16
+msgid ""
+"[!java]boolean [/!]isSmallerThan([!java]int [/!]i[!scala]:Int[/!], "
+"[!java]int [/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:17
+msgid ""
+"Returns true if the content of cell i is strictly smaller than the "
+"<code>value</code>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:17 src/plm/universe/sort/SortingWorld.html:25
+msgid "one read"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:19
+msgid ""
+"[!java]void [/!]swap([!java]int [/!]i[!scala]:Int[/!], [!java]int "
+"[/!]j[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:20
+msgid "Swaps the content of cell i and the one of cell j"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:20
+msgid "two reads, two writes"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:21
+msgid ""
+"[!java]void [/!]copy([!java]int [/!]from[!scala]:Int[/!], [!java]int "
+"[/!]to[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:22
+msgid "Copy the content of cell 'from' into the cell 'to'"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:22
+msgid "one read, one write"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:24
+msgid "[!java]int [/!]getValue([!java]int [/!]idx[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:25
+msgid "Returns the value of cell idx"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:26
+msgid ""
+"[!java]void [/!]setValue([!java]int [/!]idx[!scala]:Int[/!], [!java]int "
+"[/!]value[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:27
+msgid "Sets cell 'idx' to the <code>value</code>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:27
+msgid "one write"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/sort/SortingWorld.html:29
+msgid "[!java]boolean [/!]isSelected() [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/sort/SortingWorld.html:30 src/lessons/recursion/hanoi/universe/HanoiWorld.html:24 src/lessons/sort/pancake/universe/PancakeWorld.html:21
+msgid "Returns whether the current world is selected in the graphical interface."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/sort/SortingWorld.html:34
+msgid "History view"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/sort/SortingWorld.html:35
+msgid ""
+"It is not enough to sort the array to pass the exercises. Your solution must "
+"strictly follow the expected behavior of each exercise. This is enforced by "
+"checking that your algorithm needs the same amount of read and write "
+"operations to sort the array. When they don't match, understanding the "
+"difference between your code and the expected solution can reveal very "
+"difficult."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/sort/SortingWorld.html:42
+msgid ""
+"To help in this process, it is possible to graphically explore the history "
+"of your sorting algorithm. Switch to the Objective view and use the "
+"contextual menu (right click) to switch from the the view of the current "
+"state to the view of its history."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/sort/SortingWorld.html:47 src/lessons/sort/bubble/AlgBubbleSort1.html:18
+msgid ""
+"The history view is a bit hairly at the first glance, but actually rather "
+"simple: The time flows from left to right on this graph, and each row is a "
+"cell of your array. The curved lines that go navigate between rows represent "
+"a given data value. When two lines cross, this means that two values were "
+"swapped at this time stamp; A line fork represent a value copy; When a value "
+"is magenta and followed by an interrogation mark (?), it was read using "
+"getValue(); If the value is red and followed with an exclamation point (!), "
+"it was written using setValue()."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/sort/SortingWorld.html:56
+msgid ""
+"This view, inspired from Aldo Cortesi, reveals very helpful understand the "
+"inner behavior of sorting algorithms."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/plm/universe/turtles/TurtleWorld.html:1
+msgid "The universe of turtles"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/turtles/TurtleWorld.html:3
+msgid "This is an adaptation of LOGO for the Java Learning Machine."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/turtles/TurtleWorld.html:5
+msgid ""
+"It is directly inspired from the work of the mathematician Seymour Papert in "
+"the 60's. Inspired from the swiss psycholog Jean Piaget, he came up with a "
+"learning method called LOGO to teach programming to young childs. The world "
+"is full of turtles which leave a painting where they go and which respond to "
+"simple orders."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/turtles/TurtleWorld.html:11
+msgid "Functions to move the turtle"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:13
+#, no-wrap
+msgid ""
+"[!java]void [/!]forward([!java]double [/!]steps[!scala]:Double[/!])\n"
+"[!java]void [/!]backward([!java]double [/!]steps[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:15
+msgid "Moves forward or backward of the requested amount of steps."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:17
+#, no-wrap
+msgid ""
+"[!java]void [/!]right([!java]double [/!]angle[!scala]:Double[/!])\n"
+"[!java]void [/!]left([!java]double [/!]angle[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:19
+msgid "Turns left or right of the given angle (in degrees)."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:21
+#, no-wrap
+msgid ""
+"[!java]double [/!]getX()[!scala]:Double[/!]\n"
+"[!java]double [/!]getY()[!scala]:Double[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:23
+msgid "Returns the current position of the turtle."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:25
+#, no-wrap
+msgid ""
+"[!java]void [/!]setX([!java]double [/!]x[!scala]:Double[/!])\n"
+"[!java]void [/!]setY([!java]double [/!]y[!scala]:Double[/!])\n"
+"[!java]void [/!]setPos([!java]double [/!]x[!scala]:Double[/!], [!java]double "
+"[/!]y[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:28
+msgid "Teleports the turtle to a new position (without leaving any trace)."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:30
+#, no-wrap
+msgid ""
+"[!java]void [/!]moveTo([!java]double [/!]x[!scala]:Double[/!], [!java]double "
+"[/!]y[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:31
+msgid "Moves the turtle to a new position."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:33
+#, no-wrap
+msgid "[!java]void [/!]circle([!java]double [/!]radius[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:34
+msgid "Draw a circle of the specified radius centered on the turtle."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:36
+#, no-wrap
+msgid "[!java]double [/!]getHeading()[!scala]:Double[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:37
+msgid "Returns the current heading of the turtle (in degrees)."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:39
+#, no-wrap
+msgid "[!java]void [/!]setHeading([!java]double [/!]angle[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:40
+msgid "Sets a new heading to the turtle (in degrees)."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/turtles/TurtleWorld.html:42
+msgid "Functions about the pen"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:44
+#, no-wrap
+msgid "[!java]void [/!]penUp()"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:45
+msgid ""
+"Moves the pen up (turtles have pens, not brushes as buggles). The turtle "
+"will not leave any trace during its subsequent moves."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:48
+#, no-wrap
+msgid "[!java]void [/!]penDown()"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:49
+msgid ""
+"Moves the pen down. The turtle will leave a trace during its subsequent "
+"moves."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:51
+#, no-wrap
+msgid "[!java]boolean [/!]isPenDown()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:52
+msgid "Returns the current pen position as a boolean."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/turtles/TurtleWorld.html:54 src/plm/universe/bugglequest/BuggleWorld.html:25
+#, no-wrap
+msgid "[!java]Color [/!]getColor()[!scala]:Color[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:55
+msgid "Returns the current pen color."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:57
+#, no-wrap
+msgid "[!java]void [/!]setColor([!java]Color [/!]color[!scala]:Color[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:58
+msgid "Changes the pen color."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/turtles/TurtleWorld.html:60
+msgid "Other functions"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/plm/universe/turtles/TurtleWorld.html:62 src/plm/universe/bugglequest/BuggleWorld.html:35 src/lessons/recursion/hanoi/universe/HanoiWorld.html:23
+#, no-wrap
+msgid "[!java]boolean [/!]isSelected()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/turtles/TurtleWorld.html:63
+msgid "Returns whether the current turtle is selected in the graphical interface."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/plm/universe/bugglequest/BuggleWorld.html:1
+msgid "BuggleWorld"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/bugglequest/BuggleWorld.html:2
+msgid ""
+"This world was invented by Lyn Turbak, at Wellesley College. It is full of "
+"Buggles, little animals understanding simple orders, and offers numerous "
+"possibilities of interaction with the world: taking or dropping objects, "
+"paint the ground, hit walls, etc."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/bugglequest/BuggleWorld.html:7
+msgid "Methods understood by buggles"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:9
+msgid "<b>Moving</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:9
+msgid "(See also the note on exceptions, below)"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:9
+msgid "<b>Turn left"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:9
+msgid "Turn right"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:9
+msgid "Turn back"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:9
+msgid "Moving forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:10 src/lessons/turmites/universe/TurmiteWorld.html:9
+msgid "Moving back</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:11 src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]left()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:12 src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]right()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:13 src/lessons/turmites/universe/TurmiteWorld.html:10
+msgid "[!java]void [/!]back()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:14 src/lessons/turmites/universe/TurmiteWorld.html:11
+msgid ""
+"[!java]void [/!]forward() or [!java]void [/!]forward([!java]int "
+"[/!]steps[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:15 src/lessons/turmites/universe/TurmiteWorld.html:12
+msgid ""
+"[!java]void [/!]backward() or [!java]void [/!]backward([!java]int "
+"[/!]steps[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
+msgid "<b>Get X coordinate"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
+msgid "Get Y coordinate"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
+msgid "Set X coordinate"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
+msgid "Set Y coordinate"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:16
+msgid "Set position</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:17
+msgid "[!java]int [/!]getX()[!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:18
+msgid "[!java]int [/!]getY()[!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:19
+msgid "[!java]void [/!]setX([!java]int [/!]x[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:20
+msgid "[!java]void [/!]setY([!java]int [/!]y[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:21
+msgid ""
+"[!java]void [/!]setPos([!java]int [/!]x[!scala]:Int[/!], [!java]int "
+"[/!]y[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:23
+msgid "<b>Information on the buggle</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:24
+msgid "<b>Get the color"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:24
+msgid "Set the color</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:26
+msgid "[!java]void [/!]setColor([!java]Color [/!]c[!scala]:Color[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:27
+msgid "<b>Look for a wall forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:27
+msgid "Look for a wall backward</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:28
+msgid "[!java]boolean [/!]isFacingWall()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:29
+msgid "[!java]boolean [/!]isBackingWall()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
+msgid "<b>Get heading"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
+msgid "Set heading</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:30
+msgid "valid directions are:"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:31
+msgid "[!java]Direction [/!]getDirection()[!scala]:Direction[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:32
+msgid "[!java]void [/!]setDirection([!java]Direction [/!]dir[!scala]:Direction[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:33
+msgid "Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:34
+msgid "Check whether the buggle is currently <b>selected in the interface</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:37
+msgid "<b>About the brush</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
+msgid "<b>Brush down"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
+msgid "Brush up"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:38
+msgid "Get brush position</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:39
+msgid "[!java]void [/!]brushUp()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:40
+msgid "[!java]void [/!]brushDown()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:41
+msgid "[!java]boolean [/!]isBrushDown()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:42
+msgid "<b>Change the brush color"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:42
+msgid "Get the color of the brush</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:43
+msgid "[!java]void [/!]setBrushColor([!java]Color [/!]c[!scala]:Color[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:44
+msgid "[!java]Color [/!]getBrushColor()[!scala]:Color[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:46
+msgid "<b>Interacting with the world</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:47 src/lessons/turmites/universe/TurmiteWorld.html:14
+msgid "<b>Get the color of the ground</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:48 src/lessons/turmites/universe/TurmiteWorld.html:14
+msgid "[!java]Color [/!]getGroundColor()[!scala]:Color[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
+msgid "<b>Look for a baggle on the ground"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
+msgid "Look for a baggle in bag"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
+msgid "Pickup a baggle"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:50
+msgid "Drop a baggle</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:51
+msgid "(see the note on exceptions)"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:52
+msgid "[!java]boolean [/!]isOverBaggle()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:53
+msgid "[!java]boolean [/!]isCarryingBaggle()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:54
+msgid "[!java]void [/!]pickupBaggle()"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:55
+msgid "[!java]void [/!]dropBaggle()"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
+msgid "<b>Look for a message"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
+msgid "Add a message"
+msgstr ""
+
+#. type: Content of: <table><tr><td><b>
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
+msgid "Read the message"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:57
+msgid "Erase the message</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:58
+msgid "[!java]boolean [/!]isOverMessage()[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:59
+msgid "[!java]void [/!]writeMessage([!java]String [/!]msg[!scala]:String[/!])"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:60
+msgid "[!java]String [/!]readMessage()[!scala]:String[/!]"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/bugglequest/BuggleWorld.html:61
+msgid "[!java]void [/!]clearMessage()"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/plm/universe/bugglequest/BuggleWorld.html:64
+msgid "Note on exceptions"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/bugglequest/BuggleWorld.html:65
+msgid ""
+"Regular buggles throw a BuggleWallException exception if you ask them to "
+"traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you "
+"ask them to pickup a baggle from an empty cell, or a "
+"AlreadyHaveBaggleException exception if they already carry a baggle.  Trying "
+"to drop a baggle on a cell already containing one throws an "
+"AlreadyHaveBaggleException exception."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/bugglequest/BuggleWorld.html:71
+msgid ""
+"SimpleBuggles (ie, the one used in first exercises) display an error message "
+"on problem so that you don't need to know what an exception is."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/backtracking/Main.html:1
+msgid "Backtracking lesson"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:3
+msgid ""
+"This <b>experimental</b> lesson aims at teaching students about "
+"backtracking. It is not ready for consumtion yet, not even the first "
+"exercises. It will feature several exercices on the topic allowing to "
+"progressively build the relevant notions and mental representation in the "
+"students mind."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:9
+msgid ""
+"For now, it contains a Backtracking exercise which lacks a graphical "
+"representation to be usable. It is based on an entity KnapsackSolver which "
+"works on a KnapsackPartialSolution. This latter is not a World, but a "
+"passive world component. It is used by the solver to store the currently "
+"best solution and the working solution. This design should be rather generic "
+"and other backtracking problems, such as the ones used in my TOP teaching "
+"(pyramid, recipients) should be implmentable following this design. That is "
+"why Backtracking classes derive from generic ones: BacktrackingEntity and "
+"BacktrackingPartialSolution.  There is also a BacktrackingWorld, that "
+"specific universes should need to not override, and BacktrackingExercise, "
+"dealing with this specificity where the world does not only contain solving "
+"entities, but also two partial solutions (best know and current)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:23
+msgid ""
+"This exercise should be introduced by an interactive discovery activity such "
+"as the one used here: "
+"http://interstices.info/jcms/c_19213/le-probleme-du-sac-a-dos"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:27
+msgid ""
+"Although this exercise seems almost usable, there is a fundamental "
+"difficulty to solve in the visualization. It is envisionned that the call "
+"graph is used here, to help the students building their mental "
+"representation of recursion. The actual representation of the graph should "
+"be quite easy, thanks to the jung library. But I fail to see how to get the "
+"needed info so far. Adding sensors to the stepUI()  method is probably the "
+"best way to go, but I would need to inspect the complete call stack where "
+"Thread.currentThread().getStack() only give the static stack (method called, "
+"file location, etc). I think I need to inspect the parameters passed to each "
+"method call to rebuild the proper call tree."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:39
+msgid ""
+"The first thing that I tried to use was dtrace, but it seems non-portable "
+"and somehow linked to solaris so I didn't dig any further."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:43
+msgid ""
+"Then, I tried to use the debugging infrastructure (JPDA), but never managed "
+"to get it working. It seems to me that the original com.sun.jdi package is "
+"somehow deprecated since com.sun.jdi.BootStrap.virtualMachineManager() "
+"returns null while org.eclipse.jdi.Bootstrap.virtualMachineManager() does "
+"not. But when I'm using the eclipse version, it seem to take an endless "
+"amount of dependencies, which I'm not inclined to do. The root of my problem "
+"may be that I was using a jdi.jar comming from eclipse, but I didn' find any "
+"other. I just realised that the com.sun.jdi package is also implemented in "
+"/usr/lib/jvm/java-6-sun-1.6.0.26/lib/tools.jar on my disk. It seem to be "
+"functional, I should give it another spin."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:55
+msgid ""
+"Afterward, I tried to reuse the debugging infrastructure of DrJava. It looks "
+"like a good idea because they have several helper interfaces for debugging "
+"and compiling. Also, they have a good editor that we could reuse. Finally, "
+"they have a strong testing infrastructure with junit ensuring that their "
+"tool still work after modifications (that's something we are seriously "
+"missing in PLM). I'm really thinking that the two tools should converge to "
+"something stronger. The only argument for not doing so (beside the amount of "
+"work it'll take) is that each of us get the credit for each tool where "
+"things would be more fuzzy on a mixed tool. But I don't care, the mixed tool "
+"would be so much cooler that I'd like to find the time to ensure this "
+"convergence."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:67
+msgid ""
+"But the debugging feature of DrJava seems to suffer from an issue: "
+"http://sourceforge.net/tracker/index.php?func=detail&aid=3004294&group_id=44253&atid=438935 "
+"I was suspecting a permission error (something related to "
+"com.sun.jdi.JDIPermission), but even with a java.security.AllPermission as "
+"permission file, I still have the issue."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:73
+msgid ""
+"Another lead to get it working it to use lib ASM to modify the student code "
+"so that their recursive method gets traced. With the static backtrace and "
+"the tracing information, I guess I could rebuild the actual call tree. That "
+"seem to be possible: 2 sec of googling gave me something like "
+"http://rejeev.blogspot.com/2009/04/method-tracing.html"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/backtracking/Main.html:79
+msgid ""
+"So, here I am. The lesson would be very interesting to students, and quite "
+"easy to finish once I manage to get the information I need, but I didn't "
+"manage to do so so far, despite my efforts. If you have any hint (or "
+"patch!), please email martin.quinson#loria.fr."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/backtracking/Main.html:84
+msgid ""
+"This gives me the following todo actions: * Check whether tools.jar gives a "
+"working com.sun.jdi package * Find the DrJava bug around debugging to help "
+"them, and so that I can steal parts of their code about it for PLM (it's "
+"BSD'ed while PLM is mainly GPL'ed for now -- I'll have to ask them for an "
+"exception). That would be better since their helper interface seem to be "
+"able to deal with several debuggers (eclipse, sun or openjdk). That's quite "
+"a large amount of work I'd like to avoid duplicating.  * Check wheter I can "
+"get tracing info from ASM. It may be more robust to JVM variants than the "
+"debugging approach. On the other hand, debugging is a neat feature for PLM "
+"as is.  * Work on the convergence of PLM and DrJava. Beside of the licencing "
+"issue, it will also complicate the ongoing integration of PLM within Debian, "
+"since DrJava is composed of [[5 separated "
+"modules|http://drjava.org/docs/developer/ch02s03.html]] that can only be "
+"integrated as separated source packages. As every java package, no source "
+"archive is distributed, and they must be retrieved directly from the "
+"svn. Finally, they are quite huge, with sloccount reporting"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/chooser/LessonChooser.html:3 src/lessons/chooser/LessonChooser.html:3
+msgid "  "
+msgstr ""
+
+#. type: Content of: <table><tr><td><font>
+#: src/lessons/chooser/LessonChooser.html:3
+msgid "Welcome to the Programmer's Learning Machine"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/chooser/LessonChooser.html:7
+msgid ""
+"The PLM is a Learning Management System (LMS) aiming at teaching the art of "
+"computer programming through interactive exercises. It offers an extensive "
+"set of varied exercises, allowing you to practice at your own pace."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/chooser/LessonChooser.html:11
+msgid "Pick a classical lesson"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:13
+msgid ""
+"<a href=\"plm://lessons.welcome\">Welcome lesson</a> This lesson is intended "
+"to lead the first steps in programming of absolute beginners."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:16
+msgid ""
+"<a href=\"plm://lessons.maze\">Escape the maze</a> Will you escape the "
+"mazes?"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:18
+msgid ""
+"<a href=\"plm://lessons.bat.string1\">String lesson</a> A bunch of exercises "
+"on strings."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:20
+msgid ""
+"<a href=\"plm://lessons.sort\">Sorting lesson</a> This short lesson proposes "
+"to discover the classical sorting algorithms by practice."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:23
+msgid ""
+"<a href=\"plm://lessons.recursion\">Recursion lesson</a> Build some "
+"classical geometric figures through recursion."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:26
+msgid ""
+"<a href=\"plm://lessons.lightbot\">LightBot</a> In this little game, you "
+"must program graphically a little robot to instruct it how to switch the "
+"lights off. It is a brain teaser for programmer."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/chooser/LessonChooser.html:30
+msgid ""
+"<a href=\"plm://lessons.smn\">Digital Manual Science</a> Some activities "
+"developed for the Sciences Manuelles du Numérique (Digital Manual Science)"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/chooser/Main.html:1
+msgid "Lesson chooser"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/chooser/Main.html:3
+msgid ""
+"This isn't a real lesson, it's here that you can select a lesson among "
+"others."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/Main.html:1 src/lessons/welcome/short_desc.html:1
+msgid "First steps"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/Main.html:3
+msgid ""
+"This first lesson will lead your first steps in programming. It is intended "
+"for beginners. List of seen notions per exercise:"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:8 src/lessons/welcome/Main.html:91 src/lessons/welcome/Main.html:174 src/lessons/welcome/Main.html:254 src/lessons/welcome/Main.html:348 src/lessons/welcome/Main.html:428 src/lessons/welcome/Main.html:468
+msgid " "
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:9 src/lessons/welcome/Main.html:92 src/lessons/welcome/Main.html:175 src/lessons/welcome/Main.html:255 src/lessons/welcome/Main.html:349 src/lessons/welcome/Main.html:429 src/lessons/welcome/Main.html:469 src/lessons/welcome/instructions/Instructions.html:1
+msgid "Instructions"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:10 src/lessons/welcome/Main.html:93 src/lessons/welcome/Main.html:176 src/lessons/welcome/Main.html:256 src/lessons/welcome/Main.html:350 src/lessons/welcome/Main.html:430 src/lessons/welcome/Main.html:470
+msgid "Comments"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:11 src/lessons/welcome/Main.html:94 src/lessons/welcome/Main.html:177 src/lessons/welcome/Main.html:257 src/lessons/welcome/Main.html:351 src/lessons/welcome/Main.html:431 src/lessons/welcome/Main.html:471
+msgid "Conditionals/ Expressions"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:12 src/lessons/welcome/Main.html:78 src/lessons/welcome/Main.html:95 src/lessons/welcome/Main.html:178 src/lessons/welcome/Main.html:258 src/lessons/welcome/Main.html:352 src/lessons/welcome/Main.html:432 src/lessons/welcome/Main.html:472 src/lessons/welcome/loopwhile/LoopWhile.html:1
+msgid "While loops"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:13 src/lessons/welcome/Main.html:96 src/lessons/welcome/Main.html:179 src/lessons/welcome/Main.html:259 src/lessons/welcome/Main.html:353 src/lessons/welcome/Main.html:433 src/lessons/welcome/Main.html:473
+msgid "Variables"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:14 src/lessons/welcome/Main.html:97 src/lessons/welcome/Main.html:133 src/lessons/welcome/Main.html:180 src/lessons/welcome/Main.html:260 src/lessons/welcome/Main.html:354 src/lessons/welcome/Main.html:434 src/lessons/welcome/Main.html:474 src/lessons/welcome/loopfor/LoopFor.html:1
+msgid "For loops"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:15 src/lessons/welcome/Main.html:98 src/lessons/welcome/Main.html:181 src/lessons/welcome/Main.html:261 src/lessons/welcome/Main.html:355 src/lessons/welcome/Main.html:435 src/lessons/welcome/Main.html:475
+msgid "Do/While loops"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:16 src/lessons/welcome/Main.html:99 src/lessons/welcome/Main.html:161 src/lessons/welcome/Main.html:182 src/lessons/welcome/Main.html:262 src/lessons/welcome/Main.html:356 src/lessons/welcome/Main.html:436 src/lessons/welcome/Main.html:476 src/lessons/welcome/methods/basics/Methods.html:1
+msgid "Methods"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:17 src/lessons/welcome/Main.html:100 src/lessons/welcome/Main.html:183 src/lessons/welcome/Main.html:263 src/lessons/welcome/Main.html:357 src/lessons/welcome/Main.html:437 src/lessons/welcome/Main.html:477
+msgid "Switch"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:18 src/lessons/welcome/Main.html:101 src/lessons/welcome/Main.html:184 src/lessons/welcome/Main.html:264 src/lessons/welcome/Main.html:358 src/lessons/welcome/Main.html:438 src/lessons/welcome/Main.html:478
+msgid "Arrays"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:22 src/lessons/welcome/environment/Environment.html:1
+msgid "Welcome in the Buggles' World"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:36
+msgid "Java Instructions"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:50 src/lessons/welcome/instructions/InstructionsDrawG.html:1
+msgid "Writing more complex programs"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:64 src/lessons/welcome/conditions/Conditions.html:1
+msgid "Conditional instructions"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:105 src/lessons/welcome/loopwhile/BaggleSeeker.html:1
+msgid "Baggle Seeking"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:119 src/lessons/welcome/variables/Variables.html:1
+msgid "Storing and manipulating data"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:147 src/lessons/welcome/loopdowhile/LoopDoWhile.html:1
+msgid "Do .. while loops"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:187 src/lessons/welcome/methods/basics/MethodsDogHouse.html:1
+msgid "Building methodically"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:201 src/lessons/welcome/methods/returning/MethodsReturning.html:1
+msgid "Methods returning a result"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:214 src/lessons/welcome/methods/args/MethodsArgs.html:1
+msgid "Methods with parameters"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:228 src/lessons/welcome/methods/picture/PictureMono.html:1
+msgid "Methodically drawing"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:241 src/lessons/welcome/methods/picture/PictureMono2.html:1
+msgid "Methodically drawing (only bigger)"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:267 src/lessons/welcome/methods/picture/PictureMono3.html:1
+msgid "Drawing bigger and bigger"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:280
+msgid "Even more pattern to draw"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:294
+msgid "Buggle Dance Revolution"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:308
+msgid "Buggle Dance Revolution 2"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:322 src/lessons/welcome/methods/slug/SlugHunting.html:1
+msgid "Slug Hunting"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:335 src/lessons/welcome/methods/slug/SlugTracking.html:1
+msgid "Slug Tracking"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:361 src/lessons/welcome/traversal/Snake.html:1
+msgid "Snake World"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:375
+msgid "Knitting and Arrays"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:389
+msgid "Knitting, Arrays and modulos"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:402 src/lessons/welcome/traversal/column/TraversalByColumn.html:1
+msgid "Traversal by column"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:415 src/lessons/welcome/traversal/line/TraversalByLine.html:1
+msgid "Traversal by line"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:441 src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:1
+msgid "Zig-zag traversal"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:454 src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:1
+msgid "Diagonal Traversal"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:482
+msgid "Meaning of the symbols"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:485
+msgid "Introducing the concept"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:488
+msgid "Working on the concept"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:491
+msgid "Concept assumed mastered"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/Main.html:494
+msgid "Concept not mandated by the exercise"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/Main.html:500
+msgid "What will I learn?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/Main.html:501
+msgid ""
+"You will learn the very basics of programming. At least, you will be "
+"presented the most important concepts, allowing you to read most simple "
+"algorithms. You will not be able to write or read full programs because you "
+"will still not know about objects, but you will master what is called "
+"\"Tactical programming\", meaning that you will master the syntax enough to "
+"not have any issue with it, allowing you to focus on the fundamental "
+"problems of what you want to solve instead of struggling with syntaxic "
+"difficulties."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/short_desc.html:2
+msgid ""
+"This first lesson will lead your first steps in programming. It is intended "
+"for beginners."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/short_desc.html:5
+msgid ""
+"If you are not sure, go for this lesson that will teach you the bases of "
+"programming."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:3
+msgid ""
+"You just started the Programmer's Learning Machine. This is a Learning "
+"Management System aiming at teaching the art of computer programming through "
+"interactive exercises. It is constituted by a set of exercises grouped by "
+"lessons, allowing you to practice at your own pace. Currently, the "
+"environment is configured to be programmed in the [!thelang/] programming "
+"language, but you can change it from the Language menu if you want, or by "
+"clicking on the [!thelang/] icon at the right of the status bar below."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:10
+msgid "In this first lesson, the buggles will lead your first steps in programming."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/environment/Environment.html:12
+msgid "The <i>buggles</i>? What is this??"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:14
+msgid ""
+"The buggles are little animals obeying any order you may give them. In each "
+"exercise, you have to provide them with the right instructions so that the "
+"world turns into the objective of the exercise. For example in this "
+"exercise, you show instruct your buggle to move forward once. You can see "
+"that by checking the difference between the <i>World</i> view and the "
+"<i>Objective</i> one.  Depending on the lessons (and your settings in the "
+"Language menu), your code must be written in either Java, Python or Scala "
+"(depending on the exercise)."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/environment/Environment.html:22
+msgid "Working environment"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:24
+msgid ""
+"Before going any further, get familiar with the working environment. Have a "
+"look at the several elements composing the main window, move your mouse over "
+"them to show the tooltip, and experiment with the elements to see what they "
+"do.  The white area below is the console: this is where errors and messages "
+"get displayed. Note that when you successfully solve an exercise, the good "
+"news is spread on twitter.  Keep posted to the progress of your friends by "
+"following @jlmlovers :)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:32
+msgid ""
+"If you prefer not to post your successes online, just change the relevant "
+"properties in your config file, that is [!configfile] in your case."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:35
+msgid ""
+"If your code contains errors (and code always do at some point), the "
+"computer will display error messages in the console. You obviously have to "
+"fix the errors to pass the exercises. The messages that get displayed may "
+"sound scary at first glance, but don't panic. The compiler is only somehow "
+"limited in its communication abilities, but he's not mean. If you look "
+"closer, the solution to solve your issue is written in the middle of those "
+"cryptic messages. You will see, with a bit of habit, we get used to it."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/environment/Environment.html:43
+msgid "What am I supposed to do?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/environment/Environment.html:45
+msgid ""
+"It's time to write your first program. Simply ask your buggle to move one "
+"step forward using the Source Code pane. For that, simply write the "
+"following code (clicking on the interactive controls is not enough: You have "
+"to write the code after experimenting interactively)."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/environment/Environment.html:49 src/lessons/welcome/instructions/Instructions.html:45
+#, no-wrap
+msgid "forward()[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/environment/Environment.html:50
+msgid ""
+"Do not forget the final <code>;</code> which tells the compiler that the "
+"instruction is over (yes, computers are so dumb that they cannot "
+"<i>guess</i> obvious stuff like this)."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/environment/Environment.html:54
+msgid "Once done, clic on run. You can proceed to next exercise once it works."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/instructions/Instructions.html:3
+msgid ""
+"Congratulations! You just wrote your first program! You got the idea now: "
+"programming is nothing more than giving simple instructions to the computer "
+"that blindly apply them. The main difficulty is to explain stuff to "
+"something as stupid as a computer..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:8
+msgid ""
+"Programs are mainly suites of method calls, which are no more than a list of "
+"simple order given to the machine. It is very similar to a recipe stating "
+"<i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>.  In "
+"your programs, such built instructions are called functions or methods, and "
+"you should add parenthesis to invoke them:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:13
+#, no-wrap
+msgid "nameOfTheMethod()"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:15
+msgid ""
+"[!thelang] wants to have the instructions separated by semi-columns "
+"(;)[!python|scala] or by new lines[/!].  The previous example would thus be "
+"written in the following way[!python|scala] (you can also add semi-columns "
+"at the end of the lines, but this is not mandatory)[/!]."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:21
+#, no-wrap
+msgid ""
+"meltTheChocolatePieces()[!java];[/!]\n"
+"addSugar()[!java];[/!]\n"
+"coolMix()[!java];[/!]\n"
+"serve()[!java];[/!]\n"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/instructions/Instructions.html:27 src/lessons/welcome/variables/Variables.html:123
+msgid "[!python|scala]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:28
+msgid ""
+"It could also be written in the following way, but it's generally considered "
+"as a bad practice to group several instructions on the same line since it "
+"greatly hinders the readability."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/Instructions.html:32
+#, no-wrap
+msgid "meltTheChocolatePieces(); addSugar(); coolMix(); serve()\n"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/instructions/Instructions.html:34 src/lessons/welcome/variables/Variables.html:31 src/lessons/welcome/variables/Variables.html:61 src/lessons/welcome/variables/Variables.html:130 src/lessons/welcome/loopfor/LoopFor.html:69 src/lessons/welcome/loopdowhile/LoopDoWhile.html:53 src/lessons/welcome/loopdowhile/Poucet.html:33 src/lessons/welcome/methods/args/MethodsArgs.html:65 src/lessons/welcome/methods/picture/MethodsPicture.html:39 src/lessons/welcome/bdr/BDR.html:59 [...]
+msgid "[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:36
+msgid ""
+"Of course, these specific methods do not exist by default in "
+"[!java]Java[/!][!scala]Scala[/!][!python]Python[/!], but it may be possible "
+"to define them by yourself (we'll see later how to define your how methods)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:40
+msgid ""
+"For now, we'll simply go for the buggle instructions. There is a method for "
+"each button of the interactive control panel. To achieve the same effect "
+"than the <b>forward</b> button (making the buggle moving one step forward), "
+"you need to write the following in the editor:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:46
+msgid ""
+"Likewise, to achieve the same effect than the <b>backward</b>, <b>left</b> "
+"and <b>right</b> buttons, you need to use respectively:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/instructions/Instructions.html:49
+#, no-wrap
+msgid ""
+"backward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"right()[!java];[/!]\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/Instructions.html:54
+msgid ""
+"The <b>mark</b> button is a bit particular, since it correspond to two "
+"methods: the first one moves the pen up while the second moves it down."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/instructions/Instructions.html:57
+#, no-wrap
+msgid ""
+"brushUp()[!java];[/!]\n"
+"brushDown()[!java];[/!]\n"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/instructions/Instructions.html:60
+msgid ""
+"The buggle offers other methods, that are presented from the \"Help/about "
+"this world\" menu and will be introduced on need."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/instructions/Instructions.html:64 src/lessons/welcome/conditions/Conditions.html:108 src/lessons/welcome/loopwhile/LoopWhile.html:32 src/lessons/welcome/loopwhile/BaggleSeeker.html:8 src/lessons/welcome/variables/Variables.html:97 src/lessons/welcome/loopfor/LoopFor.html:71 src/lessons/welcome/methods/basics/Methods.html:95 src/lessons/welcome/methods/basics/MethodsDogHouse.html:37 src/lessons/welcome/methods/returning/MethodsReturning.html:48 src/lessons/welcome/m [...]
+msgid "Exercise goal"
+msgstr ""
+
+#. type: Content of: <p><a>
+#: src/lessons/welcome/instructions/Instructions.html:64
+msgid ""
+"<a name=\"Objectives\"> Our second program will be a bit more complicated, "
+"but not much. The goal for your buggle is simply to draw a house (a box), "
+"and hide inside. Check the objective world to see exactly what this means."
+msgstr ""
+
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/instructions/Instructions.html:69
+msgid ""
+"When switching to the next exercise, please note that there is a "
+"sub-exercise following this one.  By default, it is hidden in the menu and "
+"you have to open the sub-menu to see it.  When you switch the exercise, most "
+"of the exercises are hidden because the tree is folded, as follows:"
+msgstr ""
+
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/instructions/Instructions.html:74
+msgid ""
+"You have to click on the little symbol to the left of the buggle to unfold "
+"the tree, as follows:"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:2
+msgid ""
+"Now that we know how to draw things on the board, we'll enjoy this ability "
+"and draw a beautiful G on the board (check Objective panel for details on "
+"what is expected)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:6
+msgid ""
+"When you write a quite complex program, it is sometimes useful to <b>add "
+"comments</b> to simplify the code reviews afterward. Here for example, it's "
+"quite easy to get lost in the drawing process, and you may want to add "
+"comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to "
+"move back to initial position</i>. Commenting your code is almost mandatory "
+"if you (or someone else) want to read it afterward, although over-commenting "
+"(describing obvious stuff) is a bad idea as the important idea get lost in "
+"the noise."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:14
+msgid ""
+"There is [!java]three[/!][!python|scala]two[/!] types of comments in "
+"[!thelang], instructing the "
+"[!java|scala]compiler[/!][!python]interpreter[/!] to not read the text you "
+"add for humans:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:18
+msgid ""
+"<b>Comments on a single line</b>. When the "
+"[!java|scala]compiler[/!][!python]interpreter[/!] encounters the symbol "
+"[!java|scala]//[/!][!python]#[/!], it ignores the end of the line."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:20
+msgid ""
+"<b>Comments on several lines</b>. The "
+"[!java|scala]compiler[/!][!python]interpreter[/!] ignores anything placed "
+"between [!java|scala]the symbols /* and */ even if they are placed on "
+"differing lines.[/!] [!python]a line beginning with ''' and the next line "
+"ending with '''.[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:27
+#, no-wrap
+msgid ""
+"methodCallReadByThe[!java|scala]Compiler[/!][!python]Interpreter[/!]()[!java];[/!] "
+"<span class=\"comment\">[!java|scala]//[/!][!python]#[/!] all this is "
+"ignored</span>\n"
+"otherCall()[!java];[/!] [!java|scala]<span class=\"comment\">/* This "
+"is</span>\n"
+"              "
+"<span class=\"comment\"> also ignored */</span>[/!]\n"
+"[!python]<span class=\"comment\">''' This is</span>\n"
+"<span class=\"comment\">also ignored  '''</span>[/!]\n"
+"yetAnotherCall()[!java];[/!]\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:34
+msgid ""
+"There is a third kind of comments in Java, between /** and */, which are "
+"read by a specific program called JavaDoc to generate automatically the "
+"documentation explaining how to use the code. These comments must follow a "
+"very precise formalism."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/instructions/InstructionsDrawG.html:39
+msgid ""
+"The comments on several lines are often used to document how to use the "
+"code, while others are more used to describe how this code works."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/conditions/Conditions.html:3
+msgid ""
+"Programs made of simple suite of instructions similar to previous exercise "
+"are quite boring. They always do the same thing, and cannot react to "
+"external conditions. A <b>conditional</b> let the program adapt by doing "
+"something like <i>if it's raining, take an umbrella</i>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:8
+msgid "The [!thelang] syntax is the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/conditions/Conditions.html:10
+#, no-wrap
+msgid ""
+"[!java|scala]if (<b>condition</b>) {\n"
+"    <b>whatToDoIfTrue();</b>\n"
+"    <b>whatToDoNextIfTrue();</b>\n"
+"}[/!][!python]if <b>condition</b>:\n"
+"    <b>whatToDoIfTrue()</b>\n"
+"    <b>whatToDoNextIfTrue()</b>[/!]\n"
+"<b>whatToDoAnyway()[!java];[/!]</b>"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:18
+msgid ""
+"If the condition is true, the code of the next block will be executed and "
+"then it will continue with the rest of the code.  If the condition is false, "
+"the next block is ignored and the execution continues after it.  The "
+"conditional block can contain several instructions, it can even contain "
+"other tests, along with their sub-blocks."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:22
+msgid ""
+"In this example, the instructions <code>whatToDoIfTrue()</code> and "
+"<code>whatToDoNextIfTrue()</code> will be executed if and only if the "
+"condition is true, while the instruction <code>whatToDoAnyway()</code> will "
+"be executed whether or not the condition is true."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/conditions/Conditions.html:27
+msgid ""
+"In [!thelang], the blocks of code are [!java|scala]enclosed between curly "
+"brackets: a { sign opens the block, while a } sign closes it.  White spaces "
+"are not important[/!][!java].[/!][!scala], provided that your instructions "
+"are still separated with a semi-column or an end of line.[/!] "
+"[!java|scala]It is still very important to correctly indent your code to "
+"keep it readable.[/!] [!python]marked by the indentation: every lines that "
+"are a bit shifted to the right with white spaces belong to the block. Quite "
+"often, people use 4 spaces for indentation, but it works if you use more or "
+"less spaces. Simply, any lines of the block must use the same amount of "
+"spaces.  The end of Python code blocks are not marked by any specific char.  "
+"Indenting lines starts a block and unindenting ends it. Do not forget the "
+"colon (:) at the end of the <code>if</code> line, python needs it to know "
+"that a new block begins. The fact that python relies on indentation to "
+"delimit blocks is a very good property for beginners: it will force your to "
+"adhere to strict code presentation standards.[/!] It is very easy to get "
+"lost in your own code if it's not properly indented, so you want to clean it "
+"up so that working on your code remains pleasant and productive."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:43
+msgid ""
+"All indentations of a given block must be consistent, and it is not possible "
+"to cut a block. The two following codes are incorrect and will raise errors."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/conditions/Conditions.html:46
+#, no-wrap
+msgid ""
+"if <b>condition</b>:\n"
+"    <b>whatToDo()</b>\n"
+"     <b>whatToDoNext()</b> <span "
+"class=\"comment\"># one space too much </span>\n"
+"<b>whatToDoAnyway()</b>\n"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/conditions/Conditions.html:51
+#, no-wrap
+msgid ""
+"if <b>condition</b>:\n"
+"    <b>whatToDo()</b>\n"
+"<b>whatToDoAnyway()</b>\n"
+"    <b>whatToDoNext()</b> <span class=\"comment\"># this "
+"block is not hanging to a condition line</span>\n"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:57
+msgid ""
+"The condition must be a "
+"<code>[!java]boolean[/!][!scala|python]Boolean[/!]</code> expression.  The "
+"inner block of code will get executed if the expression is evaluated to "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> and it will be ignored "
+"if it is <code>[!java|scala]false[/!][!python]False[/!]</code>.  "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> and "
+"<code>[!java|scala]false[/!][!python]False[/!]</code> are constant values "
+"defined by [!thelang] directly, just as 0 or 1 in mathematics."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:63
+msgid ""
+"The condition can be a "
+"<code>[!java]boolean[/!][!scala|python]Boolean[/!]</code> variable (we will "
+"come back on variables in a latter exercise, don't worry) or an arithmetic "
+"test, such as <code>x == 5</code>, which checks whether the current value of "
+"<code>x</code> is 5, or such as <b>!=</b> (checking inequality, that is, "
+"returning [!java|scala]true[/!][!python]True[/!] only if the left hand-side "
+"is different from the right hand-side), <b><</b> (smaller than), "
+"<b>></b> (larger than), <b><=</b> (smaller or equal to), <b>>=</b> "
+"(larger or equal to)."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:70
+msgid ""
+"Beware of the classical trap, which consists in testing the equality of a "
+"variable using = instead of ==. Hopefully, the "
+"[!java|scala]compiler[/!][!python]interpreter[/!] detects this problem most "
+"of the time, but it could get trapped is some cases (such as when you are "
+"affecting a boolean variable). So you'd better to be careful..."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:75
+msgid ""
+"The condition can also be a call to some particular methods returning a "
+"boolean. For example, the <code>isFacingWall()</code> method of the buggle "
+"returns true if the buggle is facing a wall, and false in the other case."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:79
+msgid ""
+"Finally, a condition can be composed of several sub-conditions connected by "
+"boolean operations:"
+msgstr ""
+
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:82
+msgid ""
+"<code>cond1 [!java|scala]&&[/!][!python]and[/!] cond2</code> is true when "
+"<tt>cond1</tt> <b>and</b> <tt>cond2</tt> are both true (if <tt>cond1</tt> is "
+"false, <tt>cond2</tt> is not even evaluated as we already know that the "
+"conjunction of both propositions cannot be true)."
+msgstr ""
+
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:85
+msgid ""
+"<code>cond1 [!java|scala]||[/!][!python]or[/!] cond2</code> is true if "
+"<tt>cond1</tt> <b>or</b> <tt>cond2</tt> is true (if <tt>cond1</tt> is true, "
+"<tt>cond2</tt> is not even evaluated as we already know that the disjunction "
+"of both propositions cannot be true)."
+msgstr ""
+
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:88
+msgid ""
+"<code>[!java|scala]![/!][!python]not [/!]cond</code> is true if "
+"<tt>cond</tt> is false."
+msgstr ""
+
+#. type: Content of: <p><ul><li>
+#: src/lessons/welcome/conditions/Conditions.html:89
+msgid ""
+"When the expression becomes complicated, it is better to add parenthesis to "
+"force the order of evaluation.  Do not hesitate to add more parenthesis to "
+"remove any ambiguities that may appear in an expression."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:93
+msgid ""
+"Last, it is possible to specify what to do when the condition is false using "
+"the following syntax. In this case, the instruction "
+"<code>whatToDoIfItsFalse</code> will be executed only if the condition is "
+"false."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/conditions/Conditions.html:96
+#, no-wrap
+msgid ""
+"[!java|scala]if (<b>condition</b>) {\n"
+"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
+"} else {\n"
+"    <b>whatToDoIfItsFalse();</b>\n"
+"}[/!][!python]if (<b>condition</b>):\n"
+"    <b>whatToDoIfTheConditionIsTrue()</b>\n"
+"else:\n"
+"    <b>whatToDoIfItsFalse()</b>[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/conditions/Conditions.html:105
+msgid ""
+"Don't forget the colon (:) after the else, it is indicating that a new block "
+"is beginning."
+msgstr ""
+
+#. type: Content of: <p><a>
+#: src/lessons/welcome/conditions/Conditions.html:108
+msgid ""
+"<a name=\"Objectives\">If the buggle is facing a wall, you must move one "
+"step back. If not, you must move one step forward. To detect whether you are "
+"facing a wall, simply use the <code>isFacingWall()</code> built-in, that "
+"every buggle understands."
+msgstr ""
+
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/conditions/Conditions.html:113
+msgid ""
+"This exercise is a bit different: your code has to work for several buggles, "
+"each of them being in a specific initial condition. The same code will be "
+"executed for each of them."
+msgstr ""
+
+#. type: Content of: <p><a><p>
+#: src/lessons/welcome/conditions/Conditions.html:117
+msgid ""
+"When your program works, move forward to the next exercise, that is hidden "
+"in a sub-tree of the selection window."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:3
+msgid ""
+"In addition to conditionals, another handy construction is the ability to "
+"repeat an action while a specific condition does not appear. A while loop is "
+"used for that, with the following syntax."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:7
+#, no-wrap
+msgid ""
+"[!java|scala]while (<b>condition</b>) {\n"
+"    <b>action()</b>;\n"
+"}[/!][!python]while <b>condition</b>:\n"
+"    <b>action()</b>[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:12
+msgid ""
+"The inner bloc is then executed again and again, as long as the condition "
+"remains true.  More specifically, the buggle tests the value of the "
+"condition. If it's false, it ignores the bloc and continue below.  If it's "
+"true, it executes the bloc.  After that, it tests the condition. If it's now "
+"false (for example because the moves of the block made us facing the wall), "
+"it now ignores the bloc and continue.  If it's still true, it execute the "
+"bloc and reevaluate the condition. It does so as long as the condition "
+"remains true."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:19
+msgid ""
+"Naturally, if the chosen action does not modify the value of the condition, "
+"the buggle will do the action endlessly. The <b>stop</b> button of the "
+"interface becomes then handy. To test this, you can try to type the "
+"following code in the editor:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:24
+#, no-wrap
+msgid ""
+"[!java|scala]while (true) {\n"
+"    left();\n"
+"}[/!][!python]while True:\n"
+"    left()[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:29
+msgid ""
+"This will let the buggle turn left as long as "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> remains true (ie, "
+"endlessly), or until you stop it manually using the stop button."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:32
+msgid ""
+"You now have to write some code so that your buggles move forward until they "
+"encounter a wall. The idea is thus to do something like:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:35
+#, no-wrap
+msgid ""
+"while we are not facing a wall, do:\n"
+"  moveForward()"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/LoopWhile.html:38
+msgid "When your program works, move forward to the next exercise."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:2
+msgid ""
+"The buggle world can sometimes contain some <i>baggles</i>, which are little "
+"biscuits that buggles can carry from one point to another. For that, they "
+"have to use specific methods such as <code>isOverBaggle(), "
+"isCarryingBaggle(), pickupBaggle()</code> or "
+"<code>dropBaggle()</code>. Check their documentation in \"Help/About this "
+"world\" for more details."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopwhile/BaggleSeeker.html:10
+msgid ""
+"Let each buggle find its baggle by adapting the code you wrote in previous "
+"exercise (copy/paste what you've done before if you want)."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:1
+msgid "Lost in the Moria"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:3
+msgid ""
+"You buggle got stuck in a mine! Some rocks are blocking the exit, and you "
+"will have to clear your way to the exit. Well of course these are only "
+"baggles and you could simply walk away, but it will be easier to program "
+"your buggle so that it moves those \"rocks\" than convincing your buggle "
+"that it could easily walk away without solving the problem..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:9
+msgid ""
+"So, you have to find the first baggle blocking the exit (simply walk to the "
+"east until you are over a baggle), take it and move it back to the other "
+"side of the tunnel (walk to the west while you are not over a baggle, and "
+"then move back one step to the east and drop your baggle), and iterate until "
+"you find the exit (that is, the wall to the east side). Afterward, move out "
+"as in the objective world."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopwhile/WhileMoria.html:16
+msgid ""
+"Once you manage to escape this trap, you can move forward to the next "
+"exercise.  This exercise is a bit more complex, so you can also leave it for "
+"now and come back later if you don't get it right now."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/variables/Variables.html:2
+msgid ""
+"The programs we wrote so far are missing a fundamental point in computing.  "
+"Actually, it is all about processing <b>data</b> through specific "
+"<b>instructions</b>. In the buggle world, the main data are a bit hidden "
+"behind the graphical representation, but that's no reason to never "
+"manipulate some data explicitly."
+msgstr ""
+
+#. type: Content of: <p><h3>
+#: src/lessons/welcome/variables/Variables.html:8
+msgid "Data in [!thelang]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/variables/Variables.html:9
+msgid ""
+"In a program, you can use several <i>types</i> of data, such as integers or "
+"strings of chars. If you want to use a data several times, you need to store "
+"it within a <i>variable</i>, which is a memory cell containing a value: you "
+"put your data (say the value '5') in the variable (say 'length'), and you "
+"can retrieve it latter when you need it. That's very similar to a box of "
+"label 'gift' in which you would put some stuff, like a bottle of perfume "
+"\"Channel N°5\"."
+msgstr ""
+
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/variables/Variables.html:16
+msgid "Variable declarations"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:18
+msgid ""
+"<b>Declaring</b> (ie, creating) a variable in [!thelang], is very "
+"simple. You just need to write [!java]its type, a space, and the variable "
+"name.[/!] [!scala]the <code>var</code> keyword, the variable name, a column "
+"(:) and the variable type.[/!] [!python]the variable name, an equal sign (=) "
+"and an initial value.[/!] The variable name is the label to retrieve it "
+"afterward[!python].[/!] [!java|scala] while the type is the kind of data "
+"that this variable accepts to store.[/!] It is forbidden to use spaces in "
+"variable names. So you can name a variable <code>stepAmount</code> if you "
+"want, but <code>step amount</code> is not a valid name."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/variables/Variables.html:28 src/lessons/welcome/variables/Variables.html:40 src/lessons/welcome/methods/args/MethodsArgs.html:34 src/lessons/welcome/methods/picture/MethodsPicture.html:34 src/lessons/welcome/bdr/BDR.html:8 src/lessons/welcome/bdr/BDR2.html:3 src/lessons/recursion/square/FourSquare.html:27
+msgid "[!java|scala]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:29
+msgid ""
+"So, to create a variable named <b>x</b> intended to contain integers, one "
+"should write:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:30
+#, no-wrap
+msgid "[!java]int x;[/!][!scala]var x: Int[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:33
+msgid ""
+"[!java|scala]If you want, you can specify the initial value of the variable "
+"by adding a equal sign (=) followed by the value after the declaration.[/!] "
+"[!scala]If you specify a value, you don't have to specify the type of the "
+"variable, since Scala manages to guess it alone in most cases.  You are "
+"still free to specify the type if you prefer (or if the compiler fail to "
+"determine the type for some reason), but it's optional.[/!] So you want that "
+"the variable contains 5 as initial value, you should type:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:37
+#, no-wrap
+msgid ""
+"[!java]int x=5;[/!][!python]x = 5[/!][!scala]var x: Int =  5 <span "
+"class=\"comment\">// I can define the type if I want to</span>\n"
+"var y =  10      <span class=\"comment\">// or I can omit the type if I "
+"prefer</span>[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:41
+msgid ""
+"As you can see, the variables are <b>typed</b> in [!thelang], which means "
+"that they are somehow specialized: A given variable can only store data of a "
+"given type; Don't even think of storing numbers in a variable that is "
+"tailored for letters! Other languages (such as Python) are less picky and "
+"allow you to store any kind of data in any variable without restriction.  "
+"This seems easier at the first glance, but this kind of restriction allows "
+"the compiler to catch more logic errors for you, which is also good. In some "
+"sense, Python is easier to write but errors can sneak in more easily than in "
+"[!thelang].  Here are some of the existing types:"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:48
+msgid "<b>[!java]int[/!][!scala]Int[/!]</b>, for integers;"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:49
+msgid "<b>[!java]double[/!][!scala]Double[/!]</b>, for dot numbers;"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:50
+msgid ""
+"<b>[!java]boolean[/!][!scala]Boolean[/!]</b>, for booleans that are values "
+"being either true or false;"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/variables/Variables.html:51
+msgid "<b>String</b>, for char strings."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/variables/Variables.html:53
+msgid "[/!] [!python]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:56
+msgid ""
+"As you can see, the variables are not <b>typed</b> in Python, which means "
+"that they are not specialized in any type of data.  A given variable store "
+"any type of data of a given type: you can store a number in a variable and "
+"latter on store a number in the same variable.  Other languages (such as "
+"Java or Scala) are much more picky and prevent you to mix data types in a "
+"given variable.  This seems annoying at the first glance, but this kind of "
+"restriction allows the compiler to catch more logic errors for you, which is "
+"also good. In some sense, Python is easier to write but errors can sneak in "
+"more easily."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:64
+msgid ""
+"If you know that the value of your \"variable\" will never change (eg "
+"because it contains the screen size or some other constant value), then you "
+"should make it a <b>value</b> instead of a variable. Simply change the "
+"<code>var</code> keyword with the <code>val</code> one. The compiler can "
+"then perform more verifications and catch when you inadvertently modify the "
+"value. More interestingly, the compiler can produce faster code in some "
+"cases."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:69
+msgid ""
+"Variables work very similarly for strings, floating point numbers and "
+"boolean values."
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:71
+#, no-wrap
+msgid ""
+"String name = \"Martin Quinson\";\n"
+"double height=1.77; <span class=\"comment\">// in meters</span>\n"
+"boolean married=true;<span class=\"comment\">// the contrary would be "
+"written \"false\"</span>"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:75
+#, no-wrap
+msgid ""
+"val name:String = \"Martin Quinson\"; <span class=\"comment\">// this cannot "
+"be modified (it's a value)</span>\n"
+"var height: Double = 1.77; <span class=\"comment\">// in meters</span>\n"
+"var married = true; <span class=\"comment\">// the contrary would be written "
+"\"false\"</span>\n"
+"<span class=\"comment\">// Scala knows that 'true' is a Boolean value, no "
+"need to repeat it here</span>"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:80
+#, no-wrap
+msgid ""
+"firstName = \"Martin\"\n"
+"lastName = 'Quinson' <span class=\"comment\"># both single and double quote "
+"work here</span>\n"
+"motto = \"I never finish anyth' (but I keep trying)\" <span "
+"class=\"comment\"># having single quote within double quote is fine</span> "
+"\n"
+"height=1.77 <span class=\"comment\"># in meters</span>\n"
+"married=True <span class=\"comment\"># the contrary would be written "
+"\"False\"</span>"
+msgstr ""
+
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/variables/Variables.html:86
+msgid "Affectations"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:88
+msgid ""
+"Once your variable is declared, you can <b>affect</b> a new value to it "
+"later in the program. That's really easy:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:89
+#, no-wrap
+msgid "x = 3[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:91
+msgid ""
+"To the right of the equal symbol, you can put an arithmetic expression "
+"containing constants, variables and operations."
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/variables/Variables.html:93
+#, no-wrap
+msgid ""
+"x = 3 + 2[!java];[/!]\n"
+"x = 3 * x[!java];[/!]\n"
+"greeting = \"Hello \"+name[!java];[/!] <span "
+"class=\"comment\">[!python]#[/!][!scala|java]//[/!] + is (also) the "
+"operation to concatenate (ie, to join) strings</span>"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/variables/Variables.html:98
+msgid ""
+"It is now time to do more challenging exercises, don't you think? The "
+"objective is now to move forward until you find a baggle, pick it up, and "
+"then move back to your initial location before dropping the baggle."
+msgstr ""
+
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/variables/Variables.html:103
+msgid "How to do this?"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:104
+msgid ""
+"To solve this problem, you have to decompose it in easier sub-parts. For "
+"example, you may want to do the following steps:"
+msgstr ""
+
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:107
+msgid "Move forward until located over a baggle"
+msgstr ""
+
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:108
+msgid "Pickup the baggle"
+msgstr ""
+
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:109
+msgid "Move backward of the same amount of steps than done in first step"
+msgstr ""
+
+#. type: Content of: <p><p><p><ol><li>
+#: src/lessons/welcome/variables/Variables.html:110
+msgid "Drop back the baggle"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:113
+msgid ""
+"Naturally, it is impossible to do the right amount of steps backward at step "
+"3 if you didn't count the amount of steps done in the first phase. You can "
+"use a variable for that, which can be named <code>stepAmount</code>."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:117
+msgid ""
+"Create an integer variable before phase 1, initialize it to 0, and each time "
+"you move one step forward, increment its value by one (<code>stepAmount = "
+"stepAmount + 1;</code>[!java] or <code>stepAmount++;</code>, both syntaxes "
+"being equivalent[/!]).  Such variable which takes every values of a given "
+"range is often called a <b>stepper</b>."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:124
+msgid ""
+"If you know Java or other languages, you will probably try to use the "
+"<code>++</code> operator to increment the variable, but it's not allowed in "
+"[!thelang].  This is because it would be difficult to define this operator "
+"for every data types.  For example, what should ++ do when applied to a "
+"Complex value or to a String? The problem does not occur in Java as "
+"<code>int</code> is not an object but a primitive type.  (if you don't know "
+"the <code>++</code>, just ignore this paragraph: it does not exist in "
+"[!thelang])"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:132
+msgid ""
+"Then, phase 3 consists in simply creating a new integer variable "
+"<code>doneSteps</code> initialized to 0, and do one step backward until "
+"<code>doneSteps</code> equals <code>stepAmount</code>, incrementing "
+"<code>doneSteps</code> each time."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/variables/Variables.html:137
+msgid "It's your turn now!"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/variables/RunFour.html:1
+msgid "Run Four bases"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/variables/RunFour.html:3
+msgid ""
+"Today is a great day for the buggles: the Big Buggles' Race begun. It's a "
+"traditional competition in which young buggles prove their value to the "
+"tribe. Both force and intelligence is exercised: you have to rush forward, "
+"but stop as soon as you reach your fourth baggle.  Please help the buggles "
+"to move forward while counting the baggles and to determine when to stop."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/variables/RunHalf.html:1
+msgid "The Four Halves run"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/variables/RunHalf.html:3
+msgid ""
+"Here is the second day of the Big Buggles' Race.  As previously, you have to "
+"run forward until you reach the right cell to stop on.  But this time, you "
+"have to reach the cell where you saw as much baggles as orange cells plus "
+"1.  In other word, the following condition must become true <code>2 * "
+"baggles = orangeCells + 1</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/variables/RunHalf.html:8
+msgid ""
+"You can determine whether you are over a orange cell with the "
+"<code>isOverOrange()</code> method."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:3
+msgid ""
+"While loops are well adapted to situations where you want to achieve an "
+"action while a condition stays true, but it is less adapted to achieve a "
+"given action a predetermined amount of time. For example, when we wanted to "
+"move <code>stepAmount</code> steps backward in a previous exercise, we had "
+"to create a new variable, initialize it, and move backward while "
+"incrementing this variable until it became equal to <code>stepAmount</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:10
+msgid ""
+"In such situations, <code>for</code> loops become handy. Their syntax is the "
+"following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:12
+#, no-wrap
+msgid ""
+"[!java]for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>variable</b> in <b>sequence of values</b>:\n"
+"    <b>action</b>()[/!][!scala] for (<b>variable</b> <- <b>firstValue</b> "
+"to <b>lastValue</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:19
+msgid ""
+"For example to repeat the the loop body <code>n</code> times, [!python] it "
+"is handy to use the instruction <code>range(n)</code> to generate the "
+"sequence n integer value from 0 to n-1.[/!] [!java|scala] one should "
+"write:[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:22
+#, no-wrap
+msgid ""
+"[!java]for (int stepper=0; stepper<n; stepper++) {\n"
+"    <b>action</b>();\n"
+"}[/!][!python]for <b>stepper</b> in <b>range(n)</b>:\n"
+"    <b>action</b>()[/!][!scala] for (var <b>stepper</b> <- <b>1</b> to "
+"<b>n</b>) { \n"
+"    <b>action</b>();\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:29
+msgid "This code is then perfectly equivalent to the following one."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:30
+#, no-wrap
+msgid ""
+"[!java]int stepper = 0;\n"
+"while (stepper < n) {\n"
+"    <b>action</b>();\n"
+"    <b>stepper++</b>;\n"
+"}[/!][!python]stepper=0\n"
+"while stepper < n: \n"
+"    action()\n"
+"    stepper = stepper + 1[/!][!scala]\n"
+"var stepper = 1\n"
+"while (stepper <= n) {\n"
+"    <b>action</b>()\n"
+"    stepper = stepper + 1\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:44
+msgid "The <code>for</code> loop is easier to read, don't you think?"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:46 src/lessons/welcome/bdr/BDR.html:187 src/lessons/turmites/langton/Langton.html:20 src/lessons/welcome/array/basics/Array1.html:200
+msgid "[!java]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:47
+msgid ""
+"It is possible to build more advanced <tt>for</tt> loops since any valid "
+"instruction can be used as initialization, condition and incrementing "
+"instruction. The following example is a bit extreme as there is no need for "
+"a loop body to move the buggle forward until it reaches the wall, but it "
+"works well: all the work is done in the condition and incrementing "
+"instruction."
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:53
+#, no-wrap
+msgid ""
+"for (; !isFacingWall() ; forward()) { \n"
+"   <span class=\"comment\">/* nothing in the loop body */</span>\n"
+"}\n"
+"<span class=\"comment\">/* the buggle now faces a wall */</span>"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:57 src/lessons/welcome/bdr/BDR2.html:82
+msgid "[/!] [!scala]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:60
+msgid ""
+"If you want to nest several loops, you can do it on one line in Scala. This "
+"means that the two following chunks are equivalent:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:61
+#, no-wrap
+msgid ""
+"for (stepper1 <- 1 to n) {\n"
+"    for (stepper2 <- 1 to m) {\n"
+"       actions()\n"
+"    }\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopfor/LoopFor.html:66
+#, no-wrap
+msgid ""
+"for (stepper1 <- 1 to n; stepper2 <- 1 to m) { <span "
+"class=\"comment\">// Simply separate both loop conditions with a "
+"semi-column</span>\n"
+"    actions()\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/loopfor/LoopFor.html:72
+msgid ""
+"You now have to redo the same exercise than previously (move forward until "
+"being over a baggle, pick it up, move back to your original location, drop "
+"the baggle), but using a <code>for</code> loop instead of a "
+"<code>while</code> loop to move back to the initial location."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopFor.html:77
+msgid "Once done, you can proceed to next exercise."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopfor/LoopStairs.html:1
+msgid "Stairway to Heaven"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopStairs.html:3
+msgid ""
+"Your buggle feels a bit depressed today, but it's currently facing a magic "
+"stair: It leads directly to heaven, and each time you walk on it, joyful "
+"colors spur all around."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopStairs.html:6
+msgid ""
+"Your goal is to take this stair, one step after the other.  First devise the "
+"four instructions you have to give you buggle to take one stair step, and "
+"then put them in a loop to take the whole stair."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopStairs.html:10
+msgid ""
+"And before that, walk a bit forward to reach that stair, and ensure that you "
+"are in the right situation for your loop content to run properly. And once "
+"you reach the heaven, take some steps in your new home."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopfor/LoopCourse.html:1
+msgid "Training Buggle"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopCourse.html:3
+msgid ""
+"Today, your buggle wants to get some serious exercise: It wants to run 'till "
+"the track burns! Its super-shoes are just perfect to run like hell, but "
+"unfortunately, they can actually damage the track on the long run..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopCourse.html:6
+msgid ""
+"Your goal is to run the track 10 times, no matter what happens.  Even if the "
+"track suffers, you <b>really HAVE</b> to take that run.  Remember, the track "
+"has four sides, that take eight steps each to run along.  Now go, and show "
+"them what these super shoes can do."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:1
+msgid "Outdoor Training Buggle"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:3
+msgid ""
+"Well, our last training didn't went that well. The track actually burned, "
+"and we are now banned from there.  This time, our buggle decided to practice "
+"outdoor, in the middle of the forest, with its good old shoes instead.  The "
+"problem is that you have to be careful to not fall into water. The track on "
+"which you can run is rather narrow: One side is now 4 steps forward, 2 steps "
+"to the left, 4 steps to the right, 2 steps to the right, 4 steps to the "
+"left, and you want to run 7 around."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopfor/LoopCourseForest.html:9
+msgid ""
+"Oh crap, running on the grass seems to destroy it too! So just take your 7 "
+"loops around the garden, and move along to the next exercise before anyone "
+"notices the damage you made..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:3
+msgid ""
+"Some cells of the world are yellow, but your buggle cannot stand being in "
+"such cells. Write the necessary code to move forward until the ground gets "
+"white. For that, use the provided method <code>isGroundWhite()</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:7
+msgid ""
+"The trick is that most buggles of this world are currently on this yellow "
+"ground that they dislike so much. That is why they are in panic, and every "
+"buggle rushes one cell forward, even the buggle that was not on a yellow "
+"cell at first. In other worlds, even if the ground is white on the first "
+"cell, you still want to move forward to the next cell."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:12
+msgid "The general idea is to do something like:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:13
+#, no-wrap
+msgid "move forward until located in a white cell"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:15
+msgid ""
+"The main difficulty is that we want this loop body to be executed once, even "
+"we are already on a white cell.  It would be easy to do so by duplicating "
+"the loop content before the actual loop, but this would be a bad idea: code "
+"duplication is a <b>very</b> bad habit, and you should <b>always</b> avoid "
+"it."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:19
+msgid ""
+"Code duplication easily turns code maintenance into a nightmare: reading the "
+"code becomes difficult as the reader must ensure that no slight difference "
+"exist between the versions. Debugging the code becomes difficult, as bugs "
+"have to be fixed in all versions. Actually, every modification of the code "
+"becomes difficult. So, really, you should <b>always</b> strive to not "
+"duplicate you code if you can avoid. And the good news is that you always "
+"can..."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:24
+msgid "Executing the loop body at least once"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:25 src/lessons/welcome/loopdowhile/Poucet.html:27 src/lessons/turmites/helloturmite/HelloTurmite.html:53 src/lessons/welcome/array/basics/Array1.html:98
+msgid "[!python]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:26
+msgid ""
+"Some languages have specific constructs for that, but not the Python "
+"language. No problem, we can do it on our own! A good way is to have a "
+"dedicated variable indicating whether we are taking the loop for the first "
+"time or not, as follows."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:30
+#, no-wrap
+msgid ""
+"firstTime = True\n"
+"while firstTime or (other conditions):\n"
+"  firstTime = False\n"
+"  (loop body)\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:36
+msgid ""
+"When <code>firstTime</code> is true, the loop body is executed even if the "
+"other conditions would imply the contrary.  Once the loop body has been "
+"executed once, it is set to false and never impact again the decision to "
+"enter the body or not."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:38 src/lessons/turmites/helloturmite/HelloTurmite.html:60 src/lessons/welcome/array/basics/Array1.html:114
+msgid "[/!] [!java|scala]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:42
+msgid ""
+"In a <tt>while</tt> loop, the condition is evaluated before anything else, "
+"and if it's false, the loop body is never evaluated. Sometimes (although not "
+"that often), you would prefer the loop body to get evaluated at least once, "
+"even if the condition is initially false. For that, a variation of the "
+"<tt>while</tt> loop gets used, using the following syntax in [!thelang].  "
+"[!java]Do not forget the semi-column (;) after the condition, it is "
+"mandatory.[/!]"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/loopdowhile/LoopDoWhile.html:50
+#, no-wrap
+msgid ""
+"do {\n"
+"    <b>action()</b>[!java];[/!]\n"
+"} while (<b>condition</b>)[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/loopdowhile/Poucet.html:1
+msgid "Tracks of buggles"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/Poucet.html:3
+msgid ""
+"Your buggle got lost in a strange maze, and you must help it finding the "
+"exit that is represented in orange.  You cannot simply explain the path to "
+"the exit in something like <code>right();forward;forward();forward()</code> "
+"because you have to save two buggles at the same time, that are lost in "
+"similar but not identical worlds.  You can switch to the other world by "
+"using the combobox above the world representation (where it's written 'Deep "
+"Forest' right now), and selecting the other entry (that should read 'Deeper "
+"Forest')."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/Poucet.html:9
+msgid ""
+"The good news is that the path to the exit is written on the ground. As you "
+"can see, the world is made of several corridors, with baggles on the "
+"ground. After each corridor, you should turn left if the corridor contains "
+"three baggels or more, and you have to turn right if there is only 2 baggles "
+"or less."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/Poucet.html:13
+msgid ""
+"So, the general form of your code must be something like \"while I did not "
+"find the exit, take the next corridor to decide whether I should turn left "
+"or right at the next intersection\". You can determine whether you are on "
+"the exit cell (that is orange) with the provided <code>exitReached()</code> "
+"method."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/Poucet.html:17
+msgid ""
+"To take one corridor, you simply have to run from one intersection to "
+"another while counting the baggles you see on your path. The method "
+"<code>crossing()</code> tells you whether your buggle currently stands on an "
+"intersection.  The extra complexity is that at the beginning of a corridor, "
+"you obviously stand on an intersection, but you still want to move on.  "
+"[!java|scala]For that, the easiest is to use a <code>do / while</code> loop "
+"instead of a regular <code>while</code> loop to move until the next "
+"intersection.[/!] [!python]For that, use an extra variable indicating "
+"whether you already entered the corridor, as follows. This will ensure that "
+"you execute the loop body at least once (when <code>firstTime</code> is "
+"true) before we actually use the value returned by <code>crossing()</code> "
+"to determine to continue or not.[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/loopdowhile/Poucet.html:28
+#, no-wrap
+msgid ""
+"firstTime = True\n"
+"while firstTime or not crossing():\n"
+"  firstTime = False\n"
+"  (your body)\n"
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><div>
+#: src/lessons/welcome/loopdowhile/Poucet.html:35
+msgid "I cannot imagine how to count the baggles I see."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/welcome/loopdowhile/Poucet.html:36
+msgid ""
+"You need a variable that is initialized to 0, and incremented each time you "
+"see a baggle on the ground. A variable used this way is often called "
+"<i>counter</i>."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/welcome/loopdowhile/Poucet.html:38
+msgid "Don't forget to reset your counter to 0 at the beginning of each corridor!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/loopdowhile/Poucet.html:41
+msgid ""
+"Oh, and when you reach the exit, don't forget to take an extra step to "
+"actually exit the maze!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:4
+msgid ""
+"We will now write our own methods. It somehow comes down to extending the "
+"buggle vocabulary by learning it new tricks."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:7
+msgid ""
+"For example, we saw in a previous exercise how to ask the buggle to go get "
+"the baggle in front of it, and bring it back. If there is several baggles on "
+"the board, and if we want to bring all of them on the bottom line, you have "
+"to repeat this code several times, or include it in a loop. In any case, you "
+"should avoid to duplicate your code to keep it pleasant to read and easily "
+"understandable.  It would be better if the buggle could obey an "
+"<code>goAndGet()</code> order just like it understands a "
+"<code>forward()</code> one."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:15
+msgid "Defining methods"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:17
+msgid ""
+"The [!thelang] syntax to write a simple method called <code>goAndGet</code> "
+"is the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:19
+#, no-wrap
+msgid ""
+"[!java]void goAndGet() {[/!][!python]def goAndGet():[/!][!scala]def "
+"goAndGet() {[/!]\n"
+"  actions()[!java];[/!]\n"
+"  to()[!java];[/!]\n"
+"  do()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:25
+msgid ""
+"The method body [!java|scala](between curly braces)[/!][!python](the "
+"indented block)[/!] will be executed when we call the method later on (that "
+"is, when we write <code>goAndGet()</code> somewhere in our code). This "
+"method body can contain as many instructions as you want, and any "
+"construction we saw so far (for, while, if, etc).  [!java]The "
+"<code>void</code> keyword means that this method does not return any "
+"result. For example, the <code>isOverBaggle()</code> method does return a "
+"result, which is a boolean indicating whether or not the buggle is located "
+"over a baggle. We will soon learn to define such methods too. For now, just "
+"write <code>void</code> at this location.[/!]"
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:38
+msgid "Documenting methods"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:40
+msgid ""
+"You should strive to document your code to keep it readable. When you write "
+"it, its purpose and limitations are clear to you, but most of the time, this "
+"does not last for long. You will soon forget about the details of every "
+"specific method, and this day you will be happy to read its "
+"documentation. In the following example, we use the specific formalism of "
+"[!java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], a program that "
+"extracts the documentation of [!thelang] source code to produce html "
+"pages. The main advantage is that it allows to keep the documentation near "
+"to the code.  So, when you change your code, you have less chances to forget "
+"to update the documentation."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:49
+msgid ""
+"[!java|scala][!java]javadoc[/!][!scala]scaladoc[/!] comments begin with the "
+"<code>/**</code> marker (with two asterisks). They must be placed right "
+"before the method they document for the tool to find them.[/!] "
+"[!python]pydoc comments should be placed at the beginning of the method body "
+"so that the tool finds them. They should be placed between "
+"<code>\"\"\"</code>, which mark multi-line strings in python.[/!] The first "
+"line should be a brief description of what this method does while any "
+"subsequent lines should provide any important details about the method."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:58
+#, no-wrap
+msgid ""
+"[!java|scala]/**\n"
+" *  Go, retrieves the baggle in front of the buggle, and brings it back \n"
+" *\n"
+" *   Does not check for walls, so be careful to not call it when walls are "
+"present.\n"
+" */[/!]\n"
+"[!java]void goAndGet() {[/!]\n"
+"[!scala]def goAndGet() {[/!]\n"
+"[!python]def goAndGet():\n"
+"  \"\"\"Go, retrieves the baggle in front of the buggle, and brings it "
+"back.\n"
+"\n"
+"  Does not check for walls, so be careful to not call it when walls are "
+"present.\"\"\"[/!]\n"
+"  actions()[!java];[/!]\n"
+"  to()[!java];[/!]\n"
+"  do()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/methods/basics/Methods.html:74
+msgid "Naming conventions"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:75
+msgid ""
+"Most programming language forbid the use of spaces in method and variable "
+"identifiers (=their names).  Accented letters are sometimes allowed (as in "
+"[!thelang]), but they can lead to portability issues between operating "
+"systems and should thus be avoided when possible."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:79
+msgid ""
+"Across all programming languages, there is two main conventions to name "
+"variables and methods. The first one, consists in concatenating all words "
+"with only the first letter of each word in upper case. \"go and get\" "
+"becomes goAndGet().  It is called CamelCase because identifiers written this "
+"way graphically remind of a camel back. The other convention, called "
+"snake_case, is to write every words in lower case, separated with "
+"underscores symbols (_). \"go and get\" becomes go_and_get()."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:86
+msgid ""
+"Which convention to use is the topic of heated discussion across developers, "
+"but each programming language has its own habits. In Python, Perl and the C "
+"language, the snake_case is often used for methods and variables. Java and "
+"Scala prefer the lowerCamelCase (the very first letter is lower case) for "
+"that."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:90
+msgid ""
+"The CamelCase convention is used everywhere in PLM because this program is "
+"written in Java itself, so we kept our habits when adding new languages. But "
+"the fact that the Python bindings of PLM use the CamelCase instead of the "
+"snake_case is considered as a bug that we will fix in further releases."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:96
+msgid ""
+"The goal of this exercise is to write a method called "
+"<code>goAndGet()</code> which does the same than in a previous exercises "
+"(move forward until over a baggle, pick it up, move back to initial "
+"position, drop baggle)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:100
+msgid ""
+"One specificity of this exercise is that you shouldn't write directly the "
+"code that the buggle should execute, but a method it should use. The code "
+"that calls your function will be automagically added when you click on "
+"<b>Start</b>.  For your information, this calling code will look like this:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/Methods.html:105
+#, no-wrap
+msgid ""
+"[!java]for (int i=0; i<7; i++) {[/!][!python]for i in "
+"range(7):[/!][!scala]for (i <- 1 to 7) {[/!]\n"
+"    goAndGet()[!java];[/!]\n"
+"    right()[!java];[/!]\n"
+"    forward()[!java];[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:112
+msgid ""
+"Your buggle will repeat 7 times (which matches the world's dimension)  the "
+"sequence constituted of a call to the <code>goAndGet()</code> method that "
+"you should write, plus a move to get to the next row (turn right, move "
+"forward, turn left). As you can see, the buggle will do one step right from "
+"the right border of the world. It will bring it back to the left side since "
+"its world is a torus."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/Methods.html:119
+msgid "You should now write this goAndGet() method."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:3
+msgid ""
+"We now would like to learn the buggle to build a doghouse. The naive "
+"approach consists in directly writing the needed code as follows.  This "
+"works because the buggle of this exercise leaves a red path as it moves."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:7
+#, no-wrap
+msgid ""
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"forward()[!java];[/!]\n"
+"left()[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:20
+msgid ""
+"It becomes harder when we want to draw two doghouses: we have to rewrite the "
+"same code twice, which is not really handy. When the code becomes a bit long "
+"as this one, it becomes easier to see why we insist since a while on the "
+"pure evilness that code duplication represents. Indeed, if you realize that "
+"an error sneaked into a code that you copied at several locations, you will "
+"have to fix it several times. And mind your back if you forget one of these "
+"locations."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:26
+msgid ""
+"There is even a name to this good principle in programming: DRY/SPOT, which "
+"means \"Don't Repeat Yourself / Single Point Of Truth\". The latter part "
+"means that each information must be written in only one location of your "
+"program to avoid the differing locations to get out of synch when you modify "
+"your code."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:31
+msgid ""
+"So, let's apply this good principle and <b>factorize our code</b>, ie to "
+"write it only once, for example in a method. You should even to go further "
+"by factorizing the method body with a <code>for</code> loop, as seen "
+"previously.  If you do it correctly (what you should), you can use the "
+"method <code>left()</code> only once."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/basics/MethodsDogHouse.html:38
+msgid ""
+"The goal of this exercise is to write a method called <code>dogHouse</code> "
+"achieving the same result than the code above, but with a for loop to keep "
+"it short.  The buggle will call your creation to create several dog houses "
+"around its world."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono.html:3 src/lessons/welcome/methods/picture/MethodsPicture.html:3
+msgid ""
+"In this exercise, we will reproduce the geometric drawing that you can see "
+"in the \"Objective\" tab."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:6 src/lessons/welcome/methods/picture/MethodsPicture.html:6
+msgid ""
+"Your goal (here and in any well written program) is to write the simplest "
+"possible code. For that, you have to decompose your work in sub-steps, and "
+"write a specific method for each sub-step."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:10
+msgid ""
+"If you observe carefully the picture to draw, it is constituted of four "
+"parts depicting a sort of V. A possible decomposition is to write a method "
+"in charge of drawing a V from the current position. Its prototype can be: "
+"<code>[!java]void [/!]makeV()</code>"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:15
+msgid ""
+"In this method, you should use the methods <code>brushUp()</code> and "
+"<code>brushDown()</code> to mark the ground (you may want to factorize this "
+"in another method). It may be wise to write the <code>makeV()</code> so that "
+"it places directly the buggle in position for the next V."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono.html:20
+msgid ""
+"Your turn. Your code of should not be longer than 4 lines (not counting "
+"<code>makeV</code>)..."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono2.html:3
+msgid ""
+"We will now reproduce an even bigger geometrical drawing. Once again, you "
+"can see the model by clicking on the \"Objective\" tab."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:6
+msgid ""
+"You can naturally reuse all the code you typed in previous exercise (select "
+"the other exercise, do Ctrl-C, come back to the code of this exercise, do "
+"Ctrl-V)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:10
+msgid ""
+"But you want to keep your code as simple as possible. For that, define new "
+"methods to deal simply with the repetitions in the pattern. For example, a "
+"method <code>makePattern()</code> achieving the pattern of previous example "
+"seems to be a good idea (but this may not be enough)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono2.html:15
+msgid ""
+"Why don't you give it a shot? The main code method shouldn't take more than "
+"2 lines (included in a for loop)"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PictureMono3.html:3 src/lessons/welcome/methods/picture/MethodsPictureLarge.html:3
+msgid ""
+"As you can imagine, you have to reproduce the geometric drawing depicted in "
+"the \"Objectives\" tab. As you can see, it is even bigger than the previous "
+"one."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PictureMono3.html:7
+msgid ""
+"You thus have to declare even more methods to use the repetitions of the "
+"pattern and factorize your code.  Your turn..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:3
+msgid ""
+"Writing a method returning a result is not really more work than writing a "
+"method without any result.  [!java]You simply have to specify the data type "
+"of expected results before the method name (where we previously had "
+"<code>void</code>).[/!] [!scala]You simply have to add a column (:) after "
+"the parenthesis and write the type of data that your method will return, and "
+"add an equal sign (=). This syntax is actually rather close to defining a "
+"variable, with its type, that is actually a function.[/!] You can use the "
+"<code>return</code> instruction anywhere in your method body to specify that "
+"the computation is done (the method is not further executed), and that the "
+"result is the the value following the <code>return</code> keyword."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:12
+#, no-wrap
+msgid ""
+"[!java]double pi() {[/!][!scala]def pi(): Double = {[/!][!python]def "
+"pi():[/!]\n"
+"    return 3.14159[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:16
+msgid ""
+"Actually, you can also use that <code>return</code> keyword in methods that "
+"do not return any result, to interupt the computation. Of course, you should "
+"not provide any value to return in that case."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:19
+msgid ""
+"It is possible to have several <code>return</code> instructions in several "
+"branches of a conditional. In fac, it is forbidden to have any execution "
+"path of your body without any <code>return</code>, or to write some code "
+"after the <code>return</code> instruction. Indeed, if the machine reaches "
+"the end of the method without finding any <code>return</code>, it cannot "
+"know what actual value to give back to the method caller.  Moreover, "
+"<code>return</code> interrupts immediately the method execution (why bother "
+"looking further when you know the method result?). So, if there is some code "
+"after a <code>return</code>, it must be an error and the compiler warns you."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:30
+#, no-wrap
+msgid ""
+"[!java|scala][!java]boolean [/!][!scala]def "
+"[/!]isFrontFree()[!scala]:Boolean =[/!] {\n"
+"    if (isFacingWall() == true) {\n"
+"        return false;\n"
+"        <span class=\"comment\">/* no code allowed here */</span>\n"
+"    } else {\n"
+"        return true;\n"
+"        <span class=\"comment\">/* here neither */</span>\n"
+"    }\n"
+"    <span class=\"comment\">/* even here, forget it */</span>\n"
+"}[/!][!python]def isFrontFree():\n"
+"    if isFacingWall() == True:\n"
+"        return False\n"
+"        <span class=\"comment\"># no code allowed here</span>\n"
+"    else\n"
+"        return True\n"
+"        <span class=\"comment\"># here neither</span>\n"
+"<span class=\"comment\"># even here, forget it</span>[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:48
+msgid ""
+"You will once again write a method that the buggle will use. Its name must "
+"be <code>haveBaggle</code>, and it returns a boolean value indicating "
+"whether the row in front of the buggle contains a baggle or not. The buggle "
+"will use it to search the first row containing a baggle, and stop here."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:53
+msgid ""
+"The easier for this method is to use a boolean variable called "
+"<code>seenBaggle</code> indicating whether or not we saw a baggle so far. It "
+"initial value is 'false'."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:57
+msgid ""
+"Then, move 6 steps forward (the world contains 7 cells and we already are "
+"one one of them). For each cell, if it contains a baggle, we store true in "
+"<code>sawBaggle</code> (and we don't do anything but moving forward if not)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:61
+msgid ""
+"At the end, we move back by 6 steps, and we return the value of "
+"<code>seenBaggle</code> to the caller."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:65
+msgid ""
+"This exercise is a bit different since there is two initial worlds, each "
+"with a specific objective. Your code must work for each of them. Observe "
+"that the world selection scrolling menu (right below the speed slider)  "
+"allows to switch the observed world."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/returning/MethodsReturning.html:70
+msgid "When your method <code>haveBaggle</code> works, proceed to next exercise."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:3
+msgid ""
+"Don't you get tired of writing again and again the code to move by a fixed "
+"amount of steps? On the other hand, writing <tt>forward2()</tt>, "
+"<tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>, "
+"<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help, "
+"to say the less."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:9
+msgid ""
+"Luckily, it is possible to pass <b>parameters</b> to your methods. You have "
+"to specify their type and name between the parenthesis after the method "
+"name. Then, you can use them in the method body as if it were variables "
+"defined in there, and which initial value is what the caller specified."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:14
+#, no-wrap
+msgid ""
+"[!java]double [/!]divideByTwo([!java]double [/!]x[!scala]: "
+"Double[/!])[!scala]: Double =[/!] [!java|scala]{[/!][!python]:[/!]\n"
+"     return x / 2[!java];[/!]\n"
+"[!scala|java]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:18
+msgid ""
+"As caller, you have to specify the initial value of this \"variables\" "
+"between the call's parenthesis."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:20
+#, no-wrap
+msgid "[!java]double [/!][!scala]val [/!]result = divideByTwo(3.14)[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:22
+msgid ""
+"If you want several parameters, you need to separate them with comas (,)  "
+"both in the declaration and calls."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:25
+#, no-wrap
+msgid ""
+"[!java]double divide(double x, double y) {[/!]\n"
+"[!scala]def divide(x:Double, y:Double): Double = {[/!]\n"
+"[!python]def divide(x, y):[/!]\n"
+"     return x / y[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:30
+#, no-wrap
+msgid ""
+"[!java]double res = divide(3.14 , 1.5);[/!]\n"
+"[!scala]val res = divide(3.14 , 1.5)[/!]\n"
+"[!python]res = divide(3.14 , 1.5)[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:35
+msgid ""
+"In [!thelang], you can declare several methods of the same name as long as "
+"they don't have the same <b>signature</b>, that is, the same amount of "
+"parameters and the same parameters' types."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:39
+#, no-wrap
+msgid ""
+"[!java]double max(double x, double y)[/!][!scala]def max(x:Double, int "
+"y:Double): Double =[/!] {\n"
+"  if (x > y) {\n"
+"    return x;\n"
+"  }\n"
+"  return y;\n"
+"}[!java]int max(int x, int y)[/!][!scala]def max(x:Int, int y:Int): Int "
+"=[/!] {\n"
+"  if (x > y) {\n"
+"    return x;\n"
+"  }\n"
+"  return y;\n"
+"}\n"
+"[!java]int max(int x, int y; int z)[/!][!scala]def max(x:Int, int y:Int, int "
+"z:Int): Int =[/!] {\n"
+"  if (x > y && x > z) {\n"
+"    return x;\n"
+"  }\n"
+"  if (y > z) {\n"
+"    return y;\n"
+"  }\n"
+"  return z;\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:60
+msgid ""
+"Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It "
+"works anyway because a <tt>return</tt> interrupts the method execution. If "
+"we arrive to the last line of "
+"<code>[!java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>, we know "
+"that <code>x<=y</code> because otherwise, the <tt>return</tt> of line 2 "
+"would have stopped the execution."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:70
+msgid ""
+"This time, you have to write a <code> [!java]move(int stepCount,boolean "
+"forward)[/!] [!scala]move(stepCount: Int,forward: Boolean)[/!] "
+"[!python]move(stepCount,forward)[/!] </code> method which moves forward by "
+"<code>stepCount</code> steps if <code>forward</code> is true, and moves back "
+"of that amount of steps if the boolean is false."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/args/MethodsArgs.html:78
+msgid ""
+"This time, there is only one world but seven buggles, all sharing the same "
+"code.  This code should not be really problematic for you to write, "
+"actually."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:1
+msgid "Flower Pot"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:3
+msgid ""
+"Your buggle decided to flower a bit the pot it lives in. You have to help it "
+"reproducing the drawing of its dreams (check the \"Objective\" tab to see "
+"it)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:6
+msgid ""
+"For that, you have to write a <code>growFlowers()</code> method that does "
+"not take any parameter and does not return any result. As the pattern is a "
+"bit complex, you should try to decompose this drawing in sub-steps so that "
+"your code remains short and easy to read. A method to draw one flower of the "
+"color passed in parameter sounds like a good start, but it is probably not "
+"enough."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:12
+msgid ""
+"For your information, this drawing uses five colors that are listed below.  "
+"[!java|scala]The data type of these constants is <code>Color</code>, that "
+"naturally describes a particular color.[/!]"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:17
+msgid "<tt>Color.RED</tt>"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:18
+msgid "<tt>Color.PINK</tt>"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:19
+msgid "<tt>Color.CYAN</tt>"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:20
+msgid "<tt>Color.ORANGE</tt>"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:21
+msgid "<tt>Color.GREEN</tt>"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/methods/flowerpot/FlowerPot.html:22
+msgid "<tt>Color.YELLOW</tt>"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:1
+msgid "Flower Display Case"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:3
+msgid ""
+"Whao! That's not a little pot anymore! That's a huge large flower display "
+"case! Your buggle can't help but starts flowering this gorgeous place. You "
+"should help it to prevent that it bumps into a wall..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/flowerpot/FlowerCase.html:7
+msgid "PS: the newly used color is <code>Color.BLUE</code>."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:1
+msgid "Colorful drawing"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:10
+msgid ""
+"If you observe carefully the picture to draw, it is constituted of four "
+"parts depicting a sort of V using a different color. A possible "
+"decomposition is to write a method in charge of drawing a V of the specified "
+"color from the current position. Its prototype can be:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:14
+#, no-wrap
+msgid ""
+"[!java]void [/!]makeV([!java]Color [/!]c[!scala]: Color[/!])[!python]  <span "
+"class=\"comment\"># parameter c is of type Color</span>[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:16
+msgid ""
+"The <code>Color</code> data type naturally describes a particular "
+"color. Your code should probably call <code>makeV</code> with the following "
+"arguments (a different color for each call):"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:20
+msgid "Color.YELLOW"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:21
+msgid "Color.RED"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:22
+msgid "Color.BLUE"
+msgstr ""
+
+#. type: Content of: <p><p><ul><li>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:23
+msgid "Color.GREEN"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:26
+msgid ""
+"In <code>makeV()</code>, you should use the <code>setBrushColor()</code> "
+"method (predefined in the buggle) to change the color of the buggle's brush, "
+"as well as <code>brushUp()</code> and <code>brushDown()</code> to change the "
+"brush position."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:31
+msgid ""
+"It may be wise to write the <code>makeV()</code> so that it places directly "
+"the buggle in position for the next V."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/methods/picture/MethodsPicture.html:35
+msgid ""
+"Your turn now. I'm sure you can imagine the other methods you need to keep "
+"your code simple and pleasant to read.  Complete the run which prototype is "
+"already given. It will be called automatically (once).  [!java]the public "
+"keyword means more or less that anybody can call this method, which is good "
+"because the PLM infrastructure calls it directly.[/!]"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:1
+msgid "Larger colorful drawing"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:7
+msgid ""
+"You thus have to declare even more methods to use the repetitions of the "
+"pattern and factorize your code. Another solution is to <i>parametrize</i> "
+"your functions to reuse the code you wrote previously by changing the size."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/MethodsPictureLarge.html:11 src/lessons/welcome/traversal/Snake.html:39 src/lessons/welcome/traversal/column/TraversalByColumn.html:46 src/lessons/welcome/traversal/line/TraversalByLine.html:10 src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:10 src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:6
+msgid "Your turn..."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/picture/PatternPicture.html:1
+msgid "Another Colorful Pattern"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/picture/PatternPicture.html:3
+msgid ""
+"Here is yet another exercise where you have to reproduce the pattern "
+"provided in the \"Objective\" tab."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PatternPicture.html:6
+msgid ""
+"This one is a bit more difficult than the one seen previously. Look for "
+"repeating patterns, even if the color changes, and write a method drawing "
+"each of them."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/picture/PatternPicture.html:10
+msgid "Good luck!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugHunting.html:3
+msgid ""
+"Now that your <code>isFacingTrail()</code> method is working, it's time to "
+"write the code to organize the hunting party. Copy/paste your code from the "
+"previous exercise, and complete the <code>hunt()</code> method."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugHunting.html:7
+msgid ""
+"Following a track is not very difficult: move forward as long as you have "
+"the track in front of you.  If there is not track in front of you anymore, "
+"check if the rest of the track is on your left or on your right, and follow "
+"it further."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugHunting.html:11
+msgid ""
+"To ensure that you don't mix the track you come from with the one in front "
+"of you, the easier is to erase the track when you follow it. Use the method "
+"<code>brushDown()</code> to put your brush down and mark the ground, and "
+"<code>brushUp()</code> to move it up again."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugHunting.html:15
+msgid ""
+"Finally, do not forget to capture your prey once you found it (using "
+"<code>pickupBaggle()</code>)."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/methods/slug/SlugHunting.html:19
+msgid ""
+"<a name=\"Objectives\"> Complete the <code>hunt()</code> method. You "
+"probably want to copy over the <code>isFacingTrail()</code> method that you "
+"wrote in previous exercise.  </a>"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:3
+msgid ""
+"Your buggle is super happy! It just found the green dribbling trail, "
+"certainly left by a big yummy slug.  At its end, the buggle is certain to "
+"entertain itself with this appetizing slug (represented as a baggle)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:7
+msgid ""
+"To reach that goal, you had to write a boolean method "
+"<tt>isFacingTrail</tt>, which determines whether we are facing a green cell "
+"or not. Of course, if we are facing a wall, it should return false without "
+"bumping into it. You should make sure that this method has no <b>side "
+"effect</b>, i.e. that it does not change the state of the calling buggle nor "
+"of its world."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:12
+msgid ""
+"Your tool to that end is the <code>getGroundColor()</code> that returns the "
+"color of the current cell. Just go to the cell you want to test and run that "
+"function.  [!java]You cannot test whether this color is equal to "
+"<code>Color.green</code> with an <code>==</code> sign but instead you have "
+"to write something like "
+"<code>getGroundColor().equals(Color.green)</code>. This is because green is "
+"an <i>object</i> in Java, and <code>.equals()</code> is the way to go to "
+"test equality between Java objects.[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugTracking.html:20
+msgid ""
+"Complete the <code>isFacingTrail()</code> method (which gets called "
+"automatically)."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/methods/slug/SlugSnail.html:1
+msgid "Slugs and Snails"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugSnail.html:3
+msgid ""
+"Yuhu! This time, your buggle found the tracks of much more preys! In the "
+"first world, that's a yummy Kitty Slug (leaving a pink trail) while on the "
+"second world, that's a big fat snail that awaits your buggle at the end of "
+"the orange trail."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/methods/slug/SlugSnail.html:7
+msgid ""
+"You have to copy/paste your code again, and change it so that your methods "
+"take the color of the trail to follow as a parameter. Beside of this, your "
+"code should work as earlier."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/bdr/BDR.html:1
+msgid "Buggle Dance Revolution (BDR)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:3
+msgid ""
+"Today is a great day: we will learn the buggles to play Dance Revolution, "
+"this game beloved of some students where the player has to move its feet on "
+"the carpet according to the instructions presented on the screen, and "
+"following the music. But before that, we have some details to study first."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:9
+msgid "Conditionals without curly braces"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:11
+msgid ""
+"There is one detail we omitted about the conditional syntax: if a branch "
+"contains only one instruction, then the curly braces become optional. So, "
+"the two chunk of code are equivalent:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:15
+#, no-wrap
+msgid ""
+"if (<b>condition</b>) {\n"
+"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
+"} else {\n"
+"    <b>whatToDoElse();</b>\n"
+"}"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:20
+#, no-wrap
+msgid ""
+"if (<b>condition</b>) \n"
+"    <b>whatToDoIfTheConditionIsTrue();</b>\n"
+"else\n"
+"    <b>whatToDoElse();</b>"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:25
+msgid ""
+"Actually, you can do the same for loops body that are reduced to one "
+"instruction only.  But beware, this becomes dangerous if you chain the "
+"<tt>if</tt> instructions like this:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:27
+#, no-wrap
+msgid ""
+"if (isOverBaggle())    \n"
+"     if (x == 5)\n"
+"          left();\n"
+"else\n"
+"     right();\n"
+"forward();"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:34
+msgid ""
+"In fact, it does not turn right when there is no baggle on the ground AND x "
+"equals 5, but when the buggle found a baggle on the ground and x equals "
+"anything but 5. Putting this otherwise, the buggle understands the previous "
+"code as if it were written the following way (note that the <tt>else</tt> "
+"were moved to the right):"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:39
+#, no-wrap
+msgid ""
+"if (isOverBaggle())    \n"
+"        if (x == 5)\n"
+"            left();\n"
+"        else\n"
+"            right();\n"
+"forward();"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:46
+msgid ""
+"The first lesson of this is that the indentation is very important to help "
+"humans understanding, even if it does not change the actual meaning of the "
+"code. We could have written the following code and obtain the same "
+"result. But if you want a human to read and review your code, you really "
+"want to indent it correctly. That's for example the case if you want a "
+"professor to read it (to grade it or to answer a question about it), or if "
+"you want to reuse your code later, or even if you need to debug your code "
+"yourself."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:54
+#, no-wrap
+msgid "if (isOverBaggle()) if (x == 5) left(); else right(); forward();"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:56
+msgid ""
+"The second lesson is that a <tt>else</tt> branch always connects to the "
+"closest <tt>if</tt>. This may be a bit troublesome in some case, and it may "
+"be easier to add more braces than strictly needed to remove any ambiguity."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:61
+msgid "Chaining conditionals"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:63
+msgid "You sometimes want to ask the buggle something similar to:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:64
+#, no-wrap
+msgid ""
+"if it's raining, take an umbrella;\n"
+"if not, and if it's a hot day, take a bottle of water;\n"
+"if not and if it's July 4th, take an American flag"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:68
+msgid ""
+"The trap is that we want at most one of these actions to be taken. That is "
+"to say, if it's raining a very hot July 4th, we don't want the buggle to get "
+"outside with an umbrella, some water and a flag, but simply with an "
+"umbrella. The following code is thus WRONG."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:73
+#, no-wrap
+msgid ""
+"[!java|scala]if (rainy())\n"
+"    takeUmbrella();\n"
+"if (hot())\n"
+"    takeWater();\n"
+"if (todayIsJuly4th())\n"
+"    takeFlag();[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
+"if hot():\n"
+"    takeWater()\n"
+"if todayIsJuly4th():\n"
+"    takeFlag()[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:86
+msgid ""
+"Indeed, since the conditions are evaluated one after the other, there is a "
+"risk that you go to the July 4th march on a rainy day. Instead, we should "
+"use something like this to ensure that once we found a true condition, we "
+"won't evaluate the next ones."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:91
+#, no-wrap
+msgid ""
+"[!java|scala]if (rainy()) {\n"
+"    takeUmbrella();\n"
+"} else {\n"
+"    if (hotDay()) {\n"
+"        takeWater();\n"
+"    } else {\n"
+"        if (todayIsJuly4th()) {\n"
+"            takeFlag();\n"
+"        }\n"
+"    }\n"
+"}[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
+"else:\n"
+"    if hotDay():\n"
+"        takeWater()\n"
+"    else:\n"
+"        if todayIsJuly4th():\n"
+"            takeFlag()[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:111
+msgid ""
+"Unfortunately, such a cascade of conditionals is quite difficult to read. It "
+"is better to [!java|scala]omit the curly braces for the <tt>else</tt> "
+"statements. Some languages even introduce a specific construct for these "
+"<tt>else if</tt>, but not [!thelang].[/!] [!python]change the sub-blocks "
+"using the <code>elif</code> keyword to mark explicitly these \"else if\" "
+"branches.[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/bdr/BDR.html:118
+#, no-wrap
+msgid ""
+"[!java|scala]if (rainy()) { \n"
+"    takeUmbrella();\n"
+"} else if (hotDay()) {\n"
+"    takeWater();\n"
+"} else if (todayIsJuly4th()) {\n"
+"    takeFlag();\n"
+"}[/!][!python]if rainy():\n"
+"    takeUmbrella()\n"
+"elif hotDay():\n"
+"    takeWater()\n"
+"elif todayIsJuly4th():\n"
+"    takeFlag()[/!]"
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:131
+msgid "Graffiti in the Buggle World"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:133
+msgid ""
+"Buggles can tag graffitis on the ground of their world. For that, they use "
+"the four following methods:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:137
+msgid ""
+"<code>[!java]boolean[/!] isOverMessage()[!scala]:Boolean[/!]</code>: returns "
+"<code>[!java|scala]true[/!][!python]True[/!]</code> if and only if there is "
+"a message on the ground."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:140
+msgid ""
+"<code>[!java]String[/!] readMessage()[!scala]: String[/!]</code>: returns "
+"the message written on the ground (or an empty string if nothing is "
+"written)."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:142
+msgid ""
+"<code>[!java]void[/!] writeMessage([!java]String [/!]msg[!scala]: "
+"String[/!])</code>: writes the specified message down on the ground. If "
+"there is already a message on the ground, the new content is added at the "
+"end of the existing message."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/bdr/BDR.html:145
+msgid ""
+"<code>[!java]void [/!]clearMessage()</code>: clears what is written on the "
+"ground."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:149
+msgid ""
+"The goal is then to organize a BDR game between the buggles by learning them "
+"to move according to the instructions written on the ground. These "
+"instructions are messages written on the ground, with the following "
+"signification:"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:155 src/lessons/welcome/bdr/BDR2.html:138
+msgid "Message"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:156 src/lessons/welcome/bdr/BDR2.html:139
+msgid "What to do"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:157
+msgid "Mnemonic"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:159 src/lessons/welcome/bdr/BDR2.html:141 src/lessons/turmites/turmitecreator/TurmiteCreator.html:30 src/lessons/turmites/turmitecreator/TurmiteCreator.html:33
+msgid "R"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:159 src/lessons/welcome/bdr/BDR2.html:141
+msgid "Turn right and move one step forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:159
+msgid "Right"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160 src/lessons/welcome/bdr/BDR2.html:142
+msgid "L"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160 src/lessons/welcome/bdr/BDR2.html:142
+msgid "Turn left and move one step forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:160
+msgid "Left"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161 src/lessons/welcome/bdr/BDR2.html:143
+msgid "I"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161
+msgid "Turn back (U-turn) and move one step forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:161
+msgid "Inverse"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163 src/lessons/welcome/bdr/BDR2.html:145
+msgid "A"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163 src/lessons/welcome/bdr/BDR2.html:145
+msgid "Move one step forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:163
+msgid "First letter of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164 src/lessons/welcome/bdr/BDR2.html:146
+msgid "B"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164 src/lessons/welcome/bdr/BDR2.html:146
+msgid "Move two steps forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:164
+msgid "Second letter of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:147
+msgid "C"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165 src/lessons/welcome/bdr/BDR2.html:147
+msgid "Move three steps forward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:165
+msgid "Third letter of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167 src/lessons/welcome/bdr/BDR2.html:152
+msgid "Z"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167 src/lessons/welcome/bdr/BDR2.html:152
+msgid "Move one step backward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:167
+msgid "One letter before the end of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168 src/lessons/welcome/bdr/BDR2.html:153
+msgid "Y"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168 src/lessons/welcome/bdr/BDR2.html:153
+msgid "Move two steps backward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:168
+msgid "Two letters before the end of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:154
+msgid "X"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169 src/lessons/welcome/bdr/BDR2.html:154
+msgid "Move three steps backward"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:169
+msgid "Three letters before the end of the alphabet"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:158
+msgid "<i>(anything else)</i>"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR.html:170 src/lessons/welcome/bdr/BDR2.html:158
+msgid "Stop dancing."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:173
+msgid "Indications"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:175
+msgid ""
+"This exercise may seem a bit complex at the first glance, but it comes down "
+"to summarizing the information of the table in a sequence of conditionals."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:178
+msgid ""
+"You have to keep dancing as long as there is some dancing steps to do, i.e., "
+"as long as we are not in cell which content is not described in the table.  "
+"The easier for that is to use a boolean variable (<code>finished</code>)  as "
+"termination condition to a <code>while</code> loop.  It should be "
+"initialized to <code>[!java|scala]false[/!][!python]False[/!]</code>, and "
+"switched to <code>[!java|scala]true[/!][!python]True[/!]</code> as soon as "
+"the buggle find a cell with a value not described in the table.  Thus the "
+"loop, will stop and the program will terminate."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:188
+msgid ""
+"Another subtlety is that detecting if strings are equals is a bit annoying "
+"in Java.  So, we use the <code>char getIndication()</code> instead of "
+"<code>String readMessage()</code>.  This method, only known by the buggles "
+"of this exercise, returns the first char of the message written on the "
+"ground (or ' ' -- the space char -- if nothing is written down). It enables "
+"to work with chars instead of strings, that is much simpler in Java."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR.html:195
+msgid "Tips and Hints"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bdr/BDR.html:197
+msgid ""
+"If you fail to understand why the buggle does not execute the expected "
+"steps, try adding <code>brushDown()</code> in your method. This asks the "
+"buggle to put down a brush leaving a trail when it moves. It should help you "
+"understanding its trajectory, but do not forget to remove this call when you "
+"want to test whether your code is a valid solution to the exercise: you are "
+"asked to let the buggle dance, not to vandalize the dance floor."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR.html:204
+msgid "When your program finally works, move on to the next exercise."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/bdr/BDR2.html:1
+msgid "Buggle Dance Revolution 2 (BDR2)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR2.html:4
+msgid ""
+"BDR is cool, but it's a bit chaotic. First, the buggles giggle in any "
+"directions, and then the code you had to write to let them move is rather "
+"difficult to read. Here is a new BDR world where the buggle will dance a "
+"gentle circle. We will benefit this tranquillity to clean up a bit our code "
+"thanks to the new constructs we will introduce."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/welcome/bdr/BDR2.html:10
+msgid "[!java]<code>switch</code> conditionals[/!][!scala]Pattern matching[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR2.html:12
+msgid ""
+"The hardest part of previous code is certainly the conditional "
+"cascading. Somewhere in your code, you certainly had something similar to:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:15
+#, no-wrap
+msgid ""
+"if ([!java]getIndication() == 'R'[/!][!scala]readMessage() == \"R\"[/!]) {\n"
+"  right();\n"
+"  forward();\n"
+"} else if ([!java]getIndication() == 'L'[/!][!scala]readMessage() == "
+"\"L\"[/!]) {\n"
+"  left();\n"
+"  forward();\n"
+"} else if ([!java]getIndication() == 'I'[/!][!scala]readMessage() == "
+"\"I\"[/!]) {\n"
+"  back();\n"
+"  forward();\n"
+"<span class=\"comment\">/* other else if */</span>\n"
+"} else {\n"
+"  finished = true;\n"
+"}\n"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/bdr/BDR2.html:30
+msgid ""
+"When you review this code, it may not be clear at the first glance that it "
+"is simply a choice with 4 branches depending on the value of "
+"[!java]getIndication()[/!][!scala]readMessage()[/!].  To improve this, we "
+"will use a [!java]<code>switch</code> construct, which Java syntax is the "
+"following:[/!] [!scala] pattern matching, which is a very powerful construct "
+"that greatly generalizes the <code>if</code>. It is arguably one one the "
+"major advantages of Scala when compared to languages such as Java or "
+"python.  It is not new either, as other languages such as OCaml or Haskell "
+"offer this feature since long, but still.  It's really cool![/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bdr/BDR2.html:39
+msgid "[/!] [!java]"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:43
+#, no-wrap
+msgid ""
+"switch (<b>expression</b>) {\n"
+"  case <b>firstValue</b>: \n"
+"    <b>whatToDoIfExpressionEqualsFirstValue();</b>\n"
+"    break;\n"
+"  case <b>secondValue</b>: \n"
+"    <b>whatToDoIfExpressionEqualsSecondValue();</b>\n"
+"    break;\n"
+"  case <b>thirdValue</b>: \n"
+"    <b>whatToDoIfExpressionEqualsThirdValue();</b>\n"
+"    break;\n"
+"    /* as much similar cases as you want */\n"
+"  default: \n"
+"    <b>whatToDoIfExpressionDoesNotEqualsAnySeenValues();</b>\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/bdr/BDR2.html:58
+msgid ""
+"Observe that each branch of a <tt>switch</tt> must be ended by a "
+"<code>break</code>. If you forget this, the machine keeps going and execute "
+"the next branch in the list after the branch it jumped to. There is even "
+"some <b>rare</b> cases where this behavior reveals helpful."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:63
+msgid ""
+"It is then possible to rewrite previous BDR code in a cleaner way using the "
+"<tt>switch</tt> construct:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:66
+#, no-wrap
+msgid ""
+"switch (getIndication()) {\n"
+"  case 'R':\n"
+"    right(); \n"
+"    forward(); \n"
+"    break;\n"
+"  case 'L':\n"
+"    left();\n"
+"    forward(); \n"
+"    break;\n"
+"  case 'I':\n"
+"    back();\n"
+"    forward();\n"
+"    break;\n"
+"  default: \n"
+"    return;\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:84
+#, no-wrap
+msgid ""
+"<i>expression</i> <b>match</b> {\n"
+"  <b>case</b> <i>possible value</i> <b>=></b> instructions\n"
+"  <b>case</b> <i>other value</i>     <b>=></b> other instructions\n"
+"  <b>case</b> <i>another value</i> <b>=></b> yet another instructions\n"
+"  <b>case _                 =></b> default instructions\n"
+"}\n"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:91
+msgid ""
+"The expression provided before the keyword <code>match</code>, and then the "
+"branches are evaluated one after the other until we find one which value "
+"provided between <code>case</code> and <code>=&gt</code> is equal to the "
+"expression's value.  The <code>_</code> symbol acts as a wildcard, so the "
+"<code>_</code> branch <i>always</i> matches.  Here is an example where a "
+"variable <code>name</code> is matched."
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:96
+#, no-wrap
+msgid ""
+"name match {\n"
+"  case \"Martin\" => println(\"Hello Martin, how are you?\")\n"
+"  case \"Gerald\" => println(\"Hey Gerald! How are you doing?\")\n"
+"  case _            => println(\"Welcome stranger.\")\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:102
+msgid ""
+"It is possible to have more than one instruction per branch, and merge "
+"branches when the values are separated by a | symbol."
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:104
+#, no-wrap
+msgid ""
+"name match {\n"
+"  case \"Martin\" | \"Gerald\" => println(\"Hello \"+name+\", how are "
+"you?\"); openTheDoor()\n"
+"  case _                            => println(\"Hello stranger. Please do "
+"not pass.\"); lockTheDoor()\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:109
+msgid ""
+"You can even add guards to your branches. These are extra conditions that "
+"must be respected for the branch to get applied. This is handy if you want "
+"match on value ranges, as follows."
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:111
+#, no-wrap
+msgid ""
+"age match {\n"
+"  case i if i<10 => println(\"Hey kid!\")\n"
+"  case i if i<20 => println(\"Hey dude!\")\n"
+"  case i if i<30 => println(\"Hello young man\")\n"
+"  case _           => println(\"Hello Sir\")\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:117
+msgid ""
+"Note that there is no need to check whether the value is higher than 10 on "
+"the second line because the first matching branch is used. So, if the second "
+"branch gets evaluated, then the first one did not match."
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:120
+msgid "Finally, it is possible also to match several variables in one shoot!"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/bdr/BDR2.html:121
+#, no-wrap
+msgid ""
+"(x,y) match {\n"
+" case (0,0) => println(\"that's the origin\")\n"
+" case (_,0) => println(\"On the ordinate\")\n"
+" case (0,_) => println(\"On the abscissa\")\n"
+" case (_,_) => println(\"Some random point\")\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:128
+msgid ""
+"I told you that scala's pattern matching is very powerful! I actually love "
+"this feature!"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:132
+msgid ""
+"[!java|scala]Apply the improvement we just saw to rewrite your buggle code "
+"with the following dance steps. [/!] [!python]Let's teach a new dance step "
+"to the buggles. It is slightly more complex but actually better "
+"looking. Beside of that, that's the same old story.[/!] Note that we can now "
+"move up to 6 cells in one dance step."
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:143
+msgid "Turn back and move one step forward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:148
+msgid "D"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:148
+msgid "Move four cells forward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:149
+msgid "E"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:149
+msgid "Move five cells forward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:150
+msgid "F"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:150
+msgid "Move six cells forward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:155
+msgid "W"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:155
+msgid "Move four cells backward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:156
+msgid "V"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:156
+msgid "Move five cells backward"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:157
+msgid "U"
+msgstr ""
+
+#. type: Content of: <p><p><p><table><tr><td>
+#: src/lessons/welcome/bdr/BDR2.html:157
+msgid "Move six cells backward"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/bdr/BDR2.html:162
+msgid "When you program works again, proceed to next exercise."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:3
+msgid ""
+"We will now teach the buggle to explore its world. Its initial position is "
+"the bottom left corner, and it should visit any cells up to the top "
+"(coloring the ground on its path. The main loop of your code is something "
+"like:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/traversal/Snake.html:7
+#, no-wrap
+msgid ""
+" move brush down\n"
+" while we did not reach the final position\n"
+"   move like a snake\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:12
+msgid ""
+"We thus have to write two specific methods: The first one returns a boolean "
+"indicating whether we are on a final position while the second moves one "
+"snake step forward."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:16
+msgid "We reached the final position if and only if both conditions are true:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/traversal/Snake.html:18
+msgid "We are facing a wall"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/traversal/Snake.html:19
+msgid ""
+"There is a wall on the north of the buggle. So, if the buggle is facing "
+"east, you should check whether there is a wall on the left, and if the "
+"buggle is facing west, you should check on the right side."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/traversal/Snake.html:22
+msgid ""
+"We can get the current heading of the buggle using the "
+"<code>getDirection()</code>, and we know whether it looks east using "
+"<code>getDirection() == Direction.EAST</code> (WEST for west)."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/welcome/traversal/Snake.html:25
+msgid ""
+"To check, nothing magical: you have to turn the buggle and check whether it "
+"is facing a wall afterward."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:28
+msgid ""
+"Then, a snake step can be achieved by moving one step forward if we are not "
+"facing a wall, and moving to the upper line else (i.e., if you look to the "
+"west facing a wall, you have to turn right, forward and turn right)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:32
+msgid ""
+"Hint: the main loop of your code must continue while the testing function "
+"returns false. Their is thus two way of writing it:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/traversal/Snake.html:34
+#, no-wrap
+msgid "while (testingFunction() == [!java|scala]false) {[/!][!python]False):[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/Snake.html:35
+msgid ""
+"[!python]You may prefer to write it as:[/!] [!java|scala]Since the "
+"exclamation mark (!) denotes the boolean negation in [!thelang], you may "
+"write it as:[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/traversal/Snake.html:37
+#, no-wrap
+msgid ""
+"while ([!java|scala]![/!][!python]not [/!]testingFunction())[!java|scala] "
+"{[/!][!python]:[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:3
+msgid ""
+"The goal of this serie of exercises is to let the buggle traverse its "
+"world. It must number the cells it walks on to show its traversal order."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:6
+msgid "The main loop of your code should be something like:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:8
+#, no-wrap
+msgid ""
+" while we are not on the final position\n"
+"   go to the next position\n"
+"   label the cell with its number\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:13
+msgid ""
+"In contrary to the exercises we saw so far, we won't use the "
+"<code>forward()</code>, <code>backward()</code> and similar "
+"methods. Instead, we will compute the coordinate of the next buggle position "
+"and use the <code>setPos(x, y)</code> method to <i>teleport</i> the buggle "
+"directly to this position. For example, <code>setPos(3, 5)</code> teleports "
+"the buggle to the cell where x=3 and y=5."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:20
+msgid ""
+"Your first task is thus to write a boolean function indicating whether the "
+"buggle reached the final position or not, ie if it reached the bottom right "
+"corner of the world. For this, you can use <code>getWorldWidth()</code> and "
+"<code>getWorldHeight()</code> which return respectively the world's width "
+"and height. Your test is about comparing the buggle's current position (that "
+"you can access with <code>getX()</code> and <code>getY()</code>) to the "
+"world dimensions."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:27
+msgid "Beware, the first line and column are numbered 0 and not 1..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:29
+msgid ""
+"Then, you have to write the code to reach the next position. In this "
+"exercise, you have to traverse the world row after row. So, if you are at "
+"the bottom of a row, you have to move to the top of next row, and you have "
+"to move to the cell below else."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:34
+msgid ""
+"At this point, you can launch your program to check that the buggle "
+"correctly traverse the world in the expected order, and that it stops when "
+"it has to. Use the <b>stop</b> button if the buggle does not stop correctly."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:38
+msgid ""
+"It is now time to write down the cell numbers. For that, you will need a "
+"counter initialiser to zero at the begining of your code, and incremented by "
+"one at each step (for example with <code>counter += 1;</code>).  Then, you "
+"have to use <code>writeMessage()</code> to write the value on the ground."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/welcome/traversal/column/TraversalByColumn.html:43
+msgid ""
+"You probably need to write the first [!java|scala]or last [/!]value out of "
+"the main loop [!java|scala], depending on whether you prefer to use a "
+"<code>while</code> or a <code>do/while</code> one[/!]."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/traversal/line/TraversalByLine.html:3
+msgid ""
+"You once again have to let the buggle traverse the world numbering the cells "
+"on its way, but the goal of this exercise is to write a line traversal. Most "
+"of the code you wrote for previous exercise remains usable here. Simply, the "
+"method computing the coordinates of the next buggle position has to be "
+"correctly updated: if you are at the right of a line, you have to go to the "
+"begining of the next one. If not, you have to go to the right cell."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:3
+msgid ""
+"This time, you are asked to traverse the world one diagonal after the "
+"other. Have a look at the objective world for more details on the requested "
+"traversal order."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html:7
+msgid ""
+"You may find useful to use an integer variable <code>diag</code> storing the "
+"number of the diagonal you are traversing."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/traversal/zigzag/TraversalZigZag.html:3
+msgid ""
+"This time, you have to zigzag on the way up. Have a look at the objective "
+"world for more details on the requested traversal order."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/turmites/Main.html:1 src/lessons/turmites/short_desc.html:1
+msgid "The turmites"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/Main.html:3
+msgid ""
+"This set of activities lets you play with Langton's ants, that are 2D turing "
+"machines. They constitute very simple application problems, achievable by "
+"beginners, and open the door to an amazing world."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/Main.html:7
+msgid ""
+"This mechanism were invented in 1986 by Chris Langton, and later generalized "
+"in several ways (as we shall see in the next exercises). It was proven that "
+"Turmites and Turing machines are of equal power: An ant's trajectory can be "
+"used to compute any boolean circuit, and thus that an ant is capable of "
+"universal computation. Put simply, any possible computation can be achieved "
+"using a turmite as a computing device. Yet another subject of fascination..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/Main.html:13
+msgid ""
+"Multicolor Langton's ants were discovered in 1995 by Propp et Al. Another "
+"funny fact is that the ants which name is a list of consecutive pair of "
+"identical letters (LL and RR) produce symmetric patterns. This fact was even "
+"formally proved."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/Main.html:18
+msgid ""
+"Check the corresponding wikipedia web page, of which this exercise is "
+"inspired, for further details."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/turmites/Main.html:21 src/lessons/sort/pancake/Main.html:29 src/lessons/sort/baseball/Main.html:27 src/lessons/turtleart/Main.html:11
+msgid "What can I do to improve this PLM universe?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/Main.html:23 src/lessons/sort/pancake/Main.html:31 src/lessons/sort/baseball/Main.html:29 src/lessons/turtleart/Main.html:13
+msgid ""
+"As usual, there are several things that could be done in the code of this "
+"universe to improve it:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/Main.html:25
+msgid ""
+"We are probably missing some good exercises. The turmite creator exercise is "
+"a bit harsh: we could introduce the patterns in a more friendly manner."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/Main.html:27
+msgid "We may want to write an exercise on the busy beaver, maybe?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/short_desc.html:2
+msgid "Discover the Langton's ants, that are 2D turing machines."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/short_desc.html:4
+msgid ""
+"These activities are very simple application problems, achievable by "
+"beginners, and open the door to an amazing world."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/langton/Langton.html:1
+msgid "Langton's ant"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:3
+msgid ""
+"In this exercise, you will turn your buggle into a <i>Langton's "
+"ant</i>. These artificial little animals are very interesting because they "
+"are given simple rules that depend only on their local environment, and "
+"after a period of apparent chaotic behavior, a general pattern "
+"<i>emerges</i>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:8
+msgid ""
+"The rules are absolutely trivial: to compute what the next step should be, "
+"you should check the current color of the ground (using "
+"<code>getGroundColor()</code>). If it's white, change it to black, turn "
+"right and move forward by one cell. If the ground is currently black, change "
+"it to white, turn left and move forward by one cell."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:14
+msgid ""
+"It's hard to come up with simpler rules isn't it? Well, let's go and code it "
+"now. You have to complete the <code>step()</code> method, which encodes the "
+"behavior of the ant at each step. You will probably use the "
+"<code>getGroundColor()</code> method to retrieve the color of the cell on "
+"which the ant is currently.  Colors of interest are simply named "
+"<code>Color.black</code> and <code>Color.white</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:21
+msgid ""
+"To compare colors, you cannot use the equal signs (==), because these things "
+"are not scalar values but objects. Instead, you need to write something like "
+"the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/turmites/langton/Langton.html:24
+#, no-wrap
+msgid ""
+"Color c /* = some initialization */;\n"
+"if (c.equals(Color.black)) {\n"
+"  /* that's equal */\n"
+"} else {\n"
+"  /* that was not equal */\n"
+"}\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:33
+msgid ""
+"Changing the ground color is not difficult, but a bit long: you have to "
+"change the brush color of your buggle, set the brush down (to mark the "
+"current cell -- with <code>brushDown()</code>), and set the brush back up "
+"(with <code>brushUp()</code>) to avoid further issues when the buggle will "
+"move. You are naturally free of organizing your code the way you want, but "
+"you may want to write a <code>setGroundColor(color)</code> method to "
+"factorize things a bit."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langton/Langton.html:40
+msgid ""
+"As you can see from the execution of this exercise, the interest in this "
+"algorithm is that after about 10000 steps of relative chaotic behavior, the "
+"ant start building a regular pattern. This emergence of a regular pattern "
+"from the chaos is rather fascinating, isn't it? Move on to the next exercise "
+"to see more of them."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:1
+msgid "Multicolor Langton's ant"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:3
+msgid ""
+"There is several ways to extend the concept of Langton's ant. In this "
+"exercise, we explore first one, using more than two colors. It remains very "
+"similar to the base case: the behavior at each step still depends on the "
+"ground color, but you have more than 2 possibilities. It allows to have more "
+"than one kind of ant, depending on what you decide to do for each color. For "
+"example, the ant LRL takes 3 colors. It turns left on the first color, right "
+"on the second one and left on the third color. According to this definition, "
+"the basic ant is a RL (since it turns right on white cells and left on black "
+"ones)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:12
+msgid ""
+"Some of these ants draw fascinating patterns (switch the world to see them): "
+"LLRR build a symmetric figure resembling loosely to a ball, LRRRRRLLR draws "
+"a square, LLRRRLRLRLLR draws a convoluted regular pattern after a period of "
+"seemingly chaotic behavior, and RRLLLRLLLRRR seems to fill a hour glass..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:17
+msgid ""
+"Changing your buggle into a generic Langton's ant is not very complicated, "
+"although it is not completely trivial. As previously, you have to write a "
+"<code>step</code> function. But this time, it receives two arrays as "
+"parameters.  The first one defines the rules to follow depending on the "
+"ground color while the second one gives the sequence of colors to use. For "
+"example, the basic ant would have [!java]<code>{'R', 'L'}</code> and "
+"<code>{Color.white, Color.black}</code>[/!] [!python]<code>['R', 'L']</code> "
+"and <code>[Color.white, Color.black]</code>[/!] [!scala]<code>Array('R', "
+"'L')</code> and <code>Array(Color.white, Color.black)</code>[/!] as "
+"arguments."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:28
+msgid "At each step, you thus have to apply the following pseudo-code:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:30
+msgid "Find the position of the ground color in the color sequence;"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:31
+msgid ""
+"Turn left or right depending on the content of the rule array at that "
+"position;"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:32
+msgid ""
+"Mark the current ground with the next color in the sequence (the last color "
+"being followed by the first one);"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:33
+msgid "Move forward by one step."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/langtoncolors/LangtonColors.html:36 src/lessons/turmites/helloturmite/HelloTurmite.html:66
+msgid "You now should have enough information to succeed."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:1
+msgid "Turmites"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:3
+msgid ""
+"This exercise explores a new way to extend the concept of Langton's "
+"ant. Now, the behavior of the ant not only depends on the color on the "
+"ground, but also on its internal state (represented by an integer "
+"value). The idea of changing the ant into such an automata naturally comes "
+"from the Turing machine concept. This explains the name of these new "
+"animals, which is a portemanteau of <i>Turing</i> and <i>Termite</i> (if you "
+"don't know what a Turing machine is, you should run to wikipedia, because it "
+"is simply impossible to be a real computer scientist before that)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:12
+msgid ""
+"Once again, you just have to write the <code>step()</code> method, in charge "
+"of doing one turmite's step. Once again, you should first find the rank of "
+"the current's cell ground color in the color sequence. But this time, the "
+"<code>rule</code> data depends both on the current color and the current "
+"state.  <code>rule</code> actually contains 3 information in each situation: "
+"the color to write, the move to do, and the next state value. For example, "
+"[!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contains the informations "
+"to use when <code>state==1</code> and <code>color==0</code>.  In other "
+"worlds, you can retrieve the information relative to your current situation "
+"by using "
+"<code>[!java|python]rule[state][currentColor][/!][!scala]rule(state)(currentColor)[/!]</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:24
+msgid ""
+"Each such information set contains 3 values. The first one is the rank of "
+"the color to write on the ground. The second is the move to do, with the "
+"following notation: 0=stop, 1=noturn, 2=right, 4=u-turn, 8=left. Note that "
+"if the command is stop, you shouldn't even move forward on that step (but "
+"you shouldn't stop your program either: the next steps can do something else "
+"in a future state). Finally, the third integer is the next "
+"<code>state</code> value to go into after this iteration."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:31
+msgid ""
+"Since these arbitrary notations are somehow difficult to remember, you "
+"should define a set of constants that you should use instead of the direct "
+"numerical values.  Their names could be NOTURN, LEFT, RIGHT and so on.  "
+"[!scala]Just declare them using the keyword <code>val</code> instead of "
+"<code>var</code>.  You should always use <code>val</code> instead of "
+"<code>var</code> when possible anyway.[/!] [!java]The modifiers <code>final "
+"static</code> before their type is the way to mark variables as constant in "
+"Java.  You should write for example <code>static final int NOTURN=1;</code> "
+"Sorry for the complexity of this notation. [/!] [!python]By convention, such "
+"constant variables are written in upper case in python.  Technically, you "
+"can still modify them, but that would be a very bad idea.[/!] You should "
+"write them out of any method so that they are globally visible."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:43
+msgid ""
+"Using such constants greatly help making the code easier to read. Compare "
+"the next two code chunks:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:45
+#, no-wrap
+msgid ""
+"[!java]if (rule[state][currentColor][NEXT_MOVE] == LEFT) {[/!][!python]if "
+"rule[state][currentColor][NEXT_MOVE] == LEFT:[/!][!scala]if "
+"(rule(state)(currentColor)(NEXT_MOVE) == LEFT) {[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:48
+msgid "This is much more easier to read (although longer) than the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:49
+#, no-wrap
+msgid ""
+"[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == "
+"2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]\n"
+"    left()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:53
+msgid ""
+"Finally, you probably want to write a <code>elif</code> branch for the "
+"<code>STOP</code> condition too. Having a <code>else</code> branch "
+"displaying an error message such as \"unknown case\" is a good practice: it "
+"makes your assumptions about your code more explicit, and you will get an "
+"error message if they fall short. When doing so, the next problem is that "
+"you have nothing to do in the <code>STOP</code> case, but python do not "
+"allows you to write empty <code>elif</code> branches. You should use the "
+"<code>pass</code> instruction as a placeholder: it says python that you have "
+"a branch here, and that it does not contain anything."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:62
+msgid ""
+"You should probably use a [!java]switch case[/!][!scala]pattern matching[/!] "
+"construct to keep your code readable.  If you can't remember what it is, "
+"check <a href=\"plm://lessons.welcome/bdr.BDR2\">this exercise</a>."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:68
+msgid "Bibliographical notes"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/helloturmite/HelloTurmite.html:69
+msgid ""
+"According to wikipedia, turmites were invented independently by the end of "
+"the eighties. It has been shown that turmites in general are exactly "
+"equivalent in power to one-dimensional Turing machines with an infinite "
+"tape, as either can simulate the other. This means that absolutely any "
+"program that you can think of could theoretically be computed on this "
+"device..."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:1
+msgid "Creating Turmites"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:3
+msgid ""
+"This exercise allows you to build your own turmites. To pass the exercise, "
+"you should simply write a <code>init()</code> method which initializes the "
+"<code>rule</code> to use the following transitions table (from wikipedia), "
+"set the buggle initial position at (8;33), and ask for 8342 steps."
+msgstr ""
+
+#. type: Content of: <table><tr><th>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:10
+msgid "Current color"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:13 src/lessons/turmites/turmitecreator/TurmiteCreator.html:28 src/lessons/turmites/turmitecreator/TurmiteCreator.html:31 src/lessons/turmites/turmitecreator/TurmiteCreator.html:39 src/lessons/turmites/turmitecreator/TurmiteCreator.html:41 src/lessons/turmites/turmitecreator/TurmiteCreator.html:42
+msgid "0"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:14 src/lessons/turmites/turmitecreator/TurmiteCreator.html:29 src/lessons/turmites/turmitecreator/TurmiteCreator.html:32 src/lessons/turmites/turmitecreator/TurmiteCreator.html:34 src/lessons/turmites/turmitecreator/TurmiteCreator.html:37 src/lessons/turmites/turmitecreator/TurmiteCreator.html:44
+msgid "1"
+msgstr ""
+
+#. type: Content of: <table><tr><th>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:18 src/lessons/turmites/turmitecreator/TurmiteCreator.html:21
+msgid "Write color"
+msgstr ""
+
+#. type: Content of: <table><tr><th>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:19 src/lessons/turmites/turmitecreator/TurmiteCreator.html:22
+msgid "Turn"
+msgstr ""
+
+#. type: Content of: <table><tr><th>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:20 src/lessons/turmites/turmitecreator/TurmiteCreator.html:23
+msgid "Next state"
+msgstr ""
+
+#. type: Content of: <table><tr><th>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:26
+msgid "Current state"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:40 src/lessons/turmites/turmitecreator/TurmiteCreator.html:43
+msgid "N"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:48
+msgid ""
+"where the direction to turn is one of <b>L</b> (90° left), <b>R</b> (90° "
+"right), <b>N</b> (no turn) and <b>U</b> (180° U-turn)."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:50
+msgid "Going further"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:51
+msgid ""
+"This exercise is naturally an excuse to let you experiment with your own "
+"turmites.  Feel free to change the transition table and the amount of steps "
+"to experiment by yourself. To that extend, you may find the Ed Pegg Jr's "
+"library useful. If you find new interesting patterns, send them per email so "
+"that we can integrate them to this list!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:57
+msgid ""
+"In addition, wikipedia is desperately missing some good looking colorful "
+"turmites: only black and white ones are depicted.  You should consider "
+"submitting your creations directly to the free encyclopedia."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:62
+msgid ""
+"Here are some 2-color turmites, extracted from "
+"http://demonstrations.wolfram.com/Turmites/ [!python|scala]They are not "
+"written using the [!thelang] syntax, but converting them should be easy.[/!]"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:66
+#, no-wrap
+msgid ""
+"{{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant\n"
+"{{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: binary counter\n"
+"{{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: "
+"(filled triangle)\n"
+"{{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: "
+"spiral in a box\n"
+"{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: "
+"stripe-filled spiral\n"
+"{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: "
+"stepped pyramid\n"
+"{{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: "
+"contoured island\n"
+"{{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: "
+"woven placemat\n"
+"{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: "
+"snowflake-ish\n"
+"{{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: "
+"slow city builder\n"
+"{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: "
+"framed computer art\n"
+"{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: "
+"balloon bursting (makes a spreading highway)\n"
+"{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: "
+"makes a horizontal highway\n"
+"{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: "
+"makes a 45 degree highway\n"
+"{{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: "
+"makes a 45 degree highway\n"
+"{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: "
+"spiral in a filled box\n"
+"{{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: "
+"glaciers\n"
+"{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: "
+"golden rectangle!\n"
+"{{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: "
+"fizzy spill\n"
+"{{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: "
+"nested cabinets\n"
+"{{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: "
+"(cross)\n"
+"{{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: "
+"saw-tipped growth\n"
+"{{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: "
+"curves in blocks growth\n"
+"{{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: "
+"textured growth\n"
+"{{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: "
+"(diamond growth)\n"
+"{{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: "
+"coiled rope\n"
+"{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: "
+"(growth)\n"
+"{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: "
+"(square spiral)\n"
+"{{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: "
+"loopy growth with holes\n"
+"{{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: "
+"Lanton's Ant drawn with squares\n"
+"{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: "
+"growth with curves and blocks\n"
+"{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: "
+"distracted spiral builder\n"
+"{{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: "
+"cauliflower stalk (45 deg highway)\n"
+"{{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: "
+"worm trails (eventually turns cyclic!)\n"
+"{{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: "
+"eventually makes a two-way highway!\n"
+"{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: "
+"almost symmetric mould bloom\n"
+"{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: "
+"makes a 1 in 2 gradient highway\n"
+"{{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: "
+"immediately makes a 1 in 3 highway\n"
+"{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, "
+"RIGHT , 2}, {1, LEFT  , 0}}} # 39: squares and diagonals growth\n"
+"{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, "
+"RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient\n"
+"{{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, "
+"RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient\n"
+"{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, "
+"LEFT  , 1}, {1, NOTURN, 1}}} # 42: maze-like growth\n"
+"{{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, "
+"LEFT  , 0}, {0, LEFT  , 1}}} # 43: growth by cornices \n"
+"{{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, "
+"NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway\n"
+"{{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, "
+"LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:113
+msgid ""
+"Langton's ants may not share the expressiveness power of the turmites, but "
+"they remain fascinating too. You can experiment with them using the "
+"initLangton() method, provided in your template, that allows to build a "
+"Turmite transition table from a Langton's ant name. Tiny changes in the ant "
+"may result huge changes. For example, \"RRL\" does not seem to lead to any "
+"constructed pattern, even after a million steps, but \"RLL\" starts building "
+"a very simple highway pattern after less than 100 steps!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:120
+msgid ""
+"Quite a lot of Langton's ants build highways: RL, of course, but also "
+"RLRLRLLRLR (about 2500 steps).  The chaotic behavior of ants before the "
+"highway can be very short (as with RLL that only need 100 steps to converge) "
+"or very long, as with LLLLLLRRLRRR which seems chaotic for more than 500,000 "
+"steps before build the highway or even RRLLLRRRLRRR which needs 1170000 to "
+"start converging. Some are narrow, and others are very large, such as "
+"RRLRLLRLRR (200,000 steps). This ant is also notable since it is somehow "
+"squarish even before the highway start where most others do not show "
+"anything notable before their highway."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:128
+msgid ""
+"Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), "
+"RRLLLRLLLRRR (30,000 steps), RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR "
+"(20,000 steps). Some even fill the whole space (RRLRR after 3000 "
+"steps). Some of my personal favorite ones are the ones where the ant seem to "
+"be bouncing within a box that gets bigger on each bump, such as LRRRRRLLR "
+"(30,000 steps). LRRRRLLLRRR is even more impressing since the bounces within "
+"the box are regular and since it converges more rapidly to its stable "
+"behavior (15,000 steps are enough)."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:135
+msgid ""
+"Finally, some ants are just build artistic patterns. You should check this "
+"video for some beautiful ones: "
+"http://www.youtube.com/watch?v=1X-gtr4pEBU. If you want to convert them into "
+"your code, you have to shift them by one: For example, the one depicted at "
+"3:42 is not RRLRLRLLRL, but RLRLRLLRLR (the first visible move should be "
+"read as last one)."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/turmites/turmitecreator/TurmiteCreator.html:140
+msgid ""
+"As you can see by exploring the above set of turmites, they are usually not "
+"as colorful as the ants, but this may be because very few colors suffice to "
+"exhibit complex behaviors. For example, there is a specific class of "
+"turmites called <i>busy beavers</i> which are turmites that write a lot of "
+"things before stopping (busy beavers are usually classical turing machines, "
+"but the idea fits perfectly to turmites too). There is a sort of "
+"international competition where people strive to find the turmite that "
+"covers the biggest area before stopping. The web page is here: "
+"http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/turmites/universe/TurmiteWorld.html:1
+msgid "Turmite universe"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turmites/universe/TurmiteWorld.html:3
+msgid ""
+"This universe is very similar to the buggle one, but you will probably not "
+"use all buggles methods.  So, this page only recap the buggle methods that "
+"you will use."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/sort/Main.html:1 src/lessons/sort/short_desc.html:1
+msgid "Sorting Algorithms"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/Main.html:3
+msgid ""
+"This lesson allows to experiment with some classical sorting algorithms (and "
+"some less common variant of them). The goal is two fold: you can first "
+"better understand the idea of these algorithms by writing them yourself. But "
+"even if you don't code the algorithms, you can use the demo mode to organize "
+"\"races\" between these algorithms to experiment in practice what the "
+"different asymptotical complexity mean."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/Main.html:10
+msgid ""
+"More exercises are planned for the future, on recursive sorting algorithms "
+"(such as QuickSort and MergeSort) or using other microworlds to apply these "
+"algorithms to other contexts."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/short_desc.html:3
+msgid ""
+"This lesson allows to experiment with some classical sorting algorithms (and "
+"some less common variant of them :)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/short_desc.html:6 src/lessons/recursion/short_desc.html:5 src/lessons/maze/short_desc.html:5
+msgid "You are supposed to master the bases of programming to take this lesson."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:1
+msgid "BubbleSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:3
+msgid ""
+"Welcome to the sorting universe. It allows you to experiment with the "
+"existing sorting algorithms. The list of buildins that you can use in your "
+"algorithms is available in the world reference documentation "
+"(\"Help\"->\"About this world\")."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:7
+msgid ""
+"It is not enough to sort the array to pass the exercises. Your solution must "
+"strictly follow the expected behavior of each exercise. This is enforced by "
+"checking that your algorithm needs the same amount of read and write "
+"operations to sort the array."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:12
+msgid ""
+"When your algorithm diverges from the expectation, understanding the "
+"difference between your code and the expected solution can reveal very "
+"difficult. To help in this process, it is posible to graphically explore the "
+"history of your sorting algorithm. Switch to the Objective view and use the "
+"contextual menu (right click)  to switch from the the view of the current "
+"state to the view of its history."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:27
+msgid "First attempt at BubbleSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:29
+msgid ""
+"This first sorting algorithm is the most simple one: Bubble sort consists in "
+"progressively moving up the smaller elements of the array, as if they were "
+"air bubbles moving up to the surface of a liquid. The algorithm traverse the "
+"array, and compare any pair of adjacent elements. If two adjacent elements "
+"are wrongly sorted, they are swapped. Once the array was completely "
+"traversed, the operation starts again from the beginning. When no elements "
+"were sorted after a full traversal, it means that the array is completely "
+"sorted: the algorithm can stop.  Bubble sort is studied because of its "
+"simplicity, but it is almost never used in practice because of its bad "
+"performance (O(n^2) on average)."
+msgstr ""
+
+#. type: Attribute 'alt' of: <div>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:39 src/lessons/sort/bubble/AlgBubbleSort2.html:11
+msgid "Show Tip (Pseudo-code)"
+msgstr ""
+
+#. type: Content of: <div><p>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:40
+msgid "The pseudo-code of the BubbleSort algorithm is the following:"
+msgstr ""
+
+#. type: Content of: <div><pre>
+#: src/lessons/sort/bubble/AlgBubbleSort1.html:41
+#, no-wrap
+msgid ""
+"do: \n"
+"        For each i in [0,len-2]\n"
+"          If cells i and i+1 must be swapped, do it\n"
+"while we swapped something during last traversal\n"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:1
+msgid "BubbleSort (take 2)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:3
+msgid ""
+"If you look carefully at the behavior of BubbleSort, a first easy "
+"optimization appears: after one traversal, the last element of the array "
+"must be the biggest of all since the traversal moved it up like a bubble to "
+"its position. More generally, after N traversal, we know that the N last "
+"elements of the array are already sorted. It is thus not necessary to "
+"compare them again during the subsequent traversals. For now, we will have "
+"as many traversal as there is in the array."
+msgstr ""
+
+#. type: Content of: <div><p>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:12
+msgid "The pseudo-code of the BubbleSort2 algorithm is the following:"
+msgstr ""
+
+#. type: Content of: <div><pre>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:13
+#, no-wrap
+msgid ""
+"For all i in [len-2,0] (traversing from biggest to smallest)\n"
+"       For all j in [0, i]\n"
+"          If cells j and j+1 must be swapped, do it\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:19
+msgid ""
+"When we run this algorithm, it is quite disappointing to see that it runs "
+"approximately at the same speed than the basic version of BubbleSort. This "
+"is a graphical effect only since only value changes are graphically "
+"represented. Since this variation avoids some useless comparisons, it does "
+"exactly the same amount of swaps that the basic version. It is thus quite "
+"logical that the graphical interface draws this version at the same pace "
+"than the base version. But the statistics on the amount of reads show that "
+"we saved about the fourth of the amount of reads, which is not bad."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort2.html:28
+msgid ""
+"From the asymptotic complexity point of view, there is absolutely no "
+"difference: this variation is still in O(n^2) on average (our gain is only "
+"on the constant term, ignored when computing the asymptotic complexity)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:1
+msgid "BubbleSort (take 3)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:3
+msgid ""
+"Let's now reintroduce the little optimization we removed at previous step: "
+"if a traversal does not swap any element, it means that the array is already "
+"sorted. In that case, we want to stop the whole sorting process."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:7
+msgid ""
+"For that, simply use the <code>break</code> keyword, which breaks the "
+"current loop.  Beware, if you have several embedded loops, this will apply "
+"to the internal one."
+msgstr ""
+
+#. type: Attribute 'alt' of: <div>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:10
+msgid "If you want, this tip shows the pseudo-code."
+msgstr ""
+
+#. type: Content of: <div><pre>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:12
+#, no-wrap
+msgid ""
+"For all i in [len-2,0] (traversing from biggest to smallest)\n"
+"       For all j in [0, i]\n"
+"          If cells j and j+1 must be swapped, do it\n"
+"       If traversal on j did not swap anything, break the for loop\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/bubble/AlgBubbleSort3.html:19
+msgid ""
+"This optimization is even more disappointing: it only provide a gain of a "
+"few percents on the amount of reads over BubbleSort2."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/cocktail/AlgCocktailSort1.html:1
+msgid "CocktailSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/cocktail/AlgCocktailSort1.html:3
+msgid ""
+"To improve further the BubbleSort algorithm, we need to look closer its "
+"behavior. One can notice that big elements are moved very quickly in "
+"position while small ones move very slowly to their destination. They are "
+"thus traditionally referred to as \"rabbits\" and \"turtles\" respectively "
+"for big fast values and small slow ones."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/cocktail/AlgCocktailSort1.html:9
+msgid ""
+"To help the turtles moving faster, the cocktail sort traverse alternatively "
+"the array from right to left and from left to right. Here is the "
+"pseudo-code:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/cocktail/AlgCocktailSort1.html:14
+#, no-wrap
+msgid ""
+"Do\n"
+"  For all i in [0,len-2], do:\n"
+"    if i and i+1 must be swapped, do it\n"
+"  For all i in [len-2,0] (downward), do:\n"
+"    if i and i+1 must be swapped, do it\n"
+"while at least one of the traversal swapped an element\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/cocktail/AlgCocktailSort1.html:22
+msgid ""
+"One can see that cocktail sort achieves exactly the same amount of swaps "
+"than the bubble sort, but improves slightly on read amount. It is however "
+"still worse than BubbleSort2 to that extend."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/cocktail/AlgCocktailSort2.html:1
+msgid "CocktailSort (take 2)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/cocktail/AlgCocktailSort2.html:3
+msgid ""
+"We will now apply to CocktailSort the same optimization than BubbleSort2 did "
+"to BubbleSort. We must remember the limits of the array part not being "
+"sorted yet, and traverse it alternatively from left to right and from right "
+"to left:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/cocktail/AlgCocktailSort2.html:8
+#, no-wrap
+msgid ""
+"beg=0; end=len-2\n"
+"do\n"
+"  For all Pour i in [beg,end], do:\n"
+"      If cells i and i+1 must be swapped, do it    \n"
+"  end--\n"
+"  For all Pour i in [beg,end] (downwards), do:\n"
+"      If cells i and i+1 must be swapped, do it    \n"
+"  beg++\n"
+"while at least one of the traversal swapped an element\n"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/cocktail/AlgCocktailSort3.html:1
+msgid "CocktailSort (take 3)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/cocktail/AlgCocktailSort3.html:3
+msgid ""
+"Even if the asymptotic complexity of CocktailSort2 is the same than the one "
+"of BubbleSort, it seem to perform better in practice. It is even possible to "
+"improve a bit further by stopping it if the first traversal didn't found "
+"anything to swap, without achieving the downwards traversal. Likewise, we "
+"can stop if the upward traversal found something to swap, but not the "
+"downwards one."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:1
+msgid "InsertionSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:4
+msgid ""
+"This sorting algorithm is quite simple to understand and write, even if it "
+"is not as efficient as possible. Its asymptotic complexity is in O(n2), but "
+"it is more efficient in practice (linear in best case, ie when the array is "
+"already sorted, and N2/4 on average)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:9
+msgid ""
+"The idea is to traverse all elements of the array, and to insert each of "
+"them into its proper position in the already sorted part of the array. When "
+"we look at an element x, the situation is the following: any elements to the "
+"left of the array are already sorted, and we have to insert x at its "
+"position in the array."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:17
+msgid "Once this is done, the situation is the following:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:21
+msgid "The pseudo-code of this algorithm is thus the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:22
+#, no-wrap
+msgid ""
+"For each i in [1,len]\n"
+"  store the value of i in a variable val\n"
+"  copy the cell i-1 into i if i-1 contains a value bigger than val\n"
+"  copy the cell i-2 into i-1 if i-2 contains a value bigger than val\n"
+"  copy the cell i-3 into i-2 if i-3 contains a value bigger than val\n"
+"  copy the cell i-4 into i-3 if i-4 contains a value bigger than val\n"
+"  ...\n"
+"  copy val into the last cell copied above\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:32
+msgid ""
+"Naturally, you should use a loop to write the big permutation within the "
+"given loop. Writing it this way would be really ... counter-productive."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:35
+msgid ""
+"If you've always wondered what computer science researchers do nowadays, "
+"here is part of the answer: They improve fundamental algorithms so that "
+"others can write efficient programs."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:39
+msgid "Other variation of insertion sort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:41
+msgid ""
+"TreeSort builds a binary search tree to sort them. It leads to a O(n log(n))  "
+"on average, but O(n^2) in worst cases. We won't study this algorithm here "
+"since unterstanding its behavior requires to know what a binary tree is, "
+"what is beyond our present goals."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:46
+msgid ""
+"There is other variations over the insertion sort, such as PatienceSort "
+"which builds piles of values and sort each pile afterward. This algorithm "
+"presents a 0(n log(n)) timing worst case and a 0(n) space "
+"complexity. LibrarySort (proposed in 2004) also trades a bit space in "
+"exchange for time since it provide a time complexity of O(n log(n)) but "
+"needs to store some more data."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/insertion/AlgInsertionSort.html:53
+msgid ""
+"Wikipedia provides a detailled description of all these algorithms we cannot "
+"present here because of time constraints."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/shell/AlgShellSort.html:1
+msgid "ShellSort"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/shell/AlgShellSort.html:3
+msgid ""
+"This algorithm is named after its author, Donald Shell, who published it in "
+"1959. It can be seen as an application of the CombSort idea (let elements "
+"having a long path to travel take shortcuts) to the insertion sort (CombSort "
+"is a variation of BubbleSort). Instead of comparing adjacent values during "
+"the insertion sort, it compares values separated by a bigger gap. The bigger "
+"the gap, the faster the elements are moved to their final destination, but "
+"also the less precise is this move. It is thus mandatory to apply the "
+"algorithm with a serie of decreasing gaps. At the last step, when the gap is "
+"1, InsertionSort is used, but onto an array which is almost already sorted "
+"by previous steps."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/shell/AlgShellSort.html:14
+msgid ""
+"Donald Shell propose <code>len/2</code> as initial value of the gap, and "
+"then to divide it by 2 at each step. The pseudo-code is thus the following:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/sort/shell/AlgShellSort.html:17
+#, no-wrap
+msgid ""
+"gap=len/2\n"
+"while gap>0:\n"
+"  apply InsertionSort, comparing i-gap and i, then i-2gap and i-gap, then "
+"i-3gap and i-2gap, etc.\n"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/sort/shell/AlgShellSort.html:22
+msgid ""
+"Just like in CombSort, the sequence of values taken by the gap is crucial "
+"for Shell sort performance. In some rare pathological cases, the sequence we "
+"used above can lead to a O(n^2) performance. Other sequences were proposed: "
+"the Hibbard's increments of 2k − 1 lead to a complexity of O(n^(3/2)) in "
+"worst cases. Pratt's increments 2^i3^j lead to a O(nlog(n)log(n) performance "
+"in worst cases. The existance of a sequence leading to a O(n log(n)) was "
+"precluded by Poonen, Plaxton, and Suel. Thanks to this performance, "
+"ShellSort is a valid candidate for array of several hundred thousands when "
+"correctly implemented."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/sort/shell/AlgShellSort.html:32
+msgid ""
+"In our case, the array are ways too small to benefit of these "
+"optimizations. If you ever need to do so, take as initial gap the biggest "
+"value of the targeted serie still smaller than the array size, and then use "
+"decreasing values of the serie."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/sort/shell/AlgShellSort.html:37
+msgid ""
+"Interestingly enough, determining the best gap sequence for shell sort turns "
+"into a research issue of our century in computer science. For example, an "
+"article of 2001 introduces the following sequence, which seems to be optimal "
+"in practice for arrays of size up to 10^5: {1, 4, 10, 23, 57, 132, 301, 701, "
+"1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th "
+"International Symposium on Fundamentals of Computation Theory, LNCS 2001; "
+"Vol. 2138)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/selection/AlgSelectionSort.html:1
+msgid "Selection Sort"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/selection/AlgSelectionSort.html:3
+msgid ""
+"In this exercise we will implement another classical algorithm: selection "
+"sort."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/selection/AlgSelectionSort.html:6
+msgid ""
+"The idea is simply to select for each cell of the array the smallest value "
+"from the part not already sorted. Thus for the first cell, it takes the "
+"smallest value over the whole array. For the second one, it takes the second "
+"smallest value, which is the smallest value from the cell not already "
+"sorted."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/sort/selection/AlgSelectionSort.html:12
+msgid ""
+"More generally, for the cell N, it looks the cell M in [n;len] containing "
+"the smallest possible value of the interval. Then, it swaps the content of "
+"cell N with the one of cell M."
+msgstr ""
+
+#. type: Content of: <p><p><h2>
+#: src/lessons/sort/selection/AlgSelectionSort.html:16
+msgid "Existing variations"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/sort/selection/AlgSelectionSort.html:17
+msgid ""
+"Another classical algorithm which idea is based on the selection of good "
+"elements is HeapSort, but it uses a heap data structure which we did not see "
+"yet. Simply remember that HeapSort provides a O(n log n) performance in "
+"worst case, which is why it is a very interesting algorithm in practice."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/comb/AlgCombSort.html:1
+msgid "CombSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:3
+msgid ""
+"We saw that CocktailSort improve a bit for turtles (i.e. small values near "
+"to the end of the array), but it is still possible to achieve "
+"better. ComboSort comes down to providing them a short cut: instead of "
+"comparing adjacent values, we compare values separated by a gap bigger than "
+"1. That way, turtles we traverse <i>gap</i> cells at each "
+"traversal. Naturally, we have to apply the algorithm with decreasing gaps, "
+"and finish with <i>gap=1</i> to ensure that the array is correctly sorted "
+"afterward. Choosing the right gap and how to decrease it is a difficult "
+"question, but in practice, dividing it by 1.3 after each traversal leads to "
+"good performance. Here is the corresponding pseudo-code:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/comb/AlgCombSort.html:15
+#, no-wrap
+msgid ""
+"gap = len;\n"
+"do\n"
+"   if gap>1 then\n"
+"     gap = gap / 1.3\n"
+"   i = O\n"
+"   while i+gap < len do:\n"
+"     if i and i+gap must be swapped, do it\n"
+"     increase i by the gap\n"
+"while the gap is bigger than 1 or the last traversal swapped at least one "
+"pair\n"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/comb/AlgCombSort.html:26 src/lessons/maze/island/IslandMaze.html:66 src/lessons/welcome/bat/bool1/Max1020.html:5
+msgid "[!scala]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:26
+msgid ""
+"One tricky part is that we want to divide gap, that is an integer, by 1.3, "
+"that is a double.  The type system of scala won't let us do this, because "
+"such discrepency usually denotes a programmer error.  As this is not an "
+"error this time, we have to convert gap to Double for the time of the "
+"operation, and then convert the result back to Int to store it into "
+"gap. This should be written this way:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/comb/AlgCombSort.html:30
+#, no-wrap
+msgid "gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:31
+msgid ""
+"This is rather verbose, but actually, this notation is not very complex. And "
+"remember that the type checker is your friend. It's picky and sometimes "
+"annoying (as on this one), but it often catches weird bugs that would have "
+"been a pain to debug if not catched by the type checker."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort.html:36
+msgid ""
+"This algorithm was invented by Wlodek Dobosiewicz in 1980, and later "
+"rediscovered and popularized by Stephen Lacey and Richard Box, who described "
+"it in Byte Magazine in April 1991."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/comb/AlgCombSort11.html:1
+msgid "CombSort11"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/comb/AlgCombSort11.html:3
+msgid ""
+"The authors of this algorithm observed that the performance is increased if "
+"we make sure that the last values of the gap are (11, 8, 6, 4, 3, 2, 1)  "
+"rather than (9, 6, 4, 3, 2, 1) or (10, 7, 5, 3, 2, 1). Rework the code of "
+"CombSort to ensure just after the gap update that if it is 9 or 10, we "
+"should use 11 instead."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/gnome/AlgGnomeSort.html:1
+msgid "GnomeSort"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/gnome/AlgGnomeSort.html:3
+msgid ""
+"The Gnome sort is similar to insertion sort, but the elements are moved in "
+"position by a serie of swaps just like in bubble sort. It is named after the "
+"supposed behavior of garden gnomes when they sort flower pots. Here is a "
+"description of the algorithm by its author:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/gnome/AlgGnomeSort.html:8
+msgid ""
+"Gnome Sort is based on the technique used by the standard Dutch Garden Gnome "
+"(Du.: tuinkabouter). Here is how a garden gnome sorts a line of flower "
+"pots. Basically, he looks at the flower pot next to him and the previous "
+"one; if they are in the right order he steps one pot forward, otherwise he "
+"swaps them and steps one pot backwards. Boundary conditions: if there is no "
+"previous pot, he steps forwards; if there is no pot next to him, he is "
+"done.  <i>—Dick Grune</i>"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/recursion/Main.html:1
+msgid "Recursive algorithms"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/Main.html:2
+msgid "This lesson allows to experiment with recursive algorithms."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/Main.html:4
+msgid ""
+"If you need more recursive algorithms, an exercise on recursive sorting "
+"algorithms (in particular QuickSort and MergeSort) is planned in the future "
+"within the sorting lesson."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/recursion/short_desc.html:1
+msgid "Bases of recursion"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/short_desc.html:2
+msgid ""
+"Discover the recursive way of thinking by drawing trees and other figures "
+"with the Logo turtle."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/square/FourSquare.html:1
+msgid "The small cousines of Buggles"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:3
+msgid ""
+"Today, we will meet the small cousines of the buggles: the turtles. In fact, "
+"turtles are much olders than the buggles. They were invented in the 70's by "
+"a scientific from MIT called Seymour Papert to help teaching programming, "
+"and the buggles are a variation on the idea invented by Lyn Turbak from "
+"Wellesley College later."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:9
+msgid ""
+"Turtles are thus a bit like buggles, but smaller. Just like buggles, you can "
+"order them to move forward, to turn, to move backward, etc. Just like "
+"buggles, they leave a line on their path when they move (but the line is "
+"much smaller)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:14
+msgid ""
+"The main difference is that where buggles can only move of right angles, "
+"turtles can move of any arbitrary angles specified by a real number (a "
+"double). This gives them much more liberty in their movings. The buggles can "
+"do several other tricks, like reading and writting messages, picking or "
+"dropping objects, and there is sometimes walls in their worlds (but all this "
+"is completely above the capacities of turtles)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:21
+msgid ""
+"From a practical point of view, most of the methods you knew about buggles "
+"still work with turtles, with some minor adaptations. In particular, the "
+"<code>forward()</code> method takes the amount of steps to do not as an "
+"integer, but as a [!python]point number[/!][!java|scala]double[/!] (see "
+"\"About this world\" for more details)."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/recursion/square/FourSquare.html:28
+msgid "Doubles? But what is it?"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/square/FourSquare.html:29
+msgid "It's simply a point number. Example:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/square/FourSquare.html:31
+#, no-wrap
+msgid ""
+"double x = 3.72;\n"
+"x + 1.234 // Value = 4.954\n"
+"x + 2. // Value = 5.72 (2. means 2.0)\n"
+"x + 2 // [!java]Value = 5.72 (2 automatically converted to "
+"2.0)[/!][!scala]Type error (+ operator don't mix Double and Int); manual "
+"conversion mandatory[/!]\n"
+"x * 2. // Value = 7.44 \n"
+"x / 2. // Value = 1.86 \n"
+"[!java](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Value = 1 (“casting to "
+"int”, converted to integer by truncating)\n"
+"Math.round(x) // Value = 2 (1.86 rounded to nearest integer)\n"
+"Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)\n"
+"Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)\n"
+"Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)\n"
+"Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)\n"
+"[!java](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 "
+"(“casted to double”, converted to double)\n"
+msgstr ""
+
+#. type: Content of: <p><p><p><h2>
+#: src/lessons/recursion/square/FourSquare.html:47 src/lessons/recursion/circle/Circle.html:14 src/lessons/recursion/hanoi/HanoiBoard.html:20 src/lessons/welcome/array/basics/Array1.html:229
+msgid "Goal of this exercise"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:48
+msgid ""
+"Even if this is the first exercise on the recursivity lesson, the code you "
+"have to write is not recursive. The goal is to get familiar with the turtle "
+"world before getting on serious matter."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/square/FourSquare.html:52
+msgid ""
+"You must reproduce a simple geometrical painting constituted of four 100 "
+"steps long squares (see the objective world for more details). It is "
+"obviously a good idea to write a method to draw a square, and then use it in "
+"your code."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/polygonfractal/PolygonFractal.html:1
+msgid "Fractal of polygons"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/polygonfractal/PolygonFractal.html:3
+msgid ""
+"The fractal we will now draw is formed of a polygon, with little polygons on "
+"each corner. The prototype of the method drawing it is the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/polygonfractal/PolygonFractal.html:5
+#, no-wrap
+msgid ""
+"[!java]void [/!]polygonFractal ([!java]int [/!]levels[!scala]:Int[/!], "
+"[!java]int [/!]sides[!scala]:Int[/!], [!java]double "
+"[/!]length[!scala]:Double[/!], [!java]double [/!]shrink[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/polygonfractal/PolygonFractal.html:7 src/lessons/recursion/sierpinski/Sierpinski.html:8 src/lessons/recursion/dragoncurve/DragonCurve1.html:25 src/lessons/recursion/dragoncurve/DragonCurve2.html:44
+msgid ""
+"Have a look at each world's objective view to understand how to write the "
+"function."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/koch/Koch.html:1
+msgid "Snow flake"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/koch/Koch.html:3
+msgid ""
+"We will now draw snow flakes using the Koch fractal. A fractal is a "
+"geometrical pattern repeated at every scale."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/koch/Koch.html:6
+msgid ""
+"The general form is a triangle, with each side given by a serie of recursive "
+"calls. The general form is given by something like this:"
+msgstr ""
+
+#. type: Content of: <p><pre>
+#: src/lessons/recursion/koch/Koch.html:8
+#, no-wrap
+msgid ""
+"[!java]void [/!]snowFlake ([!java]int [/!]levels[!scala]:Int[/!], "
+"[!java]double [/!]length[!scala]:Double[/!])[!python]:[/!][!java|scala] "
+"{[/!]\n"
+"   snowSide(levels, length);\n"
+"   right(120);\n"
+"   snowSide(levels, length);\n"
+"   right(120);\n"
+"   snowSide(levels, length);\n"
+"   right(120);\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/recursion/koch/Koch.html:17
+msgid ""
+"Observe the drawing in each world's objective to understand the pattern's "
+"logic, and then reproduce it. You must write the <code>snowSide()</code> "
+"method, which is recursive."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/star/Star.html:1
+msgid "Turtles in the stars"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/star/Star.html:3
+msgid ""
+"This is the last hand-on turtles exercise before recursion. The goal is to "
+"draw three 5-branches stars. Like any regular stars with N branches, the "
+"angle at each external corners are 360/N degrees while the angles between "
+"branches are of 2*360/N degrees."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/star/Star.html:8
+msgid ""
+"The first star to draw is black (<code>Color.black</code>) and its branches "
+"are 100 steps long. The second is blue (<code>Color.blue</code>) and its "
+"branches are 80 steps long. It's shifted of 45 degrees from the first "
+"one. The last star is red (<code>Color.red</code>), its branches are 60 "
+"steps long and it's shifted of 45 degrees from the previous one."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/star/Star.html:14
+msgid "Observe the world's objective to visualize the picture to draw."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/circle/Circle.html:1
+msgid "Three little circles"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/circle/Circle.html:3
+msgid ""
+"As we saw (and as you can check in the documentation of this world under "
+"\"About this world\"), turtles can only draw straight lines. Despite of "
+"this, the goal of this world is to draw circles... This can be achived "
+"simply by realizing that a circle can be seen as a concatenation of very "
+"little segments."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/circle/Circle.html:9
+msgid ""
+"Differential calculus would even argue that a circle is the asymptotical "
+"limit of such construct when the size of each segment becomes infinitely "
+"small while their amount becomes infinitely large, but you can definitely "
+"solve this exercise without understanding differential calculus :)"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/circle/Circle.html:16
+msgid ""
+"Write a function drawing a circle, taking the size of each of the 360 "
+"segments as parameter. Then use it in your code to draw the whole picture.  "
+"The first circle is obtained with segments of size 0.5, the second with "
+"segments of size 1 and the last one with 1.5-long segments.  Once again, "
+"this is a warming exercise, no recursion is needed."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/tree/Tree.html:1
+msgid "Trees"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/tree/Tree.html:3
+msgid ""
+"We will now draw trees. For that, we will write a method using double "
+"recursion following this prototype"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/tree/Tree.html:5
+#, no-wrap
+msgid ""
+"[!java]void [/!]tree([!java]int [/!]steps[!scala]:Int[/!], [!java]double "
+"[/!]length[!scala]:Double[/!], [!java]double [/!]angle[!scala]:Double[/!], "
+"[!java]double [/!]shrink[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/tree/Tree.html:7
+msgid ""
+"To draw a tree of four levels, you have to draw a trunk of the given length, "
+"turn right of the given angle, draw a tree of level 3, turn left twice of "
+"the given angle, draw another tree of level 3, and come back to your initial "
+"location."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/recursion/tree/Tree.html:12
+msgid ""
+"If a tree's trunk is of length 'len', the trunk of the next level tree will "
+"be of length 'len*shrink'."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/sierpinski/Sierpinski.html:1
+msgid "Sierpinski's Triangle"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/sierpinski/Sierpinski.html:3
+msgid ""
+"The fractal we will now draw is formed of a big triangle inside which "
+"several smaller triangles are embeeded. The prototype of the fuction to draw "
+"it is the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/sierpinski/Sierpinski.html:6
+#, no-wrap
+msgid ""
+"[!java]void [/!]sierpinski([!java]int [/!]level[!scala]:Int[/!], "
+"[!java]double [/!]length[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/spiral/Spiral.html:1
+msgid "Spirals"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/spiral/Spiral.html:3
+msgid ""
+"We will now draw our first recursive function with the turtle. The goal is "
+"to draw different kind of spirals with the same function, which prototype is "
+"the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/spiral/Spiral.html:6
+#, no-wrap
+msgid ""
+"[!java]void [/!]spiral([!java]int [/!]steps[!scala]:Int[/!], [!java]int "
+"[/!]angle[!scala]:Int[/!], [!java]int [/!]length[!scala]:Int[/!], [!java]int "
+"[/!]increment[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/spiral/Spiral.html:8
+msgid ""
+"To help you understanding how to write it, here is an example of how the "
+"parameters change during one specific call:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/spiral/Spiral.html:11
+#, no-wrap
+msgid ""
+"spiral(5, 90, 0, 3);\n"
+"  forward(0);\n"
+"  left(90);\n"
+"  spiral(4,90,3,3);\n"
+"    forward(3);\n"
+"    left(90);\n"
+"    spiral(3,90,6,3);\n"
+"      forward(6);\n"
+"      left(90);\n"
+"      spiral(2,90,9,3);\n"
+"        forward(9);\n"
+"        left(90);\n"
+"        spiral(1,90,12,3);\n"
+"          forward(12);\n"
+"          left(90);\n"
+"          spiral(0,90,12,3);\n"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/spiral/SpiralUse.html:1
+msgid "Drawing spirals"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/spiral/SpiralUse.html:3
+msgid ""
+"Can you reproduce the provided patterns of this exercise using the "
+"<code>spiral()</code> method?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/spiral/SpiralUse.html:6
+msgid ""
+"You must provide a method called <code>doit(page)</code> taking the page "
+"number to draw as parameter. Its code is as following, with A0, B0, etc "
+"being integers.  The goal of this exercise is to find the good values for "
+"each page, which requires to correctly understand how the spiral method "
+"works."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/spiral/SpiralUse.html:12
+#, no-wrap
+msgid ""
+"[!java]void [/!]doit([!java]int "
+"[/!]page[!scala]:Int[/!])[!python]:[/!][!java|scala] {[/!]\n"
+"  [!java]switch (page) {[/!][!scala]page match {[/!][!python]  # select on "
+"the value of page[/!]\n"
+"    [!java]case 0:[/!][!scala]case 0 =>[/!][!python]if page==0:[/!] <span "
+"class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the first "
+"page, dubbed \"One\"</span>\n"
+"      spiral(A0,B0,C0,D0);\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 1:[/!][!scala]case 1 =>[/!][!python]if page==1:[/!] <span "
+"class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the second "
+"page, dubbed \"Two\"</span>\n"
+"      spiral(A1,B1,C1,D1);\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 2:[/!][!scala]case 2 =>[/!][!python]if page==2:[/!] <span "
+"class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page "
+"dubbed \"Three\"</span> \n"
+"      spiral(A2,B2,C2,D2);\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 3:[/!][!scala]case 3 =>[/!][!python]if page==3:[/!] <span "
+"class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page "
+"dubbed \"Four\"</span> \n"
+"      spiral(A3,B3,C3,D3);\n"
+"[!java]      break;[/!]\n"
+"    [!java]case 4:[/!][!scala]case 4 =>[/!][!python]if page==4:[/!] <span "
+"class=\"Comment\">[!java|scala]//[/!][!python]#[/!] Drawing of the page "
+"dubbed \"Five\"</span>\n"
+"      spiral(A4,B4,C4,D4);[!java|scala]\n"
+"[!java]      break;[/!]\n"
+"  }\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/spiral/SpiralUse.html:33
+msgid ""
+"No need to copy over the method of <code>spiral()</code>, the turtle of this "
+"exercise already knows it."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:1
+msgid "Dragon curve (1)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:3
+msgid "The dragon curve is a classical example of recursive method."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:5
+msgid "The definition of this curve is the following:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:6
+msgid "the dragon curve of order 1 is a vector between to arbitrary points P and Q,"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:7
+msgid ""
+"the dragon curve of order n is the dragon curve of order n-1 between P and "
+"R, followed by the same curve of order n-1 between R and Q (reverse side), "
+"where PRQ is an isoscele triangle with angle R being a right angle, and R "
+"being at the right of the PQ vector. Thus, if P and Q coordinates are (x, y)  "
+"and (z, t), the coordinate (u, v) of R are given by:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:13 src/lessons/recursion/dragoncurve/DragonCurve2.html:26
+#, no-wrap
+msgid ""
+"u = (x + z)/2 + (t - y)/2\n"
+"v = (y + t)/2 - (z - x)/2\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:17
+msgid "The prototype of the method drawing the curve is the following:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:18 src/lessons/recursion/dragoncurve/DragonCurve2.html:22
+#, no-wrap
+msgid ""
+"[!java]void [/!]dragon([!java]int [/!]order[!scala]:Int[/!], [!java]double "
+"[/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], "
+"[!java]double [/!]z[!scala]:Double[/!], [!java]double "
+"[/!]t[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve1.html:21
+msgid ""
+"You should use the method <code>setPos(x,y)</code> to put your turtle at "
+"coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line "
+"between the turtle position and the point(z,t)."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:1
+msgid "The dragon curve (2)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:3
+msgid ""
+"Previous solution induce that the turtle teleports to other location, or at "
+"the very least, that it moves its pen up during the drawing. Indeed, the end "
+"of the drawing of the first recursive call does not match the begining of "
+"the second recursive call. That is why we had to use the method "
+"<code>setPos()</code>"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:9
+msgid ""
+"In this lesson, you will write a recursive method allowing to draw the "
+"dragon curve without taking the pen up. For that, we need another recursive "
+"method drawing the mirror side of the curve."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:13
+msgid ""
+"The method <code>dragon()</code> is then recursively defined using itself "
+"and <code>dragonReverse()</code>. Likewise, the method "
+"<code>dragonReverse()</code> is defined recursively using itself and "
+"<code>dragon()</code>. This is thus an example of <i>mutual recursion</i>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:20
+msgid ""
+"The prototype of the <code>dragon()</code> method remains unchanged from "
+"previous exercise:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:24
+msgid ""
+"The new point's coordinate (u, v) introduced by the <code>dragon()</code> "
+"are:"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:30
+msgid "The prototype of the method <code>dragonReverse</code> is similar:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:31
+#, no-wrap
+msgid ""
+"[!java]void [/!]dragonReverse([!java]int [/!]order[!scala]:Int[/!], "
+"[!java]double [/!]x[!scala]:Double[/!], [!java]double "
+"[/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], "
+"[!java]double [/!]t[!scala]:Double[/!])"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:33
+msgid ""
+"The new point's coordinate (u, v) introduced by the "
+"<code>dragonReverse()</code> are:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:35
+#, no-wrap
+msgid ""
+"u = (x + z)/2 - (t - y)/2\n"
+"v = (y + t)/2 + (z - x)/2\n"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/dragoncurve/DragonCurve2.html:39
+msgid ""
+"To make the work of each method recursiv more visible, the line painted by "
+"the <code>dragon()</code> must be red (<code>Color.red</code>) while the "
+"line painted by the <code>dragonReverse()</code> must be blue "
+"(<code>Color.blue</code>)."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/recursion/hanoi/Main.html:1 src/lessons/recursion/hanoi/short_desc.html:1
+msgid "Hanoi towers"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/hanoi/Main.html:2
+msgid ""
+"Here comes the super classical exercise on recursion. It's not very "
+"developped here, I'm not sure of what I could add to this lesson. If you "
+"have any idea, please submit them."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/hanoi/short_desc.html:2
+msgid "Here comes the super classical exercise on recursion."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/hanoi/short_desc.html:4
+msgid ""
+"This is an application exercise of recursion, that you should master to take "
+"this lesson."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:1
+msgid "Tower of Hanoi"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/hanoi/HanoiBoard.html:3
+msgid ""
+"The Tower of Hanoi or Towers of Hanoi , also called the Tower of Brahma or "
+"Towers of Brahma, is a mathematical game or puzzle. It consists of three "
+"rods, and a number of disks of different sizes which can slide onto any "
+"rod. The puzzle starts with the disks in a neat stack in ascending order of "
+"size on one rod, the smallest at the top, thus forming a pyramid.  The "
+"objective of the puzzle is to move the entire stack to another rod, obeying "
+"the following rules:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:11
+msgid "Only one disk may be moved at a time."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:13
+msgid ""
+"Each move consists of taking the upper disk from one of the rods and sliding "
+"it onto another rod, on top of the other disks that may already be present "
+"on that rod."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:17
+msgid "No disk may be placed on top of a smaller disk."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/hanoi/HanoiBoard.html:22
+msgid ""
+"Write the core of the method: <code>[!java]void [/!]solve([!java]int "
+"[/!]src[!scala]:Int[/!], [!java]int [/!]dst[!scala]:Int[/!], [!java]int "
+"[/!]height[!scala]:Int[/!])</code> This method will recursively solve the "
+"presented problem. First parameter named <code>src</code> is the index of "
+"the initial tower, second parameter <code>dst</code> is the index of the "
+"expected final tower, and the third parameter <code>height</code> is the "
+"height of the tower.  A key to solving this puzzle is to recognize that it "
+"can be solved by breaking the problem down into a collection of smaller "
+"problems and further breaking those problems down into even smaller problems "
+"until a solution is reached.  The following procedure demonstrates this "
+"approach:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:36
+msgid "label the pegs A, B, C (these labels may move at different steps)"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:37
+msgid "let n be the total number of discs (the height of the initial tower)"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:38
+msgid "number the discs from 1 (smallest, topmost) to n (largest, bottommost)"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/hanoi/HanoiBoard.html:41
+msgid "To move n discs from peg A to peg C:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:43
+msgid "move n−1 discs from A to B. This leaves disc number n alone on peg A"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:44
+msgid "move disc number n from A to C"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/recursion/hanoi/HanoiBoard.html:45
+msgid "move n−1 discs from B to C so they sit on disc number n"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:1
+msgid "HanoiWorld"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:4
+msgid ""
+"This world implements the ultra-classical Hanoi problem. You are asked to "
+"move the disk pile from the stick where they are to the target stick (given "
+"as second parameter in the world's name -- number 1 for the default "
+"world). There is some extra constraint: you can only move one disk at a "
+"time, and you cannot move a big disk over a smaller one."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:11
+msgid "Only 3 functions are provided:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:13
+#, no-wrap
+msgid "[!java]void [/!]move([!java]int [/!]src, [!java]int [/!]dst)"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:15
+msgid ""
+"Moves one disk from the stick <code>src</code> onto the stick "
+"<code>dst</code>. If you try to do an invalid move (like laying a disk over "
+"a smaller one), an IllegalArgumentException is thrown."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:19
+#, no-wrap
+msgid "[!java]int [/!]getSlotSize([!java]int [/!]slot)[!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/recursion/hanoi/universe/HanoiWorld.html:20
+msgid ""
+"Returns the amount of disks placed on the specified slot. This is mainly "
+"used to initialize the recursion and set the amount of recursive call to "
+"execute."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/maze/Main.html:1 src/lessons/maze/short_desc.html:1
+msgid "Labyrinths"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/Main.html:3 src/lessons/maze/short_desc.html:3
+msgid "This lesson proposes several exercises about labyrinths in the buggle world."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:1
+msgid "The crazy mouse"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:3
+msgid ""
+"The day of your buggle starts badly. Out of luck, it got trapped into a "
+"maze. Help it finding its path out of there."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:8
+msgid ""
+"The exit is represented by a baggle and you need to pick this baggle in "
+"order to exit the maze."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:13
+msgid ""
+"Since the maze is so small, we can write the dumbest possible algorithm to "
+"do so. It relies on randomness and proves quite inefficient."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:18
+msgid ""
+"While the buggle didn't find the path to the escape, it must proceed the "
+"following way: pick a random integer between 0 and 2 by using the provided "
+"<code>random3()</code> method and make one of the following actions: moving "
+"forward if possible, turn left or turn right."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/randommouse/RandomMouseMaze.html:24
+msgid ""
+"You don't believe that it could work? Well, give it a try, you will see...  "
+"Don't forget to pick up the baggle once you've reached it."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:1
+msgid "Following the walls"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:3
+msgid ""
+"This time, the maze is a bit more complicated. Random won't be enough, we "
+"ough to be smart!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:6
+msgid ""
+"The good news is that this maze is simpler that it seems at the first "
+"glance: every wall are connected to each other. To get out of this kind of "
+"maze, the buggle only have to follow a wall (the one on its left or the one "
+"on its right, it doesn't matter).  While keeping a paw on the wall, the "
+"buggle must move forward until it finds the maze exit and this biscuit it "
+"loves so much."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:13
+msgid ""
+"This works here because there is no island of isolated walls, so our buggle "
+"cannot loop around for ever without encountering its baggle."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:17
+msgid ""
+"The goal of this exercise is to write an algorithm allowing the buggle to "
+"get out of this maze."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:20
+msgid ""
+"As said earlier, it does not matter whether you decide to follow the left "
+"wall or the right one. Simply, the demo follows the left one, so you should "
+"do the same in your solution to ease the comparison of your solution and the "
+"demo."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:25
+msgid ""
+"Write a method <code>keepHandOnSideWall()</code> which lets the buggle move "
+"one step forward while keeping the paw on the wall of the selected side. You "
+"must ensure that the buggle always keep the paw on the wall, but also that "
+"it won't crash into a wall. You can check the tip for more info on this, but "
+"only do so if you're stuck. Try to do it without the tip first."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:32
+msgid ""
+"Then, write the whole algorithm to traverse the maze step by step (using "
+"<code>keepHandOnSideWall()</code>) until it finds the biscuit and the "
+"exit. Don't forget to pick the baggle up once you've found it."
+msgstr ""
+
+#. type: Attribute 'alt' of: <div>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:37
+msgid "I'm lost, please give me some extra indications"
+msgstr ""
+
+#. type: Content of: <div><p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:38
+msgid ""
+"When your buggle has a wall on the left, there is three situations to "
+"consider, depending on the surrounding walls. The following table depicts "
+"each initial situation, and where you should let your buggle end after one "
+"step."
+msgstr ""
+
+#. type: Content of: <div><table><tr><td>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:45
+msgid "Case 1"
+msgstr ""
+
+#. type: Content of: <div><table><tr><td>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:46
+msgid "Case 2"
+msgstr ""
+
+#. type: Content of: <div><table><tr><td>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:47
+msgid "Case 3"
+msgstr ""
+
+#. type: Content of: <div><table><tr><td>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:49
+msgid "Initial situation"
+msgstr ""
+
+#. type: Content of: <div><table><tr><td>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:54
+msgid "Where is the next step"
+msgstr ""
+
+#. type: Content of: <div><p>
+#: src/lessons/maze/wallfollower/WallFollowerMaze.html:60
+msgid ""
+"If you do a <code>right()</code> in any case at the end of your function, "
+"it's possible to write it in 3 lines with a <code>while</code> loop."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/pledge/PledgeMaze.html:1
+msgid "Pledge algorithm"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:3
+msgid ""
+"Once again, you thought that your algorithm were good enough to escape the "
+"maze, and once again, you buggle is now in a maze where your previous "
+"algorithm fails. Just give it a try: copy/paste your code and hit the "
+"\"Run\" button and see your creation fail. The trap is shaped like an upper "
+"case \"G\". The buggle enters the trap and follows the inner border. At some "
+"point, it finds the north direction free, run into that direction, and falls "
+"again in the trap."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:13
+msgid ""
+"The Pledge's algorithm (named after Jon Pledge of Exeter) can solve this "
+"maze."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:16
+msgid ""
+"This algorithm is a modification of the previous one thought to avoid "
+"obstacles. It randomly picks a heading and let the buggle move in that "
+"direction. When it encounters an obstacle, a paw (for example the left one)  "
+"is kept on the wall following the obstacle while counting the turns. When "
+"the buggle is back to its original heading and when the sum of the turns is "
+"0, the buggle leaves the obstacle and continues keeping its original "
+"heading."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:24
+msgid ""
+"Note that the use of \"total turning\" rather than just the \"current "
+"direction\" allows the algorithm to avoid G-shapped traps. If one proceeds "
+"left into the trap, one gets turned around a full 360 degrees by the "
+"walls. As we said before, the naive \"current direction\" algorithm gets "
+"into a limit cycle as it leaves the lower rightmost wall heading left and "
+"runs into the curved section on the left again."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:31
+msgid ""
+"The Pledge's algorithm does not leave the rightmost wall due to the total "
+"turning not being zero at that point. It follows the wall all the way "
+"around, finally leaving it heading left on the bottom outside"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:38
+msgid ""
+"<a name=\"Objective\"/>You now have to modify your solution to implement the "
+"Pledge algorithm to escape this maze."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:41
+msgid ""
+"Change your <code>keepHandOnSideWall()</code> method to count the amount of "
+"turns done by the buggle (+1 when it turns left, and -1 when it turns "
+"right). This counting may require the addition of an <code>angleSum</code> "
+"integer value in your program."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:46
+msgid ""
+"Write a boolean method <code>isDirectionFree(dir)</code> indicating if the "
+"provided direction is free, ie, if you can move in that direction (Note that "
+"the demo uses the NORTH direction for that).  You can retrieve the current "
+"direction of the buggle using the method <code>getDirection()</code>. You "
+"can change your direction (without moving) using "
+"<code>setDirection(dir)</code>. Don't forget to store the previous direction "
+"of your buggle (in a dedicated variable) before checking if your favorite "
+"direction is free in order to restore your state afterward."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:55
+msgid ""
+"You may have to change the rest of your code also, but these changes should "
+"remain limited."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/pledge/PledgeMaze.html:58
+msgid ""
+"Don't forget that if you have a method modifying a global variable (such as "
+"angleSum), you should ensure that it declares this variable as "
+"global. Without it, the method creates a new variable of the same name, and "
+"the global never gets modified."
+msgstr ""
+
+#. type: Content of: <div><pre>
+#: src/lessons/maze/pledge/PledgeMaze.html:62
+#, no-wrap
+msgid ""
+"def myMethod():\n"
+"  global angleSum\n"
+"  ...\n"
+"  angleSum = angleSum + 1\n"
+msgstr ""
+
+#. type: Attribute 'alt' of: <div>
+#: src/lessons/maze/pledge/PledgeMaze.html:68
+msgid "Show an additional tip"
+msgstr ""
+
+#. type: Content of: <div>
+#: src/lessons/maze/pledge/PledgeMaze.html:69
+msgid ""
+"You should set your direction to your favorite one (NORTH is advised). Then, "
+"you should write the algorithm main loop. In other words, while your buggle "
+"did not find its biscuit, you have to move forward until next obstacle in "
+"the favorite direction. Then, put a paw on a wall (using "
+"(<code>keepHandOnSideWall()</code>) while the sum of turns is not null and "
+"the favorite direction is not free. Do that until you find your baggle."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/island/IslandMaze.html:1
+msgid "Lost between islands"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/island/IslandMaze.html:3
+msgid ""
+"You thought that your algorithm was enough to escape mazes? Well, not every "
+"mazes..."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/island/IslandMaze.html:7
+msgid ""
+"The <i>wall follower algorithm</i> we used so far only works if the entry "
+"and the exit are placed near to walls connected to the external wall. But if "
+"the buggle begins in the middle of the maze, it may exist wall sections "
+"disconnected from the external wall."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/maze/island/IslandMaze.html:12
+msgid ""
+"That is why the previous strategy would let the buggle round around for "
+"ever. Indeed, the maze you should now escape from contains islands, and the "
+"buggle does not start along one of the external walls. Just give it a try if "
+"you want: copy your code over, push the run button and see your previous "
+"solution failing miserabily."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/maze/island/IslandMaze.html:18
+msgid ""
+"The method of following a wall is still good and allow to escape very "
+"efficiently some sections of the maze, so we do not want to remove it "
+"entierely. Instead, we want to stop following the wall under some "
+"conditions. Notice that the baggle lays near to the external border of the "
+"maze. So, we want to reach the border and then follow that wall. We need for "
+"example to search for the north wall before following it to the baggle."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/maze/island/IslandMaze.html:26
+msgid ""
+"To find the north wall, you simply run to the north as long as it's "
+"possible, and when facing an obstacle, you avoid it (using previous method)."
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><p><div>
+#: src/lessons/maze/island/IslandMaze.html:30
+msgid "I'm lost now, please give me some extra indications"
+msgstr ""
+
+#. type: Content of: <p><p><div>
+#: src/lessons/maze/island/IslandMaze.html:31
+msgid ""
+"Our new run() method will consist in two modes: our buggle will alternate "
+"between the \"north runner mode\" and the \"left follower mode\". You begin "
+"in \"north runner mode\", and switch to \"left follower\" when you have a "
+"wall at the north (do not forget to make sure you have a wall at your left "
+"before switching to \"left follower\" mode). You switch to \"north runner\" "
+"as soon as your buggle is facing north and is not in front of a wall during "
+"its trip around its left wall. The easiest way to write such a state machine "
+"is something like"
+msgstr ""
+
+#. type: Content of: <p><p><div><pre>
+#: src/lessons/maze/island/IslandMaze.html:39
+#, no-wrap
+msgid ""
+"[!scala]var state=0;\n"
+"state match  {\n"
+"  case 0 => // North runner\n"
+"     ...\n"
+"     state = 1;\n"
+"  case 1 => // Left follower\n"
+"     ...\n"
+"     state = 0;\n"
+"  case _ => println(\"This case should not happen. Please fix me\")\n"
+"}[/!][!java]int state=0;\n"
+"switch (state) {\n"
+"  case 0: // North runner\n"
+"     ...\n"
+"     state = 1;\n"
+"     break;\n"
+"  case 1: // Left follower\n"
+"     ...\n"
+"     state = 0;\n"
+"     break;\n"
+"}[/!][!python]northRunner = True\n"
+"if northRunner:\n"
+"     ...\n"
+"     northRunner = False\n"
+"else: # left follower\n"
+"     ...\n"
+"     northRunner = True[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><div>
+#: src/lessons/maze/island/IslandMaze.html:66
+msgid ""
+"Don't forget the default case (matching _), or scala will issue an error "
+"since your matching would be incomplete.[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/maze/island/IslandMaze.html:69
+msgid "Don't forget to let the buggle pick the baggle at the end of your code."
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/maze/island/IslandMaze.html:72
+msgid ""
+"You're up. That should be enough for you to figure out how to escape this "
+"maze, but if not, you can always request for the tip. But you do not need "
+"any more help, do you?"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:1
+msgid "Basic Shortest Path algorithm"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:3
+msgid ""
+"To conclude with this introductory lesson to maze solving algorithms, we "
+"will investigate another way to find the exit. The buggle in this lesson is "
+"a special buggle: he is a jedi. He can feel the Force. This means he is able "
+"to feel his environment."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:7
+msgid ""
+"Without even leaving his position, he can retrieve information about the "
+"world he is leaving in, with the following functions:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:9
+msgid "<code>getWorldWidth()</code> gives the width of its world."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:10
+msgid "<code>getWorldHeight()</code> gives the height of its world."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:11
+msgid ""
+"<code>hasTopWall(x,y)</code> tells whether the cell (x,y) of this world has "
+"a wall on top."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:12
+msgid ""
+"<code>hasLeftWall(x,y)</code> tells whether the cell (x,y) of this world has "
+"a wall on the left."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:13
+msgid ""
+"<code>hasBaggle(x,y)</code> tells whether the cell (x,y) of this world has a "
+"baggle."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:14
+msgid ""
+"<code>setIndication(x,y,i)</code> adds the integer indication <code>i</code> "
+"to the cell (x,y)."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:15
+msgid ""
+"<code>getIndication(x,y,i)</code> retrieves the integer indication of the "
+"cell (x,y) (or 9999 if there is no indication)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:18
+msgid ""
+"It has to be noted that it is not possible to build a wall on the bottom "
+"edge or on the right edge of a cell.  Therefore when such wall exists, it "
+"means it was built on a sibling cells -- as a top (respectively left) wall "
+"on the cell that is located below (respectively at the right of) the current "
+"cell."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:24
+msgid ""
+"Your buggle should first write the distance to the exit on each cell (or at "
+"least the useful ones)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:25
+msgid ""
+"For that, find the exit and write 0 there.  Then, write 1 on every "
+"neighboring cells that is not separated from the exit with a wall.  And then "
+"mark every cells from which you can reach the exit in 2 steps, and iterate "
+"for all cells until you mark the cell where the buggle is located."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:30
+msgid ""
+"Once the cells are marked, get your jedi buggle to follow the shortest "
+"path.  Basically the buggle has only to walk on each case with the lesser "
+"distance from the exit. You can use the method "
+"<code>setDirection(direction)</code> to make your buggle look at the "
+"specific direction such as <code>Direction.NORTH</code> or "
+"<code>Direction.EAST</code>."
+msgstr ""
+
+#. type: Attribute 'alt' of: <div>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:35
+msgid "I'm lost now. Please give me some extra indications."
+msgstr ""
+
+#. type: Content of: <div>
+#: src/lessons/maze/shortestpath/ShortestPathMaze.html:36
+msgid "Use the Force, Luke!"
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:1
+msgid "Finding the walls to follow"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:3
+msgid ""
+"This is exactly the same maze than before, but the buggle does not start at "
+"the same location. In particular, it does not have any wall to its left at "
+"the beginning."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:7
+msgid ""
+"As a result, the method you wrote for the previous exercise probably don't "
+"work for this one. If you use it here with no modification, your buggle "
+"probably start looping over the four free cells around its start position "
+"(if that's not the case, well, you didn't really stick to the mission on "
+"previous exercise. Feel lucky and proceed to the next :)"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:14
+msgid ""
+"This is because your <code>keepHandOnSideWall()</code> method has an "
+"implicit <b>pre-condition</b>: it works well if and only if the buggle has a "
+"wall to its left when you call it. Such pre-condition are very heavily used "
+"when programming. Specifying them explicitly helps understanding the code "
+"written by other, and they even allow sometimes to prove that the code works "
+"correctly."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/maze/wallfindfollow/WallFindFollowMaze.html:24
+msgid ""
+"Fixing the problem should be very easy. Simply make sure that the "
+"pre-condition of <code>keepHandOnSideWall()</code> is verified before "
+"calling it. For that, update your code to first look for a wall on its left "
+"before the big <code>while</code> loop."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/plm/universe/lightbot/LightBotWorld.html:1 src/lessons/lightbot/Main.html:1 src/lessons/lightbot/short_desc.html:1
+msgid "LightBot"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/plm/universe/lightbot/LightBotWorld.html:3
+msgid ""
+"This universe introduces a little programming puzzle which can somehow be "
+"used to introduce programmation to non-reading kids since it is programmed "
+"graphically.  The goal of each board is to light up all the lights. Your "
+"robot understands the following orders:"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:7
+msgid "<b>Order</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:7
+msgid "<b>Meaning</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:8
+msgid "<b>Move forward</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:8
+msgid "Cannot be done if the destination cell is of another height than source cell"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:9
+msgid "<b>Jump forward</b>"
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:9
+msgid ""
+"Can only be done if the destination cell is one step higher than source "
+"cell, or if destination is lower than source. Cannot be used for plain "
+"moves."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:10
+msgid "<b>Turn left</b>."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:11
+msgid "<b>Turn right</b>."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:12
+msgid "<b>Switch the light</b>."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:12
+msgid ""
+"Turn it on if it was off, and off if it was on. No effect if the cell does "
+"not contain any light."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:13
+msgid "<b>Call function 1</b>."
+msgstr ""
+
+#. type: Content of: <table><tr><td>
+#: src/plm/universe/lightbot/LightBotWorld.html:14
+msgid "<b>Call function 2</b>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/lightbot/LightBotWorld.html:17
+msgid ""
+"Please note that this world is not completely suited to small kids since the "
+"main difficulty comes from the fact that your are highly limited in the "
+"amount of instructions you can give to your robot. Advanced levels thus "
+"require to write sound functions, and are often above the capacities of "
+"small kids."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/lightbot/LightBotWorld.html:19
+msgid ""
+"This game is heavily inspirated from a flash game of the same name, which "
+"can for example be played on kongregate.com. It was written by Danny "
+"Yaroslavski (Coolio-Niato), the original idea being of Matt Chase."
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/lightbot/Main.html:2
+msgid ""
+"This lesson introduces a little programming puzzle inspired from a flash "
+"game."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Main.html:4
+msgid "See the <i>About this world</i> dialog for more details."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/short_desc.html:3
+msgid ""
+"This lesson constitutes a little brain teaser for programmers. You have to "
+"instruct your robot to turn off all lights. The trick is that you program "
+"your robot graphically, and that you are limited in the amount of "
+"instructions."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/short_desc.html:8
+msgid "No previous experience is expected to take this lesson."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board01TwoSteps.html:1
+msgid "Welcome"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board01TwoSteps.html:3
+msgid ""
+"Welcome to the lightbot world. This is merely a programmer puzzle rather "
+"than a real lesson (although some use it to teach programming).  The robot "
+"is not programmed in Java, but rather graphically. You can see the existing "
+"orders in the documentation using the <i>About this world</i> menu."
+msgstr ""
+
+#. type: Content of: <p><</p><p>
+#: src/lessons/lightbot/Board01TwoSteps.html:6
+msgid ""
+"The goal of each board is simply to switch on every lights of the board "
+"using your little robot."
+msgstr ""
+
+#. type: Content of: <p><</p><p>
+#: src/lessons/lightbot/Board01TwoSteps.html:8
+msgid ""
+"This is a introduction exercise, which should be solvable by only moving "
+"forward and switching the light, using respectively"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board01TwoSteps.html:10 src/lessons/lightbot/Board02Turn.html:4 src/lessons/lightbot/Board06Func.html:3
+msgid "and"
+msgstr ""
+
+#. type: Content of: <p><</p><p>
+#: src/lessons/lightbot/Board01TwoSteps.html:10
+msgid "."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board02Turn.html:1
+msgid "Turn around"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board02Turn.html:3
+msgid "Now, you probably need to turn in addition (using"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board02Turn.html:4
+msgid ")."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board03Jump.html:1
+msgid "Jump"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board03Jump.html:3
+msgid "You can also jump using"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board03Jump.html:3
+msgid ""
+"to pass obstacles. You can either jump one level up or any amount of levels "
+"down, but you cannot jump to go on a cell of the same height."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board04Stairs.html:1
+msgid "Stairs"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board04Stairs.html:3
+msgid "Can you pass these stairs?"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board05Higher.html:1
+msgid "Higher"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board05Higher.html:3
+msgid "Let's go higher"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board06Func.html:1
+msgid "Functions"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board06Func.html:3
+msgid "You can use"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board06Func.html:3
+msgid ""
+"to call respectively the first and second functions. Define their code in "
+"their own tab."
+msgstr ""
+
+#. type: Content of: <p><p>
+#: src/lessons/lightbot/Board06Func.html:5
+msgid "This is great if you get out of space in your main function"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board07Repeat.html:1
+msgid "Repetitive tasks"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board07Repeat.html:3
+msgid "Functions are also of great use for repetitive tasks"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board08Rec.html:1
+msgid "Calling functions from functions"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board08Rec.html:3
+msgid "It is perfectly okay to call a function from within a function!"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board09Castle.html:1
+msgid "Castle"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board09Castle.html:3
+msgid "You're getting good at this..."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board10Wall.html:1
+msgid "Wall"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board10Wall.html:3
+msgid "Ready to climb the wall?"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board11Sea.html:1
+msgid "Sea"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board11Sea.html:3
+msgid "You now have to surf these waves of lamps."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/lightbot/Board12Escher.html:1
+msgid "Escher Castle"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/lightbot/Board12Escher.html:3
+msgid "This one aint easy."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/Close10.html:1
+msgid "Close to 10"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Close10.html:2
+msgid ""
+"Given 2 int values, return whichever value is nearest to the value 10, or "
+"return 0 in the event of a tie.  [!java|scala]Note that Math.abs(n) returns "
+"the absolute value of a number.[/!] [!python]Note that math.fabs(n) returns "
+"the absolute value of a number.  This function can only be used if you "
+"imported the math module.[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Close10.html:7 src/lessons/welcome/bat/bool1/Diff21.html:5 src/lessons/welcome/bat/bool1/HasTeen.html:6 src/lessons/welcome/bat/bool1/IcyHot.html:5 src/lessons/welcome/bat/bool1/In1020.html:5 src/lessons/welcome/bat/bool1/In3050.html:5 src/lessons/welcome/bat/bool1/LastDigit.html:9 src/lessons/welcome/bat/bool1/LoneTeen.html:6 src/lessons/welcome/bat/bool1/Main.html:11 src/lessons/welcome/bat/bool1/Makes10.html:5 src/lessons/welcome/bat/bool1/Max1020.html [...]
+msgid ""
+"This exercise was converted to PLM from the excellent exercising site "
+"http://javabat.com/"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/CountTeen.html:1
+msgid "Count Teen"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/CountTeen.html:2
+msgid ""
+"We'll say that a number is \"teen\" if it is in the range 13..19 "
+"inclusive. Given 4 int values, return the amount of teen ones."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/Diff21.html:1
+msgid "Diff 21"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/Diff21.html:2
+msgid ""
+"Given an int n, return the absolute difference between n and 21, except "
+"return double the absolute difference if n is over 21."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/HasTeen.html:1
+msgid "Has Teen"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/HasTeen.html:2
+msgid ""
+"We'll say that a number is \"teen\" if it is in the range 13..19 "
+"inclusive. Given 3 int values, return true if 1 or more of them are teen."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/IcyHot.html:1
+msgid "Icy Hot"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/IcyHot.html:2
+msgid ""
+"Given two temperatures, return true if one is less than 0 and the other is "
+"greater than 100."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/In1020.html:1
+msgid "In [10;20]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/In1020.html:2
+msgid ""
+"Given 2 int values, return true if either of them is in the range 10..20 "
+"inclusive."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/In3050.html:1
+msgid "In [30;50]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/In3050.html:2
+msgid ""
+"Given 2 int values, return true if they are both in the range 30..40 "
+"inclusive, or they are both in the range 40..50 inclusive."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/LastDigit.html:1
+msgid "LastDigit"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/LastDigit.html:2
+msgid ""
+"Given two non-negative int values, return true if they have the same last "
+"digit, such as with 27 and 57. Note that the % \"mod\" operator computes "
+"remainders, so 17 % 10 is 7."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/LoneTeen.html:1
+msgid "Lone Teen"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/LoneTeen.html:2
+msgid ""
+"We'll say that a number is \"teen\" if it is in the range 13..19 "
+"inclusive. Given 2 int values, return true if one or the other is teen, but "
+"not both."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/Main.html:1
+msgid "Boolean fun"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Main.html:3
+msgid ""
+"Boolean operations are one of the very basic task in programming.  As long "
+"as you cannot write a not so simple boolean test under the minute, you "
+"probably will have a very bad time writing a real program."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Main.html:8
+msgid ""
+"That is why this lesson provides you a bunch of such exercises, so that you "
+"can get trained in this."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/Makes10.html:1
+msgid "Makes 10"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/Makes10.html:2
+msgid ""
+"Given 2 ints, a and b, return true if one if them is 10 or if their sum is "
+"10."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/Max1020.html:1
+msgid "Max1020"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Max1020.html:2
+msgid ""
+"Given 2 positive int values, return the larger value that is in the range "
+"10..20 inclusive, or return 0 if neither is in that range."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/Max1020.html:5
+msgid ""
+"Note that Math.max(Int,Int):Int and Math.min(Int,Int):Int return the maximum "
+"and minimum of two integers"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/MonkeyTrouble.html:1
+msgid "MonkeyTrouble"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/MonkeyTrouble.html:3
+msgid ""
+"We have two monkeys, a and b, and the parameters aSmile and bSmile indicate "
+"if each is smiling.  We are in trouble if they are both smiling or if "
+"neither of them is smiling.  Return true if we are in trouble."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/NearHundred.html:1
+msgid "Near Hundred"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool1/NearHundred.html:2
+msgid ""
+"Given an int n, return true if it is within 10 of 100 or 200.  "
+"[!java|scala]Note that Math.abs(n) returns the absolute value of a "
+"number.[/!] [!python]Note that math.fabs(n) returns the absolute value of a "
+"number.  This function can only be used if you imported the math module.[/!]"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/ParotTrouble.html:1
+msgid "Parot Trouble"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/ParotTrouble.html:3
+msgid ""
+"We have a loud talking parrot. The \"hour\" parameter is the current hour "
+"time in the range 0..23. We are in trouble if the parrot is talking and the "
+"hour is before 7 or after 20. Return true if we are in trouble."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/PosNeg.html:1
+msgid "Positive Negative"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/PosNeg.html:2
+msgid ""
+"Given 2 int values, return true if one is negative and one is "
+"positive. Unless negative is true, then they both must be negative."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/SleepIn.html:1
+msgid "SleepDay"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/SleepIn.html:3
+msgid ""
+"The parameter weekday is true if it is a weekday, and the parameter vacation "
+"is true if we are on vacation. We sleep in if it is not a weekday or we're "
+"on vacation. Return true if we sleep in."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool1/SumDouble.html:1
+msgid "Sum Double"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool1/SumDouble.html:2
+msgid ""
+"Given two int values, return their sum. Unless the two values are the same, "
+"then return double their sum."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/AlarmClock.html:1
+msgid "AlarmClock"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/AlarmClock.html:2
+msgid ""
+"Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a "
+"boolean indicating if we are on vacation, return a string of the form "
+"\"7:00\" indicating when the alarm clock should ring. Weekdays, the alarm "
+"should be \"7:00\" and on the weekend it should be \"10:00\". Unless we are "
+"on vacation -- then on weekdays it should be \"10:00\" and weekends it "
+"should be \"off\"."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/AnswerCell.html:1
+msgid "AnswerCell"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/AnswerCell.html:2
+msgid ""
+"Your cell phone rings. Return true if you should answer it. Normally you "
+"answer, except in the morning you only answer if it is your mom calling. In "
+"all cases, if you are asleep, you do not answer."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/BlueTicket.html:1
+msgid "BlueTicket"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/BlueTicket.html:2
+msgid ""
+"You have a blue lottery ticket, with ints a, b, and c on it. This makes "
+"three pairs, which we'll call ab, bc, and ac. Consider the sum of the "
+"numbers in each pair. If any pair sums to exactly 10, the result is 10.  "
+"Otherwise if the ab sum is exactly 10 more than either bc or ac sums, the "
+"result is 5. Otherwise the result is 0."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/CaughtSpeeding.html:1
+msgid "CaughtSpeeding"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/CaughtSpeeding.html:2
+msgid ""
+"You are driving a little too fast, and a police officer stops you. Write "
+"code to compute the result, encoded as an int value: 0=no ticket, 1=small "
+"ticket, 2=big ticket. If speed is 60 or less, the result is 0. If speed is "
+"between 61 and 80 inclusive, the result is 1. If speed is 81 or more, the "
+"result is 2. Unless it is your birthday -- on that day, your speed can be 5 "
+"higher in all cases."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/CigarParty.html:1
+msgid "CigarParty"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/CigarParty.html:2
+msgid ""
+"When squirrels get together for a party, they like to have cigars. A "
+"squirrel party is successful when the number of cigars is between 40 and 60, "
+"inclusive. Unless it is the weekend, in which case there is no upper bound "
+"on the number of cigars. Return true if the party with the"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/DateFashion.html:1
+msgid "DateFashion"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/DateFashion.html:2
+msgid ""
+"You and your date are trying to get a table at a restaurant. The parameter "
+"\"you\" is the stylishness of your clothes, in the range 0..10, and \"date\" "
+"is the stylishness of your date's clothes. The result getting the table is "
+"encoded as an int value with 0=no, 1=maybe, 2=yes. If either of you is very "
+"stylish, 8 or more, then the result is 2 (yes). With the exception that if "
+"either of you has style of 2 or less, then the result is 0 (no). Otherwise "
+"the result is 1 (maybe)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/GreenTicket.html:1
+msgid "GreenTicket"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/GreenTicket.html:2
+msgid ""
+"You have a green lottery ticket, with ints a, b, and c on it. If the numbers "
+"are all different from each other, the result is 0. If all of the numbers "
+"are the same, the result is 20. If two of the numbers are the same, the "
+"result is 10."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/In1To10.html:1
+msgid "In1To10"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/In1To10.html:2
+msgid ""
+"Given a number n, return true if n is in the range 1..10, inclusive. Unless "
+"\"outsideMode\" is true, in which case return true if the number is less or "
+"equal to 1, or greater or equal to 10."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/InOrderEqual.html:1
+msgid "InOrderEqual"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/InOrderEqual.html:2
+msgid ""
+"Given three ints, a b c, return true if they are in strict increasing order, "
+"such as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the "
+"exception that if \"equalOk\" is true, equality is allowed, such as 5 5 7 or "
+"5 5 5."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/InOrder.html:1
+msgid "InOrder"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/InOrder.html:2
+msgid ""
+"Given three ints, a b c, return true if b is greater than a, and c is "
+"greater than b. However, with the exception that if \"bOk\" is true, b does "
+"not need to be greater than a."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/LastDigit2.html:1
+msgid "LastDigit 2"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/LastDigit2.html:2
+msgid ""
+"Given three ints, a b c, return true if two or more of them have the same "
+"rightmost digit. The ints are non-negative. Note: the % \"mod\" operator "
+"computes the remainder, e.g. 17 % 10 is 7."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/LessBy10.html:1
+msgid "LessBy10"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/LessBy10.html:2
+msgid ""
+"Given three ints, a b c, return true if one of them is 10 or more less than "
+"one of the others."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/Main.html:1
+msgid "Boolean (even more) fun"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/bat/bool2/Main.html:3
+msgid ""
+"A very good introduction to this type is available here: "
+"http://javabat.com/doc/ifboolean.html."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/MaxMod5.html:1
+msgid "MaxMod5"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/MaxMod5.html:2
+msgid ""
+"Given two int values, return whichever value is larger. However if the two "
+"values have the same remainder when divided by 5, then the return the "
+"smaller value. However, in all cases, if the two values are the same, return "
+"0.  Note: the % \"mod\" operator computes the remainder, e.g. 7 % 5 is 2."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/NearTen.html:1
+msgid "NearTen"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/NearTen.html:2
+msgid ""
+"Given a non-negative number \"num\", return true if num is within 2 of a "
+"multiple of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % "
+"5) is 2."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/RedTicket.html:1
+msgid "RedTicket"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/RedTicket.html:2
+msgid ""
+"You have a red lottery ticket showing ints a, b, and c, each of which is 0, "
+"1, or 2. If they are all the value 2, the result is 10. Otherwise if they "
+"are all the same, the result is 5. Otherwise so long as both b and c are "
+"different from a, the result is 1. Otherwise the result is 0."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/ShareDigit.html:1
+msgid "ShareDigit"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/ShareDigit.html:2
+msgid ""
+"Given two ints, each in the range 10..99, return true if there is a digit "
+"that appears in both numbers, such as the 2 in 12 and 23. (Note: division, "
+"e.g. n/10, gives the left digit while the % \"mod\" n%10 gives the right "
+"digit.)"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/SortaSum.html:1
+msgid "SortaSum"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/SortaSum.html:2
+msgid ""
+"Given 2 ints, a and b, return their sum. However, sums in the range 10..19 "
+"inclusive, are forbidden, so in that case just return 20."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/SquirrelPlay.html:1
+msgid "SquirrelPlay"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/SquirrelPlay.html:2
+msgid ""
+"The squirrels in Palo Alto spend most of the day playing. In particular, "
+"they play if the temperature is between 60 and 90 (inclusive). Unless it is "
+"summer, then the upper limit is 100 instead of 90. Given an int temperature "
+"and a boolean isSummer, return true if the squirrels play and false "
+"otherwise."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/TeaParty.html:1
+msgid "TeaParty"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/TeaParty.html:2
+msgid ""
+"We are having a party with amounts of tea and candy. Return the int outcome "
+"of the party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if "
+"both tea and candy are at least 5. However, if either tea or candy is at "
+"least double the amount of the other one, the party is great (2).  However, "
+"in all cases, if either tea or candy is less than 5, the party is always bad "
+"(0)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/TeenSum.html:1
+msgid "TeenSum"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/TeenSum.html:2
+msgid ""
+"Given 2 ints, a and b, return their sum. However, \"teen\" values in the "
+"range 13..19 inclusive, are extra lucky. So if either value is a teen, just "
+"return 19."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/TwoAsOne.html:1
+msgid "TwoAsOne"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/TwoAsOne.html:2
+msgid ""
+"Given three ints, a b c, return true if it is possible to add two of the "
+"ints to get the third."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/bat/bool2/WithoutDoubles.html:1
+msgid "WithoutDoubles"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/bat/bool2/WithoutDoubles.html:2
+msgid ""
+"Return the sum of two 6-sided dice rolls, each in the range 1..6. However, "
+"if noDoubles is true, if the two dice show the same value, increment one die "
+"to the next value, wrapping around to 1 if its value was 6."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/plm/universe/bat/BatWorld.html:1
+msgid "BatWorld"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/bat/BatWorld.html:3
+msgid ""
+"This world is a simplistic testing environment largely inspired from the "
+"http://codingbat.com invented by Nick Parlente."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/bat/BatWorld.html:6
+msgid ""
+"The typical exercises are very short ones, aiming at improving the tactical "
+"programming abilities of the students. That is to say that you will be "
+"presented a quite long list of very little exercises about rather simple "
+"things. The idea is to train you on these issues until they become automatic "
+"to you."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/bat/BatWorld.html:12
+msgid ""
+"In contrary to the other worlds, the BatWorld does not provide any fancy "
+"abstraction nor visualization. You have to fill a function, which gets "
+"called for a bunch of parameter sets, and that's it."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/plm/universe/bat/BatWorld.html:16
+msgid ""
+"For more information, you should refer to the CodingBat.com documentation, "
+"which contains for example a very useful documentation on boolean operators: "
+"http://codingbat.com/doc/ifboolean.html"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/Main.html:1
+msgid "String fun"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/bat/string1/Main.html:3
+msgid ""
+"Strings are the simplest of the complex data types :) They provide several "
+"operations, such as getting the length of the string, or a substring of it.."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/bat/string1/Main.html:7
+msgid ""
+"A very good introduction to this type is available here: "
+"http://javabat.com/doc/string.html."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/bat/string1/short_desc.html:1
+msgid "Small exercises about strings"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/bat/string1/short_desc.html:3
+msgid ""
+"These are some training exercises around strings. But unfortunately, its "
+"integration within PLM is still ongoing."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/bat/string1/short_desc.html:6
+msgid "Please be patient with us."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/AltPairs.html:1
+msgid "AltPairs"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/AltPairs.html:2
+msgid ""
+"Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 "
+"... so \"kittens\" yields \"kien\"."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/FrontTimes.html:1
+msgid "FrontTimes"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/FrontTimes.html:2
+msgid ""
+"Given a string and a non-negative int n, we'll say that the front of the "
+"string is the first 3 chars, or whatever is there if the string is less than "
+"length 3. Return n copies of the front;"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/Last2.html:1
+msgid "Last2"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/bat/string1/Last2.html:3
+msgid ""
+"Given a string, return the amount of times that the two last letters appear "
+"as a substring of the string. So \"hixxxhi\" yields 1 (we won't count the "
+"end substring) while \"aaaNaa\" yields 2 (substrings may overlap)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringBits.html:1
+msgid "StringBits"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringBits.html:2
+msgid ""
+"Given a string, return a new string made of every other char starting with "
+"the first, so \"Hello\" yields \"Hlo\"."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringMatch.html:1
+msgid "StringMatch"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringMatch.html:2
+msgid ""
+"Given 2 strings, a and b, return the number of the positions where they "
+"contain the same length 2 substring. So \"xxcaazz\" and \"xxbaaz\" yields 3, "
+"since the \"xx\", \"aa\", and \"az\" substrings appear in the same place in "
+"both strings."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringSplosion.html:1
+msgid "StringSplosion"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringSplosion.html:2
+msgid "Given a non-empty string like \"Code\" return a string like \"CCoCodCode\"."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringTimes.html:1
+msgid "StringTimes"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringTimes.html:2
+msgid ""
+"Given a string and a non-negative int n, return a larger string that is n "
+"copies of the original string."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringX.html:1
+msgid "StringX"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringX.html:2
+msgid ""
+"Given a string, return a version where all the \"x\" have been "
+"removed. Except an \"x\" at the very start or end should not be removed."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/bat/string1/StringYak.html:1
+msgid "StringYak"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/bat/string1/StringYak.html:2
+msgid ""
+"Suppose the string \"yak\" is unlucky. Given a string, return a version "
+"where all the \"yak\" are removed, but the \"a\" can be any char. The "
+"\"yak\" strings will not overlap."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/basics/Array1.html:1
+msgid "[!java|scala]Arrays[/!][!python]Lists[/!] and Knotting"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/basics/Array1.html:3
+msgid ""
+"The goal of this exercise is to reproduce the pattern of the first row in "
+"the other rows with a shift of one cell (see the Objective tab for "
+"details). The biggest difference between this exercise and the others we had "
+"on patterns is that you have to read the pattern (on first row) before "
+"reproducing it. You cannot do otherwise because the same code will be "
+"executed on three different worlds, each of them having a specific pattern."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array1.html:11
+msgid ""
+"One solution is to read the next cell, and go copy it in position before "
+"coming back to read the second cell. But since it is forbidden to use the "
+"methods to teleport the buggle to a specific position (<code>setPos()</code> "
+"and similar), this approach will be a pain to implement."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array1.html:16
+msgid ""
+"The simplest is to store the sequence of colors that constitute the whole "
+"pattern in an [!java|scala]<b>array</b>[/!][!python]<b>list</b>[/!].  But "
+"before we can do so, we should learn a bit what "
+"[!java|scala]arrays[/!][!python]lists[/!] are."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/welcome/array/basics/Array1.html:20
+msgid "[!java|scala]Arrays[/!][!python]List[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array1.html:22
+msgid ""
+"[!java|scala]An array[/!][!python]A list[/!] is an ordered sequence of "
+"variables that go together.  It is somehow similar to a shelve where each "
+"level can store a separate value. Each variable of the sequence is "
+"identified by its position, and can store a specific value. [!java|scala]All "
+"cells of the array must store values of the same type because arrays are "
+"homogeneous in [!thelang]. It is possible to trick this restriction by using "
+"the datatype <code>[!java]Object[/!][!scala]Any[/!]</code> that can contain "
+"[!java]almost[/!] any other datatype. [!java]Primitive types such as the "
+"ones we saw so far (int, boolean, double, char, etc) cannot be stored in an "
+"Object variable, but their objectified counter-part (Integer, Boolean, "
+"Double, Char, Boolean, etc) can.[/!] It is however a good practice to make "
+"the type of an array as specific as possible, i.e., if you plan to store "
+"some integers in your array, make it an array of integers, not of "
+"[!java]Object[/!][!scala]Any[/!].[/!] [!python]Lists can even mix values of "
+"differing types, such as integer values in some cells and colors in other "
+"cells.[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:38
+msgid ""
+"T is the [!java|scala]array[/!][!python]list[/!]'s name, "
+"[!java|python]T[0][/!][!scala]T(0)[/!] is the name of the first cell, "
+"[!java|python]T[1][/!][!scala]T(1)[/!] the name of the second cell, "
+"[!java|python]T[2][/!][!scala]T(2)[/!] the third one, etc. And yes, the "
+"first cell is numbered [!java|python]T[0][/!][!scala]T(0)[/!] while the last "
+"one of [!java|scala]an array[/!][!python]a list[/!] of size N is "
+"[!java|python]T[N-1][/!][!scala]T(N-1)[/!]. It may seem funny to count "
+"starting from 0 and not from 1 as usual, but some historical reasons make it "
+"unavoidable here."
+msgstr ""
+
+#. type: Content of: <p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:46
+msgid "Basic usage"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:48
+msgid ""
+"We can use an integer variable <i>i</i> to access with "
+"[!java|python]T[i][/!][!scala]T(i)[/!] to the cells: when the value of "
+"<i>i</i> is 0, then [!java|python]T[i][/!][!scala]T(i)[/!] accesses "
+"[!java|python]T[0][/!][!scala]T(0)[/!]; when the value of <i>i</i> is 10, "
+"then [!java|python]T[i][/!][!scala]T(i)[/!] accesses "
+"[!java|python]T[10][/!][!scala]T(10)[/!].  <i>i</i> is said to be the "
+"<b>index</b> in T.  <code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> can "
+"be used just like any variable. We can set a new value:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:56
+#, no-wrap
+msgid "[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:58
+msgid "We can retrieve and use its value:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:59
+#, no-wrap
+msgid "x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:61
+msgid "We can test this value:"
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:62
+#, no-wrap
+msgid ""
+"if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) "
+"[!scala|java]{[/!][!python]:[/!]\n"
+"    [!java|scala]//[/!][!python]#[/!] instructions...\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:66
+msgid ""
+"It is very easy to traverse the whole "
+"[!scala|java]array[/!][!python]list[/!], for example to initialize each "
+"cells."
+msgstr ""
+
+#. type: Content of: <p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:69
+#, no-wrap
+msgid ""
+"[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in "
+"range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!]\n"
+"   [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:73
+msgid ""
+"[!java|scala]The notation <code>T.length</code> retrieves the length of the "
+"array T,[/!] [!python]The function <code>len()</code> retrieves the length "
+"of the list T,[/!] allowing to build a classical for loop easily.  "
+"[!python]Actually, the <code>len()</code> function is much more generic and "
+"can be used to retrieve the length of many objects.  Applied to strings for "
+"example, it returns the amount of chars in this string.[/!] [!scala]Don't "
+"forget to start at <code>0</code> and stop at <code>T.length-1</code> "
+"instead of <code>1 to T.length</code> however.[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:81
+msgid ""
+"If you just want to iterate over the values of T without keeping track of "
+"their index, you can simply write:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:82
+#, no-wrap
+msgid ""
+"[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in "
+"T:[/!]\n"
+"  action()[!java];[/!]\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:85
+msgid ""
+"[!java]This construct is called an <i>extended loop</i> in Java. The "
+"variable <i>i</i> takes all values of the set located to the right of the "
+"colon (:), one after the other.[/!] [!python|scala]This is actually very "
+"similar to the previous construct.  Simply, "
+"<code>[!python]range(n)[/!][!scala]i to j[/!]</code> returns a set of "
+"integers over which the for construct iterates.  Actually, [!thelang] offers "
+"much more elegant ways to traverse [!python]lists[/!][!scala]arrays[/!] and "
+"other data collections, but this should be the topic of a specific set of "
+"exercises (that are still to be written in PLM).[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:96
+msgid "Declaring [!python]a list[/!][!java|scala]an array[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:99
+msgid ""
+"If you know beforehand the content of your list, you can affect these values "
+"all together.  Just put them between square braces and separated by commas "
+"as follows:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:102
+#, no-wrap
+msgid ""
+"L = [1, 3, 5, 7, 9] \n"
+"<span class=\"comment\"># L is now an array of 5 values, all of them being "
+"integers</span>"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:104
+msgid ""
+"Otherwise, you probably want to create an empty list and then append each "
+"values separately to the list:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:106
+#, no-wrap
+msgid ""
+"L2 = [] \n"
+"<span class=\"comment\"># L2 is now an empty list</span>\n"
+"L2.append(1)\n"
+"L2.append(3)\n"
+"L2.append(5)\n"
+"L2.append(7)\n"
+"L2.append(9) \n"
+"<span class=\"comment\"># Its content is now the same as L previously</span>"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:117
+msgid ""
+"To declare a variable named <b>T</b> that can store arrays of integers, one "
+"should write:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:118
+#, no-wrap
+msgid "[!java]int[] T;[/!][!scala]var T:Array[Int][/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:120
+msgid ""
+"[!java]<code>int</code> means that the elements of the array are of type "
+"integer; <code>[]</code> means that we are speaking of an array and "
+"<code>T</code> is the name of the variable.  For historical reasons, this "
+"can also be written as <code>int T[]</code> (with the [] after the variable "
+"name), but this is less readable and should probably be avoided.[/!] "
+"[!scala]The <code>[Int]</code> notation specializes the Array type (that is "
+"generic), specifying that each cell of this array is an integer. An array of "
+"booleans would simply by written <code>Array[Boolean]</code>.[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:128
+msgid "Allocating an array"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:130
+msgid ""
+"Declaring a variable <code>T</code> that stores an array only reserve the "
+"<b>name</b> <code>T</code> for later use, but not the memory area to store "
+"the cells. The array is not initialized yet: it does not have any "
+"value. What would <code>[!java]T[4][/!][!scala]T(4)[/!]</code> mean if we "
+"didn't say that the array is 5 cells long?"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:135
+msgid "First and foremost, we have to give a value to <code>T</code>:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:136
+#, no-wrap
+msgid "[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:138
+msgid ""
+"<code>new</code> means that we want to create something, and "
+"<code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> means that it is "
+"an array of 10 integer values.  In return, an array of 10 integer cells is "
+"created in memory, and the <code>T</code> variable <b>references</b> this "
+"array."
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:143
+msgid ""
+"The size of an array is fixed and cannot be changed after the creation of "
+"the array. The size of a <code>T</code> array can be retrieve by consulting "
+"the variable <code>T.length</code>."
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:147
+msgid ""
+"While allocating, you can specify the size with a variable: "
+"<code>[!java]int[] T = new int[i];[/!][!scala]var T = new "
+"Array[Int](i);[/!]</code> In this case, the array's size will be set to the "
+"value of <code>i</code> <i>when <code>new</code> gets called</i>.  The size "
+"of the array still cannot be modified : even if the variable <code>i</code> "
+"changes afterward, the size remains to the value given when it was "
+"allocated.  [!java]Also, it is forbidden to write something like <code>int "
+"T[10];</code> when declaring the variable.  You are required to use the "
+"<code>new</code> instruction to allocate it, as in <code>int[] T = new "
+"int[10];</code> [/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><h4>
+#: src/lessons/welcome/array/basics/Array1.html:155
+msgid "Declaration and initialization"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:156
+msgid ""
+"If you know beforehand the content of your array, you can declare, allocate "
+"and initialize it in one shoot:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:157
+#, no-wrap
+msgid ""
+"[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = "
+"Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:159
+msgid ""
+"To know the size of the array to allocate, the compiler counts the provided "
+"values.  This code is equivalent to:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:161
+#, no-wrap
+msgid ""
+"[!java]int[] T = new int[10];\n"
+"T[0] = 1;\n"
+"T[1] = 2;\n"
+"...\n"
+"T[9] = 10;[/!][!scala]var T = new Array[Int](10);\n"
+"T(0) = 1\n"
+"T(1) = 2\n"
+"...\n"
+"T(9) = 10[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:171
+msgid "It is also equivalent to:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:172
+#, no-wrap
+msgid ""
+"[!java]int[] T = new int[10];\n"
+"for (int i=0; i<T.length; i++) {\n"
+"  T[i] = i+1;\n"
+"}[/!][!scala]var T = new Array[Int](10);\n"
+"for (i <- 0 to T.length-1) {\n"
+"  T(i) = i+1\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><h3>
+#: src/lessons/welcome/array/basics/Array1.html:183
+msgid "[!python]Lists[/!][!scala|java]Arrays[/!] and method parameters"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:184
+msgid ""
+"It is perfectly OK to pass [!python]a list[/!][!java|scala]an array[/!] to a "
+"method as a parameter.  This method can then use this parameter as if it "
+"were defined locally:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:186
+#, no-wrap
+msgid ""
+"[!java]boolean has42First(int[] array) {\n"
+"    return array[0] == 42;\n"
+"}[/!][!python]def has42First(list):\n"
+"  return list[0] == 42[/!][!scala]def has42First(array:Array[Int]):Boolean = "
+"{\n"
+"  return array(0) == 42\n"
+"}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:193
+msgid "On the caller side, that also very simple:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:194
+#, no-wrap
+msgid ""
+"[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] "
+"(10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]\n"
+"[!java|scala]<span class=\"comment\">// Values initialization "
+"omitted</span>\n"
+"[/!]if (has42First(tab))[!java|scala] {[/!][!python]:[/!]\n"
+"   <span class=\"comment\">[!java|scala]//[/!][!python]#[/!] do "
+"something</span>\n"
+"[!java|scala]}[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:201
+msgid ""
+"If you want to allocate and initialize the array in one shoot, that's a bit "
+"more complicated as the compiler has to know the type of the parameter you "
+"are creating.  For that, use the following (ugly) construct:"
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:204
+#, no-wrap
+msgid ""
+"if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {\n"
+"   <span class=\"comment\">// do something</span>\n"
+"}"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:209
+msgid ""
+"Methods can also return [!java|scala]arrays[/!][!python]lists[/!] as result "
+"without any complication.  Here is a method that returns [!java|scala]an "
+"array[/!][!python]a list[/!] of the requested size, filled with 42s."
+msgstr ""
+
+#. type: Content of: <p><p><p><pre>
+#: src/lessons/welcome/array/basics/Array1.html:212
+#, no-wrap
+msgid ""
+"[!java]int[] fill42(int size) {\n"
+"    int[] res = new int[size];\n"
+"    for (int i=0; i<size; i++) \n"
+"        res[i] = 42;\n"
+"    return res;\n"
+"}[/!][!scala]def fill42(size:Int):Array[Int] = {\n"
+"    var res = new Array[int] (size)\n"
+"    for (i <- 0 to size -1) {\n"
+"        res(i) = 42;\n"
+"    }\n"
+"    return res;\n"
+"}[/!][!python]def fill42(size):\n"
+"    res = []\n"
+"    for i in range(size):\n"
+"        res.append(42)\n"
+"    return res[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:231
+msgid "At least! After this long explanation, we can come back to the exercise."
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:232
+msgid ""
+"Your mission is rather simple actually.  Your code should save the color "
+"pattern observed on the first row into [!java|scala]an array[/!][!python]a "
+"list[/!].  [!python]The easiest is to create an empty list, and then "
+"<code>append()</code> the colors one after the others as you read them (with "
+"<code>getGroundColor()</code>).[/!] [!java|scala]For that, you should "
+"declare and allocate an array of <code>Color</code>. Beware, there is "
+"several worlds, of differing size; use <code>getWorldHeight()</code> to "
+"retrieve the size of the current world.  Once the array allocated, fill it "
+"by reading the ground color in each locations (with "
+"<code>getGroundColor()</code>).[/!]"
+msgstr ""
+
+#. type: Content of: <p><p><p><p>
+#: src/lessons/welcome/array/basics/Array1.html:240
+msgid ""
+"Once you managed to read and save the pattern on the first row, you have to "
+"reapply the pattern on every rows, for example by executing "
+"<code>getWorldHeight()</code> times a method written specifically for this."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/basics/Array2.html:1
+msgid "[!java|scala]Arrays[/!][!python]Lists[/!], Knotting and Modulos"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:3
+msgid ""
+"This exercise is similar to the previous one: you have to reproduce the "
+"color pattern of the first cell into the other ones."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:6
+msgid ""
+"The first difference is that the world is bordered of walls: you thus have "
+"to slightly modify your trajectory to ensure that the buggle does not crash "
+"into a wall. The simpler for that is to handle the first cell out of the "
+"<code>for</code> loop and do only <code>getWorldHeight()-1</code> steps in "
+"the loop."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:12
+msgid ""
+"The other difference is that the offset to apply between columns is not "
+"fixed, but written on the first cell of each column. To get the info as an "
+"integer, we can use:"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/welcome/array/basics/Array2.html:16
+#, no-wrap
+msgid ""
+"[!java]int offset = Integer.parseInt(readMessage())[/!][!python]offset = "
+"int( readMessage() )[/!][!scala]val offset = readMessage().toInt[/!]"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:18
+msgid ""
+"<code>readMessage()</code> gets the message on the ground as a "
+"[!java|scala]String[/!][!python]string[/!], while "
+"<code>[!java]Integer.parseInt(str)[/!][!scala]str.toInt[/!][!python]int(str)[/!]</code> "
+"transforms the string <code>str</code> into an integer by <i>reading</i> it."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:22
+msgid ""
+"Then, to pick the right color, the easier is to use the <code>%</code> "
+"(modulo) operator. For example, <code>(i + 5) % size</code> allows to "
+"retrieve the <code>i</code>th cell of an array of size <code>size</code> "
+"with an offset of <code>5</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/basics/Array2.html:27
+msgid "You're up."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:1
+msgid "Searching for a given value"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:3
+msgid ""
+"The goal of this exercise is to search the cell of a given value, and return "
+"its position."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:5
+msgid ""
+"To that extend, you should fill the method <code>indexOf()</code>, which "
+"parameters are the array to explore, and the value to search. If the value "
+"<code>lookingFor</code> is not in the array <code>tab</code>, the method "
+"should return -1."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:9
+msgid ""
+"The idea of the algorithm is to sweep over the whole array, checking the "
+"value of each cell. If it's the searched value, you should return the index "
+"of the cell currently checked."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:13
+msgid ""
+"Remember that indices begin at 0 and not at 1. So, if there is 3 cells, "
+"their indices will be 0, 1 and 2. There would not be any cell numbered 3."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:16
+msgid ""
+"Remember also that the amount of cells in an array can be retrieved using "
+"the <code>length</code> attribute. So, if your array is called "
+"<code>tab</code>, its size can be retrieved as <code>tab.length</code>.  "
+"Note that there is no () after <code>length</code>. An attribute is a sort "
+"of variable embedded in another object (here, the array)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:21
+msgid "So, the last value of an array is given by <code>tab[tab.length - 1]</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:23
+msgid ""
+"Remember also that the amount of cells in an array can be retrieved with the "
+"<code>len()</code> function. So, if your array is called <code>tab</code>, "
+"its size can be retrieved as <code>len(tab)</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/value/IndexOfValue.html:27
+msgid "So, the last value of an array is given by <code>tab[ len(tab) - 1]</code>."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:1
+msgid "Index of the maximum value"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:3
+msgid ""
+"In this exercise, you must compute the index of the tab cell containing the "
+"biggest value."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:5
+msgid ""
+"For that, fill the <code>indexOfMaximum()</code> method. Its parameter is "
+"the array to explore. Should the array contain the searched value several "
+"times, you should return the index of the first occurrence."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html:9
+msgid ""
+"To solve this exercise, you should sweep over the whole array. For each "
+"value, if it's bigger than the biggest value you saw so far, you must save "
+"this new champion and its position.  You will thus need 2 extra variables; "
+"the initial value of the champion could be the value of the first cell."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:1
+msgid "Average value"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:4
+msgid ""
+"The objective of this exercise is to compute the average value of the "
+"integer values stored in an array."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:6
+msgid ""
+"You have to fill the body of the method <code>average()</code> which takes "
+"as parameter the array of integers of which it computes and returns the "
+"average value. Please note that this method must return an integer."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:8
+msgid ""
+"To compute the average value of an integer, it is necessary to traverse the "
+"whole array and to compute the sum of all its values (so you will need a "
+"variable to store this temporary result), then you have to divide this sum "
+"by the size of the array."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:10
+msgid ""
+"In Java, you can get the size of an array <code>myarray</code> by consulting "
+"its <code>length</code> attribute (in other words, "
+"<code>myarray.length</code>). Notice that there is no parenthesis after "
+"<code>length</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/averagevalue/AverageValue.html:15
+msgid ""
+"In python, retrieving the size of an array <code>myarray</code> is as easy "
+"as calling <code>len(myarray)</code>."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/maxvalue/MaxValue.html:1
+msgid "Maximal value"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/maxvalue/MaxValue.html:3
+msgid ""
+"In this exercise, you must compute the maximal value contained in an array.  "
+"For that, fill the <code>maximum()</code> method, which parameter is the "
+"array to explore."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/maxvalue/MaxValue.html:7
+msgid ""
+"To compute this value, sweep over the whole parameter. For each value, if "
+"it's bigger than the biggest value you saw so far, you must save this value "
+"somewhere to remember it afterward. You thus need an extra variable, which "
+"can be initialized to the value of the first array cell."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:1
+msgid "Occurrence of a value"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:3
+msgid ""
+"In this exercise, you must compute the amount of occurrences of a given "
+"value in an array (that is, the amount of time that this value appears in "
+"the array). For that, fill the <code>occurrences()</code> method, which "
+"returns the number of occurrence of <code>lookingFor</code> in "
+"<code>tab</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.html:8
+msgid ""
+"To compute this value, simply sweep over the array counting for the amount "
+"of cells containing the searched value. You thus need an extra variable for "
+"that."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/array123/Array123.html:1
+msgid "Array123"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/array123/Array123.html:2
+msgid ""
+"Given an array of integers, return true if .. 1, 2, 3, .. appears in the "
+"array somewhere."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/array667/Array667.html:1
+msgid "Array667"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/array667/Array667.html:2
+msgid ""
+"Given an array of integers, return the number of times that two 6's are next "
+"to each other in the array. Also count instances where the second \"6\" is "
+"actually a 7."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/arraycount9/ArrayCount9.html:1
+msgid "ArrayCount9"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/arraycount9/ArrayCount9.html:2
+msgid "Given an array of integers, return the number of 9's in the array."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/arrayfront9/ArrayFront9.html:1
+msgid "ArrayFront9"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/arrayfront9/ArrayFront9.html:2
+msgid ""
+"Given an array of integers, return true if one of the first 4 elements in "
+"the array is a 9. The array length may be less than 4."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/notriples/NoTriples.html:1
+msgid "NoTriples"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/notriples/NoTriples.html:2
+msgid ""
+"Given an array of integers, we'll say that a triple is a value appearing 3 "
+"times in a row in the array. Return true if the array does not contain any "
+"triples."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/welcome/array/has271/Has271.html:1
+msgid "Has271"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/welcome/array/has271/Has271.html:2
+msgid ""
+"Given an array of integers, return true if it contains a 2, 7, 1 pattern -- "
+"a value, followed by the value plus 5, followed by the value minus 1.  "
+"Additionally the 271 counts even if the \"1\" differs by 2 or less from the "
+"correct value."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:1
+msgid "PancakeWorld"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:3
+msgid "This universe is very simple, with only five functions provided."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:5
+#, no-wrap
+msgid "[!java]int [/!]getStackSize()  [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:6
+msgid "Returns the size of the stack, that is the amount of pancakes it contains."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:8
+#, no-wrap
+msgid ""
+"[!java]int [/!]getPancakeRadius([!java]int [/!]rank[!scala]:Int[/!])  "
+"[!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:9
+msgid ""
+"Returns the radius of the pancake passed as argument, with the rank of the "
+"top-most pancake being 0."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:11
+#, no-wrap
+msgid ""
+"[!java]boolean [/!]isPancakeUpsideDown([!java]int [/!]rank[!scala]:Int[/!])   "
+"[!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:12
+msgid ""
+"Returns whether the pancake passed as argument upside-down, that is, if its "
+"burned side is on top. As usual, the top-most pancake is of rank 0."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:14
+#, no-wrap
+msgid "[!java]void [/!]flip([!java]int [/!]amount[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:15
+msgid ""
+"Flips the <code>amount</code> first pancakes composing the stack, from the "
+"top of it."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:17
+#, no-wrap
+msgid "[!java]boolean [/!]isSorted()   [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:18
+msgid "Returns whether the pancake stack is correctly sorted."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/pancake/universe/PancakeWorld.html:20
+#, no-wrap
+msgid "[!java]boolean [/!]isSelected()   [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/pancake/Main.html:1 src/lessons/sort/pancake/BasicPancake.html:1
+msgid "Pancake Sorting"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:3
+msgid ""
+"This activity is inspired by a problem first introduced in 1975 by Harry "
+"Dweighter in the American Mathematical Monthly. The question is not only to "
+"sort the pancakes, but to determine <code>f(n)</code> the <i>minimal</i> "
+"amount of flips mandated to sort any stack of size <code>n</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:7
+msgid ""
+"This problem is now famous because Bill Gates authored (with "
+"C. Papadimitriou) his only scientific publication in 1979 on this topic, "
+"providing a faster algorithm and proving that <code>17n/16 ≤ f(n) ≤ "
+"(5n+5)/3</code>.  This was the only publication of Bill Gates before he "
+"invented Windows and became rich."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:11
+msgid ""
+"Then, David X. Cohen, the inventor of the Futurama comics with many "
+"mathematical references, introduced the variant with burnt pancakes and "
+"studied its complexity with Manuel Blum in 1993."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:14
+msgid ""
+"An article of 2012 (by L. Bulteau, G. Fertin and I. Rusu) proved that "
+"determining the minimal amount of flips to sort the stack is a NP-complete "
+"problem. Naturally, the stack sorting problem is not NP-complete since it "
+"can be solved in 2n-3 steps with the naive algorithm and (5n+5)/3 steps with "
+"the Gates algorithm.  That's determining the minimal amount of steps that is "
+"NP."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:19
+msgid "Further information can be found on the wikipedia page, as usual."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/Main.html:22
+msgid ""
+"This activity is also integrated to CSIRL (my repository of <i>free</i> "
+"unplugged activities to introduce computer science, available at "
+"http://www.loria.fr/~quinson/Mediation/SMN/), and it may be interesting to "
+"run the unplugged activities before implementing these algorithms in PLM."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/Main.html:33
+msgid "A temporal view similar to the sorting universe could be helpful"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/Main.html:34
+msgid "Other exercises, for example on the Cohen's algorithm, or on the other ones."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/sort/pancake/short_desc.html:1
+msgid "The pancake problem"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/short_desc.html:3
+msgid "Help the poor psychorigid pancakes' chef to sort its pancake stack!"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/short_desc.html:5
+msgid ""
+"This funny problem leads to algorithms that are somewhat more challenging to "
+"implement. You are supposed to master the bases of programming and some "
+"sorting algorithms to take this lesson."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/BasicPancake.html:3
+msgid ""
+"The pancake sorting problem this is a simple puzzle where you have a set of "
+"pancakes, each of differing size. The chef cooking the pancake is a bit "
+"psychorigid: he hates when the pancakes are not correctly sorted on the "
+"plate. He loves when they are correctly ordered, with the small ones over "
+"the larger ones. As every pancake maker, he masters the pancake flipping "
+"with his spatula. He can flip the pancake on top of the stack, or even "
+"several pancakes at once. The thing is that he has only one plate and the "
+"table is too dirty to place pancakes on it, even temporary. The only allowed "
+"operation is to flip some pancakes that are on top of the stack."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/BasicPancake.html:12
+msgid ""
+"Your work is to help this poor guy sorting his stack by flipping the "
+"pancakes. Each pancake is defined by its radius and rank within the stack, "
+"where the bottom pancake is at rank 0, and the one above at rank 1."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/BasicPancake.html:16
+msgid ""
+"Note that you can play physically with pieces of paper or wood at first to "
+"get the grasp on this problem. This is even one of the activities that I use "
+"in my CS-IRL (computer science in real life) project to introduce the "
+"concept of algorithm to absolute beginners that wonder about our "
+"science. More information at http://www.loria.fr/~quinson/Mediation/SMN/ (in "
+"French)."
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:22
+msgid "I don't get it. I need some help."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:23
+msgid ""
+"You should try to first move the largest pancake to the bottom, and then the "
+"largest but one pancake on top of it, and then the one just smaller on top, "
+"and so on."
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:27
+msgid "The first tip was not enough. I need another one."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:28
+msgid "So first, you need to move the largest pancake at the bottom of the stack."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:29
+msgid ""
+"Can you imagine a situation in which you can easily bring this damn large "
+"pancake to the bottom?"
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/BasicPancake.html:30
+msgid "How could you reach this situation from the current one?"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/pancake/BurnedPancake.html:1
+msgid "Burned Pancakes"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/BurnedPancake.html:3
+msgid ""
+"Hard blow for the chef! The pancakes got burnt on one side! There is no way "
+"he can deliver a stack of pancakes with visibly burnt pancakes! You've got "
+"to help him ensuring that no pancake is upside-down while sorting his stack."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/pancake/GatesPancake.html:1
+msgid "Faster Pancake Sorting"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/GatesPancake.html:3
+msgid ""
+"Unlike others sorting problem, the expensive operation is not the comparison "
+"of values, but the flipping of pancakes. In this exercise, we will explore "
+"another algorithm that attempt to reduce the amount of stack flipping. The "
+"funny side is that this algorithm was first introduced by Bill Gates, before "
+"invented Windows."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/GatesPancake.html:8
+msgid ""
+"The basic idea is to grow sequences of sorted pancakes, not necessarily "
+"starting from the bottom.  We say that a sequence of ordered pancakes "
+"constitute a <b>bloc</b> while a pancake that is not part of a bloc is said "
+"to be <b>free</b>. The algorithm then considers the topmost pancake (of "
+"radius <code>t</code>) and search for the <code>t+1</code> or "
+"<code>t-1</code> pancakes (the considered neighbor is noted "
+"<code>t+o</code>). Eight cases may happen:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:15
+msgid ""
+"<b>Case a</b>: Both <code>t</code> and <code>t+o</code> are free. They are "
+"then merged in one flip."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:19
+msgid ""
+"<b>Case b</b>: <code>t</code> is free, and <code>t+o</code> is the first of "
+"a block. They are merged in one flip."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:24
+msgid ""
+"<b>Case c</b>: <code>t</code> is free but both <code>t-1</code> and "
+"<code>t+1</code> are the last elements of blocks.  Both blocs and "
+"<code>t</code> are merged all together in 4 flips.  Beware, if either "
+"<code>t-1</code> or <code>t+1</code> does not exist (because <code>t</code> "
+"is 0 or max), only two flips are mandated."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:32
+msgid ""
+"<b>Case d</b>: <code>t</code> is in a block but <code>t+o</code> is "
+"free. They are merged in one flip."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:37
+msgid ""
+"<b>Case e</b>: <code>t</code> is in a block and <code>t+o</code> is the "
+"first element of a block. They are merged in one flip."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:41
+msgid ""
+"<b>Case f</b>: <code>t</code> is in a block and <code>t+o</code> is the last "
+"element of another block.  They are merged in 3 flips as follows."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:45
+msgid ""
+"<b>Case g</b>: <code>t</code> is in a block of length k+1 (the last element "
+"is <code>t+ko</code>), <code>t+(k+1)o</code> is either free or the last "
+"element of another block. Both blocks are merged in 2 flips:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:48
+msgid ""
+"<b>Case h</b>: <code>t</code> is in a block of length k+1 (the last element "
+"is <code>t+ko</code>), <code>t+(k+1)o</code> is the first element of another "
+"block (the difference with case g is that <code>t+(k+1)o</code> is now the "
+"<i>first</i> element of its block). Both blocks are merged in 2 flips:"
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/pancake/GatesPancake.html:54
+msgid ""
+"<b>Case i</b>: <code>t</code> is in a block of length <code>n</code> (this "
+"block contains all pancakes).  If <code>t</code> is not 1, the whole stack "
+"is fliped. The algorithm then stops."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/GatesPancake.html:57
+msgid ""
+"Each iteration increases the size of the blocks, so the algorithm eventually "
+"halts in all cases. A finer analysis would show that it takes at most "
+"<code>(5n+5)/3</code> steps to sort the stack. That's better than the naïve "
+"algorithm, that requires 2n-3 steps."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/pancake/GatesPancake.html:60
+msgid "Your turn"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/GatesPancake.html:61
+msgid ""
+"You now have almost enough information to implement this algorithm on your "
+"own. We just have to remove the last remaining ambiguities to ensure that "
+"you implement exactly the same algorithm that the correction. If several "
+"cases apply to your situation, then you should use the first given one. For "
+"example, if both cases a and b apply (e.g., with <code>t-1</code> on case "
+"<b>a</b> and <code>t+1</code> on case <b>b</b>), then you should apply the "
+"flips of case <b>a</b>. If a given case applies for both <code>t+1</code> "
+"and <code>t-1</code>, then you should apply it to <code>t+1</code>."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/pancake/GatesPancake.html:67
+msgid ""
+"Note that it is somehow harder than the other exercises we did so far, so "
+"don't be surprised if you need more time to achieve this.  But do not give "
+"hope, you can do it!"
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><div>
+#: src/lessons/sort/pancake/GatesPancake.html:70
+msgid "Well, I need some help to start."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/GatesPancake.html:71
+msgid ""
+"First write some helper functions such as <code>isFirst()</code> or "
+"<code>isFree()</code>. This will simplify your main algorithm afterward, "
+"that can be written very similarly to the explication above with a bunch of "
+"if conditions. Factorizing code this way often helps making your code more "
+"readable."
+msgstr ""
+
+#. type: Attribute 'alt' of: <p><div>
+#: src/lessons/sort/pancake/GatesPancake.html:78
+msgid "My code keeps failing and I don't know how to debug it."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/GatesPancake.html:79
+msgid ""
+"To debug one world after the other and avoid that the messages of all worlds "
+"get intermixed, you can write your debug function only if the method "
+"<code>isSelected()</code> returns true. It will be so only for the entity "
+"that is currently selected in the graphical interface, that is probably the "
+"world you are currently debugging. This will help breaking the difficulty in "
+"parts by debugging the situation on after the other."
+msgstr ""
+
+#. type: Content of: <p><div>
+#: src/lessons/sort/pancake/GatesPancake.html:85
+msgid ""
+"In particular, it may help to print textually the state of the world each "
+"time you enter the main loop."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/Main.html:1
+msgid "The Rainbow Baseball Game"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/Main.html:3
+msgid ""
+"This activity is inspired from the orange game, from the \"Computer Science "
+"Unplugged\" activities repository.  It was however heavily since then, first "
+"for the CSIRL (my repository of <i>free</i> unplugged activities to "
+"introduce computer science, available at "
+"http://www.loria.fr/~quinson/Mediation/SMN/) and now for PLM."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/Main.html:7
+msgid ""
+"In the literature, the generalized form of this problem is known as the "
+"pebble motion problem (the bases can be connected by any kind of graph, and "
+"the affinity of pebbles with bases may be different). Another variant of "
+"this problem is the well known 15-puzzle, with one player per base, and a "
+"two dimensional square grid. Much more information about these problems can "
+"be found on wikipedia, as usual."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/sort/baseball/Main.html:12
+msgid ""
+"How do you know that the naive algorithm won't loop on that initial "
+"situation?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/Main.html:14
+msgid ""
+"Well, we simply tested all possible situations to see when this algorithm "
+"loops and when it finds the correct solution. We found that it works for all "
+"situations where no player is at home (there is 84 such situations for 4 "
+"bases, once you take the symmetries into account). It obviously works for "
+"some situations that do not respect this criteria (such as all situations it "
+"encounters from one of those 84 boards to the final state), but that's "
+"another story. Having such a criteria allows us to generate pseudo-random "
+"initial situations for the first exercise for which the algorithm we propose "
+"is guarenteed to work."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/Main.html:21
+msgid ""
+"We also explored bigger instances of the problem, and unfortunately, we have "
+"no such criteria for them.  With 5 bases, the algorithm wrongly loops for 24 "
+"of the 1824 possible boards where no player is home (that's 1.31%).  With 6 "
+"bases, it fails on 1251 of the 58860 such boards (2.12%). With 7 bases, it "
+"fails for 84444 out of 2633940 (that's 3.2%). I am still looking for a "
+"criteria ensuring that the algorithm won't loop. If you discover one, please "
+"report it. Ideally, it would be simple to enforce manually so that we can "
+"use it during our unplugged activities."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/baseball/Main.html:31
+msgid ""
+"Other graphical representations could be proposed, such as a linear one (for "
+"the existing exercises) or other ones (such as a grid or a tree, if an "
+"exercise on this kind of graph proves interesting)."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/sort/baseball/Main.html:33
+msgid ""
+"Other exercises on other algorithms on this variant, or on other variants "
+"such as the 15-puzzle."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/sort/baseball/short_desc.html:1
+msgid "Rainbow baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/short_desc.html:3
+msgid ""
+"This is another funny variation on the sorting problem, adapting the main "
+"sorting algorithms on an unusual context."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:1
+msgid "Rainbow Baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:2
+msgid ""
+"The colors are represented by integers, between <code>0</code> and "
+"<code>amount of bases -1</code>.  The hole is represented by the special "
+"value <code>-1</code>.  The color of each base is its rank. So base "
+"<code>1</code> is of color <code>1</code>.  In the graphical interface, the "
+"base <code>0</code> is the dark blue one while the base <code>1</code> is "
+"the fuscia one."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:8
+msgid ""
+"Once every players on the field are in their home base, the hole should be "
+"in the last base, that is of rank <code>getBasesAmount()-1</code>."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:11
+msgid "Functions to retrieve the world's dimensions"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:13
+#, no-wrap
+msgid "[!java]int [/!]getBasesAmount() [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:14
+msgid "Returns the amount of bases on this field."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:16
+#, no-wrap
+msgid "[!java]int [/!]getPositionsAmount() [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:17
+msgid "Returns the amount of player's positions per base on this field."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:19
+msgid "Functions to retrieve the world's state"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:21
+#, no-wrap
+msgid "[!java]int [/!]getHoleBase() [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:22
+msgid "Returns the base in which the hole is located."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:24
+#, no-wrap
+msgid "[!java]int [/!]getHolePosition() [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:25
+msgid "Returns the hole position within its base"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:27
+#, no-wrap
+msgid ""
+"[!java]int [/!]getPlayerColor([!java]int [/!]base[!scala]:Int[/!], "
+"[!java]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:28
+msgid "Returns the color of the player at a given location."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:30
+#, no-wrap
+msgid "[!java]boolean [/!]isSorted()  [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:31
+msgid "Returns whether all players of the field are at home."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:33
+#, no-wrap
+msgid "[!java]boolean [/!]isBaseSorted([!java]int [/!]base)  [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:34
+msgid "Returns whether all players of a given base are at home."
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:36
+#, no-wrap
+msgid "[!java]boolean [/!]isSelected()  [!scala]:Boolean[/!]"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:37
+msgid "Returns whether the current world is selected in the interface."
+msgstr ""
+
+#. type: Content of: <h2>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:38
+msgid "Functions to change the world"
+msgstr ""
+
+#. type: Content of: <pre>
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:40
+#, no-wrap
+msgid ""
+"[!java]void [/!]move([!java]int [/!]base[!scala]:Int[/!], [!java]int "
+"[/!]position[!scala]:Int[/!])"
+msgstr ""
+
+#. type: Content of: outside any tag (error?)
+#: src/lessons/sort/baseball/universe/BaseballWorld.html:41
+msgid ""
+"Moves a given player into the hole. This throws an IllegalArgumentException "
+"if the specified player is not near the hole (at most one base away)."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/NaiveBaseball.html:1
+msgid "Naive Rainbow Baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:3
+msgid ""
+"Today, the buggles decided to play a baseball game, but they are rather out "
+"of luck, actually.  First, kinda forgot the rules, and ... well ... they "
+"cannot find the ball and bats again.  So they decided to \"adapt a bit\" the "
+"rules. As the are no ball, the buggles can only running around the field, "
+"what they do happily: for a while, all attending buggle run at full speed in "
+"all directions around the field."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:9
+msgid ""
+"But after a few collisions, they decide to invent new rules to organize a "
+"bit the game: They make one team per base and two players per team. One of "
+"the teams has only one player so that its base has an empty location. Then, "
+"the players are dispatched randomly around the bases, and the game for them "
+"is to reach their home base. The whole game stops when all players are "
+"home.  There is no winning team: either all players win, or they all "
+"lose. Actually, this game is very different from the original baseball. The "
+"only rule that remains is that you can only run around the field, from one "
+"base to the next one, without crossing middle of the field."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:17
+msgid ""
+"Now, they are asking you to help them deciding who and when should move so "
+"that each player returns to its base. Only one buggle can move at each "
+"round, from its position to the empty spot.  The maximal distance that a "
+"buggle can cover in one round is of one base."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:21
+msgid ""
+"So, at each round, the empty spot is on one base (say <code>B</code>), and "
+"you should decide which buggle enters that empty spot. There is four "
+"candidates (two from base <code>B-1</code> and two from base "
+"<code>B+1</code>). Actually, there is a fifth candidate since the buggle "
+"that is on the same base than the empty spot can change its position, but "
+"that's not really helping."
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/sort/baseball/NaiveBaseball.html:26
+msgid "The Naïve algorithm"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:28
+msgid ""
+"In this exercise, we will first explore a very simple algorithm. To decide "
+"which of the four candidate buggles should enter the empty spot, we first "
+"restrict ourselves and decide that buggles can only turn clockwise. Then, "
+"from the two remaining candidates, we pick the one that has the largest "
+"distance to cover to reach its base (turning clockwise). Click on the demo "
+"button: this works rather well in practice."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:34
+msgid ""
+"It's hard to find a simpler algorithm for this problem: While it's not "
+"sorted, search for the base containing the candidate buggles: if the hole is "
+"in base <code>B</code>, it's the base <code>B+1</code>, modulo the amount of "
+"bases. Then, compute the distance that each buggle of that base still has to "
+"run to reach its base (0 if it's already home). Once you found the buggle "
+"that should enter the empty spot, just use the <code>move</code> method on "
+"it, and iterate."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/NaiveBaseball.html:40
+msgid ""
+"The main difficulty should be to get the few equations right: determining "
+"the base next to the hole should be easy, but determining the distance that "
+"a player has to cover may reveal a bit more challenging. Don't hesitate to "
+"draw pictures on a paper to cover all possible cases. It should not be that "
+"difficult either: there is not that many cases after all."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/SelectBaseball.html:1
+msgid "Selection Baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:3
+msgid ""
+"The previous algorithm is very pleasant: it's rather simple and rather fast "
+"to implement, but unfortunately, it is also rather wrong! In some cases, it "
+"never stops, which is obviously bad. If you don't believe it, just copy "
+"paste your previous code, and hit the run button. The first world of this "
+"exercise is one of these unfortunate situations that drives our previous "
+"algorithm crazy."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:9
+msgid ""
+"So we have to find another algorithm, preferably one that works in all "
+"cases."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:11
+msgid ""
+"For that, the best solution is to start from a well known algorithm instead "
+"of trying to invent a new one from scratch as we just did. When you think a "
+"bit about this problem, this can is very similar to a sorting problem: Just "
+"make sure that the players are sorted by their colors and you're set. And "
+"while we are at it, let's generalize the game to allow more that 4 bases."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:17
+msgid ""
+"Let's adapt the selection sort to our situation. The big lines of the "
+"algorithm is then \"for each base, select the players that should occupy "
+"this base and make sure that they come to their position\". This way, we "
+"will grow an sorted area where all players are already sorted (and never "
+"changed) while the unsorted area shrinks."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:23
+msgid ""
+"Selecting the player should be no problem; Do not hesitate to define some "
+"methods such as <code>findPlayer()</code> or "
+"<code>findPlayerBase()</code>. This will ensure that your code remains "
+"understandable."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:27
+msgid ""
+"The most problematic aspect is to move the selected players into "
+"position. For that, you have to move the hole to the position where the "
+"player is, and then move both the player and the hole to the base that is "
+"next to the player's goal (probably in a loop), and finally put the player "
+"in the right position of its target base."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/SelectBaseball.html:32
+msgid ""
+"As often in programming, the devil is in the details: there is a bunch of "
+"corner cases that you should detect and deal with correctly, such as the "
+"cases where the player is already in the base (but not in the position that "
+"you would like), or when the hole is on the right of the player (probably "
+"when you sort the first base). But you will find and hunt these while "
+"debugging your code."
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/InsertBaseball.html:1
+msgid "Insertion Baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:3
+msgid ""
+"The good point of adapting the selection sort to the baseball problem is "
+"that we know that it works (provided that our adaptation is correct). That's "
+"much better than the first naive algorithm, that was unable to converge to "
+"the solution in some situations. But actually, the selection sort is not "
+"perfect either as it requires a lot of swaps: we have to bring the hole to "
+"the selected player and then both the player and hole in position, and "
+"more. We can do better."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:9
+msgid ""
+"For example, each player can run quite a long way from its initial position "
+"to its target solution.  Instead, it may be more interesting to split the "
+"field in two parts: one on the left where all players are sorted relatively "
+"to each others, and one on the right where the players are still at their "
+"initial positions. Then, at each iteration, we take the player at the border "
+"between the sorted and unsorted areas (that is, the left-most player of the "
+"unsorted area) and move it to the left (within the sorted area) until it "
+"reaches its position (that is, until the position where it's bigger that its "
+"left neighbor). This would at least reduce the travel of players to the "
+"sorted area as we use the first one on the border."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:18
+msgid ""
+"Actually, that's exactly what an insertion sort would do: maintain a sorted "
+"area on the left, and put iteratively the player on the border to its "
+"position within the sorted area. This is good, as we know that our algorithm "
+"is not inherently flawed since we adapt a well known one."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:22
+msgid ""
+"The easiest to adapt the insertion sort to the baseball problem is to "
+"consider all positions as adjacent and forget about bases. For that, we "
+"define the methods <code>getColor(pos)</code>, <code>move(pos)</code> and "
+"<code>getHole()</code> that all use a unique integer to designate a given "
+"position. These functions simply convert between the way to specify a "
+"position and then call the usual functions to interact with the world. If "
+"you have an <code>index</code> and want to convert it into a "
+"<code>base,pos</code>, then <code>base=index/2</code> and "
+"<code>pos=index%2</code>. To compute the reverse, "
+"<code>index=base*2+pos</code> (this works because "
+"<code>getPositionsAmount()</code> always returns 2)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:31
+msgid ""
+"For the algorithm itself, you should first move the hole to the position "
+"1. The position 0 is considered to be the sorted area (of size 1 for now) "
+"while the area above 2 is the unsorted area.  Then comes an iteration to "
+"sort each element of the unsorted area. Since this iteration is a bit "
+"complex, you should think of its loop invariant, that is, the condition that "
+"is true before and after the loop and which explains that the loop fulfills "
+"its goal. Here, the loop invariant is twofold: First, the hole is between "
+"the sorted area and the unsorted area, and then, the every elements of the "
+"sorted area are ... well sorted relatively to their neighbors."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:39
+msgid ""
+"Then, the loop body to sort an element should first descend the hole and the "
+"elements within the sorted area until the element is larger than the element "
+"before in the sorted area (2 moves per position to travel), and then move "
+"the hole back to its position between the sorted and unsorted areas (1 move "
+"per position)."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/InsertBaseball.html:43
+msgid ""
+"Once you insert the last element within the sorted area, your whole set is "
+"sorted and you're done.  I preserve the surprise of the border cases that "
+"will require some little adjustments to your algorithm to make it work "
+"properly :)"
+msgstr ""
+
+#. type: Content of: <h1>
+#: src/lessons/sort/baseball/BubbleBaseball.html:1
+msgid "Bubble Baseball"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/BubbleBaseball.html:3
+msgid ""
+"Crap, we adapted the insertion sort because our selection sort required too "
+"much moves to get the selected players to their position, but the insertion "
+"sort requires an inordinate amount of changes to get the border elements to "
+"their position within the sorted area without mixing the already sorted "
+"elements. At the end of the day, our selection variant was more efficient "
+"with at most <code>3*amountOfBase</code> moves to sort one element (1 to get "
+"the hole alongside with the player, and 2 to get the hole+player in "
+"position) while our insertion variant requires at most "
+"<code>3*amountOfPlayers</code> to sort one element (2 to descend the hole "
+"and player in position, 1 to get the hole back to its position). That's "
+"twice as bad as there is two players per base. It may be possible to improve "
+"the insertion sort by moving by more than one element when descending, but "
+"it seems uneasy (at least, while not mixing the already sorted elements) and "
+"it would probably only ensure that our insertion variant becomes as "
+"efficient as our selection variant, not dramatically better."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/BubbleBaseball.html:15
+msgid ""
+"If we cannot make the sort faster, we can make it easier. If you think about "
+"it, it seems rather natural to adapt the bubble sort to this problem: the "
+"hole becomes the bubble that moves up and down, sorting a bit the array "
+"during each traversal. The big lines are simply: \"while it's not sorted, "
+"move the hole down to base 0 (moving the biggest player of each base at each "
+"step) and then back to the maximal base (moving the smallest player of each "
+"base)\". After a while, <code>isSorted()</code> will return true and your "
+"algorithm will stop."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/BubbleBaseball.html:21
+msgid ""
+"This is so easy that we introduce another variant of the problem, with more "
+"than two players per base.  But actually, that shouldn't block you very "
+"long, should it?"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/sort/baseball/BubbleBaseball.html:24
+msgid ""
+"Surprisingly, the bubble sort variant requires ways less moves than the "
+"other variants. This is astonishing because usually, the bubble sort "
+"performs much worse than the others sorts, but it comes from the very good "
+"match between its big lines and the baseball universe. It actually happens "
+"rather often that a pleasantly written algorithm performs very decently. But "
+"this is not an universal rule either, as demonstrated by the naive algorithm "
+"of the first exercise, that was nice, simple and wrong ;)"
+msgstr ""
+
+#. type: Content of: <h3>
+#: src/lessons/turtleart/Main.html:1 src/lessons/turtleart/short_desc.html:1
+msgid "Turtle Art"
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:3
+msgid ""
+"Since its inception in the 60's, the LOGO turtle fascinates by its ability "
+"to draw nice figures on computer.  This lesson allows you to explore some of "
+"the classical figures, and draw your own."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:6
+msgid ""
+"The language's syntax is absolutely not presented, but if you know a bit of "
+"it or if someone tells you, you can take these exercises even if you are an "
+"absolute beginner in programming."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/Main.html:9
+msgid ""
+"Please send us your best contributions so that they get added to this "
+"gallery to inspire the next ones."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:15
+msgid ""
+"When you don't want to follow the proposed exercises but draw your own "
+"stuff, the \"you failed\" message really gets annoying.  We should have a "
+"\"Creative mode\" in PLM, where the world is not checked against the "
+"answer.  Also, we should not clean the board automatically in this mode."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:18
+msgid ""
+"Other exercises should be added. A whole lot of exercises are available from "
+"http://neoparaiso.com/logo/#sect4."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:19
+msgid ""
+"Missing: the built-ins hide()/show(), that decide whether the turtle must be "
+"shown."
+msgstr ""
+
+#. type: Content of: <ul><li>
+#: src/lessons/turtleart/Main.html:20
+msgid ""
+"Missing: the built-ins arc() and arcTo(), that draw an arc, either w/o "
+"moving or by moving to the end of the arc."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/short_desc.html:2
+msgid ""
+"Draw beautiful figures with the Logo turtle, and learn programming while "
+"playing."
+msgstr ""
+
+#. type: Content of: <p>
+#: src/lessons/turtleart/short_desc.html:4
+msgid ""
+"You should know the basic syntax of the programming language you will "
+"choose, but no exhaustive programming practice is required to take this "
+"lesson."
+msgstr ""
diff --git a/lib/resources/jlm.configuration.properties b/lib/resources/jlm.configuration.properties
deleted file mode 100644
index b9bbe86..0000000
--- a/lib/resources/jlm.configuration.properties
+++ /dev/null
@@ -1,33 +0,0 @@
-#Sun, 04 Aug 2013 21:26:51 +0200
-# JLM default configuration
-jlm.major.version=2.0
-jlm.minor.version=20130804
-
-# This should be self explanatory, actually
-# Its value is automatically updated and saved in the personal property file
-jlm.programmingLanguage=Java
-
-# These are used for our XMPP chatting feature. We may want to kill it
-jlm.xmpp.hostname=jabber.org
-jlm.xmpp.port=5222
-jlm.xmpp.username=jlmlovers at jabber.org
-jlm.xmpp.password=jlmforever
-
-# Yeah, having the pass in clear text as is is a really bad thing
-jlm.identica.username=jlmlovers
-jlm.identica.password=jlmforever
-
-jlm.appengine.url=http\://jlmserver-chmod0.appspot.com
-
-# This is not documented, as it opens the door to teacher-only
-# features, one of them being to see the correction of any exercises.
-# Not very secure either, but JLM shouldn't be used for coercitive
-# exercises anyway.
-jlm.configuration.teacher=false
-
-# This is for twitter. This is not as bad as having the pass in clear
-# text as we have for identica, but this still feels somehow wrong
-jlm.oauth.consumerKey=ibVls7COiCHxwMd5NoFThQ
-jlm.oauth.consumerSecret=XLcE0kSWDKV4iojSs6KySl5iNFqaUBF1b0CuklmU
-jlm.oauth.accessToken=75057670-caayoZpQWVbVQl3da4js1cvpL906UM3JeoOiKhk
-jlm.oauth.tokenSecret=GgZGRA48c8ylWkwIkPWy9vTtEis7VL3xbtklpniTklM
diff --git a/lib/resources/plm.configuration.properties b/lib/resources/plm.configuration.properties
new file mode 100644
index 0000000..10fbaae
--- /dev/null
+++ b/lib/resources/plm.configuration.properties
@@ -0,0 +1,23 @@
+#Fri, 30 Aug 2013 15:10:56 +0200
+# PLM default configuration
+plm.major.version=2.2
+plm.minor.version=20130830
+
+# This should be self explanatory, actually
+# Its value is automatically updated and saved in the personal property file
+plm.programmingLanguage=Java
+
+plm.appengine.url=http\://jlmserver-chmod0.appspot.com
+
+# This is not documented, as it opens the door to teacher-only
+# features, one of them being to see the correction of any exercises.
+# Not very secure either, but PLM shouldn't be used for coercitive
+# exercises nor for evaluation anyway.
+plm.configuration.teacher=false
+
+# This is for twitter. This is not as bad as having the pass in clear
+# text, but this still feels somehow wrong...
+plm.oauth.consumerKey=ibVls7COiCHxwMd5NoFThQ
+plm.oauth.consumerSecret=XLcE0kSWDKV4iojSs6KySl5iNFqaUBF1b0CuklmU
+plm.oauth.accessToken=75057670-caayoZpQWVbVQl3da4js1cvpL906UM3JeoOiKhk
+plm.oauth.tokenSecret=GgZGRA48c8ylWkwIkPWy9vTtEis7VL3xbtklpniTklM
diff --git a/po4a.conf b/po4a.conf
index a9197db..473507d 100644
--- a/po4a.conf
+++ b/po4a.conf
@@ -1,61 +1,64 @@
 [po4a_langs] fr
-[po4a_paths] lib/l10n/jlm.pot $lang:lib/l10n/$lang.po
+[po4a_paths] lib/l10n/plm.pot $lang:lib/l10n/$lang.po
 
 [po4a_alias:html] xhtml opt:"-o ontagerror=fail -L UTF-8 -M UTF-8 -v -k 1"
 
 [type: html] lib/doc/MainWindow.html	$lang:lib/doc/MainWindow.$lang.html
 
-[type: html] src/jlm/universe/sort/SortingWorld.html	$lang:src/jlm/universe/sort/SortingWorld.$lang.html
-[type: html] src/jlm/universe/turtles/TurtleWorld.html	$lang:src/jlm/universe/turtles/TurtleWorld.$lang.html
-[type: html] src/jlm/universe/bugglequest/BuggleWorld.html	$lang:src/jlm/universe/bugglequest/BuggleWorld.$lang.html
+[type: html] src/plm/universe/sort/SortingWorld.html	$lang:src/plm/universe/sort/SortingWorld.$lang.html
+[type: html] src/plm/universe/turtles/TurtleWorld.html	$lang:src/plm/universe/turtles/TurtleWorld.$lang.html
+[type: html] src/plm/universe/bugglequest/BuggleWorld.html	$lang:src/plm/universe/bugglequest/BuggleWorld.$lang.html
 
 [type: html] src/lessons/backtracking/Main.html		$lang:src/lessons/backtracking/Main.$lang.html
 
 [type: html] src/lessons/chooser/LessonChooser.html     $lang:src/lessons/chooser/LessonChooser.$lang.html
-[type: html] src/lessons/chooser/Main.html     $lang:src/lessons/chooser/Main.$lang.html
-
-[type: html] src/lessons/welcome/Main.html			$lang:src/lessons/welcome/Main.$lang.html
-[type: html] src/lessons/welcome/short_desc.html		$lang:src/lessons/welcome/short_desc.$lang.html
-[type: html] src/lessons/welcome/environment/Environment.html	$lang:src/lessons/welcome/environment/Environment.$lang.html
-[type: html] src/lessons/welcome/basics/Basics.html		$lang:src/lessons/welcome/basics/Basics.$lang.html
-[type: html] src/lessons/welcome/basicsdrawg/BasicsDrawG.html	$lang:src/lessons/welcome/basicsdrawg/BasicsDrawG.$lang.html
-[type: html] src/lessons/welcome/conditions/Conditions.html	$lang:src/lessons/welcome/conditions/Conditions.$lang.html
-[type: html] src/lessons/welcome/baggleseeker/BaggleSeeker.html	$lang:src/lessons/welcome/baggleseeker/BaggleSeeker.$lang.html
-[type: html] src/lessons/welcome/variables/Variables.html	$lang:src/lessons/welcome/variables/Variables.$lang.html
-[type: html] src/lessons/welcome/variables/RunFour.html		$lang:src/lessons/welcome/variables/RunFour.$lang.html
-[type: html] src/lessons/welcome/variables/RunHalf.html		$lang:src/lessons/welcome/variables/RunHalf.$lang.html
-
-[type: html] src/lessons/welcome/loop/forloop/LoopFor.html		$lang:src/lessons/welcome/loop/forloop/LoopFor.$lang.html
-[type: html] src/lessons/welcome/loop/forloop/LoopStairs.html		$lang:src/lessons/welcome/loop/forloop/LoopStairs.$lang.html
-[type: html] src/lessons/welcome/loop/forloop/LoopCourse.html		$lang:src/lessons/welcome/loop/forloop/LoopCourse.$lang.html
-[type: html] src/lessons/welcome/loop/forloop/LoopCourseForest.html	$lang:src/lessons/welcome/loop/forloop/LoopCourseForest.$lang.html
-[type: html] src/lessons/welcome/loop/whileloop/LoopWhile.html		$lang:src/lessons/welcome/loop/whileloop/LoopWhile.$lang.html
-[type: html] src/lessons/welcome/loop/whileloop/WhileMoria.html		$lang:src/lessons/welcome/loop/whileloop/WhileMoria.$lang.html
-[type: html] src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html	$lang:src/lessons/welcome/loop/dowhileloop/LoopDoWhile.$lang.html
-[type: html] src/lessons/welcome/loop/dowhileloop/Poucet.html		$lang:src/lessons/welcome/loop/dowhileloop/Poucet.$lang.html
+[type: html] src/lessons/chooser/Main.html     		$lang:src/lessons/chooser/Main.$lang.html
+
+[type: html] src/lessons/welcome/Main.html				$lang:src/lessons/welcome/Main.$lang.html
+[type: html] src/lessons/welcome/short_desc.html			$lang:src/lessons/welcome/short_desc.$lang.html
+[type: html] src/lessons/welcome/environment/Environment.html		$lang:src/lessons/welcome/environment/Environment.$lang.html
+[type: html] src/lessons/welcome/instructions/Instructions.html		$lang:src/lessons/welcome/instructions/Instructions.$lang.html
+[type: html] src/lessons/welcome/instructions/InstructionsDrawG.html	$lang:src/lessons/welcome/instructions/InstructionsDrawG.$lang.html
+[type: html] src/lessons/welcome/conditions/Conditions.html		$lang:src/lessons/welcome/conditions/Conditions.$lang.html
+[type: html] src/lessons/welcome/loopwhile/LoopWhile.html		$lang:src/lessons/welcome/loopwhile/LoopWhile.$lang.html
+[type: html] src/lessons/welcome/loopwhile/BaggleSeeker.html		$lang:src/lessons/welcome/loopwhile/BaggleSeeker.$lang.html
+[type: html] src/lessons/welcome/loopwhile/WhileMoria.html		$lang:src/lessons/welcome/loopwhile/WhileMoria.$lang.html
+[type: html] src/lessons/welcome/variables/Variables.html		$lang:src/lessons/welcome/variables/Variables.$lang.html
+[type: html] src/lessons/welcome/variables/RunFour.html			$lang:src/lessons/welcome/variables/RunFour.$lang.html
+[type: html] src/lessons/welcome/variables/RunHalf.html			$lang:src/lessons/welcome/variables/RunHalf.$lang.html
+
+[type: html] src/lessons/welcome/loopfor/LoopFor.html		$lang:src/lessons/welcome/loopfor/LoopFor.$lang.html
+[type: html] src/lessons/welcome/loopfor/LoopStairs.html	$lang:src/lessons/welcome/loopfor/LoopStairs.$lang.html
+[type: html] src/lessons/welcome/loopfor/LoopCourse.html	$lang:src/lessons/welcome/loopfor/LoopCourse.$lang.html
+[type: html] src/lessons/welcome/loopfor/LoopCourseForest.html	$lang:src/lessons/welcome/loopfor/LoopCourseForest.$lang.html
+[type: html] src/lessons/welcome/loopdowhile/LoopDoWhile.html	$lang:src/lessons/welcome/loopdowhile/LoopDoWhile.$lang.html
+[type: html] src/lessons/welcome/loopdowhile/Poucet.html	$lang:src/lessons/welcome/loopdowhile/Poucet.$lang.html
 
 [type: html] src/lessons/welcome/methods/basics/Methods.html		$lang:src/lessons/welcome/methods/basics/Methods.$lang.html
-[type: html] src/lessons/welcome/methods/doghouse/MethodsDogHouse.html	$lang:src/lessons/welcome/methods/doghouse/MethodsDogHouse.$lang.html
+[type: html] src/lessons/welcome/methods/basics/MethodsDogHouse.html	$lang:src/lessons/welcome/methods/basics/MethodsDogHouse.$lang.html
+[type: html] src/lessons/welcome/methods/picture/PictureMono.html	$lang:src/lessons/welcome/methods/picture/PictureMono.$lang.html
+[type: html] src/lessons/welcome/methods/picture/PictureMono2.html	$lang:src/lessons/welcome/methods/picture/PictureMono2.$lang.html
+[type: html] src/lessons/welcome/methods/picture/PictureMono3.html	$lang:src/lessons/welcome/methods/picture/PictureMono3.$lang.html
 [type: html] src/lessons/welcome/methods/returning/MethodsReturning.html	$lang:src/lessons/welcome/methods/returning/MethodsReturning.$lang.html
 [type: html] src/lessons/welcome/methods/args/MethodsArgs.html	$lang:src/lessons/welcome/methods/args/MethodsArgs.$lang.html
-[type: html] src/lessons/welcome/methods/picture/MethodsPicture.html	$lang:src/lessons/welcome/methods/picture/MethodsPicture.$lang.html
-[type: html] src/lessons/welcome/methods/picture2/MethodsPicture2.html	$lang:src/lessons/welcome/methods/picture2/MethodsPicture2.$lang.html
-[type: html] src/lessons/welcome/methods/picture3/MethodsPicture3.html	$lang:src/lessons/welcome/methods/picture3/MethodsPicture3.$lang.html
-[type: html] src/lessons/welcome/methods/picture4/MethodsPicture4.html	$lang:src/lessons/welcome/methods/picture4/MethodsPicture4.$lang.html
+
+[type: html] src/lessons/welcome/methods/flowerpot/FlowerPot.html	$lang:src/lessons/welcome/methods/flowerpot/FlowerPot.$lang.html
+[type: html] src/lessons/welcome/methods/flowerpot/FlowerCase.html	$lang:src/lessons/welcome/methods/flowerpot/FlowerCase.$lang.html
+[type: html] src/lessons/welcome/methods/picture/MethodsPicture.html   $lang:src/lessons/welcome/methods/picture/MethodsPicture.$lang.html
+[type: html] src/lessons/welcome/methods/picture/MethodsPictureLarge.html	$lang:src/lessons/welcome/methods/picture/MethodsPictureLarge.$lang.html
+[type: html] src/lessons/welcome/methods/picture/PatternPicture.html	$lang:src/lessons/welcome/methods/picture/PatternPicture.$lang.html
+[type: html] src/lessons/welcome/methods/slug/SlugHunting.html	$lang:src/lessons/welcome/methods/slug/SlugHunting.$lang.html
+[type: html] src/lessons/welcome/methods/slug/SlugTracking.html	$lang:src/lessons/welcome/methods/slug/SlugTracking.$lang.html
+[type: html] src/lessons/welcome/methods/slug/SlugSnail.html	$lang:src/lessons/welcome/methods/slug/SlugSnail.$lang.html
 
 [type: html] src/lessons/welcome/bdr/BDR.html		$lang:src/lessons/welcome/bdr/BDR.$lang.html
 [type: html] src/lessons/welcome/bdr/BDR2.html		$lang:src/lessons/welcome/bdr/BDR2.$lang.html
 
-[type: html] src/lessons/welcome/slug/SlugHunting.html	$lang:src/lessons/welcome/slug/SlugHunting.$lang.html
-[type: html] src/lessons/welcome/slug/SlugTracking.html	$lang:src/lessons/welcome/slug/SlugTracking.$lang.html
-[type: html] src/lessons/welcome/slug/SlugSnail.html	$lang:src/lessons/welcome/slug/SlugSnail.$lang.html
-
-[type: html] src/lessons/welcome/snake/Snake.html		$lang:src/lessons/welcome/snake/Snake.$lang.html
-
+[type: html] src/lessons/welcome/traversal/Snake.html				$lang:src/lessons/welcome/traversal/Snake.$lang.html
 [type: html] src/lessons/welcome/traversal/column/TraversalByColumn.html	$lang:src/lessons/welcome/traversal/column/TraversalByColumn.$lang.html
-[type: html] src/lessons/welcome/traversal/line/TraversalByLine.html	$lang:src/lessons/welcome/traversal/line/TraversalByLine.$lang.html
+[type: html] src/lessons/welcome/traversal/line/TraversalByLine.html		$lang:src/lessons/welcome/traversal/line/TraversalByLine.$lang.html
 [type: html] src/lessons/welcome/traversal/diagonal/TraversalDiagonal.html	$lang:src/lessons/welcome/traversal/diagonal/TraversalDiagonal.$lang.html
-[type: html] src/lessons/welcome/traversal/zigzag/TraversalZigZag.html	$lang:src/lessons/welcome/traversal/zigzag/TraversalZigZag.$lang.html
+[type: html] src/lessons/welcome/traversal/zigzag/TraversalZigZag.html		$lang:src/lessons/welcome/traversal/zigzag/TraversalZigZag.$lang.html
 
 [type: html] src/lessons/turmites/Main.html        			$lang:src/lessons/turmites/Main.$lang.html
 [type: html] src/lessons/turmites/short_desc.html        		$lang:src/lessons/turmites/short_desc.$lang.html
@@ -82,7 +85,7 @@
 
 [type: html] src/lessons/recursion/Main.html			$lang:src/lessons/recursion/Main.$lang.html
 [type: html] src/lessons/recursion/short_desc.html		$lang:src/lessons/recursion/short_desc.$lang.html
-[type: html] src/lessons/recursion/square/Square.html		$lang:src/lessons/recursion/square/Square.$lang.html
+[type: html] src/lessons/recursion/square/FourSquare.html		$lang:src/lessons/recursion/square/FourSquare.$lang.html
 [type: html] src/lessons/recursion/polygonfractal/PolygonFractal.html	$lang:src/lessons/recursion/polygonfractal/PolygonFractal.$lang.html
 [type: html] src/lessons/recursion/koch/Koch.html		$lang:src/lessons/recursion/koch/Koch.$lang.html
 [type: html] src/lessons/recursion/star/Star.html		$lang:src/lessons/recursion/star/Star.$lang.html
@@ -108,7 +111,7 @@
 [type: html] src/lessons/maze/shortestpath/ShortestPathMaze.html		$lang:src/lessons/maze/shortestpath/ShortestPathMaze.$lang.html
 [type: html] src/lessons/maze/wallfindfollow/WallFindFollowMaze.html		$lang:src/lessons/maze/wallfindfollow/WallFindFollowMaze.$lang.html
 
-[type: html] src/jlm/universe/lightbot/LightBotWorld.html $lang:src/jlm/universe/lightbot/LightBotWorld.$lang.html
+[type: html] src/plm/universe/lightbot/LightBotWorld.html $lang:src/plm/universe/lightbot/LightBotWorld.$lang.html
 [type: html] src/lessons/lightbot/Main.html		  $lang:src/lessons/lightbot/Main.$lang.html
 [type: html] src/lessons/lightbot/short_desc.html	  $lang:src/lessons/lightbot/short_desc.$lang.html
 [type: html] src/lessons/lightbot/Board01TwoSteps.html	  $lang:src/lessons/lightbot/Board01TwoSteps.$lang.html
@@ -124,50 +127,50 @@
 [type: html] src/lessons/lightbot/Board11Sea.html	  $lang:src/lessons/lightbot/Board11Sea.$lang.html
 [type: html] src/lessons/lightbot/Board12Escher.html	  $lang:src/lessons/lightbot/Board12Escher.$lang.html
 
-[type: html] src/lessons/welcome/bool1/Close10.html         $lang:src/lessons/welcome/bool1/Close10.$lang.html
-[type: html] src/lessons/welcome/bool1/CountTeen.html       $lang:src/lessons/welcome/bool1/CountTeen.$lang.html
-[type: html] src/lessons/welcome/bool1/Diff21.html          $lang:src/lessons/welcome/bool1/Diff21.$lang.html
-[type: html] src/lessons/welcome/bool1/HasTeen.html         $lang:src/lessons/welcome/bool1/HasTeen.$lang.html
-[type: html] src/lessons/welcome/bool1/IcyHot.html          $lang:src/lessons/welcome/bool1/IcyHot.$lang.html
-[type: html] src/lessons/welcome/bool1/In1020.html          $lang:src/lessons/welcome/bool1/In1020.$lang.html
-[type: html] src/lessons/welcome/bool1/In3050.html          $lang:src/lessons/welcome/bool1/In3050.$lang.html
-[type: html] src/lessons/welcome/bool1/LastDigit.html       $lang:src/lessons/welcome/bool1/LastDigit.$lang.html
-[type: html] src/lessons/welcome/bool1/LoneTeen.html        $lang:src/lessons/welcome/bool1/LoneTeen.$lang.html
-[type: html] src/lessons/welcome/bool1/Main.html            $lang:src/lessons/welcome/bool1/Main.$lang.html
-[type: html] src/lessons/welcome/bool1/Makes10.html         $lang:src/lessons/welcome/bool1/Makes10.$lang.html
-[type: html] src/lessons/welcome/bool1/Max1020.html         $lang:src/lessons/welcome/bool1/Max1020.$lang.html
-[type: html] src/lessons/welcome/bool1/MonkeyTrouble.html   $lang:src/lessons/welcome/bool1/MonkeyTrouble.$lang.html
-[type: html] src/lessons/welcome/bool1/NearHundred.html     $lang:src/lessons/welcome/bool1/NearHundred.$lang.html
-[type: html] src/lessons/welcome/bool1/ParotTrouble.html    $lang:src/lessons/welcome/bool1/ParotTrouble.$lang.html
-[type: html] src/lessons/welcome/bool1/PosNeg.html          $lang:src/lessons/welcome/bool1/PosNeg.$lang.html
-[type: html] src/lessons/welcome/bool1/SleepIn.html         $lang:src/lessons/welcome/bool1/SleepIn.$lang.html
-[type: html] src/lessons/welcome/bool1/SumDouble.html       $lang:src/lessons/welcome/bool1/SumDouble.$lang.html
-
-[type: html] src/lessons/welcome/bool2/AlarmClock.html      $lang:src/lessons/welcome/bool2/AlarmClock.$lang.html
-[type: html] src/lessons/welcome/bool2/AnswerCell.html      $lang:src/lessons/welcome/bool2/AnswerCell.$lang.html
-[type: html] src/lessons/welcome/bool2/BlueTicket.html      $lang:src/lessons/welcome/bool2/BlueTicket.$lang.html
-[type: html] src/lessons/welcome/bool2/CaughtSpeeding.html  $lang:src/lessons/welcome/bool2/CaughtSpeeding.$lang.html
-[type: html] src/lessons/welcome/bool2/CigarParty.html      $lang:src/lessons/welcome/bool2/CigarParty.$lang.html
-[type: html] src/lessons/welcome/bool2/DateFashion.html     $lang:src/lessons/welcome/bool2/DateFashion.$lang.html
-[type: html] src/lessons/welcome/bool2/GreenTicket.html     $lang:src/lessons/welcome/bool2/GreenTicket.$lang.html
-[type: html] src/lessons/welcome/bool2/In1To10.html         $lang:src/lessons/welcome/bool2/In1To10.$lang.html
-[type: html] src/lessons/welcome/bool2/InOrderEqual.html    $lang:src/lessons/welcome/bool2/InOrderEqual.$lang.html
-[type: html] src/lessons/welcome/bool2/InOrder.html         $lang:src/lessons/welcome/bool2/InOrder.$lang.html
-[type: html] src/lessons/welcome/bool2/LastDigit2.html      $lang:src/lessons/welcome/bool2/LastDigit2.$lang.html
-[type: html] src/lessons/welcome/bool2/LessBy10.html        $lang:src/lessons/welcome/bool2/LessBy10.$lang.html
-[type: html] src/lessons/welcome/bool2/Main.html            $lang:src/lessons/welcome/bool2/Main.$lang.html
-[type: html] src/lessons/welcome/bool2/MaxMod5.html         $lang:src/lessons/welcome/bool2/MaxMod5.$lang.html
-[type: html] src/lessons/welcome/bool2/NearTen.html         $lang:src/lessons/welcome/bool2/NearTen.$lang.html
-[type: html] src/lessons/welcome/bool2/RedTicket.html       $lang:src/lessons/welcome/bool2/RedTicket.$lang.html
-[type: html] src/lessons/welcome/bool2/ShareDigit.html      $lang:src/lessons/welcome/bool2/ShareDigit.$lang.html
-[type: html] src/lessons/welcome/bool2/SortaSum.html        $lang:src/lessons/welcome/bool2/SortaSum.$lang.html
-[type: html] src/lessons/welcome/bool2/SquirrelPlay.html    $lang:src/lessons/welcome/bool2/SquirrelPlay.$lang.html
-[type: html] src/lessons/welcome/bool2/TeaParty.html        $lang:src/lessons/welcome/bool2/TeaParty.$lang.html
-[type: html] src/lessons/welcome/bool2/TeenSum.html         $lang:src/lessons/welcome/bool2/TeenSum.$lang.html
-[type: html] src/lessons/welcome/bool2/TwoAsOne.html        $lang:src/lessons/welcome/bool2/TwoAsOne.$lang.html
-[type: html] src/lessons/welcome/bool2/WithoutDoubles.html  $lang:src/lessons/welcome/bool2/WithoutDoubles.$lang.html
-
-[type: html] src/jlm/universe/bat/BatWorld.html			$lang:src/jlm/universe/bat/BatWorld.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/Close10.html         $lang:src/lessons/welcome/bat/bool1/Close10.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/CountTeen.html       $lang:src/lessons/welcome/bat/bool1/CountTeen.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/Diff21.html          $lang:src/lessons/welcome/bat/bool1/Diff21.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/HasTeen.html         $lang:src/lessons/welcome/bat/bool1/HasTeen.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/IcyHot.html          $lang:src/lessons/welcome/bat/bool1/IcyHot.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/In1020.html          $lang:src/lessons/welcome/bat/bool1/In1020.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/In3050.html          $lang:src/lessons/welcome/bat/bool1/In3050.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/LastDigit.html       $lang:src/lessons/welcome/bat/bool1/LastDigit.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/LoneTeen.html        $lang:src/lessons/welcome/bat/bool1/LoneTeen.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/Main.html            $lang:src/lessons/welcome/bat/bool1/Main.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/Makes10.html         $lang:src/lessons/welcome/bat/bool1/Makes10.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/Max1020.html         $lang:src/lessons/welcome/bat/bool1/Max1020.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/MonkeyTrouble.html   $lang:src/lessons/welcome/bat/bool1/MonkeyTrouble.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/NearHundred.html     $lang:src/lessons/welcome/bat/bool1/NearHundred.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/ParotTrouble.html    $lang:src/lessons/welcome/bat/bool1/ParotTrouble.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/PosNeg.html          $lang:src/lessons/welcome/bat/bool1/PosNeg.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/SleepIn.html         $lang:src/lessons/welcome/bat/bool1/SleepIn.$lang.html
+[type: html] src/lessons/welcome/bat/bool1/SumDouble.html       $lang:src/lessons/welcome/bat/bool1/SumDouble.$lang.html
+
+[type: html] src/lessons/welcome/bat/bool2/AlarmClock.html      $lang:src/lessons/welcome/bat/bool2/AlarmClock.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/AnswerCell.html      $lang:src/lessons/welcome/bat/bool2/AnswerCell.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/BlueTicket.html      $lang:src/lessons/welcome/bat/bool2/BlueTicket.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/CaughtSpeeding.html  $lang:src/lessons/welcome/bat/bool2/CaughtSpeeding.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/CigarParty.html      $lang:src/lessons/welcome/bat/bool2/CigarParty.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/DateFashion.html     $lang:src/lessons/welcome/bat/bool2/DateFashion.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/GreenTicket.html     $lang:src/lessons/welcome/bat/bool2/GreenTicket.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/In1To10.html         $lang:src/lessons/welcome/bat/bool2/In1To10.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/InOrderEqual.html    $lang:src/lessons/welcome/bat/bool2/InOrderEqual.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/InOrder.html         $lang:src/lessons/welcome/bat/bool2/InOrder.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/LastDigit2.html      $lang:src/lessons/welcome/bat/bool2/LastDigit2.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/LessBy10.html        $lang:src/lessons/welcome/bat/bool2/LessBy10.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/Main.html            $lang:src/lessons/welcome/bat/bool2/Main.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/MaxMod5.html         $lang:src/lessons/welcome/bat/bool2/MaxMod5.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/NearTen.html         $lang:src/lessons/welcome/bat/bool2/NearTen.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/RedTicket.html       $lang:src/lessons/welcome/bat/bool2/RedTicket.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/ShareDigit.html      $lang:src/lessons/welcome/bat/bool2/ShareDigit.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/SortaSum.html        $lang:src/lessons/welcome/bat/bool2/SortaSum.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/SquirrelPlay.html    $lang:src/lessons/welcome/bat/bool2/SquirrelPlay.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/TeaParty.html        $lang:src/lessons/welcome/bat/bool2/TeaParty.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/TeenSum.html         $lang:src/lessons/welcome/bat/bool2/TeenSum.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/TwoAsOne.html        $lang:src/lessons/welcome/bat/bool2/TwoAsOne.$lang.html
+[type: html] src/lessons/welcome/bat/bool2/WithoutDoubles.html  $lang:src/lessons/welcome/bat/bool2/WithoutDoubles.$lang.html
+
+[type: html] src/plm/universe/bat/BatWorld.html			$lang:src/plm/universe/bat/BatWorld.$lang.html
 
 [type: html] src/lessons/bat/string1/Main.html          $lang:src/lessons/bat/string1/Main.$lang.html
 [type: html] src/lessons/bat/string1/short_desc.html    $lang:src/lessons/bat/string1/short_desc.$lang.html
@@ -181,7 +184,7 @@
 [type: html] src/lessons/bat/string1/StringX.html       $lang:src/lessons/bat/string1/StringX.$lang.html
 [type: html] src/lessons/bat/string1/StringYak.html     $lang:src/lessons/bat/string1/StringYak.$lang.html
 
-[type: html] src/lessons/welcome/array/basics/Array.html		$lang:src/lessons/welcome/array/basics/Array.$lang.html
+[type: html] src/lessons/welcome/array/basics/Array1.html		$lang:src/lessons/welcome/array/basics/Array1.$lang.html
 [type: html] src/lessons/welcome/array/basics/Array2.html		$lang:src/lessons/welcome/array/basics/Array2.$lang.html
 [type: html] src/lessons/welcome/array/indexof/value/IndexOfValue.html $lang:src/lessons/welcome/array/indexof/value/IndexOfValue.$lang.html
 [type: html] src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.html $lang:src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.$lang.html
@@ -209,3 +212,6 @@
 [type: html] src/lessons/sort/baseball/SelectBaseball.html		$lang:src/lessons/sort/baseball/SelectBaseball.$lang.html
 [type: html] src/lessons/sort/baseball/InsertBaseball.html		$lang:src/lessons/sort/baseball/InsertBaseball.$lang.html
 [type: html] src/lessons/sort/baseball/BubbleBaseball.html		$lang:src/lessons/sort/baseball/BubbleBaseball.$lang.html
+
+[type: html] src/lessons/turtleart/Main.html				$lang:src/lessons/turtleart/Main.$lang.html
+[type: html] src/lessons/turtleart/short_desc.html			$lang:src/lessons/turtleart/short_desc.$lang.html
diff --git a/site/jlm.jnlp b/site/jlm.jnlp
deleted file mode 100644
index f920205..0000000
--- a/site/jlm.jnlp
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<jnlp codebase="http://www.loria.fr/~oster/jlm/" href="jlm.jnlp">
-	<information>
-		<title>Java Learning Machine</title>
-		<homepage href="http://www.assembla.com/spaces/JLM"/>
-		<description>Java Learning Machine (JLM) - a learning platform dedicated to Java and other programming concepts</description>
-		<vendor>ESIAL / Nancy-Université</vendor>
-		<!-- <icon href="jlm.png"/> -->
-		<icon kind="splash" href="splash.png"/>
-		<offline-allowed/>
-	</information>
-	<security>
-		<all-permissions/>
-	</security>
-	<resources>
-		<j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" max-heap-size="128m"/>
-		<jar href="lib/jlm-webstart.jar"/>
-		<jar href="lib/twitter4j-core-2.1.4-SNAPSHOT.jar"/>
-		<jar href="lib/jsyntaxpane-0.9.4.jar"/>
-		<jar href="lib/simple-xml-1.7.2.jar"/>
-		<jar href="lib/miglayout-3.7.2.jar"/>
-		<jar href="lib/langtools-beta.jar"/>
-		<jar href="lib/irclib.jar"/>
-		
-		<jar href="lib/httpclient-4.1.2.jar"/>
-		<jar href="lib/httpcore-4.1.2.jar"/>
-		<jar href="lib/commons-logging-1.1.1.jar"/>
-		<jar href="lib/commons-codec-1.4.jar"/>
-		
-		<jar href="lib/collections-generic-4.01.jar"/>
-		<jar href="lib/jung-jai-2.0.1.jar"/>
-		<jar href="lib/vecmath-1.3.1.jar"/>
-		<jar href="lib/colt-1.2.0.jar"/>
-		<jar href="lib/jung-algorithms-2.0.1.jar"/>
-		<jar href="lib/wstx-asl-3.2.6.jar"/>
-		<jar href="lib/concurrent-1.3.4.jar"/>
-		<jar href="lib/jung-api-2.0.1.jar"/>
-		<jar href="lib/j3d-core-1.3.1.jar"/>
-		<jar href="lib/jung-graph-impl-2.0.1.jar"/>
-		<jar href="lib/jung-visualization-2.0.1.jar"/>
-		<jar href="lib/jung-3d-2.0.1.jar"/>
-		<jar href="lib/jung-io-2.0.1.jar"/>
-		<jar href="lib/stax-api-1.0.1.jar"/>
-		
-		<jar href="lib/smackx.jar"/>
-		<jar href="lib/smack.jar"/>
-		
-		<jar href="lib/json-smart-1.1.1.jar"/>
-		
-		<property name="twitter4j.loggerFactory" value="twitter4j.internal.logging.NullLoggerFactory"/>
-	</resources>
-	<application-desc main-class="jlm.core.ui.JavaLearningMachine"/>
-</jnlp>
-
-
-
diff --git a/site/plm.jnlp b/site/plm.jnlp
new file mode 100644
index 0000000..53ac0e8
--- /dev/null
+++ b/site/plm.jnlp
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jnlp codebase="http://www.loria.fr/~oster/plm/" href="plm.jnlp">
+	<information>
+		<title>Java Learning Machine</title>
+		<homepage href="http://www.github.com/oster/JLM"/>
+		<description>Programmer's Learning Machine (PLM) - a learning platform dedicated to programming concepts</description>
+		<vendor>ESIAL / Nancy-Université</vendor>
+		<!-- <icon href="plm.png"/> -->
+		<icon kind="splash" href="splash.png"/>
+		<offline-allowed/>
+	</information>
+	<security>
+		<all-permissions/>
+	</security>
+	<resources>
+		<j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" max-heap-size="128m"/>
+		<jar href="lib/plm-webstart.jar"/>
+		<jar href="lib/twitter4j-core-2.1.4-SNAPSHOT.jar"/>
+		<jar href="lib/jsyntaxpane-0.9.4.jar"/>
+		<jar href="lib/simple-xml-1.7.2.jar"/>
+		<jar href="lib/miglayout-3.7.2.jar"/>
+		<jar href="lib/langtools-beta.jar"/>
+		<jar href="lib/irclib.jar"/>
+		
+		<jar href="lib/httpclient-4.1.2.jar"/>
+		<jar href="lib/httpcore-4.1.2.jar"/>
+		<jar href="lib/commons-logging-1.1.1.jar"/>
+		<jar href="lib/commons-codec-1.4.jar"/>
+		
+		<jar href="lib/collections-generic-4.01.jar"/>
+		<jar href="lib/jung-jai-2.0.1.jar"/>
+		<jar href="lib/vecmath-1.3.1.jar"/>
+		<jar href="lib/colt-1.2.0.jar"/>
+		<jar href="lib/jung-algorithms-2.0.1.jar"/>
+		<jar href="lib/wstx-asl-3.2.6.jar"/>
+		<jar href="lib/concurrent-1.3.4.jar"/>
+		<jar href="lib/jung-api-2.0.1.jar"/>
+		<jar href="lib/j3d-core-1.3.1.jar"/>
+		<jar href="lib/jung-graph-impl-2.0.1.jar"/>
+		<jar href="lib/jung-visualization-2.0.1.jar"/>
+		<jar href="lib/jung-3d-2.0.1.jar"/>
+		<jar href="lib/jung-io-2.0.1.jar"/>
+		<jar href="lib/stax-api-1.0.1.jar"/>
+		
+		<jar href="lib/smackx.jar"/>
+		<jar href="lib/smack.jar"/>
+		
+		<jar href="lib/json-smart-1.1.1.jar"/>
+		
+		<property name="twitter4j.loggerFactory" value="twitter4j.internal.logging.NullLoggerFactory"/>
+	</resources>
+	<application-desc main-class="plm.core.ui.JavaLearningMachine"/>
+</jnlp>
+
+
+
diff --git a/src/jlm/core/ExoTest.java b/src/jlm/core/ExoTest.java
deleted file mode 100644
index 950d6e3..0000000
--- a/src/jlm/core/ExoTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package jlm.core;
-
-import static org.junit.Assert.fail;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Set;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Exercise.WorldKind;
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.utils.FileUtils;
-import jlm.universe.Entity;
-import jlm.universe.World;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
- at RunWith(Parameterized.class)
-public class ExoTest {
-	static private String[] lessons = new String[] { 
-		"lessons.welcome", "lessons.turmites", "lessons.maze","lessons.bat.string1", 
-		"lessons.sort", "lessons.sort.baseball", "lessons.sort.pancake",  
-		"lessons.recursion", "lessons.recursion.hanoi",
-		// "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
-		};
-
-	@BeforeClass
-	static public void setUpClass() {
-	}
-	
-	/* Generate the list of parameters we want to run our test on */
-	@Parameters
-	static public Collection<Object[]> data() {
-		LinkedList<Object[]> result = new LinkedList<Object[]>();
-		
-		FileUtils.setLocale(new Locale("en"));
-		Game g = Game.getInstance();
-
-		/* Compute the answers with the java entities */
-		Game.getInstance().setProgramingLanguage(Game.JAVA);
-		Set<Lecture> allExercises = new HashSet<Lecture>();  
-		for (String lessonName : lessons) { 
-			g.switchLesson(lessonName,true);
-			System.out.println("Lesson "+lessonName+" loaded ("+g.getCurrentLesson().getExerciseCount()+" exercises)");
-			if (g.getCurrentLesson().getExerciseCount() == 0) {
-				System.err.println("Cannot find any exercise in "+lessonName+". Something's wrong here");
-				System.exit(1);
-			}
-			for (Lecture l : g.getCurrentLesson().exercises()) 
-				if (l instanceof Exercise) {
-					result.add(new Object[] {Game.getInstance().getCurrentLesson(), l});
-					if (allExercises.contains(l)) {
-						System.err.println("Warning, I tried to add the exercise "+l.getName()+" twice. Something's wrong here");
-						System.exit(1);
-					}
-					allExercises.add(l);
-				}
-		}
-		System.out.println("There is currently "+result.size()+" exercises in our database. Yes sir.");
-		g.switchDebug();
-		
-		g.setLocale(new Locale("en"));
-		return result;
-	}
-
-	
-	private ExerciseTemplated exo;
-	public ExoTest(Lesson l, ExerciseTemplated e) {
-		this.exo = e;
-
-		Game.getInstance().setCurrentLesson(l);
-		Game.getInstance().setCurrentExercise(exo);
-		for (int worldRank=0; worldRank<exo.getWorldCount(); worldRank++) 
-			exo.getWorlds(WorldKind.INITIAL).get(worldRank).setDelay(0);
-	}
-	
-	/** Resets current world, populate it with the correction entity, and rerun it */
-	private void testCorrectionEntity() {
-		Game.getInstance().setCurrentExercise(exo);
-		exo.lastResult = new ExecutionProgress();
-		
-		exo.reset();
-		exo.mutateCorrection(WorldKind.CURRENT);
-		
-		if (exo instanceof BatExercise)
-			for (BatTest t : ((BatWorld)exo.getWorld(0)).tests) 
-				t.objectiveTest = false; // we want to set the result for real, not the expected
-		
-		for (World w : exo.getWorlds(WorldKind.CURRENT)) 
-			for (Entity ent: w.getEntities())  
-				ent.runIt(exo.lastResult);
-
-		exo.check();
-		
-		if (exo.lastResult.compilationError != null)
-			fail(exo.getClass().getSimpleName()+": compilation error: "+exo.lastResult.compilationError);
-		
-		if (exo.lastResult.totalTests == 0 
-				|| exo.lastResult.totalTests != exo.lastResult.passedTests 
-				|| !exo.lastResult.details.equals("")) {
-			System.out.println(""+exo.getClass().getName()+" failed in "+Game.getProgrammingLanguage()+": "+exo.lastResult.details);
-			fail(exo.getClass().getSimpleName()+": failed exercise ("+
-				exo.lastResult.passedTests+"/"+exo.lastResult.totalTests+" passed): '"+exo.lastResult.details+"'");
-		}
-		System.out.println(""+exo.getClass().getName()+" passed in "+Game.getProgrammingLanguage());
-
-	}
-	
-	@Test(timeout=10000)
-	public void testJavaEntity() {
-		Game.getInstance().setProgramingLanguage(Game.JAVA);
-		testCorrectionEntity();
-	}
-	
-	@Test(timeout=30000)
-	public void testPythonEntity() {
-		if (!exo.getProgLanguages().contains(Game.PYTHON)) {
-//			System.out.println("Exercise "+exo.getClass().getName()+" does not support python");
-//			return;
-			fail("Exercise "+exo.getClass().getName()+" does not support python");
-		}
-		Game.getInstance().setProgramingLanguage(Game.PYTHON);
-		testCorrectionEntity();
-	}
-}
diff --git a/src/jlm/core/GameListener.java b/src/jlm/core/GameListener.java
deleted file mode 100644
index 7d0eaa1..0000000
--- a/src/jlm/core/GameListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package jlm.core;
-
-import jlm.core.model.lesson.Lecture;
-import jlm.universe.World;
-
-public interface GameListener {
-
-	// when a lesson becomes current lesson of the game
-	public void currentLessonHasChanged() ;
-	
-	// when an exercise becomes current exercise of the game
-	public void currentExerciseHasChanged(Lecture lect) ;
-	
-	// when a world is selected as the current world
-	public void selectedWorldHasChanged(World newWorld); 
-	
-	// when an entity is selected as the current entity in a world
-	public void selectedEntityHasChanged();
-
-	// when entities are replaced in the current 
-	public void selectedWorldWasUpdated();
-}
\ No newline at end of file
diff --git a/src/jlm/core/GameStateListener.java b/src/jlm/core/GameStateListener.java
deleted file mode 100644
index 03155d3..0000000
--- a/src/jlm/core/GameStateListener.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package jlm.core;
-
-import jlm.core.model.Game;
-
-public interface GameStateListener {
-
-	public void stateChanged(Game.GameState type) ;
-	
-}
diff --git a/src/jlm/core/HumanLangChangesListener.java b/src/jlm/core/HumanLangChangesListener.java
deleted file mode 100644
index 9c138d7..0000000
--- a/src/jlm/core/HumanLangChangesListener.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package jlm.core;
-
-import java.util.Locale;
-
-public interface HumanLangChangesListener {
-    // when the used human language (English, French, etc) has changed
-	public void currentHumanLanguageHasChanged(Locale newLang);
-
-}
diff --git a/src/jlm/core/InMemoryCompiler.java b/src/jlm/core/InMemoryCompiler.java
deleted file mode 100644
index 74d0f06..0000000
--- a/src/jlm/core/InMemoryCompiler.java
+++ /dev/null
@@ -1,657 +0,0 @@
-package jlm.core;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLConnection;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import javax.tools.DiagnosticCollector;
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
-import javax.tools.JavaCompiler.CompilationTask;
-import javax.tools.JavaFileObject.Kind;
-
-
-/**
- * This class provides an adapted interface to the javax.tools compiler.
- * 
- * Its main methode is compile(), of prototype: 
- *  INPUT:  Map<String, CharSequence>  : a list of named sourcefiles
- *  OUTPUT: Map<String, Class<Object>> : a list of named compiled class 
- * 
- * It is used in {@link jlm.core.model.lesson.Exercise}, where the student code gets compiled.
- * 
- * See also "Create dynamic applications with javax.tools", David J. Biesack.
- * http://www.ibm.com/developerworks/java/library/j-jcomp/index.html?ca=dgr-lnxw82jvaxtools&S_TACT=105AGX59&S_CMP=GR
- */
-
-public class InMemoryCompiler {
-	// Compiler requires source files with a ".java" extension:
-	static final String JAVA_EXTENSION = ".java";
-
-	private final ClassLoaderImpl classLoader;
-
-	// The compiler instance that this facade uses.
-	private JavaCompiler compiler;
-
-	// The compiler options (such as "-target" "1.6").
-	private final List<String> options;
-
-	// collect compiler diagnostics in this instance.
-	private DiagnosticCollector<JavaFileObject> diagnostics;
-
-	// The FileManager which will store source and class "files".
-	private final FileManagerImpl javaFileManager;
-
-	/**
-	 * Construct a new instance which delegates to the named class loader.
-	 * 
-	 * @param loader
-	 *            the application ClassLoader. The compiler will look through to
-	 *            this class loader for dependent classes
-	 * @param options
-	 *            The compiler options (such as "-target" "1.5"). See the usage
-	 *            for javac
-	 * @throws IllegalStateException
-	 *             if the Java compiler cannot be loaded.
-	 */
-	public InMemoryCompiler(final ClassLoader loader, Iterable<String> options) {
-
-		compiler = ToolProvider.getSystemJavaCompiler();
-		if (compiler == null) {
-			try {
-				compiler = (JavaCompiler) Class.forName("com.sun.tools.javac.api.JavacTool").newInstance();
-			} catch (Exception e) {
-				e.printStackTrace();
-			}
-		}
-		if (compiler == null) {
-			throw new IllegalStateException("Cannot find the system Java compiler. "
-					+ "Please use a java SDK instead of a java runtime or check the class path.");
-		}
-
-		classLoader = (ClassLoaderImpl) AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
-			public ClassLoader run() {
-				return new ClassLoaderImpl(loader);
-			}
-		});
-
-		diagnostics = new DiagnosticCollector<JavaFileObject>();
-		final JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
-		javaFileManager = new FileManagerImpl(fileManager, classLoader);
-
-		this.options = new ArrayList<String>();
-		if (options != null) {
-			for (String option : options) {
-				this.options.add(option);
-			}
-		}
-
-		// piece of code dedicated to webstart (jnlp) support
-		// (might be improved one day...)
-		List<URL> classpath = new ArrayList<URL>();
-
-		if (loader instanceof URLClassLoader) {
-			for (URL url : ((URLClassLoader) loader).getURLs()) {
-				if (url.toString().startsWith("http:")) {
-					try {
-						String jarFilename = url.getFile();
-						jarFilename = jarFilename.substring(jarFilename.lastIndexOf('/'));
-						File tempFile = new File(System.getProperty("java.io.tmpdir"), jarFilename);
-						// if the compiler was a singleton, we could have used
-						// File.createTempFile("cached-",".jar");
-						if (!tempFile.exists()) {
-							// we have to re-download .jar since
-							// JarURLConnection is not properly working
-							download(url, tempFile);
-							tempFile.deleteOnExit();
-						}
-						URL jarLocation = new URL("file:" + tempFile.getAbsolutePath());
-						classpath.add(jarLocation);
-					} catch (Exception e) {
-						e.printStackTrace();
-					}
-				} else {
-					classpath.add(url);
-				}
-			}
-		}
-		String classPath = System.getProperty("java.class.path");
-		for (String path : classPath.split(File.pathSeparator)) {
-			try {
-				classpath.add(new URL("file:" + path));
-			} catch (MalformedURLException e) {
-				e.printStackTrace();
-			}
-		}
-
-		StringBuffer sb = new StringBuffer();
-		for (URL jar : classpath) {
-			sb.append(jar.getPath());
-			sb.append(File.pathSeparatorChar);
-		}
-		this.options.add("-cp");
-		this.options.add(sb.toString());
-	}
-
-	private static void download(URL url, File localFileName) {
-		OutputStream out = null;
-		InputStream in = null;
-		try {
-			out = new BufferedOutputStream(new FileOutputStream(localFileName));
-			URLConnection conn = url.openConnection();
-			in = conn.getInputStream();
-			byte[] buffer = new byte[1024 * 512];
-			int numRead;
-			while ((numRead = in.read(buffer)) != -1) {
-				out.write(buffer, 0, numRead);
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		} finally {
-			try {
-				if (in != null)
-					in.close();
-				if (out != null)
-					out.close();
-			} catch (IOException ioe) {
-				// ioe.printStackTrace();
-			}
-		}
-	}
-
-	/**
-	 * Compile Java source in <var>javaSource</var> and return the resulting
-	 * class.
-	 * <p>
-	 * Thread safety: this method is thread safe if the <var>javaSource</var>
-	 * and <var>diagnosticsList</var> are isolated to this thread.
-	 * 
-	 * @param qualifiedClassName
-	 *            The fully qualified class name.
-	 * @param javaSource
-	 *            Complete java source, including a package statement and a
-	 *            class, interface, or annotation declaration.
-	 * @param diagnosticsList
-	 *            Any diagnostics generated by compiling the source are added to
-	 *            this collector.
-	 * @param types
-	 *            zero or more Class objects representing classes or interfaces
-	 *            that the resulting class must be assignable (castable) to.
-	 * @return a Class which is generated by compiling the source
-	 * @throws CharSequenceCompilerException
-	 *             if the source cannot be compiled - for example, if it
-	 *             contains syntax or semantic errors or if dependent classes
-	 *             cannot be found.
-	 * @throws ClassCastException
-	 *             if the generated class is not assignable to all the optional
-	 *             <var>types</var>.
-	 */
-	public synchronized Class<Object> compile(final String qualifiedClassName, final CharSequence javaSource,
-			final DiagnosticCollector<JavaFileObject> diagnosticsList, final Class<?>... types)
-			throws JLMCompilerException, ClassCastException {
-		if (diagnosticsList != null)
-			diagnostics = diagnosticsList;
-		else
-			diagnostics = new DiagnosticCollector<JavaFileObject>();
-		Map<String, CharSequence> classes = new HashMap<String, CharSequence>(1);
-		classes.put(qualifiedClassName, javaSource);
-		Map<String, Class<Object>> compiled = compile(classes, diagnosticsList);
-		Class<Object> newClass = compiled.get(qualifiedClassName);
-		return castable(newClass, types);
-	}
-
-	/**
-	 * Compile multiple Java source strings and return a Map containing the
-	 * resulting classes.
-	 * <p>
-	 * Thread safety: this method is thread safe if the <var>classes</var> and
-	 * <var>diagnosticsList</var> are isolated to this thread.
-	 * 
-	 * @param classes
-	 *            A Map whose keys are qualified class names and whose values
-	 *            are the Java source strings containing the definition of the
-	 *            class. A map value may be null, indicating that compiled class
-	 *            is expected, although no source exists for it (it may be a
-	 *            non-public class contained in one of the other strings.)
-	 * @param diagnosticsList
-	 *            Any diagnostics generated by compiling the source are added to
-	 *            this list.
-	 * @return A mapping of qualified class names to their corresponding
-	 *         classes. The map has the same keys as the input
-	 *         <var>classes</var>; the values are the corresponding Class
-	 *         objects.
-	 * @throws CharSequenceCompilerException
-	 *             if the source cannot be compiled
-	 */
-	public synchronized Map<String, Class<Object>> compile(final Map<String, CharSequence> classes,
-			final DiagnosticCollector<JavaFileObject> diagnosticsList) throws JLMCompilerException {
-
-		if (diagnosticsList != null)
-			diagnostics = diagnosticsList;
-		else
-			diagnostics = new DiagnosticCollector<JavaFileObject>();
-
-		List<JavaFileObject> sources = new ArrayList<JavaFileObject>();
-		for (Entry<String, CharSequence> entry : classes.entrySet()) {
-			String qualifiedClassName = entry.getKey();
-			CharSequence javaSource = entry.getValue();
-			if (javaSource != null) {
-				final int dotPos = qualifiedClassName.lastIndexOf('.');
-				final String className = dotPos == -1 ? qualifiedClassName : qualifiedClassName.substring(dotPos + 1);
-				final String packageName = dotPos == -1 ? "" : qualifiedClassName.substring(0, dotPos);
-				final JavaFileObjectImpl source = new JavaFileObjectImpl(className, javaSource);
-				sources.add(source);
-				// Store the source file in the FileManager via package/class
-				// name.
-				// For source files, we add a .java extension
-				javaFileManager.putFileForInput(StandardLocation.SOURCE_PATH, packageName, className + JAVA_EXTENSION,
-						source);
-			}
-		}
-		// Get a CompliationTask from the compiler and compile the sources
-		final CompilationTask task = compiler.getTask(null, javaFileManager, diagnostics, options, null, sources);
-		final Boolean result = task.call();
-		if (result == null || !result.booleanValue()) {
-			/*
-			 * FIXME: provide a way to debug
-			 * when templates are broken
-			 */
-			 //for (String n:classes.keySet()) 
-			 // System.out.println("File "+n+":\n"+classes.get(n));
-			 
-			throw new JLMCompilerException("Compilation failed.", classes.keySet(), diagnostics);
-		}
-		try {
-			// For each class name in the input map, get its compiled
-			// class and put it in the output map
-			Map<String, Class<Object>> compiled = new HashMap<String, Class<Object>>();
-			for (String qualifiedClassName : classes.keySet()) {
-				final Class<Object> newClass = loadClass(qualifiedClassName);
-				compiled.put(qualifiedClassName, newClass);
-			}
-			return compiled;
-		} catch (ClassNotFoundException e) {
-			throw new JLMCompilerException(classes.keySet(), e, diagnostics);
-		} catch (IllegalArgumentException e) {
-			throw new JLMCompilerException(classes.keySet(), e, diagnostics);
-		} catch (SecurityException e) {
-			throw new JLMCompilerException(classes.keySet(), e, diagnostics);
-		}
-	}
-
-	/**
-	 * Load a class that was generated by this instance or accessible from its
-	 * parent class loader. Use this method if you need access to additional
-	 * classes compiled by
-	 * {@link #compile(String, CharSequence, DiagnosticCollector, Class...)
-	 * compile()}, for example if the primary class contained nested classes or
-	 * additional non-public classes.
-	 * 
-	 * @param qualifiedClassName
-	 *            the name of the compiled class you wish to load
-	 * @return a Class instance named by <var>qualifiedClassName</var>
-	 * @throws ClassNotFoundException
-	 *             if no such class is found.
-	 */
-	@SuppressWarnings("unchecked")
-	public Class<Object> loadClass(final String qualifiedClassName) throws ClassNotFoundException {
-		return (Class<Object>) classLoader.loadClass(qualifiedClassName);
-	}
-
-	/**
-	 * Check that the <var>newClass</var> is a subtype of all the type
-	 * parameters and throw a ClassCastException if not.
-	 * 
-	 * @param types
-	 *            zero of more classes or interfaces that the
-	 *            <var>newClass</var> must be castable to.
-	 * @return <var>newClass</var> if it is castable to all the types
-	 * @throws ClassCastException
-	 *             if <var>newClass</var> is not castable to all the types.
-	 */
-	private Class<Object> castable(Class<Object> newClass, Class<?>... types) throws ClassCastException {
-		for (Class<?> type : types)
-			if (!type.isAssignableFrom(newClass)) {
-				throw new ClassCastException(type.getName());
-			}
-		return newClass;
-	}
-
-	/**
-	 * Converts a String to a URI.
-	 * 
-	 * @param name
-	 *            a file name
-	 * @return a URI
-	 */
-	static URI toURI(String name) {
-		try {
-			return new URI(name);
-		} catch (URISyntaxException e) {
-			throw new RuntimeException(e);
-		}
-	}
-}
-
-/**
- * A JavaFileManager which manages Java source and classes. This FileManager
- * delegates to the JavaFileManager and the ClassLoaderImpl provided in the
- * constructor. The sources are all in memory CharSequence instances and the
- * classes are all in memory byte arrays.
- */
-final class FileManagerImpl extends ForwardingJavaFileManager<JavaFileManager> {
-	// the delegating class loader (passed to the constructor)
-	private final ClassLoaderImpl classLoader;
-
-	// Internal map of filename URIs to JavaFileObjects.
-	private final Map<URI, JavaFileObject> fileObjects = new HashMap<URI, JavaFileObject>();
-
-	/**
-	 * Construct a new FileManager which forwards to the <var>fileManager</var>
-	 * for source and to the <var>classLoader</var> for classes
-	 * 
-	 * @param fileManager
-	 *            another FileManager that this instance delegates to for
-	 *            additional source.
-	 * @param classLoader
-	 *            a ClassLoader which contains dependent classes that the
-	 *            compiled classes will require when compiling them.
-	 */
-	public FileManagerImpl(JavaFileManager fileManager, ClassLoaderImpl classLoader) {
-		super(fileManager);
-		this.classLoader = classLoader;
-	}
-
-	/**
-	 * @return the class loader which this file manager delegates to
-	 */
-	public ClassLoader getClassLoader() {
-		return classLoader;
-	}
-
-	/**
-	 * For a given file <var>location</var>, return a FileObject from which the
-	 * compiler can obtain source or byte code.
-	 * 
-	 * @param location
-	 *            an abstract file location
-	 * @param packageName
-	 *            the package name for the file
-	 * @param relativeName
-	 *            the file's relative name
-	 * @return a FileObject from this or the delegated FileManager
-	 * @see javax.tools.ForwardingJavaFileManager#getFileForInput(javax.tools.JavaFileManager.Location,
-	 *      java.lang.String, java.lang.String)
-	 */
-	@Override
-	public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
-		FileObject o = fileObjects.get(uri(location, packageName, relativeName));
-		if (o != null)
-			return o;
-		return super.getFileForInput(location, packageName, relativeName);
-	}
-
-	/**
-	 * Store a file that may be retrieved later with
-	 * {@link #getFileForInput(javax.tools.JavaFileManager.Location, String, String)}
-	 * 
-	 * @param location
-	 *            the file location
-	 * @param packageName
-	 *            the Java class' package name
-	 * @param relativeName
-	 *            the relative name
-	 * @param file
-	 *            the file object to store for later retrieval
-	 */
-	public void putFileForInput(StandardLocation location, String packageName, String relativeName, JavaFileObject file) {
-		fileObjects.put(uri(location, packageName, relativeName), file);
-	}
-
-	/**
-	 * Convert a location and class name to a URI
-	 */
-	private URI uri(Location location, String packageName, String relativeName) {
-		return InMemoryCompiler.toURI(location.getName() + '/' + packageName + '/' + relativeName);
-	}
-
-	/**
-	 * Create a JavaFileImpl for an output class file and store it in the
-	 * classloader.
-	 * 
-	 * @see javax.tools.ForwardingJavaFileManager#getJavaFileForOutput(javax.tools.JavaFileManager.Location,
-	 *      java.lang.String, javax.tools.JavaFileObject.Kind,
-	 *      javax.tools.FileObject)
-	 */
-	@Override
-	public JavaFileObject getJavaFileForOutput(Location location, String qualifiedName, Kind kind, FileObject outputFile)
-			throws IOException {
-		JavaFileObject file = new JavaFileObjectImpl(qualifiedName, kind);
-		classLoader.add(qualifiedName, file);
-		return file;
-	}
-
-	@Override
-	public ClassLoader getClassLoader(JavaFileManager.Location location) {
-		return classLoader;
-	}
-
-	@Override
-	public String inferBinaryName(Location loc, JavaFileObject file) {
-		String result;
-		// For our JavaFileImpl instances, return the file's name, else
-		// simply run the default implementation
-		if (file instanceof JavaFileObjectImpl)
-			result = file.getName();
-		else
-			result = super.inferBinaryName(loc, file);
-		return result;
-	}
-
-	@Override
-	public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse)
-			throws IOException {
-		Iterable<JavaFileObject> result = super.list(location, packageName, kinds, recurse);
-
-		ArrayList<JavaFileObject> files = new ArrayList<JavaFileObject>();
-		if (location == StandardLocation.CLASS_PATH && kinds.contains(JavaFileObject.Kind.CLASS)) {
-			for (JavaFileObject file : fileObjects.values()) {
-				if (file.getKind() == Kind.CLASS && file.getName().startsWith(packageName))
-					files.add(file);
-			}
-			files.addAll(classLoader.files());
-		} else if (location == StandardLocation.SOURCE_PATH && kinds.contains(JavaFileObject.Kind.SOURCE)) {
-			for (JavaFileObject file : fileObjects.values()) {
-				if (file.getKind() == Kind.SOURCE && file.getName().startsWith(packageName))
-					files.add(file);
-			}
-		}
-		for (JavaFileObject file : result) {
-			files.add(file);
-		}
-
-		return files;
-	}
-}
-
-/**
- * A JavaFileObject which contains either the source text or the compiler
- * generated class. This class is used in two cases.
- * <ol>
- * <li>This instance uses it to store the source which is passed to the
- * compiler. This uses the
- * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, CharSequence)}
- * constructor.
- * <li>The Java compiler also creates instances (indirectly through the
- * FileManagerImplFileManager) when it wants to create a JavaFileObject for the
- * .class output. This uses the
- * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, JavaFileObject.Kind)}
- * constructor.
- * </ol>
- * This class does not attempt to reuse instances (there does not seem to be a
- * need, as it would require adding a Map for the purpose, and this would also
- * prevent garbage collection of class byte code.)
- */
-final class JavaFileObjectImpl extends SimpleJavaFileObject {
-	// If kind == CLASS, this stores byte code from openOutputStream
-	private ByteArrayOutputStream byteCode;
-
-	// if kind == SOURCE, this contains the source text
-	private final CharSequence source;
-
-	/**
-	 * Construct a new instance which stores source
-	 * 
-	 * @param baseName
-	 *            the base name
-	 * @param source
-	 *            the source code
-	 */
-	JavaFileObjectImpl(final String baseName, final CharSequence source) {
-		super(InMemoryCompiler.toURI(baseName + InMemoryCompiler.JAVA_EXTENSION), Kind.SOURCE);
-		this.source = source;
-	}
-
-	/**
-	 * Construct a new instance
-	 * 
-	 * @param name
-	 *            the file name
-	 * @param kind
-	 *            the kind of file
-	 */
-	JavaFileObjectImpl(final String name, final Kind kind) {
-		super(InMemoryCompiler.toURI(name), kind);
-		source = null;
-	}
-
-	/**
-	 * Return the source code content
-	 * 
-	 * @see javax.tools.SimpleJavaFileObject#getCharContent(boolean)
-	 */
-	@Override
-	public CharSequence getCharContent(final boolean ignoreEncodingErrors) throws UnsupportedOperationException {
-		if (source == null)
-			throw new UnsupportedOperationException("getCharContent()");
-		return source;
-	}
-
-	/**
-	 * Return an input stream for reading the byte code
-	 * 
-	 * @see javax.tools.SimpleJavaFileObject#openInputStream()
-	 */
-	@Override
-	public InputStream openInputStream() {
-		return new ByteArrayInputStream(getByteCode());
-	}
-
-	/**
-	 * Return an output stream for writing the bytecode
-	 * 
-	 * @see javax.tools.SimpleJavaFileObject#openOutputStream()
-	 */
-	@Override
-	public OutputStream openOutputStream() {
-		byteCode = new ByteArrayOutputStream();
-		return byteCode;
-	}
-
-	/**
-	 * @return the byte code generated by the compiler
-	 */
-	byte[] getByteCode() {
-		return byteCode.toByteArray();
-	}
-}
-
-/**
- * A custom ClassLoader which maps class names to JavaFileObjectImpl instances.
- */
-final class ClassLoaderImpl extends ClassLoader {
-	private final Map<String, JavaFileObject> classes = new HashMap<String, JavaFileObject>();
-
-	ClassLoaderImpl(final ClassLoader parentClassLoader) {
-		super(parentClassLoader);
-	}
-
-	/**
-	 * @return An collection of JavaFileObject instances for the classes in the
-	 *         class loader.
-	 */
-	Collection<JavaFileObject> files() {
-		return Collections.unmodifiableCollection(classes.values());
-	}
-
-	@Override
-	protected Class<?> findClass(final String qualifiedClassName) throws ClassNotFoundException {
-		JavaFileObject file = classes.get(qualifiedClassName);
-		if (file != null) {
-			byte[] bytes = ((JavaFileObjectImpl) file).getByteCode();
-			return defineClass(qualifiedClassName, bytes, 0, bytes.length);
-		}
-		// Workaround for "feature" in Java 6
-		// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6434149
-		try {
-			Class<?> c = Class.forName(qualifiedClassName);
-			return c;
-		} catch (ClassNotFoundException nf) {
-			// Ignore and fall through
-			nf.printStackTrace();
-		}
-		return super.findClass(qualifiedClassName);
-	}
-
-	/**
-	 * Add a class name/JavaFileObject mapping
-	 * 
-	 * @param qualifiedClassName
-	 *            the name
-	 * @param javaFile
-	 *            the file associated with the name
-	 */
-	void add(final String qualifiedClassName, final JavaFileObject javaFile) {
-		classes.put(qualifiedClassName, javaFile);
-	}
-
-	@Override
-	public InputStream getResourceAsStream(final String name) {
-		if (name.endsWith(".class")) {
-			String qualifiedClassName = name.substring(0, name.length() - ".class".length()).replace('/', '.');
-			JavaFileObjectImpl file = (JavaFileObjectImpl) classes.get(qualifiedClassName);
-			if (file != null) {
-				return new ByteArrayInputStream(file.getByteCode());
-			}
-		}
-		return super.getResourceAsStream(name);
-	}
-
-}
diff --git a/src/jlm/core/JLMCompilerException.java b/src/jlm/core/JLMCompilerException.java
deleted file mode 100644
index d77ebc6..0000000
--- a/src/jlm/core/JLMCompilerException.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package jlm.core;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-/**
- * An exception thrown when trying to compile Java programs from strings
- * containing source.
- * 
- * @author <a href="mailto:David.Biesack at sas.com">David J. Biesack</a>
- */
-public class JLMCompilerException extends Exception {
-	   private static final long serialVersionUID = 1L;
-	   /**
-	    * The fully qualified name of the class that was being compiled.
-	    */
-	   private Set<String> classNames;
-	   // Unfortunately, Diagnostic and Collector are not Serializable, so we can't
-	   // serialize the collector.
-	   transient private DiagnosticCollector<JavaFileObject> diagnostics;
-
-	   public JLMCompilerException(String message,
-	         Set<String> qualifiedClassNames, Throwable cause,
-	         DiagnosticCollector<JavaFileObject> diagnostics) {
-	      super(message, cause);
-	      setClassNames(qualifiedClassNames);
-	      setDiagnostics(diagnostics);
-	   }
-
-	   public JLMCompilerException(String message,
-	         Set<String> qualifiedClassNames,
-	         DiagnosticCollector<JavaFileObject> diagnostics) {
-	      super(message);
-	      setClassNames(qualifiedClassNames);
-	      setDiagnostics(diagnostics);
-	   }
-
-	   public JLMCompilerException(Set<String> qualifiedClassNames,
-	         Throwable cause, DiagnosticCollector<JavaFileObject> diagnostics) {
-	      super(cause);
-	      setClassNames(qualifiedClassNames);
-	      setDiagnostics(diagnostics);
-	   }
-
-	   private void setClassNames(Set<String> qualifiedClassNames) {
-	      // create a new HashSet because the set passed in may not
-	      // be Serializable. For example, Map.keySet() returns a non-Serializable
-	      // set.
-	      classNames = new HashSet<String>(qualifiedClassNames);
-	   }
-
-	   private void setDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
-	      this.diagnostics = diagnostics;
-	   }
-
-	   /**
-	    * Gets the diagnostics collected by this exception.
-	    * 
-	    * @return this exception's diagnostics
-	    */
-	   public DiagnosticCollector<JavaFileObject> getDiagnostics() {
-	      return diagnostics;
-	   }
-	   
-	   /**
-	    * @return The name of the classes whose compilation caused the compile
-	    *         exception
-	    */
-	   public Collection<String> getClassNames() {
-	      return Collections.unmodifiableSet(classNames);
-	   }
-}
diff --git a/src/jlm/core/JLMException.java b/src/jlm/core/JLMException.java
deleted file mode 100644
index 32df49e..0000000
--- a/src/jlm/core/JLMException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package jlm.core;
-
-public class JLMException extends Exception {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 5763400564033977767L;
-
-	public JLMException(String msg) {
-		super(msg);
-	}
-	
-}
diff --git a/src/jlm/core/ProgLangChangesListener.java b/src/jlm/core/ProgLangChangesListener.java
deleted file mode 100644
index 053e013..0000000
--- a/src/jlm/core/ProgLangChangesListener.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package jlm.core;
-
-import jlm.core.model.ProgrammingLanguage;
-
-public interface ProgLangChangesListener {
-    // when the used programming language has changed
-	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang);
-
-}
diff --git a/src/jlm/core/StatusStateListener.java b/src/jlm/core/StatusStateListener.java
deleted file mode 100644
index 523848d..0000000
--- a/src/jlm/core/StatusStateListener.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package jlm.core;
-
-
-public interface StatusStateListener {
-
-	public void stateChanged(String txt) ;
-	
-}
diff --git a/src/jlm/core/model/Course.java b/src/jlm/core/model/Course.java
deleted file mode 100644
index 76179eb..0000000
--- a/src/jlm/core/model/Course.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package jlm.core.model;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-
-/**
- * Class to manage course data online
- * It has an id and allows to save/retrieve users results by course
- * It contains lists of students names sorted by criteria :
- * * students needing help (pressed the help button)
- * * good students (>=90% of good answers)
- * * bad students (<=5% of good answers
- * * layabout students (didn't try any exercises)
- */
-public abstract class Course {
-
-    protected String courseId;
-    protected String password;
-    protected String teacherPassword;
-    protected Map<String, ServerUserData> serverData;
-    protected ArrayList<String> needingHelpStudents;
-    protected ArrayList<String> goodStudents;
-    protected ArrayList<String> badStudents;
-    protected ArrayList<String> layaboutStudents;
-
-    public Course() {
-        this(null);
-    }
-
-    public Course(String id) {
-        courseId = id;
-        password = "";
-        teacherPassword = "";
-    }
-
-    public Course(String id, String password) {
-        courseId = id;
-        this.password = password;
-        teacherPassword = "";
-    }
-
-    /**
-     * Create a new course on the server
-     * For example "top_quinson"
-     * A user password is set to push data, a teacher password to administrate course
-     */
-    public ServerAnswer create() {
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("action", "new");
-        jsonObject.put("course", courseId);
-        jsonObject.put("password", password);
-        jsonObject.put("teacher_password", teacherPassword);
-
-        String response;
-
-        try {
-            response = sendTeacherRequest(jsonObject.toString());
-        } catch (IOException e) {
-            return null;
-        }
-
-        return ServerAnswer.values()[Integer.parseInt(response)];
-    }
-
-    /**
-     * Download updated data from server It loads a list of results by student
-     * and by exercise
-     */
-    public String refresh() {
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("action", "refresh");
-        jsonObject.put("course", courseId);
-        jsonObject.put("teacher_password", teacherPassword);
-
-        String answer = null;
-        try {
-            answer = sendTeacherRequest(jsonObject.toString());
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-
-        // test if the answer was a status code or course data
-        try {
-            Integer.parseInt(answer);
-        } catch (NumberFormatException nfe) {
-            serverData = ServerUserData.parse(answer);
-        }
-        return answer;
-    }
-
-    /**
-     * Delete the course on the server All student and exercises results will be
-     * removed
-     */
-    public String delete() {
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("action", "remove");
-        jsonObject.put("course", courseId);
-        jsonObject.put("teacher_password", teacherPassword);
-
-        try {
-            return sendTeacherRequest(jsonObject.toString());
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Get all courses identifiers from the server It allows to display it in
-     * form, to select the current course
-     *
-     * @return list of all courses on the server
-     */
-    public ArrayList<String> getAllCoursesId() {
-        String response = "";
-        ArrayList<String> coursesId = new ArrayList<String>();
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("action", "allids");
-
-        try {
-            response = sendCourseRequest(jsonObject.toString());
-        } catch (IOException e) {
-            return null;
-        }
-
-        if (response != null && !response.isEmpty()) {
-            JSONArray arrayResult = (JSONArray) JSONValue.parse(response);
-            for (Object anArrayResult : arrayResult) {
-                coursesId.add((String) anArrayResult);
-            }
-        }
-
-        return coursesId;
-    }
-
-    /**
-     * Refresh all the students filter lists from the server
-     */
-    public void refreshStudentsLists(){
-        refreshStudentsNeedingHelp();
-        refreshLayaboutStudents();
-        refreshBadStudents();
-        refreshGoodStudents();
-    }
-
-    /**
-     * Generic method that constructs a request to get a list of students, depending on a filter
-     * @param filter filter to apply in the request
-     * @return the list of students
-     */
-    public ArrayList<String> refreshStudentsFromFilter(String filter) {
-        String answer = "";
-        ArrayList<String> students = new ArrayList<String>();
-
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("action", filter);
-        jsonObject.put("course", courseId);
-        jsonObject.put("teacher_password", teacherPassword);
-
-        try {
-            answer = sendTeacherRequest(jsonObject.toString());
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-
-        try {
-            if (!answer.isEmpty()) {
-                JSONArray arrayResult = (JSONArray) JSONValue.parse(answer);
-                for (Object result : arrayResult)
-                    students.add((String) result);
-            }
-        } catch (ClassCastException cce) {
-            // the answer is a status number, it can't be casted into a list...
-            return null;
-        }
-
-        return students;
-    }
-
-    public void refreshStudentsNeedingHelp() {
-        needingHelpStudents = refreshStudentsFromFilter("needinghelp");
-    }
-
-    public void refreshLayaboutStudents() {
-        layaboutStudents = refreshStudentsFromFilter("ugly");
-    }
-
-    public void refreshBadStudents() {
-        badStudents = refreshStudentsFromFilter("bad");
-    }
-
-    public void refreshGoodStudents() {
-        goodStudents = refreshStudentsFromFilter("good");
-    }
-
-    /**
-     * Method to implement to indicate how/where to send data
-     *
-     * @param request request in json to send to the server
-     */
-    public abstract String sendTeacherRequest(String request) throws IOException;
-
-    public abstract String sendCourseRequest(String request) throws IOException;
-
-    /*
-      * Getters and setters...
-      */
-
-    public String getCourseId() {
-        if (courseId == null)
-            return "";
-        return courseId;
-    }
-
-    public void setCourseId(String courseId) {
-        this.courseId = courseId;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
-    public String getTeacherPassword() {
-        return teacherPassword;
-    }
-
-    public void setTeacherPassword(String teacherPassword) {
-        this.teacherPassword = teacherPassword;
-    }
-
-    public Map<String, ServerUserData> getServerData() {
-        return serverData;
-    }
-
-    public void setServerData(Map<String, ServerUserData> serverData) {
-        this.serverData = serverData;
-    }
-
-    public ArrayList<String> getNeedingHelpStudents() {
-        return needingHelpStudents;
-    }
-
-    public void setNeedingHelpStudents(ArrayList<String> needingHelpStudents) {
-        this.needingHelpStudents = needingHelpStudents;
-    }
-
-    public ArrayList<String> getGoodStudents() {
-        return goodStudents;
-    }
-
-    public void setGoodStudents(ArrayList<String> goodStudents) {
-        this.goodStudents = goodStudents;
-    }
-
-    public ArrayList<String> getBadStudents() {
-        return badStudents;
-    }
-
-    public void setBadStudents(ArrayList<String> badStudents) {
-        this.badStudents = badStudents;
-    }
-
-    public ArrayList<String> getLayaboutStudents() {
-        return layaboutStudents;
-    }
-
-    public void setLayaboutStudents(ArrayList<String> layaboutStudents) {
-        this.layaboutStudents = layaboutStudents;
-    }
-}
diff --git a/src/jlm/core/model/CourseAppEngine.java b/src/jlm/core/model/CourseAppEngine.java
deleted file mode 100644
index 4921eea..0000000
--- a/src/jlm/core/model/CourseAppEngine.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package jlm.core.model;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-
-/**
- * Implementation of Course which works with GAE
- * It overrides Course methods to send requests constructed by it
- */
-public class CourseAppEngine extends Course {
-
-    private static URL teacherServer;
-    private static URL courseServer;
-
-    public CourseAppEngine() {
-        this(null);
-    }
-
-    public CourseAppEngine(String id) {
-        super(id);
-        try {
-            teacherServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/teacher");
-            courseServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/course");
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public CourseAppEngine(String id, String password) {
-        super(id, password);
-        try {
-            teacherServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/teacher");
-            courseServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/course");
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public String sendTeacherRequest(String request) throws IOException{
-        return sendRequest(request, teacherServer);
-    }
-
-    @Override
-    public String sendCourseRequest(String request) throws IOException{
-       return sendRequest(request, courseServer);
-    }
-
-    public String sendRequest(String request, URL server) throws IOException{
-        String response = "";
-        try {
-
-            // Send data
-            URLConnection conn = server.openConnection();
-            conn.setDoOutput(true);
-            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
-            wr.write(request);
-            wr.flush();
-
-            // Get response data and print it
-            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-            String line;
-            while ((line = br.readLine()) != null)
-            	response += line;
-
-            wr.close();
-            br.close();
-        } catch (IOException e) {
-            System.out.println("Unable to contact JLMServer to send request " + request);
-            throw new IOException(e);
-        }
-        return response;
-    }
-}
diff --git a/src/jlm/core/model/DemoRunner.java b/src/jlm/core/model/DemoRunner.java
deleted file mode 100644
index f4b51eb..0000000
--- a/src/jlm/core/model/DemoRunner.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package jlm.core.model;
-
-import java.util.Iterator;
-import java.util.List;
-
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-
-/** 
- * This class runs the demo of the current exercise in a separated thread 
- * when the Demo button is clicked. The run and demo buttons are disabled until the demo ends.
- * 
- * Activated by {@link Game#startExerciseDemoExecution()}.
- */
-public class DemoRunner extends Thread {
-
-	private Game game;
-	private List<Thread> runners = null; // threads who run entities from lesson
-
-	public DemoRunner(Game game, List<Thread> list) {
-		super();
-		this.game = game;
-		this.runners = list;
-		this.runners.add(this);
-	}
-
-	@Override
-	public void run() {
-		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
-		if (! (lect instanceof Exercise))
-			return;
-		Exercise exo = (Exercise) lect;
-		
-		boolean stepModeWasActivated = this.game.stepModeEnabled();
-
-		try {
-			game.setState(Game.GameState.DEMO_STARTED);
-			
-			this.game.disableStepMode();
-			
-			exo.runDemo(runners);
-
-			Iterator<Thread> it = runners.iterator();
-			while (it.hasNext()) {
-				Thread t = it.next();
-				if (!t.equals(this)) { /* do not wait for myself */
-					t.join();
-					it.remove();
-				}
-			}
-		} catch (InterruptedException e) {
-			game.getOutputWriter().log(e);
-		} catch (Exception e) {
-			e.printStackTrace();
-		} finally {
-			if (stepModeWasActivated) {
-				this.game.enableStepMode();
-			}
-			game.setState(Game.GameState.DEMO_ENDED);			
-		}
-
-		runners.remove(this);
-	}
-
-}
diff --git a/src/jlm/core/model/Game.java b/src/jlm/core/model/Game.java
deleted file mode 100644
index 8615cb8..0000000
--- a/src/jlm/core/model/Game.java
+++ /dev/null
@@ -1,942 +0,0 @@
-package jlm.core.model;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.InvalidPropertiesFormatException;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import jlm.core.GameListener;
-import jlm.core.GameStateListener;
-import jlm.core.HumanLangChangesListener;
-import jlm.core.ProgLangChangesListener;
-import jlm.core.StatusStateListener;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Exercise.WorldKind;
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.model.session.ISessionKit;
-import jlm.core.model.session.SessionDB;
-import jlm.core.model.session.ZipSessionKit;
-import jlm.core.model.tracking.HeartBeatSpy;
-import jlm.core.model.tracking.IdenticaSpy;
-import jlm.core.model.tracking.LocalFileSpy;
-import jlm.core.model.tracking.ProgressSpyListener;
-import jlm.core.model.tracking.ServerSpyAppEngine;
-import jlm.core.model.tracking.TwitterSpy;
-import jlm.core.ui.MainFrame;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.utils.FileUtils;
-import jlm.universe.Entity;
-import jlm.universe.IWorldView;
-import jlm.universe.World;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-/*
- *  core model which contains all known exercises.
- */
-public class Game implements IWorldView {
-	/** Current state of the engine: whether we are running the student code, a demo, saving to files, or whatever. 
-	 *  Helps deciding which interface buttons are enabled/disabled for example.
-	 */
-	public enum GameState {
-		IDLE, 
-		SAVING, SAVING_DONE,
-		LOADING, LOADING_DONE,
-		COMPILATION_STARTED, COMPILATION_ENDED, 
-		EXECUTION_STARTED, EXECUTION_ENDED,
-		DEMO_STARTED, DEMO_ENDED,
-	}
-
-	private GameState state = GameState.IDLE;
-
-	private final static String LOCAL_PROPERTIES_FILENAME = "jlm.properties";
-
-	private static Properties defaultGameProperties = new Properties();
-	private static Properties localGameProperties = new Properties();
-	private static File localGamePropertiesLoadedFile;
-
-	private static Game instance = null;
-	private Map<String, Lesson> lessons = new HashMap<String, Lesson>();
-	private Lesson currentLesson;
-	private Course currentCourse;
-
-	public static final ProgrammingLanguage JAVA =       new ProgrammingLanguage("Java","java",ResourcesCache.getIcon("img/lang_java.png"));
-	public static final ProgrammingLanguage JAVASCRIPT = new ProgrammingLanguage("JavaScript","js",ResourcesCache.getIcon("img/lang_javascript.png"));
-	public static final ProgrammingLanguage PYTHON =     new ProgrammingLanguage("Python","py",ResourcesCache.getIcon("img/lang_python.png"));
-	public static final ProgrammingLanguage RUBY =       new ProgrammingLanguage("Ruby","rb",ResourcesCache.getIcon("img/lang_ruby.png"));
-	public static final ProgrammingLanguage LIGHTBOT =   new ProgrammingLanguage("lightbot","ignored",ResourcesCache.getIcon("img/lightbot_light.png"));
-	public static final ProgrammingLanguage[] programmingLanguages = new ProgrammingLanguage[] {
-		JAVA, PYTHON, RUBY, LIGHTBOT // TODO: re-add JAVASCRIPT to this list once it works at least a bit
-	}; 
-	private ProgrammingLanguage programmingLanguage = JAVA;
-
-	/* TODO: document these values elsewhere */
-	public static final String PROP_OUTPUT_CAPTURE = "output.capture"; // Whether to redirect stdout and stderr to the graphical console. Defaults to true
-	public static final String PROP_ANSWER_CACHE = "answers.cache"; // Whether to use the cache of answers worlds on disk, defaults to true. 
-	                                                                // Turning to false will slow down the startup process, but avoid out of date files
-	
-	public static final String PROP_PROGRESS_TWITTER = "jlm.progress.twitter";     //  
-	public static final String PROP_PROGRESS_IDENTICA = "jlm.progress.identica";   // Whether the progresses should be posted to identica (default: true)
-	public static final String PROP_PROGRESS_APPENGINE = "jlm.progress.appengine"; // Whether the progresses should be posted to the appengine (default: false)
-	public static final String PROP_APPENGINE_URL = "jlm.appengine.url"; // Where to find the appengine. This is related to the teacher console, that should be rewritten at some point.
-	
-	public static final String PROP_PROGRAMING_LANGUAGE = "jlm.programingLanguage";
-
-	private List<GameListener> listeners = new ArrayList<GameListener>();
-	private World selectedWorld;
-	private World answerOfSelectedWorld;
-	private World initialOfSelectedWorld;
-	private Entity selectedEntity;
-	private List<Thread> demoRunners = new ArrayList<Thread>();
-	private static List<Thread> initRunners = new ArrayList<Thread>();
-
-    private HeartBeatSpy heartBeatSpy;
-
-	private ArrayList<GameStateListener> gameStateListeners = new ArrayList<GameStateListener>();
-
-	private LogWriter outputWriter;
-
-	public SessionDB studentWork = new SessionDB();
-	private ISessionKit sessionKit = new ZipSessionKit(this);
-
-	private static boolean ongoingInitialization = false;
-	private static String lessonChooser = "lessons.chooser";
-	public  static I18n i18n;
-
-	public static Game getInstance() {
-		if (Game.instance == null) {
-			if (ongoingInitialization)
-				throw new RuntimeException("Loop in initialization process. This is a JLM bug.");
-			ongoingInitialization = true;
-			Game.instance = new Game();
-			ongoingInitialization = false;
-			Game.instance.loadSession();
-		}
-		return Game.instance;
-	}
-
-	private Game() {
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
-		loadProperties();
-
-		String defaultProgrammingLanguage = Game.getProperty(PROP_PROGRAMING_LANGUAGE,"Java",true);
-		if (!defaultProgrammingLanguage.equalsIgnoreCase(Game.JAVA.getLang()) &&
-			!defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang())) 
-			System.err.println(i18n.tr("Warning, the default programming language is neither ''Java'' nor ''python'' but {0}.\n"+
-					"   This language will be used to setup the worlds, possibly leading to severe issues for the exercises that don''t expect it.\n" +
-					"   It is safer to change the current language, and restart JLM before proceeding.\n"+
-					"   Alternatively, the property {1} can be changed in your configuration file ($HOME/.jlm/jlm.properties",defaultProgrammingLanguage,PROP_PROGRAMING_LANGUAGE));
-		for (ProgrammingLanguage pl : Game.getProgrammingLanguages()) {
-			if (pl.getLang().equals(defaultProgrammingLanguage)) {
-				setProgramingLanguage(pl);
-				break;
-			}
-		}
-
-		addProgressSpyListener(new LocalFileSpy(SAVE_DIR));
-		
-		if (getProperty(PROP_PROGRESS_IDENTICA, "true",true).equalsIgnoreCase("true")){
-			System.err.println(i18n.tr("Your progress will be posted to http://identi.ca/jlmlovers This can be turned off through the property {0}",Game.PROP_PROGRESS_IDENTICA));
-			addProgressSpyListener(new IdenticaSpy());
-		} else {
-			System.err.println(i18n.tr("Your progress will NOT be posted to identica, as requested by the property {0}",Game.PROP_PROGRESS_IDENTICA));			
-		}
-		if (getProperty(PROP_PROGRESS_TWITTER, "true",true).equalsIgnoreCase("true")) {
-			System.err.println(i18n.tr("Your progress will be posted to https://twitter.com/jlmlovers This can be turned off through the property {0}",Game.PROP_PROGRESS_TWITTER));
-			addProgressSpyListener(new TwitterSpy());
-		} else {
-			System.err.println(i18n.tr("Your progress will NOT be posted to twitter, as requested by the property {0}",Game.PROP_PROGRESS_TWITTER));			
-		}
-		if (getProperty(PROP_PROGRESS_APPENGINE, "false",true).equalsIgnoreCase("true"))
-			addProgressSpyListener(new ServerSpyAppEngine());
-
-        currentCourse = new CourseAppEngine();
-	}
-	
-	
-	/**
-	 * Load the chooser, stored in jlm.core.ui.chooser
-	 */
-	public void loadChooser() {
-		Game.instance.switchLesson(lessonChooser,false);
-	}
-	
-	
-	/** Change the current lesson.
-	 * 
-	 * Also, initialize the newly used lesson on need. It must already be in the classpath 
-	 * (use @loadLesson() if you want to load a lesson located in an external jar file)
-	 *  
-	 * @param lessonName package name of the lesson to load 
-	 */
-	
-	public Lesson switchLesson(String lessonName, boolean failOnError) {
-		if (stepModeEnabled())
-			disableStepMode();
-		
-		this.setState(GameState.LOADING);
-		// Try caching the lesson to avoid the possibly long loading time during which we compute the solution of each exercise  
-		Lesson lesson = lessons.get(lessonName);
-		statusArgAdd(lessonName);
-		
-		if (lesson == null) { // we have to load it 
-			try {
-				// This is where we assume here that each lesson contains a Main object, instantiating the Lesson class.
-				// We manually build a call to the constructor of this object, and fire it
-				// This creates such an object, which is in charge of creating the whole lesson (including exercises) from its constructor
-				lesson = (Lesson) Class.forName(lessonName + ".Main").newInstance();
-				
-				lessons.put(lessonName, lesson); // cache the newly created object
-			} catch (InstantiationException e) {
-				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				e.printStackTrace();
-			} catch (ClassNotFoundException e) {
-				if (failOnError)
-					throw new RuntimeException(Game.i18n.tr("Cannot switch to lesson {0}: class Main not found.",lessonName));
-				System.err.println(Game.i18n.tr("Cannot switch to lesson {0}: class Main not found.",lessonName));
-				statusArgRemove(Game.i18n.tr("Load lesson {0}",lessonName));				
-				return getCurrentLesson();
-			}
-		}
-		// Prevent an error message telling us that the JLM couldn't load our code for the chooser -- kinda obvious
-		if ( !lessonName.equals(lessonChooser))
-			sessionKit.loadLesson(SAVE_DIR, lesson);
-		try {
-			waitInitThreads();
-		} catch (InterruptedException e) {
-			System.err.println("Interrupted while loading the lesson "+lesson.getName());
-			e.printStackTrace();
-		}
-		setCurrentLesson(lesson);
-		
-		this.setState(GameState.LOADING_DONE);
-
-		return lesson;
-	}
-	private Set<String> usedJARs = new HashSet<String>(); // cache used in loadLessonFromJAR()
-	/** Load a new lesson from an external JAR file.
-	 *  
-	 * This will only work if the system classloader is an URLClassLoader. 
-	 * If your JVM gave you something else (and if you failed to change it from the command line or whatever), this will fail with an exception. 
-	 * 
-	 * @param path Path to the JAR file
-	 * @throws LessonLoadingException if the JAR file is inexistent or invalid (or if the system classloader does not accept URLs)
-	 */
-	public void loadLessonFromJAR(File jar) throws LessonLoadingException {
-		
-		if (!jar.exists())
-			throw new LessonLoadingException("File "+jar.getName()+" does not exist");
-		
-		
-		// Check if the JAR has already been added. If not, load it in the classloader.
-		if (!usedJARs.contains(jar.getAbsolutePath())) {	
-			URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
-			Class<URLClassLoader> sysclass = URLClassLoader.class;
-			
-			URL urlOfJar;
-			try {
-				urlOfJar = jar.toURI().toURL();
-			} catch (IOException e1) {
-				throw new LessonLoadingException("Error while reading the jarfile "+jar.getName(),e1);
-			}
-	        
-	        try {
-	        	// Hell yeah. That method is usually private, but I can change it that easily.
-	        	// Some people even call this bullshit "security"...
-	        	
-	            Method method = sysclass.getDeclaredMethod("addURL",new Class[]{URL.class});
-	            method.setAccessible(true);
-	            method.invoke(sysloader,new Object[]{ urlOfJar });
-	        } catch (Throwable t) {
-	        	throw new LessonLoadingException("Internal Error: The system classloader refused to load the URL of this lesson file. You may want to change the JVM classloader from the command line.",t);
-	        }
-	        
-	        usedJARs.add(jar.getAbsolutePath());
-		}
-        
-		// Load the JAR manifest file to retrieve the lesson's package name in it
-		Manifest manifest;
-		try {
-			manifest = new JarFile(jar).getManifest();
-		} catch (Exception e) {
-			throw new LessonLoadingException("Invalid lesson file (Manifest not found): "+jar.getName(), e);
-		}
-		
-		String lessonPackage = manifest.getMainAttributes().getValue("LessonPackage");
-		if (lessonPackage == null)
-			throw new LessonLoadingException("Invalid lesson file (Attribute 'LessonPackage' not found in Manifest): "+jar.getName());
-		
-		// We are ready to launch this lesson
-		Game.getInstance().switchLesson("lessons." + lessonPackage,false);
-    }//end method
-
-	
-
-	public static void addInitThread(Thread t) {
-		initRunners.add(t);
-	}
-	public static void waitInitThreads() throws InterruptedException {
-		for (Thread t:initRunners) 
-			t.join();
-	}
-
-	public Collection<Lesson> getLessons() {
-		return this.lessons.values();
-	}
-
-	public Lesson getCurrentLesson() {
-		if (this.currentLesson == null && this.lessons.size() > 0) {
-			setCurrentLesson(this.lessons.get(0));
-		}
-		return this.currentLesson;
-	}
-
-	public void setCurrentLesson(Lesson lesson) {
-		try {
-			saveSession(); // don't loose user changes 
-			
-			this.currentLesson = lesson;
-			fireCurrentLessonChanged();
-			setCurrentExercise(this.currentLesson.getCurrentExercise());
-			
-		} catch (UserAbortException e) { 
-			System.out.println(i18n.tr("Operation cancelled by the user"));
-		}
-	}
-
-	// only to avoid that exercise views register as listener of a lesson
-	public void setCurrentExercise(Lecture lect) {
-		try {
-			saveSession(); // don't loose user changes 
-
-			this.currentLesson.setCurrentExercise(lect);
-			fireCurrentExerciseChanged(lect);
-			if (lect instanceof Exercise) {
-				Exercise exo = (Exercise) lect;
-				exo.reset();
-				setSelectedWorld(exo.getWorld(0));
-
-				boolean seenJava=false;
-				for (ProgrammingLanguage l:exo.getProgLanguages()) {
-					if (l.equals(programmingLanguage))
-						return; /* The exo accepts the language we currently have */
-					if (l.equals(Game.JAVA))
-						seenJava = true;
-				}
-				/* Use java as a fallback programming language (if the exo accepts it)  */
-				if (seenJava)
-					setProgramingLanguage(Game.JAVA);
-				/* The exo don't like our currently set language, nor Java. Let's pick its first selected language */
-				setProgramingLanguage( exo.getProgLanguages().iterator().next() );
-			}
-			MainFrame.getInstance().currentExerciseHasChanged(lect); // make sure that the right language is selected -- yeah that's a ugly way of doing it
-
-		} catch (UserAbortException e) { 
-			System.out.println(i18n.tr("Operation cancelled by the user"));
-		}
-	}
-
-	public World getSelectedWorld() {
-		Lecture lecture = this.currentLesson.getCurrentExercise();
-		if (lecture instanceof Exercise) {
-			if (this.selectedWorld == null) {
-				setSelectedWorld(((Exercise) lecture).getWorld(0));
-			}
-			return this.selectedWorld;
-		} else {
-			return null;
-		}
-	}
-	public World[] getSelectedWorlds() {
-		World[] res = new World[3];
-		res[0] = selectedWorld;
-		res[1] = answerOfSelectedWorld;
-		res[2] = initialOfSelectedWorld;
-		return res;
-	}
-
-	public void setSelectedWorld(World world) {
-		Lecture lect = getCurrentLesson().getCurrentExercise();
-		if (lect instanceof Exercise) {
-			Exercise exo = (Exercise) lect;
-			if (this.selectedWorld != null)
-				this.selectedWorld.removeEntityUpdateListener(this);
-			this.selectedWorld = world;
-			this.selectedWorld.addEntityUpdateListener(this);
-
-			int index = exo.indexOfWorld(this.selectedWorld);
-			this.answerOfSelectedWorld = exo.getAnswerOfWorld(index);
-			this.initialOfSelectedWorld = exo.getWorlds(WorldKind.INITIAL).get(index);
-			if (this.selectedWorld.getEntityCount()>0) {
-				this.selectedEntity = this.selectedWorld.getEntity(0);
-			}
-			fireSelectedWorldHasChanged(world);
-		} else {
-			throw new RuntimeException(Game.i18n.tr("The lecture {0} has no world that I can select",lect));
-		}
-	}
-
-	public World getAnswerOfSelectedWorld() {
-		return this.answerOfSelectedWorld;
-	}
-
-	public void setSelectedEntity(Entity b) {
-		this.selectedEntity = b;
-		fireSelectedEntityHasChanged();
-	}
-
-	public Entity getSelectedEntity() {
-		return this.selectedEntity;
-	}
-
-	/* Actions of the toolbar buttons */
-	private boolean stepMode = false;
-	private LessonRunner runner;
-	public void startExerciseExecution() {
-		runner = new LessonRunner(Game.getInstance());
-		runner.start();
-	}
-	public void stopExerciseExecution() {
-		if (stepModeEnabled()) 
-			disableStepMode();
-
-		if (runner != null)
-			runner.stopAll();
-		
-		Lecture lecture = this.currentLesson.getCurrentExercise();
-		if (lecture instanceof Exercise)
-			for (World w : ((Exercise) lecture).getWorlds(WorldKind.ANSWER))
-				w.doneDelay();
-
-		setState(GameState.EXECUTION_ENDED);
-	}
-	public void startExerciseDemoExecution() {
-		DemoRunner runner = new DemoRunner(Game.getInstance(), this.demoRunners);
-		runner.start();
-	}
-	public void startExerciseStepExecution() {
-		stepMode = true;
-		startExerciseExecution();
-	}
-
-	public void enableStepMode() {
-		this.stepMode = true;
-	}
-	public void disableStepMode() {
-		this.stepMode = false;
-	}
-
-	public boolean stepModeEnabled() {
-		return this.stepMode;
-	}
-
-	public void allowOneStep() {
-		Lecture lecture = this.currentLesson.getCurrentExercise();
-		if (lecture instanceof Exercise)
-			for (World w: ((Exercise) lecture).getWorlds(WorldKind.CURRENT))
-				for (Entity e : w.getEntities())
-					e.allowOneStep();
-	}
-
-	/**  Reset the current exercise (see {@link Exercise.reset()} */
-	public void reset() {
-		Lecture lecture = this.currentLesson.getCurrentExercise();
-		if (lecture instanceof Exercise) {
-			((Exercise) lecture).reset();
-			fireCurrentExerciseChanged(lecture);
-		}
-	}
-
-	public void setState(GameState status) {
-		this.state = status;
-		fireStateChanged(status);
-	}
-
-	public GameState getState() {
-		return this.state;
-	}
-
-	public void setOutputWriter(LogWriter writer) {
-		this.outputWriter = writer;
-		if (!getProperty(PROP_OUTPUT_CAPTURE, "false",true).equals("true")) {
-			Logger l = new Logger(outputWriter);
-			System.setOut(l);
-			System.setErr(l);
-		}
-	}
-
-	public LogWriter getOutputWriter() {
-		return this.outputWriter;
-	}
-
-	public void quit() {
-		try {
-			// FIXME: this method is not called when pressing APPLE+Q on OSX
-
-            // report user leave on the server
-            for(ProgressSpyListener spyListener: progressSpyListeners){
-                spyListener.leave();
-            }
-            // stop the heartbeat report to JLMServer
-            if(heartBeatSpy != null)
-                heartBeatSpy.die();
-
-			saveSession();
-			storeProperties();
-			System.exit(0);
-		} catch (UserAbortException e) {
-			// Ok, user decided to not quit (to get a chance to export the session)
-			System.out.println("Exit aborted");
-		}
-	}
-
-	public void clearSession() {
-		this.sessionKit.cleanAll(SAVE_DIR);
-		for (Lesson l : this.lessons.values())
-			for (Lecture lect : l.exercises())
-				if (lect instanceof Exercise)
-					for (ProgrammingLanguage lang:((Exercise) lect).getProgLanguages()) 
-						Game.getInstance().studentWork.setPassed(lect, lang, false);
-
-		fireCurrentExerciseChanged(currentLesson.getCurrentExercise());
-	}
-
-	public void loadSession() {
-		this.setState(GameState.LOADING);
-		this.sessionKit.loadAll(SAVE_DIR);
-		this.setState(GameState.LOADING_DONE);
-	}
-
-	public void saveSession() throws UserAbortException {
-		this.setState(GameState.SAVING);
-		this.sessionKit.storeAll(SAVE_DIR);
-		this.setState(GameState.SAVING_DONE);
-	}
-
-	public ISessionKit getSessionKit() {
-		return this.sessionKit;
-	}
-
-	public static void loadProperties() {
-		InputStream is = null;
-		try {
-			is = Game.class.getClassLoader().getResourceAsStream("resources/jlm.configuration.properties");
-			if (is==null) // try to find the file in the debian package
-				is = Game.class.getClassLoader().getResourceAsStream("/etc/jlm.configuration.properties");
-			Game.defaultGameProperties.load(is);
-		} catch (InvalidPropertiesFormatException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		} catch (NullPointerException e) {
-			// resources/jlm.configuration.properties not found. Try jlm.configuration.properties afterward
-		} finally {
-			if (is != null)
-				try {
-					is.close();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-		}
-
-		File localPropertiesFile = new File(SAVE_DIR + File.separator + Game.LOCAL_PROPERTIES_FILENAME);
-		if (localPropertiesFile.exists()) {
-			FileInputStream fi = null;
-			try {
-				fi = new FileInputStream(localPropertiesFile);
-				Game.localGameProperties.load(fi);
-				Game.localGamePropertiesLoadedFile = localPropertiesFile;
-			} catch (InvalidPropertiesFormatException e) {
-				e.printStackTrace();
-			} catch (FileNotFoundException e) {
-				e.printStackTrace();
-			} catch (IOException e) {
-				e.printStackTrace();
-			} finally {
-				if (fi != null)
-					try {
-						fi.close();
-					} catch (IOException e) {
-						e.printStackTrace();
-					}
-			}
-			System.out.println(String.format("Loading properties [%s]", localPropertiesFile));
-		}
-	}
-
-	public static void storeProperties() {
-		Game.localGamePropertiesLoadedFile = new File(SAVE_DIR + File.separator + Game.LOCAL_PROPERTIES_FILENAME);
-		FileOutputStream fo;
-		try {
-			fo = new FileOutputStream(Game.localGamePropertiesLoadedFile);
-			Game.localGameProperties.store(fo, "Java Learning Machine properties");
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-	}
-	public static void setProperty(String key, String value) {
-		Game.localGameProperties.setProperty(key, value);
-	}
-
-	public static String getProperty(String key) {
-		return Game.getProperty(key, "", false);
-	}
-
-	/** 
-	 * Gets the value from either the local properties set (in ~/.jlm) or the global one (in the jar file).
-	 * If the value is not defined in either of them, use the default value. If so and if the save parameter is true, this is saved back to the local properties file. 
-	 */
-	public static String getProperty(String key, String defaultValue, boolean save) {
-		if (Game.localGameProperties.containsKey(key)) {
-			return Game.localGameProperties.getProperty(key);
-		} else {
-			String res = Game.defaultGameProperties.getProperty(key, defaultValue);
-			if (save)
-				setProperty(key, res);
-			return res;
-		}
-	}
-
-	public void addGameListener(GameListener l) {
-		this.listeners.add(l);
-	}
-
-	public void removeGameListener(GameListener l) {
-		this.listeners.remove(l);
-	}
-
-	protected void fireCurrentLessonChanged() {
-		for (GameListener v : this.listeners) {
-			v.currentLessonHasChanged();
-		}
-	}
-
-    protected void fireCurrentExerciseChanged(Lecture lect) {
-		if (stepModeEnabled())
-			disableStepMode();
-
-        for (GameListener v : this.listeners) {
-            v.currentExerciseHasChanged(lect);
-        }
-
-        if(lect instanceof Exercise){
-            for(ProgressSpyListener p: this.progressSpyListeners){
-                p.switched((Exercise)lect);
-            }
-        }
-    }
-
-	protected void fireSelectedWorldHasChanged(World w) {
-		for (GameListener v : this.listeners) {
-			v.selectedWorldHasChanged(w);
-		}
-	}
-
-	protected void fireSelectedWorldWasUpdated() {
-		for (GameListener v : this.listeners) {
-			v.selectedWorldWasUpdated();
-		}
-	}
-
-	protected void fireSelectedEntityHasChanged() {
-		for (GameListener v : this.listeners) {
-			v.selectedEntityHasChanged();
-		}
-	}
-
-	public void addGameStateListener(GameStateListener l) {
-		this.gameStateListeners.add(l);
-	}
-
-	public void removeGameStateListener(GameStateListener l) {
-		this.gameStateListeners.remove(l);
-	}
-
-	protected void fireStateChanged(GameState status) {
-		for (GameStateListener l : this.gameStateListeners) 
-			l.stateChanged(status);
-	}
-
-	private ArrayList<ProgressSpyListener> progressSpyListeners = new ArrayList<ProgressSpyListener>();
-	public void addProgressSpyListener(ProgressSpyListener l) {
-		this.progressSpyListeners.add(l);
-	}
-	public void removeProgressSpyListener(ProgressSpyListener l) {
-		this.progressSpyListeners.remove(l);
-	}
-	public void fireProgressSpy(Exercise exo) {
-		for (ProgressSpyListener l : this.progressSpyListeners) {
-			l.executed(exo);
-		}
-	}
-
-	@Override
-	public void worldHasChanged() {
-		if (selectedWorld.getEntityCount()>0)
-			setSelectedEntity(this.selectedWorld.getEntity(0));
-		fireSelectedWorldWasUpdated();
-	}
-
-	@Override
-	public void worldHasMoved() {
-		// don't really care that something moved within the current world
-	}
-
-	/* Status bar label changing logic */
-	ArrayList<StatusStateListener> statusStateListeners = new ArrayList<StatusStateListener>();
-	public void addStatusStateListener(StatusStateListener l) {
-		this.statusStateListeners.add(l);
-	}
-	public void removeStatusStateListener(StatusStateListener l) {
-		this.statusStateListeners.remove(l);
-	}
-	ArrayList<String> statusArgs = new ArrayList<String>();
-	String stateTxt = "";
-	public void statusRootSet(String txt) {
-		stateTxt = txt;
-	}
-	public void statusArgAdd(String txt) {
-		synchronized (statusArgs) {
-			statusArgs.add(txt);
-			statusChanged();
-		}
-	}
-	public void statusArgRemove(String txt) {
-		synchronized (statusArgs) {
-			statusArgs.remove(txt);
-			statusChanged();
-		}
-	}
-	public void statusArgEmpty(){
-		synchronized (statusArgs) {
-			statusArgs.clear();
-			statusChanged();
-		}
-	}
-	private void statusChanged() {
-		StringBuffer sb = new StringBuffer(stateTxt);
-		boolean first = true;
-		for (String s:statusArgs) {
-			if (first)
-				first = false;
-			else
-				sb.append(", ");
-			sb.append(s);
-		}
-		
-		String msg = first ? "" : sb.toString(); // remove everything if no argument at all 
-		for (StatusStateListener l : this.statusStateListeners) 
-			l.stateChanged(msg);
-	}
-	public void setLocale(Locale lang) {
-		FileUtils.setLocale(lang);
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-		fireHumanLangChange(lang);
-
-		/* FIXME: convert all this to a humanLanguage listener */
-		if (  Game.getInstance() != null && Game.getInstance().getCurrentLesson() != null ) {
-			Game.getInstance().getCurrentLesson().resetAboutLoaded();
-			Lecture lect = Game.getInstance().getCurrentLesson().getCurrentExercise();
-			if ( lect instanceof Exercise )
-				((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).resetAbout();
-		}
-
-		for (Lesson lesson : lessons.values()) {
-			for (Lecture lect:lesson.exercises()) {
-				if (lect instanceof ExerciseTemplated) {
-					lect.loadHTMLMission();
-				}
-			}
-		}
-		setCurrentLesson(getCurrentLesson());
-		currentLesson.setCurrentExercise(currentLesson.getCurrentExercise());
-	}
-	public Locale getLocale(){
-		return FileUtils.getLocale();
-	}
-
-
-
-	public void setProgramingLanguage(ProgrammingLanguage newLanguage) {
-		if (programmingLanguage.equals(newLanguage))
-			return;
-
-		if (isValidProgLanguage(newLanguage)) {
-			//System.out.println("Switch programming language to "+newLanguage);
-			this.programmingLanguage = newLanguage;
-			fireProgLangChange(newLanguage);
-			// TODO: do that only if the selected language is stable enough as this language will be used to compute all answers at the next startup
-			setProperty(PROP_PROGRAMING_LANGUAGE, newLanguage.lang);
-			return;
-		}
-		throw new RuntimeException("Ignoring request to switch the programming language to the unknown "+newLanguage);
-	}
-
-	public static ProgrammingLanguage getProgrammingLanguage() {
-		if (ongoingInitialization) /* break an initialization loop -- the crude way (FIXME) */
-			return JAVA;
-		else
-			return getInstance().programmingLanguage;
-	}
-	public static ProgrammingLanguage[] getProgrammingLanguages(){
-		return programmingLanguages;
-	}
-
-	public boolean isValidProgLanguage(ProgrammingLanguage newL) {
-		for (ProgrammingLanguage pl : programmingLanguages)
-			if (pl.equals(newL))
-				return true;
-		return false;
-	}
-	private List<ProgLangChangesListener> progLangListeners = new Vector<ProgLangChangesListener>();
-	public void addProgLangListener(ProgLangChangesListener l) {
-		progLangListeners.add(l);
-	}
-	public void fireProgLangChange(ProgrammingLanguage newLang) {
-		for (ProgLangChangesListener l : progLangListeners)
-			l.currentProgrammingLanguageHasChanged(newLang);
-	}
-	public void removeProgLangListener(ProgLangChangesListener l) {
-		this.progLangListeners.remove(l);
-	}
-
-	private List<HumanLangChangesListener> humanLangListeners = new Vector<HumanLangChangesListener>();
-	public void addHumanLangListener(HumanLangChangesListener l) {
-		humanLangListeners.add(l);
-	}
-	public void fireHumanLangChange(Locale newLang) {
-		for (HumanLangChangesListener l : humanLangListeners)
-			l.currentHumanLanguageHasChanged(newLang);
-	}
-	public void removeHumanLangListener(HumanLangChangesListener l) {
-		this.humanLangListeners.remove(l);
-	}
-	
-	private boolean doDebug = false;
-	public void switchDebug() {
-		doDebug = !doDebug;
-		if (doDebug) {
-			Lesson l = Game.getInstance().getCurrentLesson();
-			System.out.println("Saving location: "+SAVE_DIR.getAbsolutePath());
-			System.out.println("Lesson: "+(l==null?"None loaded yet":l.getName()));
-			System.out.println("Exercise: "+(l==null?"None loaded yet":l.getCurrentExercise().getName()));
-			System.out.println("JLM version: "+Game.getProperty("jlm.major.version","internal",false)+" ("+Game.getProperty("jlm.major.version","internal",false)+"."+Game.getProperty("jlm.minor.version","",false)+")");
-			System.out.println("Java version: "+System.getProperty("java.version")+" (VM: "+ System.getProperty("java.vm.name")+" "+ System.getProperty("java.vm.version")+")");
-			System.out.println("System: " +System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")");
-		}
-	}
-	public boolean isDebugEnabled() {
-		return doDebug;
-	}
-
-    /*
-     * Getter and Setter for the course ID for the current session.
-     * This ID will be used by the ServerSpy, to associate this
-     * JLM student with a course started by a teacher on the server
-     */
-    public String getCourseID() {
-    	if (this.currentCourse == null)
-    		return "";
-    	else
-    		return currentCourse.getCourseId();
-    }
-
-    public String getCoursePassword(){
-        if(this.currentCourse == null)
-            return "";
-        else
-            return currentCourse.getPassword();
-    }
-
-    public void setCourseID(String courseID) {
-    	this.currentCourse.setCourseId(courseID);
-    }
-
-    public Course getCurrentCourse() {
-        return currentCourse;
-    }
-
-    public void setCurrentCourse(Course currentCourse) {
-        this.currentCourse = currentCourse;
-    }
-
-    public HeartBeatSpy getHeartBeatSpy(){ return this.heartBeatSpy; }
-
-    public void setHeartBeatSpy(HeartBeatSpy heartBeatSpy){ this.heartBeatSpy = heartBeatSpy; }
-
-    public ArrayList<ProgressSpyListener> getProgressSpyListeners(){ return this.progressSpyListeners; }
-    
-    
-    /* Mechanism to find where to save our data */
-	
-    private static String HOME_DIR = System.getProperty("user.home");
-	
-	/* These names are tested one after the other, searching for one that exist or that we can create */
-	static String[] rootDirNames = new String[] { 
-		HOME_DIR + File.separator + ".jlm", /* preferred, default directory name */
-		HOME_DIR + File.separator + "_jlm", /* Some paranoid administrator refuse directories which name starts with a dot */
-		HOME_DIR + File.separator + "jlm",  /* one day, hidden directories with make trouble... */
-		"z:"     + File.separator + ".jlm", /* windows-preferred directory name */
-		"z:"     + File.separator + "_jlm",
-		"z:"     + File.separator + "jlm",
-	};
-	private static File SAVE_DIR = initializeSaveDir();
-	private static File initializeSaveDir() {
-		StringBuffer sb = new StringBuffer();
-		for (String path : rootDirNames) {
-			File res = new File(path);
-			sb.append(path);
-			sb.append(", ");
-			try {
-				if (res.exists()) {
-					if (res.isDirectory()) {
-						if (res.canWrite()) {
-							return res;
-						} else {
-							System.out.println(i18n.tr("{0} is not writable",res.getAbsolutePath()));
-							continue;
-						}
-					} else {
-						System.out.println(i18n.tr("{0} is not a directory",res.getAbsolutePath()));
-						continue;
-					}
-				}
-				if (res.mkdir())
-					return res;
-				else {
-					System.out.println(i18n.tr("Cannot create {0}",res.getAbsolutePath()));
-				}
-			} catch (SecurityException e) {
-				e.getLocalizedMessage();
-			}
-		}
-		throw new RuntimeException(i18n.tr("Impossible to find a path for JLM datas. Tested {0}",sb.toString()));
-	}
-	public static String getSavingLocation() {
-		return SAVE_DIR.getPath();
-	}
-}
diff --git a/src/jlm/core/model/HelpAppEngine.java b/src/jlm/core/model/HelpAppEngine.java
deleted file mode 100644
index 746df4f..0000000
--- a/src/jlm/core/model/HelpAppEngine.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package jlm.core.model;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-
-import org.json.simple.JSONObject;
-
-/**
- * Implementation of HelpServer that sends requests to an App Engine server
- */
-public class HelpAppEngine extends HelpServer {
-
-    private static URL helpServer;
-
-    public HelpAppEngine() {
-    	String url = Game.getProperty(Game.PROP_APPENGINE_URL);
-    	if (! url.equals("")) { // no configuration were provided
-    		try {
-    			helpServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/student");
-    		} catch (MalformedURLException e) {
-    			e.printStackTrace();
-    		}
-    	} else {
-    		System.out.println("No course server configured");
-    	}
-    }
-
-    @Override
-    public String sendRequest(String request) {
-        String response = "";
-        try {
-
-            // Send data
-            URLConnection conn = helpServer.openConnection();
-            conn.setDoOutput(true);
-            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
-            wr.write(request);
-            wr.flush();
-
-            // Get response data and print it
-            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-            String line;
-            while ((line = br.readLine()) != null)
-            	response += line;
-
-            wr.close();
-            br.close();
-        } catch (IOException e) {
-            System.out.println("Unable to contact JLMServer to send request " + request);
-        }
-        return response;
-    }
-    
-    /**
-     * Construct a request to ask teacher help in a course
-     */
-    @Override
-    public void setStatus(boolean isRequestingHelp){
-    	super.setStatus(isRequestingHelp);
-
-        JSONObject jsonObject = new JSONObject();
-		jsonObject.put("username", username);
-		jsonObject.put("action", "help");
-        jsonObject.put("course", Game.getInstance().getCourseID());
-        jsonObject.put("password", Game.getInstance().getCoursePassword());
-        jsonObject.put("status", isRequestingHelp ? "true" : "false");
-
-		sendRequest(jsonObject.toString());
-    }
-
-}
-
diff --git a/src/jlm/core/model/HelpServer.java b/src/jlm/core/model/HelpServer.java
deleted file mode 100644
index 2563a90..0000000
--- a/src/jlm/core/model/HelpServer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package jlm.core.model;
-
-import jlm.core.ui.MainFrame;
-
-/**
- * Abstract class that allows the user to ask help to a teacher by clicking on help button
- * This class only constructs the request with JSON, an implementation must be done to send requests
- * For now it's App Engine which is used
- */
-public abstract class HelpServer {
-	protected String username;
-    // the user is already requesting help
-
-	public HelpServer() {
-		username = System.getenv("USER");
-		if (username == null)
-			username = System.getenv("USERNAME");
-		if (username == null)
-			username = "John Doe";
-	}
-
-    /**
-     * Construct a request to ask teacher help in a course
-     */
-    public void setStatus(boolean isRequestingHelp){
-    	if (isRequestingHelp) {
-    		System.out.println(MainFrame.getInstance().i18n.tr("Asking to the teacher for help"));
-    	} else {
-    		System.out.println(MainFrame.getInstance().i18n.tr("Cancel call for help to the teacher"));
-    	}    
-    }
-
-   	/**
-	 * Method to implement to indicate how/where to send data
-	 *
-	 * @param request
-	 *            request in json to send to the server
-	 */
-    public abstract String sendRequest(String request);
-
-}
diff --git a/src/jlm/core/model/LessonLoadingException.java b/src/jlm/core/model/LessonLoadingException.java
deleted file mode 100644
index eed9bb9..0000000
--- a/src/jlm/core/model/LessonLoadingException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package jlm.core.model;
-
-public class LessonLoadingException extends Exception {
-	private static final long serialVersionUID = 1L;
-
-	public LessonLoadingException(String msg) {
-		super(msg);
-	}
-
-	public LessonLoadingException(String msg, Throwable t) {
-		super(msg,t);
-	}
-}
diff --git a/src/jlm/core/model/LessonRunner.java b/src/jlm/core/model/LessonRunner.java
deleted file mode 100644
index 76b3b80..0000000
--- a/src/jlm/core/model/LessonRunner.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package jlm.core.model;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.JOptionPane;
-import javax.swing.SwingUtilities;
-
-import jlm.core.JLMCompilerException;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.ui.ExerciseFailedDialog;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.utils.FileUtils;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-/** 
- * This class runs the student code of the current exercise in a separated thread 
- * when the Run button is clicked. The run and demo buttons are disabled until the demo ends.
- * 
- * It sends an update to the remote GoogleAppEngine when the exercise is successfully passed.
- * 
- * Activated by {@link Game#startExerciseExecution()} and {@link Game#startExerciseStepExecution()}.
- */
-public class LessonRunner extends Thread {
-	
-	private Game game;
-	private List<Thread> runners = new LinkedList<Thread>(); // threads who run entities from lesson
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages", FileUtils.getLocale(), I18nFactory.FALLBACK);
-
-	public LessonRunner(Game game) {
-		super();
-		this.game = game;
-	}
-
-	@Override
-	public void run() {
-		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
-		if (! (lect instanceof Exercise))
-			return;
-		final Exercise exo = (Exercise) lect;
-		
-		exo.lastResult = new ExecutionProgress();
-		
-		try {
-			game.saveSession(); // for safety reasons;
-			
-			game.setState(Game.GameState.COMPILATION_STARTED);
-			exo.compileAll(this.game.getOutputWriter());
-			game.setState(Game.GameState.COMPILATION_ENDED);
-			
-			game.setState(Game.GameState.EXECUTION_STARTED);
-			exo.reset();
-			
-			exo.run(runners);
-			while (runners.size()>0) {
-				Thread t = runners.remove(0);
-				t.join();
-			}
-			
-			exo.check();
-			game.setState(Game.GameState.EXECUTION_ENDED);
-
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-//			game.getOutputWriter().log(e);
-			game.setState(Game.GameState.EXECUTION_ENDED);
-		} catch (JLMCompilerException e) {
-			game.setState(Game.GameState.COMPILATION_ENDED);
-			game.setState(Game.GameState.EXECUTION_ENDED);
-		} catch (Exception e) {
-			e.printStackTrace();
-//			game.getOutputWriter().log(e);
-			game.setState(Game.GameState.COMPILATION_ENDED);
-			game.setState(Game.GameState.EXECUTION_ENDED);
-		}
-		
-		if (   exo.lastResult.totalTests > 0 
-			&& exo.lastResult.totalTests == exo.lastResult.passedTests) {
-			Game.getInstance().studentWork.setPassed(exo, null, true);
-			
-			Vector<Lecture> nextExercises =  exo.getDependingLectures();	
-			if ( nextExercises.size() == 0) {
-				if (exo.lastResult.passedTests > 1) {
-					JOptionPane.showMessageDialog(null, 
-							i18n.tr("Congratulations, you passed this exercise.\n{0} tests passed.",
-									exo.lastResult.passedTests) + exo.lastResult.details, 
-									i18n.tr("Exercice passed \\o/"), 
-									JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"));
-				} else {
-					JOptionPane.showMessageDialog(null, 
-							i18n.tr("Congratulations, you passed this exercise.",
-									exo.lastResult.passedTests) + exo.lastResult.details, 
-									i18n.tr("Exercice passed \\o/"), 
-									JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"));
-				}
-			} else {
-				Lecture selectedValue;
-				if (exo.lastResult.passedTests > 1) {
-
-					selectedValue = (Lecture) JOptionPane.showInputDialog(null, 
-							i18n.tr("Congratulations, you passed this exercise.\n({0} tests passed)\nWhich exercise will you do now?"), 
-							i18n.tr("Exercice passed \\o/"),
-							JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"),
-							nextExercises.toArray(), nextExercises.get(0));
-				} else {
-					selectedValue = (Lecture) JOptionPane.showInputDialog(null, 
-							i18n.tr("Congratulations, you passed this exercise.\nWhich exercise will you do now?"), 
-							i18n.tr("Exercice passed \\o/"),
-							JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"),
-							nextExercises.toArray(), nextExercises.get(0));
-					
-				}
-				if (selectedValue != null) 
-					Game.getInstance().setCurrentExercise(selectedValue);
-			}
-		} else {
-			 SwingUtilities.invokeLater(new Runnable() {
-		            public void run() {
-		            	new ExerciseFailedDialog(exo.lastResult);
-		            }
-		        });
-
-		}
-		Game.getInstance().fireProgressSpy(exo);									
-
-		runners.remove(this);
-	}
-	
-	/** Stop all the threads that were already started. Harmful but who cares? */
-	@SuppressWarnings("deprecation")
-	public void stopAll() {
-		while (runners.size()>0) {
-			Thread t = runners.remove(runners.size() - 1);
-			t.stop(); // harmful but who cares ?
-		}
-	}
-	
-}
diff --git a/src/jlm/core/model/LogWriter.java b/src/jlm/core/model/LogWriter.java
deleted file mode 100644
index 64744b9..0000000
--- a/src/jlm/core/model/LogWriter.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package jlm.core.model;
-
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-/**
- * Interface that all output consoles that we may use must implement. 
- * 
- * There is only one of them, but I was told that interfaces are the right way for a model to speak of its view elements.
- */
-public interface LogWriter {
-
-	public void log(String msg) ;
-
-	public void log(DiagnosticCollector<JavaFileObject> diagnostics) ;
-	
-	public void log(Exception e) ;
-}
diff --git a/src/jlm/core/model/Logger.java b/src/jlm/core/model/Logger.java
deleted file mode 100644
index a291f5d..0000000
--- a/src/jlm/core/model/Logger.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package jlm.core.model;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-
-
-/**
- * The log console used within JLM. It is setup by Game as the default System.out, 
- * and points into the console pane at the bottom of the interface.
- */
-public class Logger extends PrintStream {
-	private LogWriter writer;
-	private static boolean ENABLED = true;
-
-	public static void log(String method, String msg) {
-		if (Logger.ENABLED)
-			System.out.println("[" + System.currentTimeMillis() + "] " + method + " " + msg);
-	}
-	
-	public Logger(LogWriter w){
-		super(new ByteArrayOutputStream());
-		writer = w;
-	}
-
-	@Override
-	public void print(boolean b) {
-		writer.log(""+b);
-	}
-
-	@Override
-	public void print(char c) {
-		writer.log(""+c);
-	}
-
-	@Override
-	public void print(char[] s) {
-		StringBuilder stringBuilder = new StringBuilder();
-		stringBuilder.append(s);
-		writer.log(stringBuilder.toString());
-	}
-
-	@Override
-	public void print(double d) {
-		writer.log(""+d);
-	}
-
-	@Override
-	public void print(float f) {
-		writer.log(""+f);
-	}
-
-	@Override
-	public void print(int i) {
-		writer.log(""+i);
-	}
-
-	@Override
-	public void print(long l) {
-		writer.log(""+l);
-	}
-
-	@Override
-	public void print(Object obj) {
-		writer.log(obj.toString());
-	}
-
-	@Override
-	public void print(String s) {
-		writer.log(s);
-	}
-
-	@Override
-	public void println() {
-		writer.log("\n");
-	}
-
-	@Override
-	public void println(boolean x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(char x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(char[] x) {
-		StringBuilder stringBuilder = new StringBuilder();
-		stringBuilder.append(x);
-		stringBuilder.append("\n");
-		writer.log(stringBuilder.toString());
-	}
-
-	@Override
-	public void println(double x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(float x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(int x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(long x) {
-		writer.log(""+x+"\n");
-	}
-
-	@Override
-	public void println(Object x) {
-		writer.log(x.toString()+"\n");
-	}
-
-	@Override
-	public void println(String x) {
-		writer.log(x+"\n");
-	}
-}
diff --git a/src/jlm/core/model/ProgrammingLanguage.java b/src/jlm/core/model/ProgrammingLanguage.java
deleted file mode 100644
index b1d969e..0000000
--- a/src/jlm/core/model/ProgrammingLanguage.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package jlm.core.model;
-
-import javax.swing.ImageIcon;
-
-public class ProgrammingLanguage implements Comparable<ProgrammingLanguage> {
-	String lang;
-	String ext;
-	ImageIcon icon;
-	public ProgrammingLanguage(String l, String ext, ImageIcon i) {
-		lang = l;
-		this.ext = ext;
-		this.icon = i;
-	}
-	public boolean equals(Object o) {
-		if (!super.equals(o))
-			return false;
-		if (getClass() != o.getClass())
-			return false;
-		return lang.equals(((ProgrammingLanguage)o).lang);
-	}
-	public String getLang() {
-		return lang;
-	}
-	public String getExt() {
-		return ext;
-	}
-	@Override
-	public String toString() {
-		return lang;
-	}
-	@Override
-	public int hashCode() {
-		return lang.hashCode();
-	}
-	@Override
-	public int compareTo(ProgrammingLanguage o) {
-		if (o == null)
-			return 1;
-		int res = lang.compareTo(o.lang);
-		if (res != 0)
-			return res;
-		return ext.compareTo(o.ext);
-	}
-	public ImageIcon getIcon() {
-		return icon;
-	}
-}
diff --git a/src/jlm/core/model/ServerAnswer.java b/src/jlm/core/model/ServerAnswer.java
deleted file mode 100644
index 229b28b..0000000
--- a/src/jlm/core/model/ServerAnswer.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package jlm.core.model;
-
-/**
- * Enum that contains all answers that the server can send (errors or success messages)
- */
-public enum ServerAnswer {
-	ALL_IS_FINE, WRONG_PASSWORD, WRONG_TEACHER_PASSWORD, COURSE_NAME_ALREADY_USED, DATA_NOT_IN_DATABASE
-}
diff --git a/src/jlm/core/model/ServerExerciseData.java b/src/jlm/core/model/ServerExerciseData.java
deleted file mode 100644
index 0a158a6..0000000
--- a/src/jlm/core/model/ServerExerciseData.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package jlm.core.model;
-
-import java.util.Date;
-
-/**
- * Class that contains exercises data sent by the server
- * It describes an exercise and its results
- */
-public class ServerExerciseData {
-
-	private String name;
-	private String lang;
-	private int passedTests;
-	private int totalTests;
-	private String source;
-	private Date date;
-	
-	public String getName() {
-		return name;
-	}
-	
-	public void setName(String name) {
-		this.name = name;
-	}
-	
-	public String getLang() {
-		return lang;
-	}
-	
-	public void setLang(String lang) {
-		this.lang = lang;
-	}
-	
-	public int getPassedTests() {
-		return passedTests;
-	}
-	
-	public void setPassedTests(int passedTests) {
-		this.passedTests = passedTests;
-	}
-	
-	public int getTotalTests() {
-		return totalTests;
-	}
-	
-	public void setTotalTests(int totalTests) {
-		this.totalTests = totalTests;
-	}
-	
-	public String getSource() {
-		return source;
-	}
-	
-	public void setSource(String source) {
-		this.source = source;
-	}
-	
-	public Date getDate() {
-		return date;
-	}
-	
-	public void setDate(Date date) {
-		this.date = date;
-	}
-	
-	@Override
-	public String toString() {
-		return "Exercise [name=" + name + ", lang=" + lang + ", passedTests="
-				+ passedTests + ", totalTests=" + totalTests + ", source="
-				+ source + ", date=" + date + "]";
-	}
-
-}
diff --git a/src/jlm/core/model/ServerUserData.java b/src/jlm/core/model/ServerUserData.java
deleted file mode 100644
index 9b045ab..0000000
--- a/src/jlm/core/model/ServerUserData.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package jlm.core.model;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-
-/**
- * Class that contains the data sent by the server
- * It describes a student and its results
- */
-public class ServerUserData {
-
-    private String username;
-    private List<ServerExerciseData> exercises;
-    private Date lastJoin;
-    private Date lastLeave;
-    private Date lastHeartbeat;
-
-    public ServerUserData() {
-        exercises = new ArrayList<ServerExerciseData>();
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public List<ServerExerciseData> getExercises() {
-        return exercises;
-    }
-
-    public Date getLastJoin() {
-        return lastJoin;
-    }
-
-    public void setLastJoin(Date lastJoin) {
-        this.lastJoin = lastJoin;
-    }
-
-    public Date getLastLeave() {
-        return lastLeave;
-    }
-
-    public void setLastLeave(Date lastLeave) {
-        this.lastLeave = lastLeave;
-    }
-
-    public Date getLastHeartbeat() {
-        return lastHeartbeat;
-    }
-
-    public void setLastHeartbeat(Date lastHeartbeat) {
-        this.lastHeartbeat = lastHeartbeat;
-    }
-
-    @Override
-    public String toString() {
-        return "User [username=" + username + ", exercises=" + exercises
-                + ", lastJoin=" + lastJoin + ", lastLeave=" + lastLeave
-                + ", lastHeartbeat=" + lastHeartbeat + "]";
-    }
-
-    /**
-     * Method to transform a json response from the server to ServerUserData objects
-     * @param answer response to parse
-     * @return list of results by student
-     */
-    public static Map<String, ServerUserData> parse(String answer) {
-        Map<String, ServerUserData> data = new HashMap<String, ServerUserData>();
-
-        JSONObject dataMap = (JSONObject) JSONValue.parse(answer);
-        // for each user
-        for (Object user : dataMap.keySet()) {
-            JSONObject userMap = (JSONObject) dataMap.get(user);
-            ServerUserData sud = new ServerUserData();
-            sud.setUsername((String) userMap.get("username"));
-
-            String lastJoinString = (String) userMap.get("lastJoin");
-            sud.setLastJoin(lastJoinString == null ? null : new Date(lastJoinString));
-
-            String lastHeartbeatString = (String)userMap.get("lastHeartbeat");
-            sud.setLastHeartbeat(lastHeartbeatString == null ? null : new Date(lastHeartbeatString));
-
-            String lastLeaveString = (String)userMap.get("lastLeave");
-            sud.setLastLeave(lastLeaveString == null ? null : new Date(lastLeaveString));
-
-            JSONArray exercisesArray = (JSONArray) userMap.get("exercises");
-            // for each exercise done by the user
-            for (Object anExercisesArray : exercisesArray) {
-                JSONObject exerciseMap = (JSONObject) anExercisesArray;
-                ServerExerciseData sed = new ServerExerciseData();
-                sed.setName((String) exerciseMap.get("name"));
-                sed.setLang((String) exerciseMap.get("lang"));
-                sed.setPassedTests((Integer) exerciseMap.get("passedTests"));
-                sed.setTotalTests((Integer) exerciseMap.get("totalTests"));
-                sed.setSource((String) exerciseMap.get("source"));
-                sed.setDate(new Date((String) exerciseMap.get("date")));
-
-                sud.getExercises().add(sed);
-            }
-
-            data.put((String)user, sud);
-        }
-
-        return data;
-    }
-
-    /**
-     * Get the number of exercises passed successfully in all exercises done
-     * @return the number..
-     */
-    public int getExercisesPassed(){
-        int exercisesPassed = 0;
-        for(ServerExerciseData exercise: exercises){
-            exercisesPassed += exercise.getPassedTests();
-        }
-
-        return exercisesPassed;
-    }
-
-    /**
-     * Get the total number of exercises performed (successfully or with fail)
-     * @return number
-     */
-    public int getExercisesTotal(){
-        int exercisesTotal = 0;
-        for(ServerExerciseData exercise: exercises){
-            exercisesTotal += exercise.getTotalTests();
-        }
-
-        return exercisesTotal;
-    }
-}
diff --git a/src/jlm/core/model/UserAbortException.java b/src/jlm/core/model/UserAbortException.java
deleted file mode 100644
index 9b09f15..0000000
--- a/src/jlm/core/model/UserAbortException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package jlm.core.model;
-
-
-/**
- * Exception raised when the user cancels the "Quit" procedure.
- */
-public class UserAbortException extends Exception {
-	private static final long serialVersionUID = 1L;
-	public UserAbortException(String msg) {
-		super(msg);
-	}
-	public UserAbortException(String msg, Exception ex) {
-		super(msg,ex);
-	}
-}
diff --git a/src/jlm/core/model/lesson/AccessibleExercisesListener.java b/src/jlm/core/model/lesson/AccessibleExercisesListener.java
deleted file mode 100644
index c17c672..0000000
--- a/src/jlm/core/model/lesson/AccessibleExercisesListener.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package jlm.core.model.lesson;
-
-public interface AccessibleExercisesListener {
-	void accessibleExercisesChanged();
-}
diff --git a/src/jlm/core/model/lesson/BrokenLessonException.java b/src/jlm/core/model/lesson/BrokenLessonException.java
deleted file mode 100644
index 45cf32c..0000000
--- a/src/jlm/core/model/lesson/BrokenLessonException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package jlm.core.model.lesson;
-
-public class BrokenLessonException extends RuntimeException {
-
-	public BrokenLessonException(String msg) {
-		super(msg);
-	}
-
-	private static final long serialVersionUID = 1L;
-
-}
diff --git a/src/jlm/core/model/lesson/ExecutionProgress.java b/src/jlm/core/model/lesson/ExecutionProgress.java
deleted file mode 100644
index dae6443..0000000
--- a/src/jlm/core/model/lesson/ExecutionProgress.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.util.Date;
-
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-
-/** Class representing the result of pressing on the "run" button. Either a compilation error, or a percentage of passed/failed tests + a descriptive message */ 
-public class ExecutionProgress {
-	public String compilationError;
-	public int passedTests, totalTests=0;
-	public String details = "";
-	public Date date = new Date();
-	public ProgrammingLanguage language = Game.getProgrammingLanguage();
-
-	public static ExecutionProgress newCompilationError(
-			DiagnosticCollector<JavaFileObject> diagnostics) {
-		ExecutionProgress ep = new ExecutionProgress();
-		StringBuffer sb = new StringBuffer();
-		for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {			
-			sb.append(diagnostic.getSource().getName()+":"+diagnostic.getLineNumber()+":"+ diagnostic.getMessage(null));
-			sb.append("\n");
-		}
-
-		ep.compilationError = sb.toString();
-		ep.passedTests = -1;
-		ep.totalTests = -1;
-		if (ep.compilationError == null)
-			ep.compilationError = "Unknown compilation error";
-		return ep;
-	}
-	
-	public void setCompilationError(String msg) {
-		compilationError = msg;
-		passedTests = -1;
-	}
-
-}
diff --git a/src/jlm/core/model/lesson/Exercise.java b/src/jlm/core/model/lesson/Exercise.java
deleted file mode 100644
index fa75ff2..0000000
--- a/src/jlm/core/model/lesson/Exercise.java
+++ /dev/null
@@ -1,289 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-import jlm.core.InMemoryCompiler;
-import jlm.core.JLMCompilerException;
-import jlm.core.model.Game;
-import jlm.core.model.LogWriter;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public abstract class Exercise extends Lecture {
-	public static enum WorldKind {INITIAL,CURRENT, ANSWER}
-
-	protected Map<ProgrammingLanguage, List<SourceFile>> sourceFiles= new HashMap<ProgrammingLanguage, List<SourceFile>>();
-	
-	public Map<String, Class<Object>> compiledClasses = new TreeMap<String, Class<Object>>(); /* list of entity classes defined in the lesson */
-
-	/* to make sure that the subsequent version of the same class have different names, in order to bypass the cache of the class loader */
-	private static final String packageNamePrefix = "jlm.runtime";
-	private int packageNameSuffix = 0;
-
-	protected Vector<World> currentWorld; /* the one displayed */
-	protected Vector<World> initialWorld; /* the one used to reset the previous on each run */
-	protected Vector<World> answerWorld;  /* the one current should look like to pass the test */
-
-	protected Map<String, String> runtimePatterns = new TreeMap<String, String>();
-
-	public ExecutionProgress lastResult;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
-
-	public Exercise(Lesson lesson) {
-		super(lesson);
-	}
-	
-	public void setupWorlds(World[] w) {
-		currentWorld = new Vector<World>(w.length);
-		initialWorld = new Vector<World>(w.length);
-		answerWorld  = new Vector<World>(w.length);
-		for (int i=0; i<w.length; i++) {
-			currentWorld.add( w[i].copy() );
-			initialWorld.add( w[i].copy() );
-			answerWorld. add( w[i].copy() );
-		}
-	}
-	
-	public abstract void run(List<Thread> runnerVect);	
-	public abstract void runDemo(List<Thread> runnerVect);	
-	
-	public void check() {
-		for (int i=0; i<currentWorld.size(); i++) {
-			currentWorld.get(i).notifyWorldUpdatesListeners();
-			
-			lastResult.totalTests++;
-
-			if (!currentWorld.get(i).equals(answerWorld.get(i))) {
-				String diff = answerWorld.get(i).diffTo(currentWorld.get(i));
-				lastResult.details += i18n.tr("The world ''{0}'' differs",currentWorld.get(i).getName());
-				if (diff != null) 
-					lastResult.details += ":\n"+diff;
-				lastResult.details += "\n";
-			} else {
-				lastResult.passedTests++;
-			}
-		}
-	}
-	/** Reset the current worlds to the state of the initial worlds */
-	public void reset() {
-		lastResult = new ExecutionProgress();
-
-		for (int i=0; i<initialWorld.size(); i++) 
-			currentWorld.get(i).reset(initialWorld.get(i));
-	}
-
-	/*
-	 * +++++++++++++++++++++++++
-	 * Compilation related stuff
-	 * +++++++++++++++++++++++++
-	 * 
-	 */
-	//TODO: why do we instantiate a compiler per exercise ? is there any way to re-use the same compiler. 
-	//TODO: I tried to put it as static, but of course strange behaviors happen afterwards
-	// Create a compiler of classes (using java 1.6)
-	private final InMemoryCompiler compiler = new InMemoryCompiler(
-			getClass().getClassLoader(), Arrays.asList(new String[] { "-target", "1.6" }));
-
-
-	/**
-	 * Generate Java source from the user function
-	 * @throws JLMCompilerException 
-	 */
-	public void compileAll(LogWriter out) throws JLMCompilerException {
-		/* Make sure each run generate a new package to avoid that the loader cache prevent the reloading of the newly generated class */
-		packageNameSuffix++;
-		runtimePatterns.put("\\$package", "package "+packageName()+";");
-
-		/* Do the compile (but only if the current language is Java: scripts are not compiled of course)
-		 * Instead, scripting languages get the source code as text directly from the sourceFiles 
-		 */
-		if (Game.getProgrammingLanguage().equals(Game.JAVA)) {
-			/* Prepare the source files */
-			Map<String, CharSequence> sources = new TreeMap<String, CharSequence>();
-			if (sourceFiles.get(Game.JAVA) != null)
-				for (SourceFile sf: sourceFiles.get(Game.JAVA)) 
-					sources.put(className(sf.getName()), sf.getCompilableContent(runtimePatterns)); 
-			
-			if (sources.isEmpty()) 
-				return;
-			
-			try {
-				DiagnosticCollector<JavaFileObject> errs = new DiagnosticCollector<JavaFileObject>();			
-				compiledClasses = compiler.compile(sources, errs);
-
-				out.log(errs);
-			} catch (JLMCompilerException e) {
-				System.err.println("Compilation error:");
-				out.log(e.getDiagnostics());
-				lastResult = ExecutionProgress.newCompilationError(e.getDiagnostics());
-
-				if (Game.getInstance().isDebugEnabled() && sourceFiles.get(Game.JAVA) != null)
-					for (SourceFile sf: sourceFiles.get(Game.JAVA)) 
-						System.out.println("Source file "+sf.getName()+":"+sf.getCompilableContent(runtimePatterns)); 
-
-				throw e;
-			}
-		}
-		
-	}
-	
-	private String packageName(){
-		return packageNamePrefix + packageNameSuffix;
-	}
-	public String className(String name) {
-		return packageName() + "." + name;
-	}
-	/** get the list of source files for a given language, or create it if not existent yet */
-	protected List<SourceFile> getSourceFilesList(ProgrammingLanguage lang) {
-		List<SourceFile> res = sourceFiles.get(lang); 
-		if (res == null) {
-			res = new ArrayList<SourceFile>();
-			sourceFiles.put(lang, res);
-		}
-		return res;
-	}
-	public int getSourceFileCount(ProgrammingLanguage lang) {
-		return getSourceFilesList(lang).size();
-	}	
-	public SourceFile getSourceFile(ProgrammingLanguage lang, int i) {
-		return getSourceFilesList(lang).get(i);
-	}
-
-	public void newSource(ProgrammingLanguage lang, String name, String initialContent, String template) {
-		getSourceFilesList(lang).add(new SourceFileRevertable(name, initialContent, template));
-	}
-
-	protected void mutateEntities(Vector<World> worlds, String newClassName) {
-		/* Sanity check for broken lessons: the entity name must be a valid Java identifier */
-		String[] forbidden = new String[] {"'","\""};
-		for (String stringPattern : forbidden) {
-			Pattern pattern = Pattern.compile(stringPattern);
-			Matcher matcher = pattern.matcher(newClassName);
-			
-			if (matcher.matches())
-				throw new RuntimeException(newClassName+" is not a valid java identifier (forbidden char: "+stringPattern+"). "+
-						"Does your exercise use a broken tabname or entityname?");
-		}
-
-		for (World current:worlds) {
-			ArrayList<Entity> newEntities = new ArrayList<Entity>();
-			for (Entity old : current.getEntities()) {
-				/* This is never called with lightbot entities, no need to deal with it here */
-				if (Game.getProgrammingLanguage().equals(Game.JAVA)) {
-					/* Instantiate a new entity of the new type */
-					Entity ent;
-					try {
-						ent = (Entity) compiledClasses.get(className(newClassName)).newInstance();
-					} catch (InstantiationException e) {
-						throw new RuntimeException("Cannot instanciate entity of type "+className(newClassName), e);
-					} catch (IllegalAccessException e) {
-						throw new RuntimeException("Illegal access while instanciating entity of type "+className(newClassName), e);
-					} catch (NullPointerException e) {
-						/* this kind of entity was not written by student. try to get it from default class loader, or complain if it also fails */
-						try {
-							ent = (Entity)compiler.loadClass(newClassName).newInstance(); 
-						} catch (Exception e2) {
-							throw new RuntimeException("Cannot find an entity of name "+className(newClassName)+" or "+newClassName+". Broken lesson.", e2);
-						}
-					}
-					/* change fields of new entity to copy old one */
-					ent.copy(old);
-					ent.initDone();
-					/* Add new entity to the to be returned entities set */
-					newEntities.add(ent);
-				} else { 
-					/* In scripting, we don't need to actually mutate the entity, just set the script to be interpreted later.
-					 * Also, since the classloader don't cross our way, don't mess with package names to force reloads. In other words, don't use className() in here!! 
-					 */	
-					
-					ProgrammingLanguage lang = Game.getProgrammingLanguage();
-					boolean foundScript = false;
-					for (SourceFile sf : sourceFiles.get(lang)) {
-						if (newClassName.equals(sf.name)) {
-							old.setScript(lang, sf.getCompilableContent());
-							old.setScriptOffset(lang, sf.getOffset());
-							foundScript = true;
-						} 
-					}
-					if (!foundScript) {
-						StringBuffer sb = new StringBuffer();
-						for (SourceFile sf: sourceFiles.get(lang)) {
-							sb.append(sf.name+", ");
-						}
-						throw new RuntimeException(getClass().getName()+": Cannot retrieve the script for "+newClassName+". Known scripts: "+sb+"(EOL)");						
-					}
-				}
-			}
-			if (Game.getProgrammingLanguage().equals(Game.JAVA)) 
-				current.setEntities(newEntities);
-		}
-	}
-			
-	public Vector<World> getWorlds(WorldKind kind) {
-		switch (kind) {
-		case INITIAL: return initialWorld;
-		case CURRENT: return currentWorld;
-		case ANSWER:  return answerWorld;
-		default: throw new RuntimeException("Unhandled kind of world: "+kind);
-		}
-	}
-	
-	public int getWorldCount() {
-		return this.initialWorld.size();
-	}
-	
-	/** Returns the current world number index 
-	 * @see #getAnswerOfWorld(int)
-	 */
-	public World getWorld(int index) {// FIXME: rename to getCurrentWorld or KILLME
-		return this.currentWorld.get(index);
-	}
-	
-	public int indexOfWorld(World w) {
-		int index = 0;
-		do {
-			if (this.currentWorld.get(index) == w)
-				return index;
-			index++;
-		} while (index < this.currentWorld.size());
-		
-		throw new RuntimeException("World not found (please report this bug)");
-	}
-	
-	public World getAnswerOfWorld(int index) { // FIXME: rename or KILLME
-		return this.answerWorld.get(index);
-	}
-	
-	public String toString() {
-		return getName();
-	}
-
-	/* setters and getter of the programming language that this exercise accepts */ 
-	private Set<ProgrammingLanguage> progLanguages = new HashSet<ProgrammingLanguage>();
-	public Set<ProgrammingLanguage> getProgLanguages() {
-		return progLanguages;
-	}
-	protected void addProgLanguage(ProgrammingLanguage newL) {
-		progLanguages.add(newL);
-	}
-}
-
diff --git a/src/jlm/core/model/lesson/ExerciseTemplated.java b/src/jlm/core/model/lesson/ExerciseTemplated.java
deleted file mode 100644
index 001170f..0000000
--- a/src/jlm/core/model/lesson/ExerciseTemplated.java
+++ /dev/null
@@ -1,420 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.utils.FileUtils;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-
-
-public abstract class ExerciseTemplated extends Exercise {
-
-	protected String tabName = getClass().getSimpleName(); /** Name of the tab in editor -- must be a valid java identifier */
-	protected String worldFileName = getClass().getCanonicalName(); /** Name of the save files */
-	protected String nameOfCorrectionEntity = getClass().getCanonicalName()+"Entity"; /** name of the entity class computing the answer. Usually no need to redefine this */
-
-	public ExerciseTemplated(Lesson lesson) {
-		super(lesson);
-	}
-	
-	public void newSourceFromFile(ProgrammingLanguage lang, String name, String filename) throws NoSuchEntityException {
-		newSourceFromFile(lang, name, filename, "");
-	}
-	public void newSourceFromFile(ProgrammingLanguage lang, String name, String filename,String patternString) throws NoSuchEntityException {
-
-		String shownFilename =  filename.replaceAll("\\.", "/")+"."+lang.getExt();
-		StringBuffer sb = null;
-		try {
-			sb = FileUtils.readContentAsText(filename, lang.getExt(), false);
-		} catch (IOException ex) {
-			throw new NoSuchEntityException(Game.i18n.tr("Source file {0}.{1} not found.",filename,lang.getExt()));			
-		}
-
-
-		/* Remove line comments since at some point, we put everything on one line only, 
-		 * so this would comment the end of the template and break everything */
-		Pattern lineCommentPattern = Pattern.compile("//.*$", Pattern.MULTILINE);
-		Matcher lineCommentMatcher = lineCommentPattern.matcher(sb.toString());
-		String content = lineCommentMatcher.replaceAll("");
-
-		/* Extract the template, the initial content and the solution out of the file */
-		int state = 0;
-		int savedState = 0;
-		StringBuffer head = new StringBuffer(); /* before the template (state 0) */
-		StringBuffer templateHead = new StringBuffer(); /* in template before solution (state 1) */
-		StringBuffer solution = new StringBuffer(); /* the solution (state 2) */
-		StringBuffer templateTail = new StringBuffer(); /* in template after solution (state 3) */
-		StringBuffer tail = new StringBuffer("\n"); /* after the template (state 4) 
-		                                             *   This contains a preliminar \n to help python understanding that the following is not in the same block.
-		                                             *   Not doing Without it, we would have issues if the student puts some empty lines with the indentation marker at tail
-		                                             */
-		StringBuffer skel = new StringBuffer(); /* within BEGIN/END SKEL */
-
-		boolean seenTemplate=false; // whether B/E SOLUTION seems included within B/E TEMPLATE
-		for (String line : content.split("\n")) {
-			//if (this.debug)
-			//	System.out.println(state+"->"+line);
-			switch (state) {
-			case 0: /* initial content */
-				if (line.contains("public class ")) {
-					head.append(line.replaceAll("public class \\S*", "public class "+name));
-				} else if (line.contains("package")) {
-					head.append("$package \n");						
-				} else if (line.contains("BEGIN TEMPLATE")) {
-					seenTemplate = true;
-					state = 1;
-				} else if (line.contains("BEGIN SOLUTION")) {
-					state = 2; 
-				} else if (line.contains("BEGIN SKEL")) {
-					savedState = state;
-					state = 6; 
-				} else {
-					head.append(line+"\n");
-				}
-				break;
-			case 1: /* template head */
-				if (line.contains("BEGIN TEMPLATE")) {
-					System.out.println(i18n.tr("{0}: BEGIN TEMPLATE within the template. Please fix your entity.",shownFilename));
-					state = 4;
-				} else if (line.contains("public class "))
-					templateHead.append(line.replaceAll("public class \\S*", "public class "+name)+"\n");
-				else if (line.contains("END TEMPLATE")) {
-					state = 4;
-				} else if (line.contains("BEGIN SOLUTION")) {
-					state = 2; 
-				} else if (line.contains("BEGIN HIDDEN")) {
-					savedState = 1;
-					state = 5; 
-				} else if (line.contains("BEGIN SKEL")) {
-					savedState = state;
-					state = 6; 
-				} else {
-					templateHead.append(line+"\n");
-				}
-				break;
-			case 2: /* solution */
-				if (line.contains("END TEMPLATE")) {
-					System.out.println(i18n.tr("{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity.",shownFilename));
-					state = 4;
-				} else if (line.contains("END SOLUTION")) {
-					state = 3;  
-				} else if (line.contains("BEGIN SKEL")) {
-					savedState = state;
-					state = 6; 
-				} else {
-					solution.append(line+"\n");
-				}
-				break;
-			case 3: /* template tail */
-				if (line.contains("END TEMPLATE")) {
-					if (!seenTemplate)
-						System.out.println(i18n.tr("{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity.",shownFilename));
-						
-					state = 4;
-				} else if (line.contains("BEGIN SOLUTION")) {
-					throw new RuntimeException(i18n.tr("{0}: Begin solution in template tail. Change it to BEGIN HIDDEN",shownFilename));
-				} else if (line.contains("BEGIN SKEL")) {
-					savedState = state;
-					state = 6; 
-				} else if (line.contains("BEGIN HIDDEN")) {
-					savedState = 3;
-					state = 5; 
-				} else {
-					templateTail.append(line+"\n");	
-				}
-				break;
-			case 4: /* end of file */
-				tail.append(line+"\n");
-				break;
-			case 5: /* Hidden but not bodied */
-				if (line.contains("END HIDDEN")) {
-					state = savedState;
-				} 
-				break;
-			case 6: /* skeleton */
-				if (line.contains("END SKEL")) {
-					state = savedState;
-				} else {
-					skel.append(line+"\n");					
-				}
-				break;
-			default: 	
-				throw new RuntimeException(i18n.tr("Parser error in file {0}. This is a parser bug (state={1}), please report.",filename,state));	
-			}
-		}
-		if (state == 3) {
-			if (seenTemplate)
-				System.out.println(i18n.tr("{0}: End of file unexpected after the solution but within the template. Please fix your entity.",shownFilename,state));
-		} else if (state != 4)
-			System.out.println(i18n.tr("{0}: End of file unexpected (state: {1}). Did you forget to close your template or solution? Please fix your entity.",shownFilename,state));
-
-		String initialContent = templateHead.toString() + templateTail.toString();
-		String skelContent;
-		String headContent;
-		if (lang == Game.PYTHON) { 
-			skelContent = skel.toString();
-			headContent = head.toString();
-		} else {
-			skelContent = skel.toString().replaceAll("\n", " ");
-			headContent = head.toString().replaceAll("\n", " ");
-		}
-
-		String template = (headContent+"$body"+tail);
-		
-		/* Remove the unnecessary leading spaces from the initial content */
-		Pattern newLinePattern = Pattern.compile("\n",Pattern.MULTILINE);
-		if (lang != Game.PYTHON) {
-			initialContent = initialContent.replaceAll("\t","    ");
-			String[] ctn = newLinePattern.split(initialContent);
-			/* Compute the minimal amount of leading spaces on all lines */
-			int minAmountOfLeadingSpace = -1;
-			for (String line:ctn) {
-				if (line.equals(""))
-					continue;
-				int len = 0;
-				for (char c:line.toCharArray())
-					if (c == ' ') {
-						len ++;
-					} else { 
-						break;
-					} 
-				if (minAmountOfLeadingSpace == -1 || len<minAmountOfLeadingSpace)
-					minAmountOfLeadingSpace = len;
-			}
-			if (minAmountOfLeadingSpace > 0) {
-				/* Remove that amount of leading spaces on all lines, and rebuilds initialContent */
-				StringBuffer sbCtn = new StringBuffer();
-				for (String line : ctn) 
-					if (line.equals(""))
-						sbCtn.append("\n");
-					else 
-						sbCtn.append(line.substring(minAmountOfLeadingSpace)+"\n");
-				/* Rebuild the initial content */
-				initialContent = sbCtn.toString();
-			}
-		}
-
-		/* remove any \n from template to not desynchronize line numbers between compiler and editor */ 
-		if (lang != Game.PYTHON) {
-			Matcher newLineMatcher = newLinePattern.matcher(template);
-			template = newLineMatcher.replaceAll(" ");
-		}
-
-		/* Apply all requested rewrites, if any */
-		if (patternString != null) {
-			Map<String, String> patterns = new HashMap<String, String>();
-			for (String pattern: patternString.split(";")) {
-				String[] parts = pattern.split("/");
-				if (parts.length != 1 || !parts[0].equals("")) {
-					if (parts.length != 3 || !parts[0].equals("s")) 
-						throw new RuntimeException("Malformed pattern for file "+name+": '"+ pattern+"' (from '"+patterns+"')");
-
-					if (Game.getInstance().isDebugEnabled())
-						System.out.println("Replace all "+parts[1]+" to "+parts[2]);
-					template = template.replaceAll(parts[1], parts[2]);
-					initialContent = initialContent.replaceAll(parts[1], parts[2]);
-					skelContent = skelContent.replaceAll(parts[1], parts[2]);
-				}
-			}
-
-		}
-
-		/*if (this.debug) {
-			System.out.println("<<<<<<<<template:"+template);
-			System.out.println("<<<<<<<<debugCtn:"+debugContent);
-			System.out.println("<<<<<<<<initialContent:"+initialContent);
-		    System.out.println("<<<<<<<<Skel: "+skelContent);
-		}*/
-
-		newSource(lang, name, initialContent,
-						skelContent.length()>0?skelContent:template);
-	}
-
-	protected final void setup(World w) {
-		setup(new World[] {w});
-	}
-	protected void setup(World[] ws) {
-		boolean foundALanguage=false;
-		setupWorlds(ws);
-
-		for (ProgrammingLanguage lang: Game.getProgrammingLanguages()) {
-			boolean foundThisLanguage = false;
-			String searchedName = null;
-			for (SourceFile sf : getSourceFilesList(lang)) {
-				if (searchedName == null) {//lazy initialization if there is any sourcefile to parse
-					Pattern p = Pattern.compile(".*?([^.]*)$");
-					Matcher m = p.matcher(nameOfCorrectionEntity);
-					if (m.matches())
-						searchedName = m.group(1);
-					p = Pattern.compile("Entity$");
-					m = p.matcher(searchedName);
-					searchedName = m.replaceAll("");
-				}
-				if (Game.getInstance().isDebugEnabled())
-					System.out.println("Saw "+sf.name+" in "+lang.getLang()+", searched for "+searchedName+" or "+tabName+" while checking for the need of creating a new tab");
-				if (sf.name.equals(searchedName)||sf.name.equals(tabName))
-					foundThisLanguage=true;
-			}
-			if (!foundThisLanguage) {
-				try {
-					newSourceFromFile(lang, tabName, nameOfCorrectionEntity);
-					super.addProgLanguage(lang);
-					foundALanguage = true;
-					if (Game.getInstance().isDebugEnabled())
-						System.out.println("Found suitable templating entity "+nameOfCorrectionEntity+" in "+lang);
-
-				} catch (NoSuchEntityException e) {
-					if (lang.equals(Game.PYTHON))
-						System.out.println("Cannnot find any suitable templating entity "+nameOfCorrectionEntity+" in "+lang+":\n  "+e);
-						
-					if (getProgLanguages().contains(lang)) 
-						throw new RuntimeException("Exercise "+getName()+" is said to be compatible with language "+lang+", but I fail to find an entity for this language",e);
-					/* Ok, this language does not work for this exercise but didn't promise anything. I can deal with it */
-				}
-			} else {
-				foundALanguage = true;
-			}
-		}
-		if (!foundALanguage) {
-			throw new RuntimeException("Cannot find an entity for exercise "+getName()+". You should fix your paths and such");
-		}
-		computeAnswer();
-	}
-	
-	protected void computeAnswer() {
-		Thread t = new Thread() {
-			@Override
-			public void run() {
-				Game.getInstance().statusArgAdd(getClass().getSimpleName());
-				boolean allFound = true;
-				if (answerWorld.get(0).haveIO()) {
-					if (Game.getProperty(Game.PROP_ANSWER_CACHE, "true",true).equalsIgnoreCase("true")) {
-						Vector<World> newAnswer = new Vector<World>();
-						int rank = 0;
-						for (World aw:answerWorld) {
-							String name = worldFileName+"-answer"+(rank++);
-							try {
-								World nw = aw.readFromFile(name);
-								newAnswer.add(nw);
-							} catch (BrokenWorldFileException bwfe) {
-								System.err.println(i18n.tr("World {0} is broken ({1}). Recompute all answer worlds.",name,bwfe.getLocalizedMessage()) );
-								allFound = false;
-								break;
-							} catch (IOException ioe) {
-								System.err.println(i18n.tr("IO exception while reading world {0} ({1}). Recompute all answer worlds.",name,ioe.getLocalizedMessage()));
-								allFound = false;
-								break;
-							}
-						}
-						if (allFound) {
-							answerWorld = newAnswer;
-							Game.getInstance().statusArgRemove(getClass().getSimpleName());
-							return;
-						}
-					} else {
-						System.out.println(i18n.tr("Recompute the answer of {0} despite the cache file, as requested by the property {1}",worldFileName,Game.PROP_ANSWER_CACHE));
-					}
-				}
-				
-				/* I/O didn't work. We have to load the files manually */
-				ExecutionProgress progress = new ExecutionProgress();
-				
-				mutateCorrection(WorldKind.ANSWER);
-
-				for (World aw : answerWorld) 
-					for (Entity ent: aw.getEntities()) 
-						ent.runIt(progress);
-				
-				/* Try to write all files for next time */
-				if (answerWorld.get(0).haveIO()) {
-					int rank = 0;
-					for (World aw:answerWorld) {
-						String name = "src/"+worldFileName+"-answer"+(rank++);
-						name = name.replaceAll("\\.", "/") + ".map";
-						if (new File(name).getParentFile().canWrite()) {
-							try {
-								aw.writeToFile(new File(name));
-							} catch (Exception e) {
-								System.err.println(i18n.tr("Error while writing answer world of {0}:",name));
-								e.printStackTrace();
-							}
-						} else {
-							System.err.println(i18n.tr("Cannot write answer world of {0}. Please check the permissions.",name));
-						}
-					}
-				}
-				Game.getInstance().statusArgRemove(getClass().getSimpleName());
-			}
-		};
-		t.start();
-		Game.addInitThread(t);
-	}
-
-	@Override
-	public void run(List<Thread> runnerVect){
-		if (lastResult == null)
-			lastResult = new ExecutionProgress();
-		
-		mutateEntities(currentWorld, tabName);
-
-		for (World cw: getWorlds(WorldKind.CURRENT)) {
-			cw.doDelay();
-			cw.runEntities(runnerVect, lastResult);
-		}
-	}
-
-	@Override
-	public void runDemo(List<Thread> runnerVect){
-		ExecutionProgress ignored = new ExecutionProgress();
-		
-		for (int i=0; i<initialWorld.size(); i++) { 
-			answerWorld.get(i).reset(initialWorld.get(i));
-			answerWorld.get(i).doDelay();
-		}
-		mutateCorrection(WorldKind.ANSWER);
-
-		for (World aw:getWorlds(WorldKind.ANSWER))
-			aw.runEntities(runnerVect,ignored);
-	}
-	
-	public void mutateCorrection(WorldKind kind) {
-		ProgrammingLanguage lang = Game.getProgrammingLanguage();
-		Vector<World> worlds;
-		switch (kind) {
-		case INITIAL: worlds = initialWorld; break;
-		case CURRENT: worlds = currentWorld; break;
-		case ANSWER:  worlds = answerWorld;  break;
-		default: throw new RuntimeException("kind is invalid: "+kind);
-		}
-
-		/* No need to deal with lightbot here: this method is redefined in LightBotExercise from scratch */
-		if (lang.equals(Game.JAVA)) {
-			mutateEntities(worlds,nameOfCorrectionEntity);
-		} else {
-			for (World aw : worlds) {
-				for (Entity ent: aw.getEntities()) {
-					StringBuffer sb = null;
-					try {
-						sb = FileUtils.readContentAsText(nameOfCorrectionEntity, lang.getExt(), false);
-					} catch (IOException ex) {
-						throw new RuntimeException("Cannot compute the answer from file "+nameOfCorrectionEntity+"."+lang.getExt()+" since it does not exist.");			
-					}
-
-
-					ent.setScript(lang, sb.toString());
-				}
-			}
-		}		
-	}
-}
diff --git a/src/jlm/core/model/lesson/ExerciseTemplatingEntity.java b/src/jlm/core/model/lesson/ExerciseTemplatingEntity.java
deleted file mode 100644
index af86cbf..0000000
--- a/src/jlm/core/model/lesson/ExerciseTemplatingEntity.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.universe.World;
-
-/** This class of Exercises are useful to merge the entity and world within the same class.
- * #BatExercice is a known implementation 
- *
- *
- */
-
-public abstract class ExerciseTemplatingEntity extends ExerciseTemplated {
-	protected Map<ProgrammingLanguage,String> corrections = new HashMap<ProgrammingLanguage, String>();
-	private boolean isSetup = false;
-	
-	public ExerciseTemplatingEntity(Lesson lesson) {
-		super(lesson);
-	}
-	protected void setup(World[] ws, String entName, String template) {
-		boolean foundOne = false;
-		this.tabName=entName;
-		setupWorlds(ws);
-		
-		for (ProgrammingLanguage pl : Game.getProgrammingLanguages()) {
-			try {
-				newSourceFromFile(pl, entName, getClass().getCanonicalName());
-				foundOne = true;
-				addProgLanguage(pl);
-			} catch (NoSuchEntityException e) {
-				/* Ok, this language does not work. I can deal with it */
-			} 
-		}
-		if (!foundOne)
-			throw new RuntimeException("Cannot find an entity of name "+entName+" for this exercise. You should fix your pathes and such");
-
-		SourceFile sf = sourceFiles.get(Game.JAVA).get(0);
-		sf.setTemplate("$package "+template+" "+sf.getTemplate()+" $body }");
-		//System.out.println("New template: "+sf.getTemplate());
-		computeAnswer();
-		isSetup  = true;
-	}
-	protected void langTemplate(ProgrammingLanguage pl, String entName, String initialCode, String correction) {
-		/* The following test is intended to make sure that this function is called before setup() right above.
-		 * This is because setup() needs all programming languages to be declared when it runs */
-		if (isSetup)
-			throw new RuntimeException("The exercise "+getName()+" is already setup, too late to add a programming language template");
-		
-		newSource(pl, entName, initialCode, "$body");
-		corrections.put(pl, initialCode+correction);
-		addProgLanguage(pl);
-	}
-}
diff --git a/src/jlm/core/model/lesson/ISourceFileListener.java b/src/jlm/core/model/lesson/ISourceFileListener.java
deleted file mode 100644
index f47a92c..0000000
--- a/src/jlm/core/model/lesson/ISourceFileListener.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package jlm.core.model.lesson;
-
-public interface ISourceFileListener {
-
-	public void sourceFileContentHasChanged() ;
-
-	public void clear(); /* before removing it */
-	
-}
diff --git a/src/jlm/core/model/lesson/Lecture.java b/src/jlm/core/model/lesson/Lecture.java
deleted file mode 100644
index 8b9f220..0000000
--- a/src/jlm/core/model/lesson/Lecture.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.JlmHtmlEditorKit;
-import jlm.core.utils.FileUtils;
-
-/** Represents an element of the pedagogic sequence, be it a lecture or 
- * an exercise. A better name would be useful, but I feel limited in 
- * English today. Sorry. */
-public abstract class Lecture {
-	private String id; // used in session to identify this lecture or exercise
-	
-	public static final String HTMLTipHeader = "<head>\n"+
-			"  <meta content=\"text/html; charset=UTF-8\" />\n"+	
-			"  <style>\n"+
-			"    body { font-family: tahoma, \"Times New Roman\", serif; font-size:10px; margin:10px; }\n"+
-			"    code { background:#EEEEEE; }\n"+
-			"    pre { background: #EEEEEE;\n"+
-			"          margin: 5px;\n"+
-			"          padding: 6px;\n"+
-			"          border: 1px inset;\n"+
-			"          width: 400px;\n"+
-			"          overflow: auto;\n"+
-			"          text-align: left;\n"+
-			"          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"+
-			"   .comment { background:#EEEEEE;\n"+
-			"              font-family: \"Times New Roman\", serif;\n"+
-			"              color:#00AA00;\n"+
-			"              font-style: italic; }\n"+
-			"  </style>\n"+
-			"</head>\n";
-	private String name = "<no name>";                     /** indicate whether this Exercise was successfully done or not */
-	private String mission = "";                        /** The text to display to present the lesson */
-	private Lesson lesson;
-	
-	protected Map<String, String> tips = new HashMap<String, String>();
-	
-	public Lecture(Lesson lesson) {
-		this.lesson = lesson;
-		loadHTMLMission();
-		id = lesson.getId()+getClass().getName();
-	}
-	public String getId() {
-		return id;
-	}
-
-	public void setName(String n) {
-		name = n;
-	}
-	public String getName() {
-		return this.name;
-	}
-
-	public Lesson getLesson() {
-		return this.lesson;
-	}
-
-
-	public String getMission(ProgrammingLanguage lang) {
-		String res = "<html><head>"+JlmHtmlEditorKit.getCSS(lang)+"</head><body>"+this.mission+"</body></html>";
-		return res;
-	}
-	public void setMission(String mission) {
-		this.mission=mission;
-	}
-	public String getTip(String tipsId) {
-		return this.tips.get(tipsId);
-	}
-
-	public void loadHTMLMission() {
-		String filename = getClass().getCanonicalName().replace('.',File.separatorChar);
-	
-		StringBuffer sb = null;
-		try {
-			sb = FileUtils.readContentAsText(filename, "html",true);
-		} catch (IOException ex) {
-			setMission(Game.i18n.tr("File {0}.html not found.",filename));
-			return;			
-		}
-		String str = sb.toString();
-	
-		/* search the mission name */
-		Pattern p =  Pattern.compile("<h[123]>([^<]*)<");
-		Matcher m = p.matcher(str);
-		if (!m.find())
-			System.out.println(Game.i18n.tr("Cannot find the name of mission in {0}.html",filename));
-		setName( m.group(1) );
-	
-		/* prepare the tips, if any */
-		Pattern p3 =  Pattern.compile("<div class=\"tip\" id=\"(tip-\\d+?)\" alt=\"([^\"]+?)\">(.*?)</div>",Pattern.MULTILINE|Pattern.DOTALL);
-		Matcher m3 = p3.matcher(str);
-		while (m3.find()) {	
-			tips.put("#"+m3.group(1), m3.group(3));
-		}
-		str = m3.replaceAll("<a href=\"#$1\">$2</a>");
-	
-		Pattern p4 =  Pattern.compile("<div class=\"tip\" id=\"(tip-\\d+?)\">(.*?)</div>",Pattern.MULTILINE|Pattern.DOTALL);
-		Matcher m4 = p4.matcher(str);
-		while (m4.find()) {	
-			tips.put("#"+m4.group(1), m4.group(2));
-		}		
-		str=m4.replaceAll("<a href=\"#$1\">Show Tip</a>");				
-	
-	
-		/* get the mission explanation */
-		setMission(str);
-	}
-
-	protected Vector<Lecture> dependingLectures = new Vector<Lecture>(); /* To display the graph */
-	private DefaultMutableTreeNode myNode;
-	public DefaultMutableTreeNode getNode() {
-		if (myNode == null) {
-			myNode = new DefaultMutableTreeNode(this);
-			for (Lecture l : dependingLectures)
-				myNode.add(l.getNode());
-		}
-		return myNode;
-	}
-	public Vector<Lecture> getDependingLectures() {
-		return dependingLectures;
-	}
-}
diff --git a/src/jlm/core/model/lesson/Lesson.java b/src/jlm/core/model/lesson/Lesson.java
deleted file mode 100644
index 8a83833..0000000
--- a/src/jlm/core/model/lesson/Lesson.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Vector;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.utils.FileUtils;
-import jlm.universe.BrokenWorldFileException;
-
-
-public abstract class Lesson {
-	private String name;
-	private String id;
-	protected String about = "(no information provided by the lesson)";
-	protected ArrayList<Lecture> lectures = new ArrayList<Lecture>();
-	
-	protected Vector<Lecture> rootLectures = new Vector<Lecture>(); /* To display the graph */
-	
-	protected Lecture currentExercise;
-	
-	final static String LessonHeader = "<head>\n" + "  <meta content=\"text/html; charset=UTF-8\" />\n"
-	+ "  <style>\n"
-	+ "    body { font-family: tahoma, \"Times New Roman\", serif; font-size:10px; margin:10px; }\n"
-	+ "    code { background:#EEEEEE; }\n" + "    pre { background: #EEEEEE;\n" + "          margin: 5px;\n"
-	+ "          padding: 6px;\n" + "          border: 1px inset;\n" + "          width: 640px;\n"
-	+ "          overflow: auto;\n" + "          text-align: left;\n"
-	+ "          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"
-	+ "   .comment { background:#EEEEEE;\n" + "              font-family: \"Times New Roman\", serif;\n"
-	+ "              color:#00AA00;\n" + "              font-style: italic; }\n" + "  </style>\n" + "</head>\n";
-
-	public Lesson() {
-		id = getClass().getCanonicalName().replaceAll(".Main$","");
-		id = id.replaceAll("^lessons.", "");
-		
-		try {
-			loadExercises(); /* FIXME: remove this line when session savers can deal with laziness */
-		} catch (IOException e) {
-			System.err.println("Cannot load the exercises. This lesson is severely broken..");
-			e.printStackTrace();
-		} catch (BrokenWorldFileException e) {
-			System.err.println("Cannot load the exercises. This lesson is severely broken..");
-			e.printStackTrace();
-		} 
-		for (ProgrammingLanguage lang: Game.programmingLanguages) {
-			int possible = 0;
-			int passed = 0;
-			for (Lecture l: lectures) {
-				if (l instanceof Exercise) {
-					Exercise exo = (Exercise) l;
-					if (exo.getProgLanguages().contains(lang)) {
-						possible++;
-						if (Game.getInstance().studentWork.getPassed(l, lang))
-							passed++;
-					}
-				}
-			}
-			Game.getInstance().studentWork.setPassedExercises(id, lang, passed);
-			Game.getInstance().studentWork.setPossibleExercises(id, lang, possible);
-		}
-	}
-	public String getId() {
-		return id;
-	}
-	
-	private boolean aboutLoaded = false;
-
-	public void resetAboutLoaded() {
-		this.aboutLoaded = false;
-	}
-	
-	private void loadAboutAndName() {
-		aboutLoaded = true;		/* read it */
-		String filename = getClass().getCanonicalName().replace('.',File.separatorChar);
-		StringBuffer sb = null;
-		try {
-			sb = FileUtils.readContentAsText(filename,"html",true);
-		} catch (IOException ex) {
-			about = Game.i18n.tr("File {0}.html not found.",filename);
-			name = filename;
-			return;
-		}
-		String str = sb.toString();
-		
-		/* search the mission name */
-		Pattern p =  Pattern.compile("<h[123]>([^<]*)<");
-		Matcher m = p.matcher(str);
-		if (!m.find())
-			System.out.println(Game.i18n.tr("Cannot find the name of mission in {0}.html",filename));
-		name = m.group(1);
-		/* get the mission explanation */
-		about = "<html>"+LessonHeader+"<body>\n"+str+"</body>\n</html>\n";		
-	}
-	public String getName() {
-		if (!aboutLoaded)
-			loadAboutAndName();
-		return this.name;
-	}
-	public String getAbout(){
-		if (!aboutLoaded) {
-			loadAboutAndName();
-		}
-		return about;
-	}
-
-	Lecture rootExo, lastAdded;
-	public Vector<Lecture> getRootLectures() {
-		return rootLectures;
-	}
-	public Lecture addExercise(Lecture exo) {
-		lectures.add(exo);		
-		rootLectures.add(exo);
-		if (rootExo == null) {
-			rootExo = exo;
-		}
-		lastAdded = exo;
-		return exo;
-	}
-	public Lecture addExercise(Lecture exo, Lecture previousExo) {
-		lectures.add(exo);
-		
-		if (rootExo == null) {
-			rootExo = exo;
-		}
-		lastAdded = exo;
-		previousExo.dependingLectures.add(exo);
-		return exo;
-	}
-	public Lecture getCurrentExercise() {
-		if (this.currentExercise == null && lectures.size() > 0) {
-			this.currentExercise = lectures.get(0);
-		}
-		if (currentExercise == null)
-			System.out.print("There is only "+lectures.size()+" lectures so far in the lesson "+getName());
-		return this.currentExercise;
-	}
-
-	abstract protected void loadExercises() throws IOException, BrokenWorldFileException;
-
-	public void setCurrentExercise(Lecture exo) {
-		this.currentExercise = exo;
-	}
-	public void setCurrentExercise(String exoName) {
-		this.currentExercise = getExercise(exoName);
-	}
-	
-	public int exerciseCount() {
-		return this.lectures.size();
-	}
-
-	public List<Lecture> exercises() {
-		return this.lectures;
-	}
-	public Lecture getExercise(String name) {
-		String searchedName = getClass().getPackage().getName()+"."+name;
-		for (Lecture l: lectures) {
-			if (l.getClass().getCanonicalName().equals(searchedName) ||
-					l.getClass().getCanonicalName().equals(name))
-				return l;
-		}
-		return null;
-	}
-	public int getExerciseCount() {
-		return this.lectures.size();
-	}
-}
\ No newline at end of file
diff --git a/src/jlm/core/model/lesson/NoSuchEntityException.java b/src/jlm/core/model/lesson/NoSuchEntityException.java
deleted file mode 100644
index 144c63f..0000000
--- a/src/jlm/core/model/lesson/NoSuchEntityException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package jlm.core.model.lesson;
-
-import jlm.core.JLMException;
-
-public class NoSuchEntityException extends JLMException {
-	private static final long serialVersionUID = 1L;
-	
-	public NoSuchEntityException(String msg) {
-		super(msg);
-	}
-}
diff --git a/src/jlm/core/model/lesson/SourceFile.java b/src/jlm/core/model/lesson/SourceFile.java
deleted file mode 100644
index 37ed427..0000000
--- a/src/jlm/core/model/lesson/SourceFile.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package jlm.core.model.lesson;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-import javax.swing.JScrollPane;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.JavaEditorPanel;
-
-
-public class SourceFile {
-
-	protected String name;
-	private String template;
-	private String body;
-	private ISourceFileListener listener = null;
-
-	public SourceFile(String name, String initialBody) {
-		this(name, initialBody, null);
-	}
-
-	public SourceFile(String name, String initialBody, String template) {
-		this.name = name;
-		this.body = initialBody;
-		setTemplate( template );
-	}
-
-	public String getName() {
-		return this.name;
-	}
-
-	public String getBody() {
-		return this.body;
-	}
-
-	public void setBody(String text) {
-		this.body = text;
-		notifyListener();
-	}
-	public void setTemplate(String string) {
-		this.template = string;
-	}
-	public String getTemplate() {
-		return template;
-	}
-
-
-	public String getCompilableContent() {
-		return getCompilableContent(null);
-	}
-
-	public String getCompilableContent(Map<String, String> runtimePatterns) {
-		String res;
-
-		if (template != null) {
-			res = template.replaceAll("\\$body", this.body+" \n");;			
-			if (runtimePatterns != null)
-				for (Entry<String, String> pattern : runtimePatterns.entrySet()) {
-					res = res.replaceAll(pattern.getKey(), pattern.getValue());
-				        // This is a trap to find issue #42 that I fail to reproduce
-					if (pattern.getValue().contains("\n")) { 
-						System.out.println("Damn! I integrated a pattern being more than one line long, line numbers will be wrong."
-                                                                   +"Please repport this bug (alongside with the following informations) as it will help us fixing our issue #42!");
-						System.out.println("pattern key: "+pattern.getKey());
-						System.out.println("pattern value: "+pattern.getValue());
-						System.out.println("Exercise: "+Game.getInstance().getCurrentLesson().getCurrentExercise().getName());
-						System.out.println("JLM version: "+Game.getProperty("jlm.major.version","internal",false)+" ("+Game.getProperty("jlm.major.version","internal",false)+"."+Game.getProperty("jlm.minor.version","",false)+")");
-						System.out.println("Java version: "+System.getProperty("java.version")+" (VM version: "+ System.getProperty("java.vm.version")+")");
-						System.out.println("System: " +System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")");
-					}
-				}
-
-		} else {
-			res = this.body;
-		}
-		return res.replaceAll("\\xa0", " "); // Kill those damn \160 chars, which are non-breaking spaces (got them from copy/pasting source examples?)
-	}
-
-	public void setListener(ISourceFileListener l) {
-		this.listener = l;
-	}
-
-	public void removeListener() {
-		this.listener = null;
-	}
-
-	public void notifyListener() {
-		if (this.listener != null)
-			this.listener.sourceFileContentHasChanged();
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((body == null) ? 0 : body.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		final SourceFile other = (SourceFile) obj;
-		if (body == null) {
-			if (other.body != null)
-				return false;
-		} else if (!body.equals(other.body))
-			return false;
-		return true;
-	}
-
-	public JScrollPane getEditorPanel(ProgrammingLanguage lang) {
-		return new JavaEditorPanel(this, lang);
-	}
-
-	public int getOffset() {
-		if (template != null) {
-			return template.split("\n").length -1;
-		}
-		return 0;
-	}
-}
diff --git a/src/jlm/core/model/lesson/SourceFileRevertable.java b/src/jlm/core/model/lesson/SourceFileRevertable.java
deleted file mode 100644
index bb5434c..0000000
--- a/src/jlm/core/model/lesson/SourceFileRevertable.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.core.model.lesson;
-
-public class SourceFileRevertable extends SourceFile {
-
-	private String initialBody; 
-	
-	public SourceFileRevertable(String name, String initialBody) {
-		this(name, initialBody, null);
-	}
-
-	public SourceFileRevertable(String name, String initialBody, String template) {
-		super(name, initialBody, template);
-		this.initialBody = initialBody;
-	}
-	
-	public void revert() {
-		setBody(this.initialBody);
-	}
-
-	public boolean hasChanged() {
-		return (! this.initialBody.equals(getBody()));
-	}
-	
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = super.hashCode();
-		result = prime * result + ((initialBody == null) ? 0 : initialBody.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (!super.equals(obj))
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		SourceFileRevertable other = (SourceFileRevertable) obj;
-		if (initialBody == null) {
-			if (other.initialBody != null)
-				return false;
-		} else if (!initialBody.equals(other.initialBody))
-			return false;
-		return true;
-	}
-}
diff --git a/src/jlm/core/model/lesson/package-info.java b/src/jlm/core/model/lesson/package-info.java
deleted file mode 100644
index 8d26608..0000000
--- a/src/jlm/core/model/lesson/package-info.java
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Building bricks for exercises and lessons: 
- *     storing students' code in memory and compiling it; grouping exercises together, 
- *     providing templates to students
- */
-package jlm.core.model.lesson;
-
diff --git a/src/jlm/core/model/package-info.java b/src/jlm/core/model/package-info.java
deleted file mode 100644
index 2ae422f..0000000
--- a/src/jlm/core/model/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Model of the JLM core: Game singleton, ability to save student files, log stuff, etc. 
- * 
- *  <p>
- */
-package jlm.core.model;
\ No newline at end of file
diff --git a/src/jlm/core/model/session/FileSessionKit.java b/src/jlm/core/model/session/FileSessionKit.java
deleted file mode 100644
index 3e617b5..0000000
--- a/src/jlm/core/model/session/FileSessionKit.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package jlm.core.model.session;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.model.lesson.SourceFile;
-import jlm.core.model.lesson.SourceFileRevertable;
-
-/**
- * Implementation of the {@link ISessionKit} saving the student data as a collection of 
- * separated files. It is not used by default, and you have to edit the source to activate it.
- *
- */
-public class FileSessionKit /* FIXME implements ISessionKit  */ {
-
-	private Game game;
-
-	private static String HOME_DIR = System.getProperty("user.home");
-	private static String SEP = System.getProperty("file.separator");
-	private static File SAVE_DIR = new File(HOME_DIR + SEP + ".jlm");
-
-	public FileSessionKit(Game game) {
-		this.game = game;
-	}
-
-	public void storeAll() {
-		if (!SAVE_DIR.exists())
-			if (! SAVE_DIR.mkdir()) {
-				Logger.log("FileSessionKit:store", "cannot create session store directory");
-			};
-
-			// File lessonDir;
-			File exerciseDir;
-			for (Lesson lesson : this.game.getLessons()) {
-
-				for (Lecture lecture : lesson.exercises()) {
-					if (lecture instanceof Exercise) {
-						Exercise exercise = (Exercise) lecture;
-						exerciseDir = new File(SAVE_DIR, exercise.getId());
-						if (!exerciseDir.exists())
-							if (! exerciseDir.mkdir()) 
-								Logger.log("FileSessionKit:store", "cannot remove "+exerciseDir+" directory");
-
-
-						// create file DONE if exercise has been successfully passed
-						for (ProgrammingLanguage lang: exercise.getProgLanguages()) {
-							File exerciseFile = new File(exerciseDir, "DONE."+lang.getExt());
-							if (Game.getInstance().studentWork.getPassed(exercise, lang)) {
-								if (!exerciseFile.exists()) {
-									try {
-										exerciseFile.createNewFile();
-									} catch (IOException e) {
-										e.printStackTrace();
-									}
-								}
-							} else {
-								if (exerciseFile.exists()) {
-									if (!exerciseFile.delete()) {
-										Logger.log("FileSessionKit:store", "cannot remove "+exerciseFile+" directory");
-									}
-								}
-							}
-						}
-
-						// save exercise body
-						for (ProgrammingLanguage lang:exercise.getProgLanguages()) 
-							for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
-								SourceFile sf = exercise.getSourceFile(lang,i);
-
-								if (!(sf instanceof SourceFileRevertable))
-									continue;
-
-								SourceFileRevertable srcFile = (SourceFileRevertable)sf;
-								File outputFile = new File(exerciseDir+"/"+lang, srcFile.getName());
-
-								if (srcFile.hasChanged()) {
-									BufferedWriter bw = null;
-									try {
-										bw = new BufferedWriter(new FileWriter(outputFile));
-										bw.write(srcFile.getBody());
-									} catch (IOException e) {
-										e.printStackTrace();
-									} finally {
-										try {
-											bw.close();
-										} catch (IOException e) {
-											e.printStackTrace();
-										}
-									}
-								} else {
-									if (outputFile.exists())
-										if (! outputFile.delete())
-											Logger.log("FileSessionKit:store", "cannot remove "+outputFile);
-								}
-							}
-					} // is exercise
-				} // end-for lecture
-			} // end-for lesson
-	}
-
-	public void loadAll() {
-		if (!SAVE_DIR.exists())
-			return;
-
-		// File lessonDir;
-		File exerciseDir;
-		for (Lesson lesson : this.game.getLessons()) {
-			for (Lecture lecture : lesson.exercises()) {
-				if (lecture instanceof Exercise) {
-					Exercise exercise = (Exercise) lecture;
-					exerciseDir = new File(SAVE_DIR, exercise.getId());
-					if (!exerciseDir.exists())
-						continue;
-
-
-					// load exercise body
-					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
-						File exerciseFile = new File(exerciseDir, "DONE"+lang.getExt());
-						if (exerciseFile.exists()) {
-							Game.getInstance().studentWork.setPassed(lecture, lang, true);
-						}
-						
-						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
-							SourceFile srcFile = exercise.getSourceFile(lang,i);
-
-							File of = new File(exerciseDir+"/"+lang, srcFile.getName());
-							if (!of.exists()) /* try to load using the old format (not specifying the programming language) */
-								of = new File(exerciseDir+"/"+lang, srcFile.getName());
-							if (of.exists()) {
-								BufferedReader br = null;
-								try {
-									br = new BufferedReader(new FileReader(of));
-									String s;
-									StringBuffer b = new StringBuffer();
-
-									while ((s = br.readLine()) != null) {
-										b.append(s);
-										b.append("\n");
-									}
-
-									srcFile.setBody(b.toString());
-								} catch (IOException e) {
-									e.printStackTrace();
-								} finally {
-									try {
-										br.close();
-									} catch (IOException e) {
-										e.printStackTrace();
-									}
-								}
-							}
-						}
-					}
-				} // is exercise
-			} // end-for lecture
-		} // end-for lesson
-	}
-
-	public void cleanUp() {
-		if (!SAVE_DIR.exists())
-			return;
-
-		File exerciseDir;
-		for (Lesson lesson : this.game.getLessons()) {
-			for (Lecture lecture : lesson.exercises()) {
-				if (lecture instanceof Exercise) {
-					Exercise exercise = (Exercise) lecture;
-					exerciseDir = new File(SAVE_DIR, exercise.getId());
-					if (!exerciseDir.exists())
-						continue;
-
-					File exerciseFile = new File(exerciseDir, "DONE");
-					if (exerciseFile.exists()) {
-						if (!exerciseFile.delete()) {
-							Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseFile);
-						};
-					}
-
-					for (ProgrammingLanguage lang:exercise.getProgLanguages()) 
-						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
-							SourceFile srcFile = exercise.getSourceFile(lang, i);
-
-							File of = new File(exerciseDir, srcFile.getName());
-							if (of.exists()) {
-								if (! of.delete()) {
-									Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseDir+"/"+srcFile.getName()+" directory");				
-								}
-							}
-						}
-
-					if (! exerciseDir.delete()) {
-						Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseDir+" directory");					
-					}
-				} // is exercise
-			} // end-for lectures
-		} // end-for lesson
-		if (! SAVE_DIR.delete()) {
-			Logger.log("FileSessionKit:cleanup", "cannot remove session store directory");
-		}
-	}
-}
diff --git a/src/jlm/core/model/session/ISessionKit.java b/src/jlm/core/model/session/ISessionKit.java
deleted file mode 100644
index 422711d..0000000
--- a/src/jlm/core/model/session/ISessionKit.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package jlm.core.model.session;
-
-import java.io.File;
-
-import jlm.core.model.UserAbortException;
-import jlm.core.model.lesson.Lesson;
-
-/** 
- * This interface is to be implemented by every session kits, aka mecanisms able to 
- * save and restore the state of the code written by the students. 
- * 
- * For now, 2 sessions kits are implemented in JLM: {@link FileSessionKit} and {@link ZipSessionKit}. 
- * The one used is hardcoded in the variable {@link jlm.core.model.Game#sessionKit}. 
- * There is no way to switch from the interface.
- */
-public interface ISessionKit {
-
-	/** Saves the user content of all loaded lessons
-	 * 
-	 *  On error, the user is given an opportunity to cancel the procedure through a dialog window.
-	 */
-	public void storeAll(File path) throws UserAbortException;	
-
-	/** Loads saved user content for all loaded lessons */
-	public void loadAll(File path);
-	
-	/** Saves the user content of the specified lessons
-	 * 
-	 *  On error, the user is given an opportunity to cancel the procedure through a dialog window.
-	 */
-	public void storeLesson(File path, Lesson l) throws UserAbortException;
-	
-	/** Loads saved user content of the specified lessons */
-	public void loadLesson(File path, Lesson l);
-	
-	/** Removes all user content for all loaded lessons */
-	public void cleanAll(File path) ;
-	
-	/** Removes all user content for all loaded lessons */
-	public void cleanLesson(File path, Lesson l);
-}
diff --git a/src/jlm/core/model/session/SessionDB.java b/src/jlm/core/model/session/SessionDB.java
deleted file mode 100644
index 7986ab0..0000000
--- a/src/jlm/core/model/session/SessionDB.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package jlm.core.model.session;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Lecture;
-
-public class SessionDB {
-	private Map<String, Map<ProgrammingLanguage, Map<String, String>>> body = new HashMap<String, Map<ProgrammingLanguage,Map<String,String>>>(); 
-	private Map<String, Map<ProgrammingLanguage, Boolean>> passed = new HashMap<String, Map<ProgrammingLanguage,Boolean>>();
-	
-	/* Per lesson summary */
-	private Map<String, Map<ProgrammingLanguage, Integer>> passedExercises = new HashMap<String, Map<ProgrammingLanguage,Integer>>();
-	private Map<String, Map<ProgrammingLanguage, Integer>> possibleExercises = new HashMap<String, Map<ProgrammingLanguage,Integer>>();
-	
-	public void setBody(Lecture exo, ProgrammingLanguage lang, String sourceName, String _body) {
-		if (exo == null)
-			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Map<String, String>> bodyE = body.get(exo);
-		if (bodyE == null) {
-			bodyE = new HashMap<ProgrammingLanguage,Map<String, String>>();
-			body.put(exo.getId(), bodyE);
-		}
-		Map<String, String> bodyLEP = bodyE.get(lang);
-		if (bodyLEP == null) {
-			bodyLEP = new HashMap<String, String>();
-			bodyE.put(lang, bodyLEP);
-		}
-		
-		bodyLEP.put(sourceName, _body);
-	}
-	public String getBody(Lecture exo, ProgrammingLanguage lang, String sourceName) {
-		if (exo == null)
-			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Map<String, String>> bodyE = body.get(exo.getId());
-		if (bodyE == null) 
-			return null;
-		Map<String, String> bodyEP = bodyE.get(lang);
-		if (bodyEP == null)
-			return null;
-		return bodyEP.get(sourceName);
-	}
-
-
-	public void setPassed(Lecture exo, ProgrammingLanguage lang, boolean _passed) {
-		if (exo == null)
-			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-		
-		if (getPassed(exo, lang) == _passed)
-			return;
-		
-		setPassedExercises(exo.getLesson().getId(), lang, getPassedExercises(exo.getLesson().getId(), lang) + (_passed?1:-1));
-		
-		Map<ProgrammingLanguage, Boolean> passedE = passed.get(exo.getId());
-		if (passedE == null) {
-			passedE = new HashMap<ProgrammingLanguage, Boolean>();
-			passed.put(exo.getId(), passedE);
-		}
-		passedE.put(lang,_passed);		
-	}
-	
-	/** If the exercise was never attempted (not present in DB), it returns false */
-	public boolean getPassed(Lecture exo, ProgrammingLanguage lang) {
-		if (exo == null)
-			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Boolean> passedE = passed.get(exo.getId());
-		if (passedE == null)
-			return false;
-		
-		Boolean res = passedE.get(lang);
-		if (res == null) 
-			return false;
-		return res;
-	}
-	public Integer getPossibleExercises(String lesson, ProgrammingLanguage lang) {
-		if (lesson == null)
-			lesson = Game.getInstance().getCurrentLesson().getId();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Integer> passedL = possibleExercises.get(lesson);
-		if (passedL == null)
-			return 0;
-		
-		Integer res = passedL.get(lang);
-		if (res == null) 
-			return 0;
-		return res;
-	}
-	public void setPassedExercises(String lesson, ProgrammingLanguage lang, int val) {
-		if (lesson == null)
-			lesson = Game.getInstance().getCurrentLesson().getId();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Integer> passedL = passedExercises.get(lesson);
-		if (passedL == null) {
-			passedL = new HashMap<ProgrammingLanguage, Integer>();
-			passedExercises.put(lesson, passedL);
-		}
-		
-		passedL.put(lang, val);
-	}
-	public void setPossibleExercises(String lesson, ProgrammingLanguage lang, int val) {
-		if (lesson == null)
-			lesson = Game.getInstance().getCurrentLesson().getId();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Integer> possibleL = possibleExercises.get(lesson);
-		if (possibleL == null) {
-			possibleL = new HashMap<ProgrammingLanguage, Integer>();
-			possibleExercises.put(lesson, possibleL);
-		}
-		
-		possibleL.put(lang,val);
-	}
-	public Integer getPassedExercises(String lesson, ProgrammingLanguage lang) {
-		if (lesson == null)
-			lesson = Game.getInstance().getCurrentLesson().getId();
-		if (lang == null)
-			lang = Game.getProgrammingLanguage();
-
-		Map<ProgrammingLanguage, Integer> passedL = passedExercises.get(lesson);
-		if (passedL == null)
-			return 0;
-		
-		Integer res = passedL.get(lang);
-		if (res == null) 
-			return 0;
-		return res;
-	}
-	public Set<String> getLessonsNames() {
-		return possibleExercises.keySet();
-	}
-}
diff --git a/src/jlm/core/model/session/ZipSessionKit.java b/src/jlm/core/model/session/ZipSessionKit.java
deleted file mode 100644
index 1dcb2b9..0000000
--- a/src/jlm/core/model/session/ZipSessionKit.java
+++ /dev/null
@@ -1,387 +0,0 @@
-package jlm.core.model.session;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.zip.Deflater;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
-
-import javax.swing.JOptionPane;
-
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.UserAbortException;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.model.lesson.SourceFile;
-import jlm.core.model.lesson.SourceFileRevertable;
-
-import org.json.simple.JSONObject;
-import org.json.simple.JSONValue;
-import org.json.simple.parser.ParseException;
-
-/**
- * Implementation of the {@link ISessionKit} saving the student data in a zip file.
- * 
- * Unless you edit the source, this is the session kit used.
- */
-public class ZipSessionKit implements ISessionKit {
-
-	private Game game;
-	
-	public ZipSessionKit(Game game) {
-		this.game = game;
-	}
-
-	private File openSaveFile(File path, Lesson lesson) {
-		return new File(path, "jlm-"+lesson.getId()+".zip");
-	}
-
-	@SuppressWarnings("unchecked")
-	@Override
-	public void storeAll(File path) throws UserAbortException {
-		/* First save the bodies */
-		for (Lesson lesson : this.game.getLessons()) 
-			storeLesson(path, lesson);
-			
-		/* Save the per lesson summaries */
-		JSONObject allLessons = new JSONObject();
-		for (String lessonName : this.game.studentWork.getLessonsNames()) {
-			JSONObject allLangs = new JSONObject();
-			for (ProgrammingLanguage lang: Game.getProgrammingLanguages()) {
-				int possible = Game.getInstance().studentWork.getPossibleExercises(lessonName, lang);
-				int passed = Game.getInstance().studentWork.getPassedExercises(lessonName, lang);
-
-				if (possible>0) {
-					JSONObject oneLang = new JSONObject();
-					oneLang.put("possible",possible);
-					oneLang.put("passed",passed);
-					allLangs.put(lang.getLang(),oneLang);
-				}
-			}
-			if (allLangs.size()>0) 
-				allLessons.put(lessonName, allLangs);
-		}
-		//System.out.println("JSON written: "+allLessons.toJSONString());
-		
-
-		ZipOutputStream zos = null;
-		try {
-			zos = new ZipOutputStream(new FileOutputStream(new File(path, "overview.zip")));
-			zos.setMethod(ZipOutputStream.DEFLATED);
-			zos.setLevel(Deflater.BEST_COMPRESSION);
-
-			zos.putNextEntry(new ZipEntry("passed"));
-			zos.write(allLessons.toJSONString().getBytes());
-			zos.closeEntry();
-		} catch (IOException ex) { // FileNotFoundException or IOException
-			// It's ok to loose this data as it will be recomputed when the lessons are actually loaded
-
-		} finally {
-			try {
-				if (zos != null)
-					zos.close();
-			} catch (IOException ioe) {
-				ioe.printStackTrace();
-			}
-		}
-	}
-
-	@Override
-	public void loadAll(File path) {
-		/* First get the bodies */
-		for (Lesson lesson : this.game.getLessons())
-			loadLesson(path, lesson);
-		
-		/* Also get the per lesson summaries */
-		
-		// get the zip content
-		String content = null;
-		ZipFile zf = null;
-		BufferedReader br = null;
-		try {
-			zf = new ZipFile(new File(path, "overview.zip"));
-			ZipEntry entry = zf.getEntry("passed");
-			if (entry == null) 
-				return;
-			
-			InputStream is = zf.getInputStream(entry);
-
-			br = new BufferedReader(new InputStreamReader(is));
-			String s;
-			StringBuffer b = new StringBuffer();
-
-			while ((s = br.readLine()) != null) 
-				b.append(s);
-
-			content = b.toString();
-		} catch (IOException e) {
-			e.printStackTrace();
-		} finally {
-			try {
-				if (zf != null)
-					zf.close();
-				if (br != null)
-					br.close();
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-		if (content == null)
-			return;
-		//System.out.println("JSON Read: "+content);
-		
-		// now parse it
-		Object value = null;
-		try {
-			value = JSONValue.parseWithException(content);
-		} catch (ParseException e) {
-			System.err.println("Parse error while reading the scores from disk:");
-			e.printStackTrace();
-		}
-		if (! (value instanceof JSONObject)) {
-			System.err.println("Retrieved passed-values is not a JSONObject: "+value);
-			return;
-		}
-		JSONObject allLessons = (JSONObject) value; 
-		for (Object lessonName: allLessons.keySet()) {
-			JSONObject allLangs = (JSONObject) allLessons.get(lessonName);
-			for (Object langName: allLangs.keySet()) {
-				ProgrammingLanguage lang = null;
-				for (ProgrammingLanguage l:Game.getProgrammingLanguages())
-					if (l.getLang().equals(langName))
-						lang = l;
-				
-				JSONObject oneLang = (JSONObject) allLangs.get(langName);
-				int possible = Integer.parseInt(""+oneLang.get("possible"));
-				int passed = Integer.parseInt(""+oneLang.get("passed"));
-				Game.getInstance().studentWork.setPossibleExercises((String) lessonName, lang, possible);
-				Game.getInstance().studentWork.setPassedExercises((String) lessonName, lang, passed);
-			}
-		}
-	}
-
-	@Override
-	public void cleanAll(File path) {
-		for (Lesson lesson : this.game.getLessons())
-			cleanLesson(path, lesson);
-	}
-
-	@Override
-	public void storeLesson(File path, Lesson lesson) throws UserAbortException {
-		File saveFile = openSaveFile(path, lesson);
-
-		if (!saveFile.exists()) {
-			File parentDirectory = saveFile.getParentFile().getAbsoluteFile();
-			if (!parentDirectory.exists()) {
-				if (!parentDirectory.mkdir()) {
-					throw new RuntimeException("cannot create session store directory '" + parentDirectory + "'");
-				}
-			}
-		}
-
-		ZipOutputStream zos = null;
-		boolean wroteSomething = false;
-		try {
-			zos = new ZipOutputStream(new FileOutputStream(saveFile));
-			zos.setMethod(ZipOutputStream.DEFLATED);
-			zos.setLevel(Deflater.BEST_COMPRESSION);
-
-			zos.putNextEntry(new ZipEntry("README"));
-			String text = "This file is a JLM session file. Please see http://www.loria.fr/~quinson/Teaching/JLM/ for more details";
-			zos.write(text.getBytes());
-			zos.closeEntry();
-			
-			for (Lecture lecture : lesson.exercises()) {
-				if (lecture instanceof Exercise) {
-					Exercise exercise = (Exercise) lecture;
-					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
-						// flag successfully passed exercise
-						if (Game.getInstance().studentWork.getPassed(exercise, lang)) {
-							ZipEntry ze = new ZipEntry(exercise.getId() + "/DONE."+lang.getExt());
-							zos.putNextEntry(ze);
-							byte[] bytes = new byte[1];
-							// bytes[0] = 'x';
-							zos.write(bytes);
-							zos.closeEntry();
-							wroteSomething  = true;
-						}
-
-					// save exercise body
-						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
-							SourceFile sf = exercise.getSourceFile(lang,i);
-
-							if (!(sf instanceof SourceFileRevertable))
-								continue;
-
-							SourceFileRevertable srcFile = (SourceFileRevertable) sf;
-
-							ZipEntry ze = new ZipEntry(lang+"/"+exercise.getId() + "/" + srcFile.getName());
-							zos.putNextEntry(ze);
-
-							String content = srcFile.getBody();
-
-							if (content.length() > 0 && content.charAt(content.length() - 1) != '\n') {
-								content = content + "\n";
-							}
-
-							byte[] bytes = srcFile.getBody().getBytes();
-							zos.write(bytes);
-							zos.closeEntry();
-							wroteSomething = true;
-						}
-					} // foreach lang
-				} // is exercise
-			} // end-for lecture
-			ZipEntry ze = new ZipEntry("currently_selected_exercise");
-			zos.putNextEntry(ze);
-			zos.write(lesson.getCurrentExercise().getClass().getCanonicalName().getBytes());
-			zos.closeEntry();
-
-		} catch (IOException ex) { // FileNotFoundException or IOException
-			// FIXME: should raise an exception and not show a dialog (it is not a UI class)
-			ex.printStackTrace();
-			Object[] options = { "Ok, quit and lose my data", "Please stop! I'll save it myself first" };
-			int n = JOptionPane.showOptionDialog(null, "JLM were unable to save your session file for lesson "+lesson.getName()+"("
-					+ ex.getClass().getSimpleName() + ":" + ex.getMessage() + ").\n\n"
-					+ " Would you like proceed anyway (and lose any solution typed so far)?",
-					"Your changes are NOT saved", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE,
-					null, options, options[1]);
-			if (n == 1) {
-				throw new UserAbortException("User aborted saving on system error",ex);
-			}
-
-
-		} finally {
-			try {
-				if (zos != null && wroteSomething)
-					zos.close();
-			} catch (IOException ioe) {
-				ioe.printStackTrace();
-			}
-			if (!wroteSomething || saveFile.length() == 0)
-				saveFile.delete();
-		}
-	}
-
-	public void loadLesson(File path, Lesson lesson) {
-		File saveFile = openSaveFile(path, lesson);
-
-		if (!saveFile.exists() || saveFile.length()==0)
-			return;
-
-		ZipFile zf = null;
-		try {
-			zf = new ZipFile(saveFile);
-
-			for (Lecture lecture : lesson.exercises()) {
-				if (lecture instanceof Exercise) {
-					Exercise exercise = (Exercise) lecture;
-
-					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
-						ZipEntry entry = zf.getEntry(exercise.getId() + "/DONE."+lang.getExt());
-						if (entry != null) {
-							Game.getInstance().studentWork.setPassed(exercise, lang, true);
-						}
-
-						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
-							SourceFile srcFile = exercise.getSourceFile(lang,i);
-
-							ZipEntry srcEntry = zf.getEntry(lang+"/"+exercise.getId() + "/" + srcFile.getName());
-							if (srcEntry == null) /* try to load using the old format (not specifying the programming language) */
-								srcEntry = zf.getEntry(exercise.getId() + "/" + srcFile.getName());
-
-							if (srcEntry != null) {
-								InputStream is = zf.getInputStream(srcEntry);
-
-								BufferedReader br = null;
-								try {
-									br = new BufferedReader(new InputStreamReader(is));
-
-									String s;
-									StringBuffer b = new StringBuffer();
-
-									while ((s = br.readLine()) != null) {
-										b.append(s);
-										b.append("\n");
-									}
-
-									srcFile.setBody(b.toString());
-								} catch (IOException e) {
-									e.printStackTrace();
-								} finally {
-									try {
-										br.close();
-									} catch (IOException e) {
-										e.printStackTrace();
-									}
-								}
-							}
-						}
-					} // foreach lang
-				} // is exercise
-			} // end-for lecture
-
-			/* Get the previously selected exercise */
-			ZipEntry entry = zf.getEntry("currently_selected_exercise");
-			if (entry != null) {
-				BufferedReader br = null;
-				try {
-					br = new BufferedReader(new InputStreamReader(zf.getInputStream(entry)));
-					String exoName = br.readLine();
-
-					lesson.setCurrentExercise(exoName);
-				} catch (IOException e) {
-					e.printStackTrace();
-				} finally {
-					try {
-						br.close();
-					} catch (IOException e) {
-						e.printStackTrace();
-					}
-				}
-			}
-			
-		} catch (IOException ex) { // ZipExecption or IOException
-			// FIXME: should raise an exception and not show a dialog (it is not a UI class)
-			ex.printStackTrace();
-			Object[] options = { "Proceed", "Abort" };
-			int n = JOptionPane.showOptionDialog(null, "JLM were unable to load your code for lesson "+lesson.getName()+" ("
-					+ ex.getClass().getSimpleName() + ":" + ex.getMessage() + ").\n\n"
-					+ " Would you like proceed anyway (and lose any solution typed previously)?",
-					"Error while loading your session", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE,
-					null, options, options[1]);
-			if (n == 1) {
-				System.err.println("Abording on user request");
-				// should throw exception to calling method, no System.exit() here !!!
-				System.exit(1);
-			}
-		} finally {
-			try {
-				if (zf != null)
-					zf.close();
-			} catch (IOException ioe) {
-				ioe.printStackTrace();
-			}
-		}
-	}
-
-	@Override
-	public void cleanLesson(File path, Lesson lesson) {
-		File saveFile = openSaveFile(path, lesson);
-
-		if (saveFile.exists()) {
-			if (saveFile.delete()) {
-				Logger.log("ZipSessionKit:cleanup", "cannot remove session store directory");
-			}
-		}
-	}
-
-}
diff --git a/src/jlm/core/model/session/package-info.java b/src/jlm/core/model/session/package-info.java
deleted file mode 100644
index d3d3f41..0000000
--- a/src/jlm/core/model/session/package-info.java
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Interface and implementation of session management. 
- * A session contains the code written by a student. 
-
- * @author oster
- *
- */
-package jlm.core.model.session;
diff --git a/src/jlm/core/model/tracking/HeartBeatSpy.java b/src/jlm/core/model/tracking/HeartBeatSpy.java
deleted file mode 100644
index f4f571f..0000000
--- a/src/jlm/core/model/tracking/HeartBeatSpy.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package jlm.core.model.tracking;
-
-import java.util.ArrayList;
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * Class that report the heartbeat of the user
- * Every minute, the presence of the user on the soft is sent to the server
- * This allows to know who is still connected on a specific course on JLM
- */
-public class HeartBeatSpy extends TimerTask{
-
-    private final static int timeOut = 60;
-    private Timer timer;
-    private ArrayList<ProgressSpyListener> spyListeners;
-
-    public HeartBeatSpy(ArrayList<ProgressSpyListener> spyListeners){
-        timer = new Timer();
-        timer.schedule(this, 0, timeOut * 1000);
-        this.spyListeners = spyListeners;
-    }
-
-    @Override
-    public void run() {
-        // Send a report to the server
-        for(ProgressSpyListener listener: spyListeners){
-            if(listener instanceof ServerSpy)
-                listener.heartbeat();
-        }
-    }
-
-    public void die(){
-        timer.cancel();
-    }
-
-}
diff --git a/src/jlm/core/model/tracking/IdenticaSpy.java b/src/jlm/core/model/tracking/IdenticaSpy.java
deleted file mode 100644
index dd611f2..0000000
--- a/src/jlm/core/model/tracking/IdenticaSpy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package jlm.core.model.tracking;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-import org.apache.http.NameValuePair;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-public class IdenticaSpy implements ProgressSpyListener {
-    private String username;
-
-    public IdenticaSpy() {
-        username = System.getenv("USER");
-        if (username == null)
-            username = System.getenv("USERNAME");
-        if (username == null)
-            username = "John Doe";
-
-    }
-
-    @Override
-    public void executed(Exercise exo) {
-        if (Game.getInstance().studentWork.getPassed(exo, exo.lastResult.language)) {
-
-            DefaultHttpClient httpclient = new DefaultHttpClient();
-            try {
-                HttpPost post = new HttpPost(new URI("http://identi.ca/api/statuses/update.json"));
-
-                httpclient.getCredentialsProvider().setCredentials(
-                        new AuthScope("identi.ca", 80),
-                        new UsernamePasswordCredentials(Game.getProperty("jlm.identica.username"),
-                                Game.getProperty("jlm.identica.password")));
-
-                List<NameValuePair> formparams = new ArrayList<NameValuePair>();
-                formparams.add(new BasicNameValuePair("status", username + " solved " + exo.getName() + " in " + exo.lastResult.language + "!"));
-                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
-                post.setEntity(entity);
-
-                httpclient.execute(post);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    @Override
-    public void switched(Exercise exo) {    /* i don't care, i'm a viking */ }
-
-    @Override
-    public void heartbeat(){    /* i don't care, i'm a viking */ }
-
-    @Override
-    public String join() { return ""; }
-
-    @Override
-    public void leave() {
-    }
-}
diff --git a/src/jlm/core/model/tracking/LocalFileSpy.java b/src/jlm/core/model/tracking/LocalFileSpy.java
deleted file mode 100644
index 0c682c3..0000000
--- a/src/jlm/core/model/tracking/LocalFileSpy.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package jlm.core.model.tracking;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-
-/**
- * Spy that registers events in a local file
- */
-public class LocalFileSpy implements ProgressSpyListener {
-
-    private String username;
-    private String filePath;
-
-    public LocalFileSpy(File path) {
-        username = System.getenv("USER");
-        if (username == null)
-            username = System.getenv("USERNAME");
-        if (username == null)
-            username = "John Doe";
-
-        filePath = path.getAbsolutePath() + System.getProperty("file.separator")+ "progress.spy";
-    }
-
-    @Override
-    public void executed(Exercise exo) {
-        if (Game.getInstance().studentWork.getPassed(exo, exo.lastResult.language)) {
-            write(username + " solved " + exo.getName() + " in "
-                    + exo.lastResult.language + "!");
-        } else {
-            write(username + " failed " + exo.getName() + " in "
-                    + exo.lastResult.language + "!");
-        }
-    }
-
-    private void write(String msg) {
-        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
-        try {
-            BufferedWriter bw = new BufferedWriter(new FileWriter(filePath,
-                    true));
-            bw.write("[" + formatter.format(new java.util.Date()) + "] " + msg);
-            bw.newLine();
-            bw.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void switched(Exercise exo) {    /* i don't care, i'm a viking */ }
-
-    @Override
-    public void heartbeat() { /* don't talk to me */ }
-
-    @Override
-    public String join() { return ""; }
-
-    @Override
-    public void leave() { /* good idea, go away */ }
-}
diff --git a/src/jlm/core/model/tracking/ProgressSpyListener.java b/src/jlm/core/model/tracking/ProgressSpyListener.java
deleted file mode 100644
index 7159166..0000000
--- a/src/jlm/core/model/tracking/ProgressSpyListener.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package jlm.core.model.tracking;
-
-import jlm.core.model.lesson.Exercise;
-
-public interface ProgressSpyListener {
-	public void executed(Exercise exo);
-
-    public void switched(Exercise exo);
-
-    public void heartbeat();
-
-    public String join();
-
-    public void leave();
-}
diff --git a/src/jlm/core/model/tracking/ServerSpy.java b/src/jlm/core/model/tracking/ServerSpy.java
deleted file mode 100644
index 51f33c8..0000000
--- a/src/jlm/core/model/tracking/ServerSpy.java
+++ /dev/null
@@ -1,119 +0,0 @@
-package jlm.core.model.tracking;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.model.lesson.Exercise;
-
-import org.json.simple.JSONObject;
-
-/**
- * Abstract class to send users results to a server It constructs the request to
- * send, you have to extend this class to indicate how/where to send the request
- */
-public abstract class ServerSpy implements ProgressSpyListener {
-
-	protected String username;
-
-	public ServerSpy() {
-		username = System.getenv("USER");
-		if (username == null)
-			username = System.getenv("USERNAME");
-		if (username == null)
-			username = "John Doe";
-	}
-
-	/**
-	 * Receive an exercise progress from progressSpyListener, and construct the
-	 * request to send to a server in json
-	 * 
-	 * @param exo
-	 *            progress data
-	 */
-	@Override
-	public void executed(Exercise exo) {
-		JSONObject jsonObject = new JSONObject();
-
-		Game game = Game.getInstance();
-		ExecutionProgress lastResult = exo.lastResult;
-		String exoCode = exo.getSourceFile(lastResult.language, 0)
-				.getBody();
-
-		// Retrieve appropriate parameters regarding the current exercise
-		jsonObject.put("username", username);
-		jsonObject.put("course", game.getCourseID());
-        jsonObject.put("password", game.getCoursePassword());
-		jsonObject.put("exoname", exo.getName());
-		jsonObject.put("exolang", lastResult.language.toString());
-        // passedTests and totalTests are initialized at -1 and 0 in case of compilation error...
-		jsonObject.put("passedtests", lastResult.passedTests != -1 ? lastResult.passedTests + "" : 0 + "");
-		jsonObject.put("totaltests", lastResult.totalTests != 0 ? lastResult.totalTests + "" : 1 + "");
-		jsonObject.put("source", exoCode);
-		jsonObject.put("action", "execute");
-
-		sendRequest(jsonObject.toString());
-	}
-
-	@Override
-	public void switched(Exercise exo) {
-		JSONObject jsonObject = new JSONObject();
-
-		Game game = Game.getInstance();
-		ExecutionProgress lastResult = exo.lastResult;
-		// Retrieve appropriate parameters regarding the new exercise
-		jsonObject.put("username", username);
-		jsonObject.put("course", game.getCourseID());
-        jsonObject.put("password", game.getCoursePassword());
-		jsonObject.put("exoname", exo.getName());
-		jsonObject.put("exolang", lastResult != null ? lastResult.language.toString() : "");
-		jsonObject.put("action", "switch");
-
-		sendRequest(jsonObject.toString());
-	}
-
-	/**
-	 * Send a presence report to the server
-	 */
-	@Override
-	public void heartbeat() {
-		JSONObject jsonObject = new JSONObject();
-        Game game = Game.getInstance();
-		jsonObject.put("username", username);
-		jsonObject.put("action", "heartbeat");
-        jsonObject.put("course", game.getCourseID());
-        jsonObject.put("password", game.getCoursePassword());
-
-		sendRequest(jsonObject.toString());
-	}
-
-	@Override
-	public String join() {
-		JSONObject jsonObject = new JSONObject();
-        Game game = Game.getInstance();
-		jsonObject.put("username", username);
-		jsonObject.put("action", "join");
-        jsonObject.put("course", game.getCourseID());
-        jsonObject.put("password", game.getCoursePassword());
-
-        return sendRequest(jsonObject.toString());
-	}
-
-	@Override
-	public void leave() {
-		JSONObject jsonObject = new JSONObject();
-        Game game = Game.getInstance();
-		jsonObject.put("username", username);
-		jsonObject.put("action", "leave");
-        jsonObject.put("course", game.getCourseID());
-        jsonObject.put("password", game.getCoursePassword());
-
-		sendRequest(jsonObject.toString());
-	}
-
-	/**
-	 * Method to implement to indicate how/where to send data
-	 * 
-	 * @param request
-	 *            request in json to send to the server
-	 */
-	public abstract String sendRequest(String request);
-}
diff --git a/src/jlm/core/model/tracking/ServerSpyAppEngine.java b/src/jlm/core/model/tracking/ServerSpyAppEngine.java
deleted file mode 100644
index 76a24e0..0000000
--- a/src/jlm/core/model/tracking/ServerSpyAppEngine.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package jlm.core.model.tracking;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-
-import jlm.core.model.Game;
-
-/**
- * Implementation of the ServerSpy class, to indicate how/where to send json requests
- * It opens a connection with an App Engine servlet, and send it the request
- * It listens for answer from the server
- */
-public class ServerSpyAppEngine extends ServerSpy {
-
-    private URL server;
-
-    public ServerSpyAppEngine() {
-        super();
-
-        try {
-            server = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/student");
-        } catch (MalformedURLException e) {
-            e.printStackTrace();
-        }
-    }
-
-    public String sendRequest(String request) {
-        String response = "";
-        try {
-
-            // Send data
-            URLConnection conn = server.openConnection();
-            conn.setDoOutput(true);
-            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
-            wr.write(request);
-            wr.flush();
-
-            // Get response data and print it
-            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-            String line;
-            while ((line = br.readLine()) != null)
-                response += line;
-
-            wr.close();
-            br.close();
-
-        } catch (IOException e) {
-            System.out.println("Unable to contact JLMServer to send request " + request);
-        }
-
-        return response;
-    }
-
-}
diff --git a/src/jlm/core/model/tracking/TwitterSpy.java b/src/jlm/core/model/tracking/TwitterSpy.java
deleted file mode 100644
index bdf9b7e..0000000
--- a/src/jlm/core/model/tracking/TwitterSpy.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package jlm.core.model.tracking;
-
-import twitter4j.Twitter;
-import twitter4j.TwitterFactory;
-import twitter4j.http.AccessToken;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-
-public class TwitterSpy implements ProgressSpyListener {
-	private String username;
-	private Twitter twitter;
-
-	public TwitterSpy() {
-		username = System.getenv("USER");
-		if (username == null)
-			username = System.getenv("USERNAME");
-		if (username == null)
-			username = "John Doe";
-
-		twitter = new TwitterFactory().getOAuthAuthorizedInstance(
-				Game.getProperty("jlm.oauth.consumerKey"), 
-				Game.getProperty("jlm.oauth.consumerSecret"), 
-				new AccessToken(Game.getProperty("jlm.oauth.accessToken"), Game.getProperty("jlm.oauth.tokenSecret")));
-	}
-
-	@Override
-	public void executed(Exercise exo) {
-		if (Game.getInstance().studentWork.getPassed(exo, exo.lastResult.language)) {
-			try {
-				twitter.updateStatus(username+" solved "+exo.getName()+" in "+exo.lastResult.language+"!");
-			} catch (Exception e) {
-				// silently ignore network unavailability ;)
-				//e.printStackTrace();
-			}
-		}
-	}
-
-    @Override
-    public void switched(Exercise exo) {    /* i don't care, i'm a viking */    }
-
-    @Override
-    public void heartbeat() {}
-
-    @Override
-    public String join() { return ""; }
-
-    @Override
-    public void leave() {
-    }
-
-}
diff --git a/src/jlm/core/model/tracking/package-info.java b/src/jlm/core/model/tracking/package-info.java
deleted file mode 100644
index 94cd04c..0000000
--- a/src/jlm/core/model/tracking/package-info.java
+++ /dev/null
@@ -1,7 +0,0 @@
-/**
- * Track student activities.
- * 
- * @author oster
- *
- */
-package jlm.core.model.tracking;
\ No newline at end of file
diff --git a/src/jlm/core/package-info.java b/src/jlm/core/package-info.java
deleted file mode 100644
index 2c6fd67..0000000
--- a/src/jlm/core/package-info.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Basic JLM infrastructure: Data Model, User Interface, basic exercise building bricks.
- * 
- * <p>
- * The classes defined directly in this package are stuff that were difficult 
- * to sort properly somewhere. The main sub-packages are
- * <ul>
- *   <li>{@link jlm.core.model} Model of the JLM core: Game singleton, ability to save student 
- *                              files, log stuff, etc.</li>
- *   <li>{@link jlm.core.model.lesson} Building bricks for exercises and lessons: storing students'
- *       code in memory and compiling it; grouping exercises together, providing templates to 
- *       students</li>                            
- *   <li>{@link jlm.core.ui} User interface.</li>
- *   <li>{@link jlm.core.ui.action} The action listeners of the UI, calling the right functions 
- *        of the game singleton.</li>
- * </ul>
- */
-package jlm.core;
diff --git a/src/jlm/core/ui/AboutJLMDialog.java b/src/jlm/core/ui/AboutJLMDialog.java
deleted file mode 100644
index ad67b1b..0000000
--- a/src/jlm/core/ui/AboutJLMDialog.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-import jlm.core.model.Game;
-
-public class AboutJLMDialog extends JDialog {
-
-	private static final long serialVersionUID = -1800747039420103759L;
-	private static AboutJLMDialog instance = null;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	
-	public static AboutJLMDialog getInstance() {
-		if (AboutJLMDialog.instance == null)
-			AboutJLMDialog.instance = new AboutJLMDialog();
-		return AboutJLMDialog.instance;
-	}
-	
-	private AboutJLMDialog() {
-		super(MainFrame.getInstance(), "About JLM", true);
-		this.setTitle(i18n.tr("About JLM dialogTitle"));
-		initComponent();
-	}
-	
-	
-	public void initComponent() {
-		
-		JPanel upperPane = new JPanel();
-		upperPane.setLayout(new BorderLayout());
-		JLabel icon = new JLabel(ResourcesCache.getIcon("img/BuggleQuestBack.png"));
-		upperPane.add(BorderLayout.NORTH, icon);
-		JLabel iconTitle = new JLabel(ResourcesCache.getIcon("img/BuggleQuestBETA.png"));
-		upperPane.add(BorderLayout.CENTER, iconTitle);
-		
-		JLabel text = new JLabel(
-				"<html>"+
-				"<h3 style=\"color:#666666;margin:0px;padding:0px;\">version "+Game.getProperty("jlm.major.version","internal",false)+" "+
-				"<span style=\"font-size:8px; color:#AAAAAA;margin:0px;padding:0px;\">("+Game.getProperty("jlm.major.version","internal",false)+"."+Game.getProperty("jlm.minor.version","",false)+")</span>"+
-				"</h3>"+
-				"<br/>"+
-				"© 2008-2011 Contributors. All rights reserved.<br/>"+
-				"<ul style=\"margin-left:20px;\">" +
-				"<li>Original idea: <i>L. Turbak (Wellesley College)</i></li>"+
-				"<li>Design and code: <i>M. Quinson and G. Oster</i></li>"+
-				"<li>Tests: <i>esial students (class '11, '12, '13, '14)</i></li>"+
-				"</ul><br/>"+
-				"Your code is saved to "+Game.getSavingLocation()+"<br/>"+
-				"</html>"
-		);
-		text.setBackground(Color.white);
-		text.setOpaque(true);
-		upperPane.add(BorderLayout.SOUTH, text);
-		
-		JPanel pane = new JPanel();
-		pane.setLayout(new BorderLayout());
-		pane.add(BorderLayout.CENTER, upperPane);
-		
-		JButton close = new JButton(i18n.tr("Close"));
-		close.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				dispose();
-			}
-		});
-		pane.add(BorderLayout.SOUTH, close);
-		
-		setContentPane(pane);
-		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-		pack();
-		setResizable(false);
-				
-		setLocationRelativeTo(getParent());
-	}
-	
-}
diff --git a/src/jlm/core/ui/AboutLessonDialog.java b/src/jlm/core/ui/AboutLessonDialog.java
deleted file mode 100644
index ce5779c..0000000
--- a/src/jlm/core/ui/AboutLessonDialog.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JFrame;
-
-import jlm.core.model.Game;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public class AboutLessonDialog extends AbstractAboutDialog {
-
-	private static final long serialVersionUID = 1766486738385426108L;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public AboutLessonDialog(JFrame parent) {
-		super(parent);
-		currentLessonHasChanged();
-	}
-
-	@Override
-	public void currentLessonHasChanged() {
-		setTitle(i18n.tr("About lesson - ") + Game.getInstance().getCurrentLesson().getName());
-
-		area.setText(Game.getInstance().getCurrentLesson().getAbout());
-		area.setCaretPosition(0);
-	}
-
-}
diff --git a/src/jlm/core/ui/AboutWorldDialog.java b/src/jlm/core/ui/AboutWorldDialog.java
deleted file mode 100644
index 9a6dd77..0000000
--- a/src/jlm/core/ui/AboutWorldDialog.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JFrame;
-
-import jlm.core.ProgLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Exercise.WorldKind;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public class AboutWorldDialog extends AbstractAboutDialog implements ProgLangChangesListener {
-
-	private static final long serialVersionUID = 1766486738385426108L;
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public AboutWorldDialog(JFrame parent) {
-		super(parent);
-		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
-		Game.getInstance().addProgLangListener(this);
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lecture) {
-		if (lecture instanceof Exercise) {
-			Exercise exo = (Exercise) lecture;
-			setTitle(i18n.tr("About world - {0}",
-					exo.getWorlds(WorldKind.CURRENT).get(0).getClass().getSimpleName()));
-			area.setText(exo.getWorlds(WorldKind.CURRENT).get(0).getAbout());
-			area.setCaretPosition(0);
-		} else {
-			// FIXME: should disable the entry menu when seing a lecture, and close any preexisting window when switching to a lecture
-			setVisible(false);
-		}
-	}
-
-	@Override
-	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
-		int pos = area.getCaretPosition();
-		area.setText(((Exercise) Game.getInstance().getCurrentLesson().getCurrentExercise()).getWorlds(WorldKind.CURRENT).get(0).getAbout());
-		area.setCaretPosition(pos);
-	}
-}
diff --git a/src/jlm/core/ui/AbstractAboutDialog.java b/src/jlm/core/ui/AbstractAboutDialog.java
deleted file mode 100644
index f1759bf..0000000
--- a/src/jlm/core/ui/AbstractAboutDialog.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Dimension;
-
-import javax.swing.JDialog;
-import javax.swing.JEditorPane;
-import javax.swing.JFrame;
-import javax.swing.JScrollPane;
-
-import jlm.core.GameListener;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lecture;
-import jlm.universe.World;
-import net.miginfocom.swing.MigLayout;
-
-public abstract class AbstractAboutDialog extends JFrame implements GameListener {
-
-	private static final long serialVersionUID = -6550658679688214378L;
-	protected JEditorPane area = new JEditorPane("text/html","");
-	
-	protected AbstractAboutDialog(JFrame parent) {
-		super();
-		Game.getInstance().addGameListener(this);
-		
-		setResizable(true);
-		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-		setLocationRelativeTo(getParent());
-		
-		setMinimumSize(new Dimension(600,400));
-		
-		area.setEditorKit(new JlmHtmlEditorKit());
-		area.setEditable(false);
-		
-		setLayout(new MigLayout("fill"));
-		add(new JScrollPane(area),"grow");
-	}
-		
-	@Override
-	public void currentExerciseHasChanged(Lecture l)   { /* I dont care I'm a punk */ }
-	@Override
-	public void currentLessonHasChanged()              { /* I dont care I'm a punk */ }
-	@Override
-	public void selectedEntityHasChanged()             { /* I dont care I'm a punk */ }
-	@Override
-	public void selectedWorldHasChanged(World w)       { /* I dont care I'm a punk */ }
-	@Override
-	public void selectedWorldWasUpdated()              { /* I dont care I'm a punk */ }
-}
diff --git a/src/jlm/core/ui/ChooseCourseDialog.java b/src/jlm/core/ui/ChooseCourseDialog.java
deleted file mode 100644
index 1e287b4..0000000
--- a/src/jlm/core/ui/ChooseCourseDialog.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package jlm.core.ui;
-
-import jlm.core.model.*;
-import jlm.core.model.tracking.HeartBeatSpy;
-import jlm.core.model.tracking.ProgressSpyListener;
-import jlm.core.model.tracking.ServerSpy;
-
-import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.util.ArrayList;
-
-
-/**
- * Dialog to allow students or teachers to select the current course
- * It get the updated list of courses from the server, display it
- * You have to enter the course password, and the admin password if you're teacher
- */
-public class ChooseCourseDialog extends JDialog {
-
-    private static final long serialVersionUID = 2234402839093122248L;
-
-    protected ArrayList<String> courseListIDs;
-    protected JList jListID = new JList();
-    protected JButton OKButton;
-    protected JPasswordField passwordField;
-    protected JPasswordField teacherPasswordField;
-    
-    private boolean isChoosen;
-
-
-    public ChooseCourseDialog() {
-        super(MainFrame.getInstance(), "JLM Course", false);
-        isChoosen = false;
-
-        initComponent(this.getContentPane());
-
-        setMinimumSize(new Dimension(300, 400));
-        pack();
-
-        setLocationRelativeTo(getParent());
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(false);
-        //setVisible(true);
-    }
-
-    public void initComponent(Container c) {
-        c.setLayout(new BorderLayout());
-        c.add(new JLabel("Please select your course:", JLabel.CENTER), BorderLayout.NORTH);
-
-        // OK/Cancel button
-        OKButton = new JButton("OK");
-        OKButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                selectCourse();
-            }
-        });
-        OKButton.setEnabled(false);
-
-        JButton cancelButton = new JButton("Cancel");
-        cancelButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                setVisible(false);
-            }
-        });
-
-        JPanel bottomButtons = new JPanel();
-        bottomButtons.setLayout(new FlowLayout());
-        bottomButtons.add(cancelButton);
-        bottomButtons.add(OKButton);
-
-        c.add(bottomButtons, BorderLayout.SOUTH);
-
-        JPanel coursesPanel = new JPanel(new BorderLayout());
-
-        // Load the list of available "courses", or a message to say nope.
-        Course currentCourse = Game.getInstance().getCurrentCourse();
-        courseListIDs = currentCourse.getAllCoursesId();
-
-        if (courseListIDs.isEmpty()) {
-            coursesPanel.add(new JLabel("No course currently opened, sorry.", JLabel.CENTER), BorderLayout.CENTER);
-        } else {
-            jListID.setListData(courseListIDs.toArray());
-
-            jListID.setSelectedValue(currentCourse.getCourseId(), true);
-            if(!currentCourse.getCourseId().isEmpty())
-                OKButton.setEnabled(true);
-            jListID.addListSelectionListener(new ListSelectionListener() {
-                @Override
-                public void valueChanged(ListSelectionEvent listSelectionEvent) {
-                    OKButton.setEnabled(true);
-                    isChoosen = true;
-                }
-            });
-            jListID.addKeyListener(new KeyAdapter() {
-                @Override
-                public void keyReleased(KeyEvent e) {
-                    if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
-                        selectCourse();
-                }
-            });
-            coursesPanel.add(jListID, BorderLayout.CENTER);
-        }
-
-        // Password panel and field (for the student and for the teacher)
-        JPanel passwordsPanel = new JPanel(new BorderLayout()); // i hate swing...
-        JLabel passwordLabel = new JLabel("Course password: ");
-        passwordField = new JPasswordField(10);
-        passwordField.addKeyListener(new KeyAdapter() {
-            @Override
-            public void keyPressed(KeyEvent e) {
-                if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
-                    selectCourse();
-            }
-        });
-        
-        JPanel passwordPanel = new JPanel(new FlowLayout());
-        passwordPanel.add(passwordLabel);
-        passwordPanel.add(passwordField);
-        passwordsPanel.add(passwordPanel, BorderLayout.NORTH);
-        
-        	//Teacher password field
-        if(Game.getProperty("jlm.configuration.teacher").equals("true")) {
-            JLabel teacherPasswordLabel = new JLabel("Teacher password: ");
-            teacherPasswordField = new JPasswordField(10);
-            teacherPasswordField.addKeyListener(new KeyAdapter() {
-                @Override
-                public void keyPressed(KeyEvent e) {
-                    if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
-                        selectCourse();
-                }
-            });
-            
-            JPanel teacherPasswordPanel = new JPanel(new FlowLayout());
-            teacherPasswordPanel.add(teacherPasswordLabel);
-            teacherPasswordPanel.add(teacherPasswordField);
-            passwordsPanel.add(teacherPasswordPanel, BorderLayout.SOUTH);
-        }
-
-        coursesPanel.add(passwordsPanel, BorderLayout.SOUTH);
-        c.add(coursesPanel, BorderLayout.CENTER);
-    }
-
-    /**
-     * Select a new course in the list
-     * if a course was already selected, send a leave and heartbeat die signal
-     * Launch new heartbeat and join events, change current course
-     */
-    public void selectCourse() {
-        Game game = Game.getInstance();
-
-        // leave the previous course and kill the heartbeat if existing
-        if (game.getHeartBeatSpy() != null)
-            game.getHeartBeatSpy().die();
-        if (game.getCourseID() != null && !game.getCourseID().isEmpty())
-            for (ProgressSpyListener spyListener : game.getProgressSpyListeners())
-                spyListener.leave();
-
-        // select the new course
-        String courseName = (jListID.getSelectedValue() != null) ? jListID.getSelectedValue().toString() : "";
-        String coursePass = (passwordField.getPassword() != null) ? new String(passwordField.getPassword()) : "";
-        
-        String teacherCoursePass =  "";
-        if (teacherPasswordField != null) {
-        	teacherCoursePass = (teacherPasswordField.getPassword() != null) ? new String(teacherPasswordField.getPassword()) : "";
-        }
-        		
-        Course course = new CourseAppEngine(courseName, coursePass);
-        course.setTeacherPassword(teacherCoursePass);
-        game.setCurrentCourse(course);
-
-        // report the user presence on the server and verify password
-        boolean passwordError = false;
-        for (ProgressSpyListener spyListener : game.getProgressSpyListeners()) {
-            String response = spyListener.join();
-            if (spyListener instanceof ServerSpy) {
-                if (ServerAnswer.values()[Integer.parseInt(response)] == ServerAnswer.WRONG_PASSWORD)
-                    passwordError = true;
-            }
-        }
-
-        if (passwordError) {
-            JOptionPane.showMessageDialog(getParent(), "Wrong module password", "Server error",
-                    JOptionPane.ERROR_MESSAGE);
-            game.getCurrentCourse().setCourseId(null);
-            MainFrame.getInstance().appendToTitle("");
-        } else {
-            // launch the heartbeat timertask and change window title
-            game.setHeartBeatSpy(new HeartBeatSpy(game.getProgressSpyListeners()));
-            MainFrame.getInstance().appendToTitle("[ " + jListID.getSelectedValue() + " ]");
-        }
-
-        setVisible(false);
-    }
-
-}
diff --git a/src/jlm/core/ui/ChooseLectureDialog.java b/src/jlm/core/ui/ChooseLectureDialog.java
deleted file mode 100644
index 11e51a1..0000000
--- a/src/jlm/core/ui/ChooseLectureDialog.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Component;
-
-import javax.swing.ImageIcon;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTree;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import javax.swing.tree.TreeSelectionModel;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-
-public class ChooseLectureDialog implements TreeSelectionListener {
-	private JTree tree;
-
-	public ChooseLectureDialog() {
-		Lesson l = Game.getInstance().getCurrentLesson();
-		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
-		for (Lecture lect : l.getRootLectures()) 
-			root.add(lect.getNode());
-		
-		tree = new JTree(root);
-		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
-		tree.setRootVisible(false);
-		tree.setShowsRootHandles(true);
-		tree.addTreeSelectionListener(this);
-		tree.setCellRenderer(new DefaultTreeCellRenderer() {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public Component getTreeCellRendererComponent(JTree tree, Object o,
-					boolean selected, boolean expanded, boolean leaf, int row,
-					boolean hasFocus) {
-				super.getTreeCellRendererComponent(tree, o, selected, expanded, leaf, row, hasFocus);
-				Object lect = ((DefaultMutableTreeNode)o).getUserObject();
-
-				ImageIcon icon = null;
-				if (lect instanceof Exercise) {
-					Exercise exo = (Exercise) lect;
-					icon = ResourcesCache.getStarredIcon(exo.getWorld(0).getIcon(), exo);
-				} else {
-					icon = ResourcesCache.getIcon("img/world_lesson.png");
-					if (lect != null && (! (lect instanceof Lecture))) // null may occur -- ignore but don't fail 
-						System.out.println("The exercise chooser contains something that is not a Lecture:"+lect.getClass().getName());
-				}
-				setIcon(icon);
-				return this;
-			}
-		});
-		
-		/* Build the selection */
-		tree.setExpandsSelectedPaths(true);
-		TreeNode[] nodes = l.getCurrentExercise().getNode().getPath();
-		TreePath path = new TreePath(nodes);
-        tree.scrollPathToVisible(path);
-		tree.setSelectionPath(path);
-		
-		JScrollPane jsp = new JScrollPane(tree);
-
-		JPanel p = new JPanel();
-		p.add(jsp);
-		int result = JOptionPane.showConfirmDialog(null, p, "Choose your next exercise",
-				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
-		if (result == JOptionPane.OK_OPTION) {
-			DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
-			if (node != null) {
-				Object selection = node.getUserObject();
-
-				if (selection instanceof Lecture) 
-					Game.getInstance().setCurrentExercise((Lecture) selection);
-				else 
-					System.out.println("selection is not a lecture: "+selection);
-			}
-		}
-
-	}
-
-	@Override
-	public void valueChanged(TreeSelectionEvent e) {
-
-	}
-}
diff --git a/src/jlm/core/ui/CreateCourseDialog.java b/src/jlm/core/ui/CreateCourseDialog.java
deleted file mode 100644
index a5fdb44..0000000
--- a/src/jlm/core/ui/CreateCourseDialog.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package jlm.core.ui;
-
-import jlm.core.model.Course;
-import jlm.core.model.CourseAppEngine;
-import jlm.core.model.Game;
-import jlm.core.model.ServerAnswer;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-
-/**
- * Dialog to create a course on the server, with a name, a user password and an administrator password
- */
-public class CreateCourseDialog extends JDialog {
-
-	private static final long serialVersionUID = 2678745555760465778L;
-	
-	private Course course;
-    private JButton OKButton;
-    private JTextField nameField;
-    private JTextField passwordField;
-    private JTextField teacherPasswordField;
-
-    public CreateCourseDialog() {
-        super(MainFrame.getInstance(), "Add a course", false);
-
-        this.course = new CourseAppEngine();
-        initComponent();
-    }
-
-    public void initComponent() {
-        setLayout(new BorderLayout());
-
-        // OK and Cancel buttons
-
-        OKButton = new JButton("OK");
-        OKButton.setEnabled(false);
-        OKButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                createCourse();
-            }
-        });
-        this.add(OKButton);
-
-        JButton cancelButton = new JButton("Cancel");
-        cancelButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent arg0) {
-                setVisible(false);
-            }
-        });
-        this.add(cancelButton);
-
-        // labels describing fields
-        JLabel nameLabel = new JLabel("Name: ");
-        JLabel passwordLabel = new JLabel("Password (optionnal): ");
-        JLabel teacherPasswordLabel = new JLabel("Teacher password: ");
-
-        // fields where to enter data
-        nameField = new JTextField(10);
-        nameField.addKeyListener(new KeyAdapter() {
-
-            @Override
-            public void keyReleased(KeyEvent e) {
-            	boolean valid = !nameField.getText().isEmpty() && !teacherPasswordField.getText().isEmpty();
-            	
-                OKButton.setEnabled(valid);
-                
-                if(valid && e.getKeyCode() == KeyEvent.VK_ENTER)
-                    createCourse();
-            }
-        });
-
-        passwordField = new JPasswordField(10);
-
-        teacherPasswordField = new JPasswordField(10);
-        teacherPasswordField.addKeyListener(new KeyAdapter() {
-
-            @Override
-            public void keyReleased(KeyEvent e) {
-            	boolean valid = !nameField.getText().isEmpty() && !teacherPasswordField.getText().isEmpty();
-            	
-                OKButton.setEnabled(valid);
-
-                if(valid && e.getKeyCode() == KeyEvent.VK_ENTER)
-                    createCourse();
-            }
-        });
-
-        // panels to contain all those components
-
-        JPanel bottomButtons = new JPanel();
-        bottomButtons.setLayout(new FlowLayout());
-        bottomButtons.add(cancelButton);
-        bottomButtons.add(OKButton);
-
-        JPanel fieldsPanel = new JPanel();
-        fieldsPanel.setLayout(new BorderLayout());
-
-        JPanel namePanel = new JPanel();
-        namePanel.setLayout(new FlowLayout());
-        namePanel.add(nameLabel);
-        namePanel.add(nameField);
-        
-        JPanel passwordPanel = new JPanel();
-        passwordPanel.setLayout(new FlowLayout());
-        passwordPanel.add(passwordLabel);
-        passwordPanel.add(passwordField);
-
-        JPanel teacherPasswordPanel = new JPanel();
-        teacherPasswordPanel.setLayout(new FlowLayout());
-        teacherPasswordPanel.add(teacherPasswordLabel);
-        teacherPasswordPanel.add(teacherPasswordField);
-
-        fieldsPanel.add(namePanel, BorderLayout.NORTH);
-        fieldsPanel.add(passwordPanel, BorderLayout.CENTER);
-        fieldsPanel.add(teacherPasswordPanel, BorderLayout.SOUTH);
-
-        add(fieldsPanel, BorderLayout.CENTER);
-        add(bottomButtons, BorderLayout.SOUTH);
-
-        pack();
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(true);
-
-        setLocationRelativeTo(getParent());
-
-    }
-
-    /**
-     * Create a new course with given name, password and admin password, if name is not empty
-     * We considerate that a course can be created without any password
-     */
-    public void createCourse() {
-        if (!nameField.getText().isEmpty()) {
-            course.setCourseId(nameField.getText());
-            course.setPassword(passwordField.getText());
-            course.setTeacherPassword(teacherPasswordField.getText());
-            setVisible(false);
-
-            if (course.getCourseId() != null){
-                ServerAnswer answer = course.create();
-                if(answer == ServerAnswer.COURSE_NAME_ALREADY_USED)
-                    JOptionPane.showMessageDialog(getParent(), "Course name already used on the server", "Server error",
-                            JOptionPane.ERROR_MESSAGE);
-                else if(answer == ServerAnswer.ALL_IS_FINE){
-                    Game.getInstance().setCurrentCourse(course);
-                    MainFrame.getInstance().appendToTitle("[" + course.getCourseId() + "]");
-                }
-            }
-        }
-    }
-}
diff --git a/src/jlm/core/ui/EntityCellRenderer.java b/src/jlm/core/ui/EntityCellRenderer.java
deleted file mode 100644
index 781af06..0000000
--- a/src/jlm/core/ui/EntityCellRenderer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Component;
-
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.ListCellRenderer;
-
-import jlm.universe.Entity;
-
-
-public class EntityCellRenderer extends JLabel implements ListCellRenderer {
-
-	private static final long serialVersionUID = 5274134398293975047L;
-
-	public EntityCellRenderer() {
-		//setOpaque(true);
-	}
-
-	@Override
-	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
-			boolean cellHasFocus) {
-
-		if (value instanceof Entity) {
-			Entity b = (Entity) value;
-			setText(b.getName());
-		} else {
-			setText(value!=null?value.toString():"");
-		}     
-       
-        if (isSelected) {
-            setBackground(list.getSelectionBackground());
-            setForeground(list.getSelectionForeground());
-        } else {
-            setBackground(list.getBackground());
-            setForeground(list.getForeground());
-        }
-        
-        setFont(list.getFont());
-        setOpaque(true);
-        return this;
-	}
-
-}
diff --git a/src/jlm/core/ui/EntityComboListAdapter.java b/src/jlm/core/ui/EntityComboListAdapter.java
deleted file mode 100644
index 28f7904..0000000
--- a/src/jlm/core/ui/EntityComboListAdapter.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.AbstractListModel;
-import javax.swing.ComboBoxModel;
-
-import jlm.core.GameListener;
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.lesson.Lecture;
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-
-public class EntityComboListAdapter extends AbstractListModel implements ComboBoxModel, GameListener {
-
-	private static final long serialVersionUID = -4602618861291726344L;
-	private Game game;
-	private World[] worlds;
-
-	public EntityComboListAdapter(Game game) {
-		this.game = game;
-		this.game.addGameListener(this);
-		this.worlds = this.game.getSelectedWorlds();
-	}
-
-	@Override
-	public Object getElementAt(int index) {
-		return this.worlds[0].getEntity(index);
-	}
-
-	@Override
-	public int getSize() {
-		return worlds==null || worlds[0]==null ? 0: this.worlds[0].getEntityCount();
-	}
-
-	@Override
-	public Object getSelectedItem() {
-		return this.game.getSelectedEntity();
-	}
-
-	@Override
-	public void setSelectedItem(Object anItem) {
-		if (anItem instanceof Entity) {
-			Entity e = (Entity) anItem;
-			this.game.setSelectedEntity(e);
-			this.worlds[0].setSelectedEntity(e);
-			/* Also inform the objective world that it was changed */
-			for (World w:worlds)
-				w.notifyWorldUpdatesListeners();
-		} else {
-			Logger.log("entityComboListAdapter:setSelectedItem", "parameter is not an entity");
-		}
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lect) { /* don't care */ }
-
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldHasChanged(World w) {
-		this.worlds = this.game.getSelectedWorlds();
-		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
-	}
-
-	@Override
-	public void selectedEntityHasChanged() {
-		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
-	}
-	
-	@Override
-	public void selectedWorldWasUpdated() {
-		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
-	}
-
-}
diff --git a/src/jlm/core/ui/ExerciseFailedDialog.java b/src/jlm/core/ui/ExerciseFailedDialog.java
deleted file mode 100644
index 66a3b7c..0000000
--- a/src/jlm/core/ui/ExerciseFailedDialog.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.Icon;
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.UIManager;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-import jlm.core.model.lesson.ExecutionProgress;
-import net.miginfocom.swing.MigLayout;
-
-public class ExerciseFailedDialog extends JDialog {
-	private static final long serialVersionUID = 1L;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-
-	public ExerciseFailedDialog(ExecutionProgress ep) {
-		super(MainFrame.getInstance(), "Exercise failed /o\\", true);
-		
-		this.setTitle(i18n.tr("Exercise failed /o\\"));
-		
-		setLayout(new MigLayout("fill",""));
-		add(new JLabel( (Icon) UIManager.getLookAndFeelDefaults().get("OptionPane.errorIcon") ));
-		
-		JLabel msg;
-		JTextArea ta = new JTextArea();
-		ta.setEditable(false);
-		if (ep.compilationError == null) { 
-			msg = new JLabel(i18n.tr("You didn't manage to reach your objective." ));
-			ta.setText(ep.details);
-		} else {
-			msg = new JLabel( i18n.tr("Compilation error") );
-			ta.setText(ep.compilationError);
-		}
-		ta.setCaretPosition(0);
-		add(msg,"wrap");
-		add(new JScrollPane(ta),"spanx, grow, growprio 200, wrap");
-		
-		JButton close = new JButton(i18n.tr("Close"));
-		close.addActionListener(new ActionListener() {
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				dispose();
-			}
-		});
-		add(close,"span, alignx 50%");
-		
-		
-		pack();
-		setVisible(true);
-	}
-}
diff --git a/src/jlm/core/ui/ExerciseView.java b/src/jlm/core/ui/ExerciseView.java
deleted file mode 100644
index 96b7e60..0000000
--- a/src/jlm/core/ui/ExerciseView.java
+++ /dev/null
@@ -1,380 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.AWTKeyStroke;
-import java.awt.KeyboardFocusManager;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.swing.BoundedRangeModel;
-import javax.swing.InputMap;
-import javax.swing.JComboBox;
-import javax.swing.JComponent;
-import javax.swing.JPanel;
-import javax.swing.JSlider;
-import javax.swing.JSplitPane;
-import javax.swing.JTabbedPane;
-import javax.swing.KeyStroke;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.event.EventListenerList;
-
-import jlm.core.GameListener;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Exercise.WorldKind;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
-import net.miginfocom.swing.MigLayout;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public class ExerciseView extends JPanel implements GameListener {
-
-	private static final long serialVersionUID = 6649968807663790018L;
-	private Game game;
-	private WorldView worldView;
-	private WorldView objectivesView;
-
-	private JComboBox entityComboBox;
-	private JComboBox worldComboBox;
-	private EntityControlPanel buttonPanel;
-	private JTabbedPane tabPane;
-	private JPanel controlPane;
-	private JSlider speedSlider;
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public ExerciseView(Game game) {
-		super();
-		this.game = game;
-		this.game.addGameListener(this);
-		initComponents();
-		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
-	}
-
-	public void setEnabledControl(boolean enabled) {
-		if (buttonPanel != null)
-			buttonPanel.setEnabledControl(enabled);
-	}
-
-	public void initComponents() {	
-		JPanel upperPane = new JPanel();
-		
-		// TODO: add key shortcuts
-				
-		upperPane.setLayout(new MigLayout("insets 0 0 0 0,wrap","[fill]"));
-
-		worldComboBox = new JComboBox(new WorldComboListAdapter(Game.getInstance()));
-		worldComboBox.setRenderer(new WorldCellRenderer());
-		worldComboBox.setEditable(false);
-		worldComboBox.setToolTipText(i18n.tr("Switch the displayed world"));
-		upperPane.add(worldComboBox, "growx");
-
-		// TODO: logarithmic slider ?
-		speedSlider = new JSlider(new DelayBoundedRangeModel(Game.getInstance()));
-		speedSlider.setOrientation(JSlider.HORIZONTAL);
-		speedSlider.setMajorTickSpacing(50);
-		speedSlider.setMinorTickSpacing(10);
-		speedSlider.setPaintTicks(true);
-		speedSlider.setPaintLabels(true);
-		speedSlider.setToolTipText(i18n.tr("Change the speed of execution"));
-		upperPane.add(speedSlider, "growx");
-
-		tabPane = new JTabbedPane();
-		removeControlPage(tabPane);
-		if (Game.getInstance().getSelectedWorld() != null) {
-			worldView = Game.getInstance().getSelectedWorld().getView();
-			tabPane.addTab(i18n.tr("World")+worldView.getTabName(), null, worldView, 
-					i18n.tr("Current world")+worldView.getTip());
-		}
-		if (Game.getInstance().getAnswerOfSelectedWorld() != null) {
-			objectivesView = Game.getInstance().getAnswerOfSelectedWorld().getView();
-			tabPane.addTab(i18n.tr("Objective")+objectivesView.getTabName(), null, objectivesView, 
-					i18n.tr("Target world")+objectivesView.getTip());
-		}
-		
-		upperPane.add(tabPane, "grow 100 100,push");
-
-		entityComboBox = new JComboBox(new EntityComboListAdapter(Game.getInstance()));
-		entityComboBox.setRenderer(new EntityCellRenderer());
-		entityComboBox.setEditable(false);
-		entityComboBox.setToolTipText(i18n.tr("Switch the entity"));
-		upperPane.add(entityComboBox, "alignx center");
-
-		/*
-		 * FIXME: strange behavior on OSX, if you click on long time on the
-		 * selected entity item then it tries to edit it and throw an exception.
-		 * Even if the editable property is set to false
-		 */
-
-		
-		controlPane = new JPanel();
-		controlPane.setLayout(new MigLayout("insets 0 0 0 0, fill"));
-		if (Game.getInstance().getSelectedWorld()!=null) {
-			buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
-			controlPane.add(buttonPanel, "grow");
-		}
-		//add(controlPane, "span,growx,wrap");
-		
-		
-		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperPane, controlPane);
-		splitPane.setBorder(null);
-		splitPane.setOneTouchExpandable(true);
-		splitPane.setResizeWeight(1.0);
-		splitPane.setDividerLocation(420);
-		
-		this.setLayout(new MigLayout("insets 0 0 0 0, fill"));
-		this.add(splitPane, "grow");
-		
-		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
-		worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);
-		entityComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).getEntityCount() > 1); 
-	}
-
-	public void selectObjectivePane() {
-		tabPane.setSelectedIndex(1);
-	}
-
-	public void selectWorldPane() {
-		tabPane.setSelectedIndex(0);
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lect) {
-		if (worldComboBox != null)
-			worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);
-	}
-
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldHasChanged(World newWorld) {
-		if (worldView != null && worldView.isWorldCompatible(this.game.getSelectedWorld())) {
-			worldView.setWorld(this.game.getSelectedWorld());
-			objectivesView.setWorld(this.game.getAnswerOfSelectedWorld());
-		} else {
-			tabPane.removeAll();
-			worldView = Game.getInstance().getSelectedWorld().getView();
-			tabPane.addTab(i18n.tr("World")+worldView.getTabName(), null, worldView, 
-					i18n.tr("Current world")+worldView.getTip());
-			objectivesView = Game.getInstance().getAnswerOfSelectedWorld().getView();
-			tabPane.addTab(i18n.tr("Objective")+objectivesView.getTabName(), null, objectivesView, 
-					i18n.tr("Target world")+objectivesView.getTip());
-		}
-		// To refresh the controlPane in any case ( else the SortingWorldPanel is not refreshed )
-		controlPane.removeAll();
-		buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
-		controlPane.add(buttonPanel, "grow");
-		
-		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
-		entityComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).getEntityCount() > 1); 
-		worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);		
-	}
-
-	// To refresh the controlPane in the BDR & BDR2 exercise from welcome
-	@Override
-	public void selectedEntityHasChanged() { 
-		controlPane.removeAll();
-		buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
-		controlPane.add(buttonPanel, "grow");
-	}
-
-	@Override
-	public void selectedWorldWasUpdated() { /* don't care */ }
-	
-	 private static void removeControlPage(JComponent comp)
-	  {
-	    KeyStroke ctrlTab = KeyStroke.getKeyStroke("ctrl TAB");
-	    KeyStroke ctrlShiftTab = KeyStroke.getKeyStroke("ctrl shift TAB");
-	 
-	    // Remove ctrl-tab from normal focus traversal
-	    Set<AWTKeyStroke> forwardKeys = new HashSet<AWTKeyStroke>(comp.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
-	    forwardKeys.remove(ctrlTab);
-	    comp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
-	 
-	    // Remove ctrl-shift-tab from normal focus traversal
-	    Set<AWTKeyStroke> backwardKeys = new HashSet<AWTKeyStroke>(comp.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
-	    backwardKeys.remove(ctrlShiftTab);
-	    comp.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
-	 
-	    // Add keys to the tab's input map
-	    InputMap inputMap = comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
-	    inputMap.put(ctrlTab, "navigateNext");
-	    inputMap.put(ctrlShiftTab, "navigatePrevious");
-	  }
-
-	public JTabbedPane getTabPane() {
-		return tabPane;
-	}
-	 
-}
-
-class DelayBoundedRangeModel implements BoundedRangeModel, GameListener {
-
-	public static int MIN_DELAY = 0;
-	public static int DEFAULT_DELAY = 100;
-	public static int MAX_DELAY = 500;
-
-	protected EventListenerList listenerList = new EventListenerList();
-	protected transient ChangeEvent changeEvent = null;
-
-	private int extent = 0;
-	private int min = MIN_DELAY;
-	private int max = MAX_DELAY;
-	private boolean isAdjusting = false;
-
-	private Game game;
-
-	public DelayBoundedRangeModel(Game game) {
-		this.game = game;
-		this.game.addGameListener(this);
-	}
-
-	@Override
-	public int getMaximum() {
-		return this.max;
-	}
-
-	@Override
-	public void setMaximum(int newMaximum) {
-		this.max = newMaximum;
-	}
-
-	@Override
-	public int getMinimum() {
-		return this.min;
-	}
-
-	@Override
-	public void setMinimum(int newMinimum) {
-		this.min = newMinimum;
-	}
-
-	@Override
-	public int getValue() {
-		return game.getSelectedWorld() == null? 0: game.getSelectedWorld().getDelay();
-	}
-
-	@Override
-	public void setValue(int n) {
-		if (game.getSelectedWorld() != null) {
-			n = Math.min(n, Integer.MAX_VALUE - extent);
-
-			int newValue = Math.max(n, min);
-			if (newValue + extent > max) {
-				newValue = max - extent;
-			}
-			setRangeProperties(newValue, extent, min, max, isAdjusting);
-		}
-	}
-
-	@Override
-	public boolean getValueIsAdjusting() {
-		return isAdjusting;
-	}
-
-	@Override
-	public void setValueIsAdjusting(boolean b) {
-		setRangeProperties(game.getSelectedWorld().getDelay(), extent, min, max, b);
-	}
-
-	@Override
-	public int getExtent() {
-		return this.extent;
-	}
-
-	@Override
-	public void setExtent(int n) {
-        int newExtent = Math.max(0, n);
-        int value = game.getSelectedWorld().getDelay();
-        if(value + newExtent > max) {
-            newExtent = max - value;
-        }
-        setRangeProperties(value, newExtent, min, max, isAdjusting);
-	}
-
-	@Override
-	public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) {
-		if (newMin > newMax) {
-			newMin = newMax;
-		}
-		if (newValue > newMax) {
-			newMax = newValue;
-		}
-		if (newValue < newMin) {
-			newMin = newValue;
-		}
-
-		/*
-		 * Convert the addends to long so that extent can be Integer.MAX_VALUE
-		 * without rolling over the sum. A JCK test covers this, see bug
-		 * 4097718.
-		 */
-		if (((long) newExtent + (long) newValue) > newMax) {
-			newExtent = newMax - newValue;
-		}
-
-		if (newExtent < 0) {
-			newExtent = 0;
-		}
-
-		boolean isChange = (newValue != game.getSelectedWorld().getDelay()) || (newExtent != extent)
-				|| (newMin != min) || (newMax != max) || (adjusting != isAdjusting);
-
-		if (isChange) {
-			for (World w:game.getSelectedWorlds())
-				w.setDelay(newValue);
-			extent = newExtent;
-			min = newMin;
-			max = newMax;
-			isAdjusting = adjusting;
-
-			fireStateChanged();
-		}
-	}
-
-	@Override
-	public void addChangeListener(ChangeListener x) {
-		listenerList.add(ChangeListener.class, x);
-	}
-
-	@Override
-	public void removeChangeListener(ChangeListener x) {
-		listenerList.remove(ChangeListener.class, x);
-	}
-
-	protected void fireStateChanged() {
-		Object[] listeners = listenerList.getListenerList();
-		for (int i = listeners.length - 2; i >= 0; i -= 2) {
-			if (listeners[i] == ChangeListener.class) {
-				if (changeEvent == null) {
-					changeEvent = new ChangeEvent(this);
-				}
-				((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
-			}
-		}
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lect) { /* don't care */ }
-
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldHasChanged(World w) {
-		fireStateChanged();
-	}
-
-	@Override
-	public void selectedEntityHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldWasUpdated() {
-		fireStateChanged();
-	}
-}
diff --git a/src/jlm/core/ui/FeedbackDialog.java b/src/jlm/core/ui/FeedbackDialog.java
deleted file mode 100644
index 4287e19..0000000
--- a/src/jlm/core/ui/FeedbackDialog.java
+++ /dev/null
@@ -1,179 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JEditorPane;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.ScrollPaneConstants;
-
-import jlm.core.model.Game;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class FeedbackDialog extends JDialog {
-
-	private static final long serialVersionUID = 0;
-	private static FeedbackDialog instance = null;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	
-	public static FeedbackDialog getInstance() {
-		if (FeedbackDialog.instance == null)
-			FeedbackDialog.instance = new FeedbackDialog();
-		return FeedbackDialog.instance;
-	}
-	
-	private FeedbackDialog() {
-		super(MainFrame.getInstance(), "Report your feedback", true);
-		this.setTitle(i18n.tr("Report your feedback"));
-		initComponent();
-	}
-	
-	
-	public void initComponent() {
-		
-		setLayout(new BorderLayout());
-		JEditorPane explain = new JEditorPane("text/html", "");
-		explain.setText(i18n.tr(
-				"<html><p>Thanks for your feedback on JLM. We deeply need this to make the tool match <br>" +
-				"your needs, so please don't hesitate to report any suggestion, such as typos and <br/>" +
-				"unclear parts in the mission texts, other improvement to the existing exercises<br/>" +
-				"or prospective exercises. We will do our best to integrate your suggestions.</p>" +
-				"<p>Please write here your suggestion (if possible in english or french), with all<br/>" +
-				"necessary details, and then click on 'Send' below.</p>" +
-				"<p><b>Please provide your email address so that we can contact you back</b> but <br/>" +
-				"NEVER DISCLOSE A PASSWORD while reporting issues.</p>" +
-				"<p>Note that some technical information (such as your version of JLM and Java) will <br/>" +
-				"automatically be added to your feedback. None of these automatic information <br/>" +
-				"are personal and you still have to identify yourself if you want to.</p>" +
-
-				"<p>Alternatively, you can use the <a href='http://github.com/oster/JLM/issues'>github interface</a> for feedback.</p></html>"));
-		explain.setBackground(new Color(235,235,235));
-		explain.setOpaque(true);
-		explain.setEditable(false);
-		add(explain, BorderLayout.NORTH);
-		
-		final JEditorPane feedback = new JEditorPane("text/plain",
-				i18n.tr("(your feedback comes here)"));
-		
-		feedback.setBackground(Color.white);
-		feedback.setOpaque(true);
-		feedback.setEditable(true);
-		JScrollPane jsp =new JScrollPane(feedback);
-		jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
-		jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
-		add(jsp,BorderLayout.CENTER);
-		
-		
-		final JButton cancelBtn = new JButton(i18n.tr("Cancel"));
-		cancelBtn.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				int dialogResult = JOptionPane.showConfirmDialog(cancelBtn, 
-						i18n.tr("Do you really want to cancel your feedback and lose any edit?"),
-						i18n.tr("are you sure?"),
-						JOptionPane.YES_NO_OPTION);
-				if(dialogResult==JOptionPane.YES_OPTION)
-					dispose();
-			}
-		});
-		
-		final JButton sendBtn = new JButton(i18n.tr("Send feedback"));
-		sendBtn.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				
-	            DefaultHttpClient httpclient = new DefaultHttpClient();
-	            try {
-	                HttpPost post = new HttpPost(new URI("http://www.loria.fr/~quinson/JLM-feedback/report.php"));
-
-	                List<NameValuePair> formparams = new ArrayList<NameValuePair>();
-	                formparams.add(new BasicNameValuePair("lesson", Game.getInstance().getCurrentLesson().getId()));
-	                formparams.add(new BasicNameValuePair("exercise", Game.getInstance().getCurrentLesson().getCurrentExercise().getId()));
-	                formparams.add(new BasicNameValuePair("language", Game.getProgrammingLanguage().getLang()));
-	                formparams.add(new BasicNameValuePair("locale", Game.getInstance().getLocale().getDisplayName()));
-	                formparams.add(new BasicNameValuePair("java", System.getProperty("java.version")+" (VM: "+System.getProperty("java.vm.name")+"; version: "+System.getProperty("java.vm.version")+")"));
-	                
-	                formparams.add(new BasicNameValuePair("os", System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")"));
-	                formparams.add(new BasicNameValuePair("jlm", Game.getProperty("jlm.major.version","internal",false)+" ("+
-	                		Game.getProperty("jlm.minor.version","internal",false)+")"));
-	                
-	                formparams.add(new BasicNameValuePair("text", feedback.getText()));
-
-	                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
-	                post.setEntity(entity);
-
-	                HttpResponse response = httpclient.execute(post);
-	                
-	                
-	                BufferedReader reader = new BufferedReader(
-	                        new InputStreamReader(response.getEntity().getContent()));
-	                StringBuffer ctn = new StringBuffer();
-	                while (true) {
-	                	String s = reader.readLine();
-	                	if (s == null)
-	                		break;
-	                	ctn.append(s);
-	                } 
-	                if (response.getStatusLine().getStatusCode() == 200) {
-	    				JOptionPane.showMessageDialog(cancelBtn, 
-	    						ctn.toString(),
-	    						i18n.tr("Thank you for your feedback"),
-	    						JOptionPane.INFORMATION_MESSAGE);
-	    				dispose();	                	
-	                } else {
-	    				JOptionPane.showMessageDialog(cancelBtn, 
-	    						ctn.toString(),
-	    						i18n.tr("Error while uploading your feedback"),
-	    						JOptionPane.ERROR_MESSAGE);
-	                }
-	            } catch (Exception ex) {
-	            	StringBuffer ctn = new StringBuffer(ex.getLocalizedMessage()+"\n");
-	            	for (StackTraceElement elm : ex.getStackTrace())
-	            		ctn.append(elm.toString());
-    				JOptionPane.showMessageDialog(cancelBtn, 
-    						ctn.toString(),
-    						i18n.tr("Error while uploading your feedback"),
-    						JOptionPane.ERROR_MESSAGE);
-	                ex.printStackTrace();
-	            }
-
-			}
-		});
-		
-		JPanel toolbar = new JPanel();
-		toolbar.add(cancelBtn);
-		toolbar.add(sendBtn);
-		add(toolbar,BorderLayout.SOUTH);
-		
-		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-		pack();
-		setMinimumSize(new Dimension(200, 600));
-		setPreferredSize(new Dimension(500, 800));
-		setResizable(true);
-				
-		setLocationRelativeTo(getParent());
-	}
-	
-}
diff --git a/src/jlm/core/ui/IEditorPanel.java b/src/jlm/core/ui/IEditorPanel.java
deleted file mode 100644
index 53f1a1f..0000000
--- a/src/jlm/core/ui/IEditorPanel.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package jlm.core.ui;
-
-public interface IEditorPanel {
-	public void clear();
-}
diff --git a/src/jlm/core/ui/JavaEditorPanel.java b/src/jlm/core/ui/JavaEditorPanel.java
deleted file mode 100644
index 074bfc7..0000000
--- a/src/jlm/core/ui/JavaEditorPanel.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JEditorPane;
-import javax.swing.JScrollPane;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.SourceFile;
-import jlm.universe.Entity;
-import jlm.universe.IEntityStackListener;
-
-public class JavaEditorPanel extends JScrollPane implements IEditorPanel,IEntityStackListener {
-	private static final long serialVersionUID = 1L;
-	SourceFile srcFile;
-	SourceFileDocumentSynchronizer sync ;
-	JEditorPane codeEditor;
-	Entity tracedEntity;
-
-	public JavaEditorPanel(SourceFile srcFile, ProgrammingLanguage lang) {
-		super();
-		this.srcFile = srcFile;
-
-		codeEditor = new JEditorPane();
-		setViewportView(codeEditor);
-		codeEditor.setContentType("text/"+lang.getLang().toLowerCase());
-		codeEditor.setCaretPosition(0);
-		//((SyntaxDocument) codeEditor.getDocument()).setCurrentEditedLineNumber(0); TODO: find the new way of doing so in jsyntaxpan 0.9.5
-		
-		/* Create a synchronization element, and connect it to the editor */
-		sync = new SourceFileDocumentSynchronizer(codeEditor.getEditorKit());
-		sync.setDocument(codeEditor.getDocument());
-		codeEditor.getDocument().addDocumentListener(sync);
-		
-		/* Connect the synchronization element to the source file */
-		srcFile.setListener(sync);
-		sync.setSourceFile(srcFile);
-		
-		codeEditor.setText(srcFile.getBody());
-		
-		/* Highlighting stuff, to trace entities */
-		tracedEntity = Game.getInstance().getSelectedEntity();
-		if (tracedEntity != null)
-			tracedEntity.addStackListener(this);
-	}
-	@Override
-	public void clear() {
-		sync.clear();
-		srcFile = null;
-		sync=null;
-		codeEditor=null;
-		if (tracedEntity != null)
-			tracedEntity.removeStackListener(this);
-	}
-	@Override
-	public void entityTraceChanged(Entity e, StackTraceElement[] trace) {
-		/* TODO: The symbol setCurrentEditedLineNumber() is not in jsyntaxpane anymore. 
-		 * But the following code was not working anyway... 
-		for (StackTraceElement elm:trace) {
-			// added defenses against NPE because sometimes (launched from a .jar file, a NullPointerException might happen...)
-			if (elm.getFileName() != null && codeEditor != null && (elm.getFileName().equals(srcFile.getName()) || elm.getFileName().equals(srcFile.getName()+".java from JavaFileObjectImpl"))) {				
-				SyntaxDocument sd = ((SyntaxDocument) codeEditor.getDocument());
-				if (sd != null)
-					sd.setCurrentEditedLineNumber(elm.getLineNumber());
-				codeEditor.repaint();
-			}
-		}		
-		 */
-	}
-	@Override
-	public void tracedEntityChanged(Entity e) {
-		if (tracedEntity != null)
-			tracedEntity.removeStackListener(this);
-
-		tracedEntity = e;
-		if (tracedEntity != null)
-			tracedEntity.addStackListener(this);
-	}
-}
diff --git a/src/jlm/core/ui/JavaLearningMachine.java b/src/jlm/core/ui/JavaLearningMachine.java
deleted file mode 100644
index f74a01c..0000000
--- a/src/jlm/core/ui/JavaLearningMachine.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JFrame;
-
-import jlm.core.model.Game;
-import jlm.core.utils.FileUtils;
-
-
-public class JavaLearningMachine {
-	
-	public static void main(String args[]) {
-		
-		if (System.getProperty("os.name").startsWith("Mac")) {
-			System.setProperty("apple.laf.useScreenMenuBar", "true");
-			System.setProperty("com.apple.mrj.application.apple.menu.about.name", "JLM");
-		}
-		
-		
-		FileUtils.setLocale(new JFrame().getLocale());
-		
-		Game.getInstance().loadChooser();
-		MainFrame.getInstance().setVisible(false);		
-		new LessonChooser();
-		
-	}
-}
diff --git a/src/jlm/core/ui/JlmHtmlEditorKit.java b/src/jlm/core/ui/JlmHtmlEditorKit.java
deleted file mode 100644
index 9959f7a..0000000
--- a/src/jlm/core/ui/JlmHtmlEditorKit.java
+++ /dev/null
@@ -1,291 +0,0 @@
-package jlm.core.ui;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.imageio.ImageIO;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.UIManager;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Element;
-import javax.swing.text.IconView;
-import javax.swing.text.Position;
-import javax.swing.text.StyleConstants;
-import javax.swing.text.View;
-import javax.swing.text.ViewFactory;
-import javax.swing.text.html.HTML;
-import javax.swing.text.html.HTMLEditorKit;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Lecture;
-
-
-public class JlmHtmlEditorKit extends HTMLEditorKit {
-	private static final long serialVersionUID = 1L;
-
-	public static class HTMLFactoryX extends HTMLEditorKit.HTMLFactory implements ViewFactory {
-		boolean visible=false;
-		@Override
-		public View create(Element element) {
-			Element iterElem = element;
-			String theCSSClass = (String) iterElem.getAttributes().getAttribute(HTML.Attribute.CLASS);
-			while (theCSSClass == null && iterElem != null) {
-				iterElem = iterElem.getParentElement();
-				if (iterElem != null)
-					theCSSClass = (String) iterElem.getAttributes().getAttribute(HTML.Attribute.CLASS);
-			}
-			if (theCSSClass != null && 
-				!theCSSClass.toLowerCase().equals(Game.getProgrammingLanguage().getLang().toLowerCase())) {
-				return new EmptyView(element);
-			}
-			
-			Object tagName = element.getAttributes().getAttribute(StyleConstants.NameAttribute);
-			if (tagName instanceof HTML.Tag) {
-				HTML.Tag tag = (HTML.Tag) tagName;
-				if (tag == HTML.Tag.IMG)
-					return new MyIconView(element, baseExercise);
-			}
-			return super.create(element);
-		}
-	}
-
-	protected static Lecture baseExercise = null;
-	public JlmHtmlEditorKit() {
-		baseExercise = null;
-	}
-
-	public JlmHtmlEditorKit(Lecture _baseExercise) {
-		baseExercise = _baseExercise;
-	}
-
-	@Override
-	public ViewFactory getViewFactory() {
-		return new HTMLFactoryX();
-	}
-	private static Map<ProgrammingLanguage,String> css; /** The CSS to use for a given language */
-	public static String getCSS(ProgrammingLanguage lang) {
-		if (css==null) 
-			 css = new HashMap<ProgrammingLanguage, String>();
-		String res = css.get(lang);
-		if (res == null) {
-			res =		"  <style type=\"text/css\">\n"+
-				        "    body { font-family: tahoma, \"Times New Roman\", serif; font-size:10px; margin:10px; }\n"+
-				        "    code { background:#EEEEEE; }\n"+
-				        "    pre { background: #EEEEEE;\n"+
-				        "          margin: 5px;\n"+
-				        "          padding: 6px;\n"+
-				        "          border: 1px inset;\n"+
-				        "          width: 640px;\n"+
-				        "          overflow: auto;\n"+
-				        "          text-align: left;\n"+
-				        "          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"+
-				        "   .comment { background:#EEEEEE;\n"+
-				        "              font-family: \"Times New Roman\", serif;\n"+
-				        "              color:#00AA00;\n"+
-				        "              font-style: italic; }\n";
-			for (ProgrammingLanguage l2 : Game.programmingLanguages) {
-				if (!lang.equals(l2)) {
-					res += "."+l2.getLang()+" {display: none; color:#FF0000;}\n";
-					res += "."+l2.getLang().toLowerCase()+" {display: none; color:#FF0000;}\n";
-				} else {
-					/* DEBUG ONLY, to see the specific elements*/ 
-					res += "."+l2.getLang()+" {visibility: visible; color:#000000;}\n";
-					res += "."+l2.getLang().toLowerCase()+" {visibility: visible; color:#000000;}\n";
-				}
-			}
-			res +=  "  </style>\n";
-			css.put(lang, res);
-		}
-		return res;
-	}
-}
-
-class EmptyView extends IconView {
-
-	public EmptyView(Element elem) {
-		super(elem);
-	}
-	@Override
-	public float getPreferredSpan(int axis) {
-		return 0;
-	}
-	@Override
-	public void paint(Graphics g, Shape a) {
-	}
-}
-
-/* This is a crude copy/paste of IconView where all I changed is the constructor. 
- * The day where swing authors won't fight against subclassing by for example putting the c field as 
- * private here, I will stop doing such nasty thing. 
- * 
- * But I have the feeling that we will move to SWT before that day happens :-/ [Mt] */
-
-class MyIconView extends View {
-	/**
-	 * Creates a new icon view that represents an element.
-	 *
-	 * @param elem the element to create a view for
-	 * @param baseExercise 
-	 * @throws FileNotFoundException 
-	 */
-	public MyIconView(Element elem, Lecture baseExercise) {
-		super(elem);
-		String filename = (String) elem.getAttributes().getAttribute(HTML.Attribute.SRC);
-		if (filename == null) {
-			System.err.println(Game.i18n.tr("<img> tag without src attribute in exercise {0}",baseExercise.getName()));
-			c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
-		} else {
-			c = ResourcesCache.getIcon(filename,true);
-			if (c != null)
-				return;
-			if (baseExercise != null) 
-				c = ResourcesCache.getIcon(baseExercise, filename);
-			if (c != null)
-				return;
-			
-			String resourceName = "/"+filename.replace('.','/');
-			resourceName = resourceName.replaceAll("/png$", ".png").replaceAll("/jpg$", ".jpg");
-			resourceName = resourceName.replaceAll("/jpeg$", ".jpeg").replaceAll("/gif$", ".gif");
-
-			InputStream s = getClass().getResourceAsStream(resourceName);
-			
-			try {
-				if (s == null) {
-					c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
-					System.out.println("Broken image link: "+resourceName);
-				} else
-					c = new ImageIcon(ImageIO.read(s));
-			} catch (IOException e) {
-				e.printStackTrace();
-				c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
-			}
-		}
-	}
-
-	// --- View methods ---------------------------------------------
-
-	/**
-	 * Paints the icon.
-	 * The real paint behavior occurs naturally from the association
-	 * that the icon has with its parent container (the same
-	 * container hosting this view), so this simply allows us to
-	 * position the icon properly relative to the view.  Since
-	 * the coordinate system for the view is simply the parent
-	 * containers, positioning the child icon is easy.
-	 *
-	 * @param g the rendering surface to use
-	 * @param a the allocated region to render into
-	 * @see View#paint
-	 */
-	@Override
-	public void paint(Graphics g, Shape a) {
-		Rectangle alloc = a.getBounds();
-		c.paintIcon(getContainer(), g, alloc.x, alloc.y);
-	}
-
-	/**
-	 * Determines the preferred span for this view along an
-	 * axis.
-	 *
-	 * @param axis may be either View.X_AXIS or View.Y_AXIS
-	 * @return  the span the view would like to be rendered into
-	 *           Typically the view is told to render into the span
-	 *           that is returned, although there is no guarantee.
-	 *           The parent may choose to resize or break the view.
-	 * @exception IllegalArgumentException for an invalid axis
-	 */
-	@Override
-	public float getPreferredSpan(int axis) {
-		switch (axis) {
-		case View.X_AXIS:
-			return c.getIconWidth();
-		case View.Y_AXIS:
-			return c.getIconHeight();
-		default:
-			throw new IllegalArgumentException("Invalid axis: " + axis);
-		}
-	}
-
-	/**
-	 * Determines the desired alignment for this view along an
-	 * axis.  This is implemented to give the alignment to the
-	 * bottom of the icon along the y axis, and the default
-	 * along the x axis.
-	 *
-	 * @param axis may be either View.X_AXIS or View.Y_AXIS
-	 * @return the desired alignment >= 0.0f && <= 1.0f.  This should be
-	 *   a value between 0.0 and 1.0 where 0 indicates alignment at the
-	 *   origin and 1.0 indicates alignment to the full span
-	 *   away from the origin.  An alignment of 0.5 would be the
-	 *   center of the view.
-	 */
-	@Override
-	public float getAlignment(int axis) {
-		switch (axis) {
-		case View.Y_AXIS:
-			return 1;
-		default:
-			return super.getAlignment(axis);
-		}
-	}
-
-	/**
-	 * Provides a mapping from the document model coordinate space
-	 * to the coordinate space of the view mapped to it.
-	 *
-	 * @param pos the position to convert >= 0
-	 * @param a the allocated region to render into
-	 * @return the bounding box of the given position
-	 * @exception BadLocationException  if the given position does not
-	 *   represent a valid location in the associated document
-	 * @see View#modelToView
-	 */
-	@Override
-	public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
-		int p0 = getStartOffset();
-		int p1 = getEndOffset();
-		if ((pos >= p0) && (pos <= p1)) {
-			Rectangle r = a.getBounds();
-			if (pos == p1) {
-				r.x += r.width;
-			}
-			r.width = 0;
-			return r;
-		}
-		throw new BadLocationException(pos + " not in range " + p0 + "," + p1, pos);
-	}
-
-	/**
-	 * Provides a mapping from the view coordinate space to the logical
-	 * coordinate space of the model.
-	 *
-	 * @param x the X coordinate >= 0
-	 * @param y the Y coordinate >= 0
-	 * @param a the allocated region to render into
-	 * @return the location within the model that best represents the
-	 *  given point of view >= 0
-	 * @see View#viewToModel
-	 */
-	@Override
-	public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
-		Rectangle alloc = (Rectangle) a;
-		if (x < alloc.x + (alloc.width / 2)) {
-			bias[0] = Position.Bias.Forward;
-			return getStartOffset();
-		}
-		bias[0] = Position.Bias.Backward;
-		return getEndOffset();
-	}
-
-	// --- member variables ------------------------------------------------
-
-	private Icon c;
-}
-
diff --git a/src/jlm/core/ui/LessonChooser.java b/src/jlm/core/ui/LessonChooser.java
deleted file mode 100644
index d78eb75..0000000
--- a/src/jlm/core/ui/LessonChooser.java
+++ /dev/null
@@ -1,256 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.io.IOException;
-
-import javax.swing.Icon;
-import javax.swing.JButton;
-import javax.swing.JEditorPane;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
-import jlm.core.model.Game;
-import jlm.core.model.LessonLoadingException;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.utils.FileUtils;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class LessonChooser extends JFrame {
-	private static final long serialVersionUID = 1L;
-	I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public LessonChooser() {
-		super();
-		setTitle(i18n.tr("Choose your lesson"));
-		FileUtils.setLocale(this.getLocale());
-		initComponents(Game.getInstance());
-	}
-
-	private void initComponents(Game g) {
-		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
-
-		setBackground(Color.white);
-		setLayout(new BorderLayout());
-
-		JEditorPane blurb = new JEditorPane("text/html", "");
-		blurb.setEditable(false);
-		blurb.setEditorKit(new JlmHtmlEditorKit());
-		blurb.setText(i18n.tr("<table border=\"0\" align=\"center\"><tr>\n" +
-				"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n" +
-				"<td valign=\"center\">  <font size=\"+2\">Welcome to the Java Learning Machine</font>  </td>\n" +
-				"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n" +
-				"</tr></table>\n" +
-				"\n" +
-				"<p><font size=\"+1\">The JLM is a Learning Management System (LMS) aiming at teaching the art of computer " +
-				"programming through interactive exercises. It offers an extensive set of varied " +
-				"exercises, allowing you to practice at your own pace.</font></p><br/>"));
-
-		LessonOverview overview = new LessonOverview(this);
-		
-		LessonMatrix matrix = new LessonMatrix(overview, new String[][] { // WARNING, keep ExoTest.lessons synchronized
-				{"lessons/welcome","lessons/turmites","lessons/maze", "lessons/bat/string1"},
-				{"lessons/sort", "lessons/sort/baseball", "lessons/sort/pancake"},
-				{"lessons/recursion", "lessons/recursion/hanoi" },
-				{"lessons/lightbot" },
-		    }); 
-	
-
-		add(blurb,BorderLayout.NORTH);
-
-		JSplitPane mainPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
-
-		mainPane.setBackground(Color.white);
-		mainPane.setLeftComponent(matrix);
-		mainPane.setRightComponent(overview);
-		
-		add(mainPane, BorderLayout.CENTER);
-
-		pack();
-		setSize(700, 500);
-		setVisible(true);
-		setResizable(false);
-	}
-}
-
-
-class LessonMatrix extends JPanel {
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	private static final long serialVersionUID = 1L;
-
-	public LessonMatrix(LessonOverview overview, String[][] lessons) {
-		setBackground(Color.white);
-		GridBagLayout gl = new GridBagLayout(); 
-		setLayout(gl);
-		
-        GridBagConstraints c = new GridBagConstraints();
-        c.insets = new Insets(3, 3, 3, 3);
-        c.gridwidth = 1;
-
-        int maxCol=0;
-        for (int row = 0; row < lessons.length; row++) {
-        	for (int col=0; col < lessons[row].length; col++) {
-        		LessonButton btLesson = new LessonButton(overview, lessons[row][col]);
-        		
-        		c.gridy = row;
-        		c.gridx = col;
-        		gl.setConstraints(btLesson, c);
-        		add(btLesson);
-        	}
-        	if (row < lessons.length) {
-        		if (lessons[row].length>maxCol)
-        			maxCol = lessons[row].length-1;
-        	} else if (lessons[row].length>maxCol) // React correctly to when the last line is longer than the others
-    			maxCol = lessons[row].length;
-        }
-        /* add a load lesson button */
-        JButton btLoadLesson = new JButton();
-        btLoadLesson.setIcon(ResourcesCache.getIcon("img/bt-load-lesson.png")); 
-		btLoadLesson.setSize(50,50);
-		btLoadLesson.setBackground(Color.white);
-		btLoadLesson.addActionListener(new ActionListener() {
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				JFileChooser fc = new JFileChooser();
-				fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("JLM lesson files"), "jlm"));
-				fc.setDialogType(JFileChooser.OPEN_DIALOG);
-				fc.showOpenDialog(MainFrame.getInstance());
-				File selectedFile = fc.getSelectedFile();
-
-				try {
-					if (selectedFile != null)
-						Game.getInstance().loadLessonFromJAR(fc.getSelectedFile());
-				} catch (LessonLoadingException lle) {
-					JOptionPane.showMessageDialog(null, lle.getMessage(), i18n.tr("Error"), JOptionPane.ERROR_MESSAGE); 
-				}
-			}
-		});
-		c.gridy = lessons.length-1;
-		c.gridx = maxCol;
-		gl.setConstraints(btLoadLesson, c);
-		add(btLoadLesson);
-	}
-	
-}
-
-class LessonOverview extends JPanel {
-	private static final long serialVersionUID = 1L;
-	
-	private JButton btGo;
-	private String path;
-	private JEditorPane desc;
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public LessonOverview(final LessonChooser lc) {
-		setLayout(new BorderLayout());
-		
-		setBackground(Color.white);
-		desc = new JEditorPane("text/html", "");
-		desc.setEditable(false);
-		desc.setEditorKit(new JlmHtmlEditorKit());
-		desc.setText(i18n.tr("<h1>Please pick a lesson</h1>\n" +
-				"<p>Please click on an icon on the left to select a lesson.</p>\n" +
-				"<p>Lessons located above are generally simpler than the ones located below.</p>"));
-
-		JScrollPane descScrol = new JScrollPane(desc);
-		JPanel descPanel = new JPanel(new BorderLayout());
-		descPanel.add(descScrol,BorderLayout.CENTER);
-		descPanel.setBackground(Color.white);
-		descPanel.setSize(new Dimension(27, 15));
-		descPanel.doLayout();
-		add(descPanel,BorderLayout.CENTER);
-		
-		btGo = new JButton(i18n.tr("Go"));
-		btGo.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				Game.getInstance().switchLesson(path.replaceAll("/", "."),false);
-				MainFrame.getInstance().setVisible(true);
-				lc.dispose();
-			}
-		});
-		btGo.setEnabled(false);
-		
-        JPanel bottomButtons = new JPanel();
-        bottomButtons.setBackground(Color.white);
-        bottomButtons.setLayout(new FlowLayout());
-        bottomButtons.add(btGo);
-
-        add(bottomButtons,BorderLayout.SOUTH);
-	}
-	
-	public void setPath(String path) {
-		btGo.setEnabled(true);
-		btGo.requestFocusInWindow();
-		this.path = path;
-		
-		String filename = path.replace('.',File.separatorChar)+"/short_desc";
-		StringBuffer sb = null;
-		try {
-			sb = FileUtils.readContentAsText(filename, "html",true);
-		} catch (IOException ex) {
-			filename += ".html";
-			sb = new StringBuffer(i18n.tr("<p>(unable to display the short description of this lesson: file {0} not found)</p>",filename));
-		}
-
-		sb.append(i18n.tr("<p><b>Your score:</b> "));
-		String id = path.replaceAll("/", ".").replaceAll("^lessons\\.", "");
-		boolean foundOne = false;
-		for (ProgrammingLanguage lang:Game.programmingLanguages) {
-			int possible = Game.getInstance().studentWork.getPossibleExercises(id, lang);
-			int passed = Game.getInstance().studentWork.getPassedExercises(id, lang);
-			if (possible>0) {
-				if (lang == Game.LIGHTBOT) 
-					sb.append(" "+i18n.tr("{0} out of {1} exercises passed.",passed,possible));
-				else {
-					sb.append("<br/>");
-					sb.append("    <img src=\"img/lang_"+lang.getLang().toLowerCase()+".png\">  ");
-					sb.append(i18n.tr("{0} out of {1} exercises passed in {2}.",passed,possible,lang.getLang()));
-				}
-				foundOne = true;
-			}
-		}
-		if (!foundOne) 
-			sb.append(i18n.tr("You never attempted this lesson."));
-		sb.append("</p>");
-		
-		desc.setText(sb.toString());
-		desc.setCaretPosition(0);
-	}	
-}
-
-class LessonButton extends JButton {
-	private static final long serialVersionUID = 1L;
-
-	public LessonButton(final LessonOverview overview, final String path) {
-		super();
-		Icon icon = ResourcesCache.getIcon(path+"/icon.png"); 
-		setIcon(icon);
-		setSize(icon.getIconWidth(), icon.getIconHeight());
-		this.setBackground(Color.white);
-		addActionListener(new ActionListener() {
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				overview.setPath(path);
-			}
-		});
-	}
-}
\ No newline at end of file
diff --git a/src/jlm/core/ui/LoggerPanel.java b/src/jlm/core/ui/LoggerPanel.java
deleted file mode 100644
index 229950f..0000000
--- a/src/jlm/core/ui/LoggerPanel.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package jlm.core.ui;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.swing.JTextArea;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaFileObject;
-
-import jlm.core.model.Game;
-import jlm.core.model.LogWriter;
-
-import java.util.Locale;
-import jlm.core.HumanLangChangesListener;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public class LoggerPanel extends JTextArea implements LogWriter, HumanLangChangesListener {
-
-	private static final long serialVersionUID = 468774822833769775L;
-	
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-
-	public LoggerPanel(Game game) {
-		super();
-		setEditable(false);
-		setToolTipText(i18n.tr("Where error and other messages get written"));
-		game.setOutputWriter(this);
-		game.addHumanLangListener(this);
-	}
-	
-	public void clear() {
-		setText(null);
-	}
-	
-	@Override
-	public void log(String msg) {
-		append(msg);
-	}
-
-	@Override
-	public void log(DiagnosticCollector<JavaFileObject> diagnostics) {
-		boolean warnedJava6= false;
-		Pattern isJava6Pattern = Pattern.compile("major version 51 is newer than 50, the highest major version supported by this compiler");
-		
-		for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
-			String source = diagnostic.getSource() == null ? "(null)" : diagnostic.getSource().getName();
-			String msg = diagnostic.getMessage(getLocale());
-			
-			Matcher isJava6Matcher = isJava6Pattern.matcher(msg);
-			if (isJava6Matcher.find()) {
-				if (!warnedJava6 && Game.getInstance().isDebugEnabled())
-					append("You are using a JLM jarfile that was compiled for Java 6, but you have a Java 7 runtime. This is *believed* to work.\n");
-				warnedJava6 = true;
-			} else {
-				append(source+":"+diagnostic.getLineNumber()+":"+ msg+"\n");
-			}
-		}
-	}
-
-	/**
-	 * Add an exception into the text area
-	 * 
-	 * @param e
-	 *            what to log
-	 */
-	public void log(Exception e) {
-		append(e.toString() + "\n");
-		for (StackTraceElement s : e.getStackTrace()) {
-			if (s.getClassName().contains("bugglequest.BugglePanel"))
-				break;
-			append("  in " + s.getClassName() + "." + s.getMethodName() + " at " + s.getFileName() + ":"
-					+ s.getLineNumber() + "\n");
-		}
-		Throwable t = e.getCause();
-		if (t != null) {
-			append("Caused by:\n  " + t.toString() + "\n");
-			for (StackTraceElement s : t.getStackTrace()) {
-				if (s.getClassName().contains("bugglequest.BugglePanel"))
-					break;
-				append("    in " + s.getClassName() + "." + s.getMethodName() + " at " + s.getFileName() + ":"
-						+ s.getLineNumber() + "\n");
-			}
-
-		}
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n.setLocale(newLang);
-		
-		setToolTipText(i18n.tr("Where error and other messages get written"));
-		
-	}
-
-}
diff --git a/src/jlm/core/ui/MainFrame.java b/src/jlm/core/ui/MainFrame.java
deleted file mode 100644
index 98e90f9..0000000
--- a/src/jlm/core/ui/MainFrame.java
+++ /dev/null
@@ -1,723 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.BorderLayout;
-import java.awt.EventQueue;
-import java.awt.event.ActionEvent;
-import java.awt.event.KeyEvent;
-import java.io.File;
-import java.util.Locale;
-
-import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.ButtonGroup;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JComponent;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JToggleButton;
-import javax.swing.JToolBar;
-import javax.swing.KeyStroke;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
-import jlm.core.GameListener;
-import jlm.core.GameStateListener;
-import jlm.core.HumanLangChangesListener;
-import jlm.core.ProgLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.model.LessonLoadingException;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.ui.action.AbstractGameAction;
-import jlm.core.ui.action.ExportSession;
-import jlm.core.ui.action.HelpMe;
-import jlm.core.ui.action.ImportSession;
-import jlm.core.ui.action.PlayDemo;
-import jlm.core.ui.action.QuitGame;
-import jlm.core.ui.action.Reset;
-import jlm.core.ui.action.RevertExercise;
-import jlm.core.ui.action.SetLanguage;
-import jlm.core.ui.action.SetProgLanguage;
-import jlm.core.ui.action.StartExecution;
-import jlm.core.ui.action.StepExecution;
-import jlm.core.ui.action.StopExecution;
-import jlm.core.ui.action.SwitchExo;
-import jlm.core.utils.FileUtils;
-import jlm.universe.World;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class MainFrame extends JFrame implements GameStateListener, GameListener, HumanLangChangesListener {
-
-	private static final long serialVersionUID = -5022279647890315264L;
-
-	private static MainFrame instance = null;
-
-	private ExerciseView exerciseView;
-	private JButton startButton;
-	private JButton debugButton;
-	private JButton stopButton;
-	private JButton resetButton;
-	private JButton demoButton;
-    private JToggleButton helpMeButton;
-    private JButton exoChangeButton;
-    
-    private JMenu menuFile;
-    private JMenuItem miFileLoad,miFileSwitch,miFileExercise,miFileConsole=null,miFileCourse,miFileQuit;
-    private JMenu menuSession;
-    private JMenuItem miSessionRevert, miSessionExport, miSessionImport, miSessionDebug;
-
-    private JMenu menuLanguage, menuLangHuman, menuLangProg;
-    private JMenu menuHelp;
-    private JMenuItem miHelpFeedback, miHelpLesson,miHelpWorld,miHelpAbout;
-        
-	private LoggerPanel outputArea;
-	private MissionEditorTabs met;
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	private JSplitPane mainPanel;
-	
-	private static final String frameTitle = "Java Learning Machine";
-
-	private MainFrame() {
-		super(frameTitle);
-		FileUtils.setLocale(this.getLocale());
-		initComponents(Game.getInstance());
-		this.keyListeners(exerciseView);
-		Game.getInstance().addHumanLangListener(this);
-	}
-
-	public static MainFrame getInstance() {
-		if (MainFrame.instance == null)
-			MainFrame.instance = new MainFrame();
-		return MainFrame.instance;
-	}
-
-	private void initComponents(final Game g) {
-		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
-		getContentPane().setLayout(new BorderLayout());
-
-		JSplitPane logPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
-		logPane.setOneTouchExpandable(true);
-		double ratio = 0.7;
-		logPane.setResizeWeight(ratio);
-		logPane.setDividerLocation((int) (768 * ratio));
-
-		mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
-
-		mainPanel.setOneTouchExpandable(true);
-		double weight = 0.6;
-		mainPanel.setResizeWeight(weight);
-		mainPanel.setDividerLocation((int) (1024 * weight));
-
-		mainPanel.setLeftComponent(met=new MissionEditorTabs());
-		exerciseView = new ExerciseView(g);
-		mainPanel.setRightComponent(exerciseView);
-
-		logPane.setTopComponent(mainPanel);
-		outputArea = new LoggerPanel(g);
-		JScrollPane outputScrollPane = new JScrollPane(outputArea);
-		logPane.setBottomComponent(outputScrollPane);
-		getContentPane().add(logPane, BorderLayout.CENTER);
-
-		initMenuBar(g);
-		initToolBar(g);
-		initStatusBar(g);
-		currentExerciseHasChanged(g.getCurrentLesson().getCurrentExercise()); 
-
-		g.addGameStateListener(this);
-		g.addGameListener(this);
-
-		pack();
-		setSize(1024, 768);
-		setVisible(false);
-	}
-
-	private void initMenuBar(Game g) {
-		JMenuBar menuBar = new JMenuBar();
-		
-		
-		/* === FILE menu === */
-		// for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
-		menuFile = new JMenu(i18n.tr("File"));
-		menuFile.setMnemonic(KeyEvent.VK_F);
-		menuFile.getAccessibleContext().setAccessibleDescription(i18n.tr("File related functions"));
-
-		
-		miFileLoad = new JMenuItem(new AbstractGameAction(g, i18n.tr("Load lesson"), null, KeyEvent.VK_L) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				JFileChooser fc = new JFileChooser();
-				fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("JLM lesson files"), "jlm"));
-				fc.setDialogType(JFileChooser.OPEN_DIALOG);
-				fc.showOpenDialog(MainFrame.getInstance());
-				File selectedFile = fc.getSelectedFile();
-
-				try {
-					if (selectedFile != null)
-						game.loadLessonFromJAR(fc.getSelectedFile());
-				} catch (LessonLoadingException lle) {
-					JOptionPane.showMessageDialog(null, lle.getMessage(), i18n.tr("Error"), JOptionPane.ERROR_MESSAGE); 
-				}
-			}
-		});
-		menuFile.add(miFileLoad);
-		
-		
-		miFileSwitch = new JMenuItem(new AbstractGameAction(g, i18n.tr("Switch lesson"), null, KeyEvent.VK_L) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				new LessonChooser();
-				MainFrame.getInstance().setVisible(false);		
-			}
-		});
-		miFileSwitch.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
-		menuFile.add(miFileSwitch);
-		
-		miFileExercise = new JMenuItem(new AbstractGameAction(g, i18n.tr("Switch exercise"), null, KeyEvent.VK_E) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				new ChooseLectureDialog();
-			}
-		});
-		miFileExercise.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));
-		menuFile.add(miFileExercise);
-		
-		// Teacher console menu item (shown only if defined in the JLM properties)
-        if(Game.getProperty("jlm.configuration.teacher").equals("true")) {
-            miFileConsole = new JMenuItem(new AbstractGameAction(g,i18n.tr("Teacher Console")) {
-
-				private static final long serialVersionUID = 1L;
-				private TeacherConsoleDialog dialog = null;
-
-                @Override
-                public void actionPerformed(ActionEvent e) {
-                    // launch teacher console
-					if (dialog == null) {
-						dialog = new TeacherConsoleDialog();
-					}
-                    dialog.setVisible(true);
-                }
-            });
-            miFileConsole.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK));
-            menuFile.add(miFileConsole);
-        }
-        
-        // Menu item to change the current Course
-        miFileCourse = new JMenuItem(new AbstractGameAction(g, i18n.tr("Choose your course")) {
-
-			private static final long serialVersionUID = 1L;
-			private ChooseCourseDialog dialog = null;
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                // launch a dialog to choose the course
-                if (dialog == null) {
-					dialog = new ChooseCourseDialog();
-				}
-				dialog.setVisible(true);
-            }
-        });
-
-        miFileCourse.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.CTRL_MASK));
-        menuFile.add(miFileCourse);
-       
-        
-        miFileQuit = new JMenuItem(new QuitGame(g, i18n.tr("Quit"), null,  KeyEvent.VK_Q));
-        miFileQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
-
-		menuFile.add(miFileQuit);
-
-		menuBar.add(menuFile);
-
-		/* === Edit menu === */
-		menuSession = new JMenu(i18n.tr("Session"));
-		menuSession.setMnemonic(KeyEvent.VK_S);
-		menuBar.add(menuSession);
-		menuSession.setEnabled(true);
-		
-		miSessionRevert = new JMenuItem(new RevertExercise(g, i18n.tr("Revert Exercise"), null));
-		menuSession.add(miSessionRevert);
-
-		miSessionExport = new JMenuItem(new ExportSession(g, i18n.tr("Export Session Cache"),	null, this));
-		menuSession.add(miSessionExport);
-
-		miSessionImport = new JMenuItem(new ImportSession(g, i18n.tr("Import Session Cache"),
-				null, this));
-		menuSession.add(miSessionImport);
-
-		miSessionDebug = new JCheckBoxMenuItem(new AbstractGameAction(g, i18n.tr("Debug mode"), null, KeyEvent.VK_D) {
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				game.switchDebug();
-
-			}
-		});
-		menuSession.add(miSessionDebug);
-
-
-		/* === Language menu === */
-		menuLanguage = new JMenu(i18n.tr("Language"));
-		menuLanguage.setMnemonic(KeyEvent.VK_L);
-		menuBar.add(menuLanguage);
-
-		/* === Programming language changing === */
-		menuLangHuman = new JMenu(i18n.tr("Human"));
-		menuLanguage.add(menuLangHuman);
-
-		ButtonGroup group = new ButtonGroup();
-
-		for (String[] lang : new String[][] { {"Francais","fr"}, {"English","en"}}) {
-			JMenuItem item = new JRadioButtonMenuItem(new SetLanguage(g, lang[0], new Locale(lang[1])));
-			if (lang[1].equals(FileUtils.getLocale().getLanguage())) 
-				item.setSelected(true);
-			group.add(item);
-			menuLangHuman.add(item);		
-		}
-
-		
-		menuLangProg = new ProgLangSubMenu(i18n.tr("Computer"));
-		menuLanguage.add( menuLangProg );
-
-		/* === Help menu === */
-		menuHelp = new JMenu(i18n.tr("Help"));
-		menuHelp.setMnemonic(KeyEvent.VK_H);
-		menuBar.add(menuHelp);
-
-		miHelpFeedback = new JMenuItem(new AbstractGameAction(g, i18n.tr("Provide feedback")) {
-			private static final long serialVersionUID = 1L;
-
-			public void actionPerformed(ActionEvent arg0) {
-				FeedbackDialog.getInstance().setVisible(true);
-			}			
-		});
-		miHelpFeedback.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, ActionEvent.CTRL_MASK));
-		menuHelp.add(miHelpFeedback);
-		
-		miHelpLesson = new JMenuItem(new AbstractGameAction(g, i18n.tr("About this lesson")) {
-			private static final long serialVersionUID = 1L;
-			private AbstractAboutDialog dialog = null;
-
-			public void actionPerformed(ActionEvent arg0) {
-				if (this.dialog == null) 
-					this.dialog = new AboutLessonDialog(MainFrame.getInstance());
-
-				this.dialog.setVisible(true);
-			}			
-		});
-		menuHelp.add(miHelpLesson);
-
-		miHelpWorld = new JMenuItem(new AbstractGameAction(g, i18n.tr("About this world"), null) {
-			private static final long serialVersionUID = 1L;
-
-			private AbstractAboutDialog dialog = null;
-
-			public void actionPerformed(ActionEvent arg0) {
-				if (this.dialog == null) {
-					this.dialog = new AboutWorldDialog(MainFrame.getInstance());
-				}
-				this.dialog.setVisible(true);
-			}
-		});
-		miHelpWorld.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK));
-		menuHelp.add(miHelpWorld);
-
-		if (!System.getProperty("os.name").startsWith("Mac")) {
-			miHelpAbout = new JMenuItem(new AbstractGameAction(g, i18n.tr("About JLM"), null) {
-				private static final long serialVersionUID = 1L;
-
-				public void actionPerformed(ActionEvent e) {
-					AboutJLMDialog.getInstance().setVisible(true);
-				}
-			});
-			menuHelp.add(miHelpAbout);
-
-		} else {
-			try {
-				OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", (Class[]) null));
-				OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", (Class[]) null));
-			} catch (SecurityException e) {
-				e.printStackTrace();
-			} catch (NoSuchMethodException e) {
-				e.printStackTrace();
-			}
-		}
-
-		setJMenuBar(menuBar);
-	}
-	
-	public void appendToTitle(String addendum) {
-		this.setTitle(MainFrame.frameTitle +"      "+ addendum);
-	}
-
-	private void initToolBar(Game g) {
-		JToolBar toolBar = new JToolBar();
-		toolBar.setFloatable(true);
-		toolBar.setBorder(BorderFactory.createEtchedBorder());
-
-		ImageIcon ii = ResourcesCache.getIcon("img/btn-start.png");
-		startButton = new PropagatingButton(new StartExecution(g, i18n.tr("Run"), ii));
-		//shortcut ctrl-r
-		startButton.setMnemonic(KeyEvent.VK_R);
-
-		debugButton = new PropagatingButton(new StepExecution(g, i18n.tr("Step"), 
-				ResourcesCache.getIcon("img/btn-debug.png")));
-		//shortcut ctrl-b
-		debugButton.setMnemonic(KeyEvent.VK_B);
-
-		stopButton = new PropagatingButton(new StopExecution(g, i18n.tr("Stop"), 
-				ResourcesCache.getIcon("img/btn-stop.png")));
-		//shortcut ctrl-s
-		stopButton.setMnemonic(KeyEvent.VK_S);
-		stopButton.setEnabled(false);
-
-		resetButton = new PropagatingButton(new Reset(g, i18n.tr("Reset"), 
-				ResourcesCache.getIcon("img/btn-reset.png")));
-		//shortcut ctrl-z
-		resetButton.setMnemonic(KeyEvent.VK_Z);
-		resetButton.setEnabled(true);
-
-		demoButton = new PropagatingButton(new PlayDemo(g, i18n.tr("Demo"), 
-				ResourcesCache.getIcon("img/btn-demo.png")));
-		//shortcut ctrl-d
-		demoButton.setMnemonic(KeyEvent.VK_D);
-		demoButton.setEnabled(true);
-
-        helpMeButton = new PropagatingToggleButton(new HelpMe(g, i18n.tr("Call for Help"),
-                ResourcesCache.getIcon("img/btn-alert-off.png")));
-
-		toolBar.add(startButton);
-		toolBar.add(debugButton);
-		toolBar.add(stopButton);
-		toolBar.add(resetButton);
-		toolBar.add(demoButton);
-        toolBar.add(helpMeButton);
-
-        toolBar.addSeparator();
-        
-        exoChangeButton = new PropagatingButton(new SwitchExo(g, i18n.tr("Switch exercise"), ResourcesCache.getIcon("img/btn-switch-exo.png")));
-        toolBar.add(exoChangeButton);
-        
-		getContentPane().add(toolBar, BorderLayout.NORTH);
-	}
-
-	private void initStatusBar(Game g) {
-		StatusBar statusBar = new StatusBar(g);
-		getContentPane().add(statusBar, BorderLayout.SOUTH);
-	}
-
-	@Override
-	public void stateChanged(Game.GameState type) {
-		switch (type) {
-		case LOADING:
-		case SAVING:
-			startButton.setEnabled(false);
-			debugButton.setEnabled(false);
-			resetButton.setEnabled(false);
-			demoButton.setEnabled(false);
-			exerciseView.setEnabledControl(false);
-			break;
-		case COMPILATION_STARTED:
-			if (!Game.getInstance().isDebugEnabled())
-				outputArea.clear();
-			startButton.setEnabled(false);
-			debugButton.setEnabled(false);
-			resetButton.setEnabled(false);
-			demoButton.setEnabled(false);
-			exerciseView.setEnabledControl(false);
-			break;
-		case LOADING_DONE:
-		case SAVING_DONE:
-			startButton.setEnabled(true);
-			debugButton.setEnabled(true);
-			resetButton.setEnabled(true);
-			demoButton.setEnabled(true);
-			exerciseView.setEnabledControl(true);
-			break;
-		case COMPILATION_ENDED:
-			// startButton.setEnabled(true);
-			// exerciseView.setEnabledControl(true);
-			break;
-		case EXECUTION_STARTED:
-			exerciseView.selectWorldPane();
-			if (Game.getInstance().stepModeEnabled()) {
-				debugButton.setEnabled(true);
-				startButton.setEnabled(true);
-				debugButton.setText(i18n.tr("Next"));
-				debugButton.setIcon(ResourcesCache.getIcon("img/btn-debug-step.png"));
-			} else {
-				startButton.setEnabled(false);
-				debugButton.setEnabled(false);				
-			}
-			resetButton.setEnabled(false);
-			demoButton.setEnabled(false);
-			stopButton.setEnabled(true);
-			exerciseView.setEnabledControl(false);
-			break;
-		case EXECUTION_ENDED:
-			stopButton.setEnabled(false);
-			startButton.setEnabled(true);
-			debugButton.setEnabled(true);
-			debugButton.setText(i18n.tr("Step"));
-			debugButton.setIcon(ResourcesCache.getIcon("img/btn-debug.png"));
-			resetButton.setEnabled(true);
-			demoButton.setEnabled(true);
-			exerciseView.setEnabledControl(true);
-			break;
-		case DEMO_STARTED:
-			exerciseView.selectObjectivePane();
-			startButton.setEnabled(false);
-			debugButton.setEnabled(false);
-			resetButton.setEnabled(false);
-			demoButton.setEnabled(false);
-			stopButton.setEnabled(true);
-			// exerciseView.setEnabledControl(false);
-			break;
-		case DEMO_ENDED:
-			stopButton.setEnabled(false);
-			startButton.setEnabled(true);
-			debugButton.setEnabled(true);
-			resetButton.setEnabled(true);
-			demoButton.setEnabled(true);
-			exerciseView.setEnabledControl(true);
-			break;
-		default:
-		}
-
-	}
-
-	public void hideWorldView() {
-		mainPanel.getBottomComponent().setVisible(false);
-		mainPanel.setDividerSize(0);
-		validate();
-	}
-	public void showWorldView() {
-		mainPanel.getBottomComponent().setVisible(true);
-		mainPanel.setDividerSize(10);
-
-		validate();
-	}
-	public void lessonChooser() {
-
-	}
-
-
-	public void quit() {
-		MainFrame.getInstance().dispose();
-		Game.getInstance().quit();
-	}
-
-	public void about() {
-		EventQueue.invokeLater(new Runnable() {
-			public void run() {
-				EventQueue.invokeLater(new Runnable() {
-					public void run() {
-						AboutJLMDialog.getInstance().setVisible(true);
-					}
-				});
-			}
-		});
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lecture) {
-		Game g = Game.getInstance();
-		if (lecture instanceof Exercise) {
-			showWorldView();
-			Exercise exo = (Exercise) lecture;
-			for (ProgrammingLanguage l:exo.getProgLanguages()) {
-				if (!g.isValidProgLanguage(l)) 
-					System.err.println("Request to add the programming language '"+l+"' to exercise "+exo.getName()+" ignored. Fix your exercise or upgrade your JLM.");
-			}
-		} else {
-			hideWorldView();
-		}
-	}
-
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedEntityHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldHasChanged(World w) { /* don't care */ }
-
-	@Override
-	public void selectedWorldWasUpdated() { /* don't care */ }
-
-	/** Simple JButton which pass the enabled signals to their action */
-	class PropagatingButton extends JButton {
-		private static final long serialVersionUID = 1L;
-		public PropagatingButton(AbstractGameAction act) {
-			super(act);
-			setBorderPainted(false);
-		}
-		@Override
-		public void setEnabled(boolean enabled) {
-			getAction().setEnabled(enabled);
-			super.setEnabled(enabled);
-		}
-	}
-
-    /** Simple JToggleButton which pass the enabled signals to their action */
-	class PropagatingToggleButton extends JToggleButton {
-		private static final long serialVersionUID = 1L;
-		public PropagatingToggleButton(AbstractGameAction act) {
-			super(act);
-			setBorderPainted(false);
-		}
-		@Override
-		public void setEnabled(boolean enabled) {
-			getAction().setEnabled(enabled);
-			super.setEnabled(enabled);
-		}
-	}
-
-	public void keyListeners(ExerciseView e){
-		//CTLR PAGEUP
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0 ), null );
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0), null );
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0), "action pageup" );
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0 ), "action pagedown" );
-		this.getRootPane().getActionMap().put("action pageup", new AbstractAction() {
-			private static final long serialVersionUID = 1L;
-
-			public void actionPerformed(ActionEvent ae) {
-				int index=(met.getSelectedIndex()==0?met.getTabCount()-1:met.getSelectedIndex()-1);
-				met.setSelectedIndex(index);
-			}
-		});
-		this.getRootPane().getActionMap().put("action pagedown", new AbstractAction() {
-			private static final long serialVersionUID = 1L;
-
-			public void actionPerformed(ActionEvent ae) {
-				int index=(met.getSelectedIndex()==met.getTabCount()-1?0:met.getSelectedIndex()+1);
-				met.setSelectedIndex(index);
-			}
-		});
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("left"), "action left" );
-		
-		//F1
-		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("F1" ), "action F1" );
-		this.getRootPane().getActionMap().put("action F1", new AbstractAction() {
-			/**
-			 * 
-			 */
-			private static final long serialVersionUID = 1L;
-
-			public void actionPerformed(ActionEvent ae) {
-				System.out.println("touche F1 press��e" );
-			}
-		}
-				);
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n.setLocale(newLang);
-		//Buttons
-		startButton.setText(i18n.tr("Run"));
-		debugButton.setText(i18n.tr("Step"));
-		stopButton.setText(i18n.tr("Stop"));
-		resetButton.setText(i18n.tr("Reset"));
-		demoButton.setText(i18n.tr("Demo"));
-        helpMeButton.setText(i18n.tr("Call for Help"));
-        exoChangeButton.setText(i18n.tr("Switch exercise"));
-
-        // Menus
-		menuFile.setText(i18n.tr("File"));
-		miFileLoad.setText(i18n.tr("Load lesson"));
-		miFileSwitch.setText(i18n.tr("Switch lesson"));
-		miFileExercise.setText(i18n.tr("Switch exercise"));
-		if (miFileConsole != null)
-			miFileConsole.setText(i18n.tr("Teacher Console"));
-		miFileCourse.setText(i18n.tr("Choose your course"));
-        miFileQuit.setText(i18n.tr("Quit"));
-
-		menuSession.setText(i18n.tr("Session"));
-		menuSession.getAccessibleContext().setAccessibleDescription(i18n.tr("Lesson related functions"));
-		miSessionRevert.setText(i18n.tr("Revert Exercise"));
-		miSessionExport.setText(i18n.tr("Export Session Cache"));
-		miSessionImport.setText(i18n.tr("Import Session Cache"));
-		miSessionDebug.setText(i18n.tr("Debug mode"));
-
-		
-		menuLanguage.setText(i18n.tr("Language"));
-		menuLangHuman.setText(i18n.tr("Human"));
-		menuLangProg.setText(i18n.tr("Computer"));
-		
-		menuHelp.setText(i18n.tr("Help"));
-		miHelpFeedback.setText(i18n.tr("Provide feedback"));
-		miHelpLesson.setText(i18n.tr("About this lesson"));
-		miHelpWorld.setText(i18n.tr("About this world"));
-		if (miHelpAbout != null)
-			miHelpAbout.setText(i18n.tr("About JLM"));
-
-
-
-	}
-}
-
-class ProgLangSubMenu extends JMenu implements ProgLangChangesListener, GameListener {
-	private static final long serialVersionUID = 1L;
-
-	public ProgLangSubMenu(String name) {
-		super(name);
-		Game.getInstance().addGameListener(this);
-		Game.getInstance().addProgLangListener(this);
-		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
-	}
-
-	@Override
-	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
-		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());		
-	}
-	@Override
-	public void currentExerciseHasChanged(Lecture lecture) {
-		Game g = Game.getInstance();
-		if (lecture instanceof Exercise) {
-			setEnabled(true);
-			Exercise exo = (Exercise) lecture;
-			removeAll();
-			for (ProgrammingLanguage pl : exo.getProgLanguages()) {
-				ButtonGroup group = new ButtonGroup();
-				JMenuItem item = new JRadioButtonMenuItem(new SetProgLanguage(g,pl));
-				if (pl.equals(Game.getProgrammingLanguage()))
-					item.setSelected(true);
-				group.add(item);
-				add(item);
-			}
-		} else {
-			setEnabled(false);
-		}
-	}
-
-	@Override
-	public void currentLessonHasChanged() {   /* don't care */ }
-	@Override
-	public void selectedWorldHasChanged(World w) {   /* don't care */ }
-	@Override
-	public void selectedEntityHasChanged() {  /* don't care */ }
-	@Override
-	public void selectedWorldWasUpdated() {   /* don't care */ }
-
-}
diff --git a/src/jlm/core/ui/MissionEditorTabs.java b/src/jlm/core/ui/MissionEditorTabs.java
deleted file mode 100644
index 41218d6..0000000
--- a/src/jlm/core/ui/MissionEditorTabs.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Color;
-import java.awt.Component;
-
-import javax.swing.JComponent;
-import javax.swing.JEditorPane;
-import javax.swing.JScrollPane;
-import javax.swing.JTabbedPane;
-import javax.swing.KeyStroke;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-
-import jlm.core.GameListener;
-import jlm.core.ProgLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.model.lesson.SourceFile;
-import jlm.universe.IEntityStackListener;
-import jlm.universe.World;
-import jsyntaxpane.DefaultSyntaxKit;
-import jsyntaxpane.SyntaxStyle;
-import jsyntaxpane.SyntaxStyles;
-import jsyntaxpane.TokenType;
-import jsyntaxpane.util.Configuration;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-
-public class MissionEditorTabs extends JTabbedPane implements GameListener, ProgLangChangesListener {
-	private static final long serialVersionUID = 1L;
-
-	private Game game;
-	private JEditorPane missionTab = new JEditorPane("text/html", "");
-	
-	/* for code tabs */
-	private Lecture currentExercise;
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-	
-	public MissionEditorTabs() {
-		super();
-		
-		/* Setup the mission tab */
-		missionTab.setEditable(false);
-		missionTab.setEditorKit(new JlmHtmlEditorKit());
-
-		missionTab.addHyperlinkListener(new HyperlinkListener() {
-			TipsDialog tipsDialog = null;
-			
-			@Override
-			public void hyperlinkUpdate(HyperlinkEvent event) {
-				if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
-					String desc = event.getDescription();
-					if (desc.startsWith("#tip-")) {
-						if (this.tipsDialog == null) {
-							this.tipsDialog = new TipsDialog(MainFrame.getInstance());
-						}
-						this.tipsDialog.setText("<html>\n"+Lecture.HTMLTipHeader+"<body>\n"+currentExercise.getTip(desc)+"</body>\n</html>\n");
-						this.tipsDialog.setVisible(true);
-					}
-					if (desc.startsWith("jlm://")) {
-						//Load a regular lesson
-						String lessonName = desc.substring(new String("jlm://").length());
-						String exoName = null;
-						int sep = lessonName.indexOf("/");
-						if (sep != -1) {
-							exoName = lessonName.substring(sep+1);
-							lessonName = lessonName.substring(0, sep);
-							if (exoName.length()==0)
-								exoName = null;
-						}
-						if (Game.getInstance().isDebugEnabled()) 
-							System.out.println("Following a link to lesson: "+lessonName+( (exoName != null) ? "; exo: "+exoName : " (no exo specified)"));
-								
-						Lesson lesson = Game.getInstance().switchLesson(lessonName,false);
-						Game.getInstance().setCurrentLesson(lesson);
-						if (exoName != null && exoName.length()>0) {
-							Lecture lect = lesson.getExercise(exoName);
-							if (lect != null) {
-								Game.getInstance().setCurrentExercise(lect);
-							} else {
-								System.err.println("Broken link: no such lecture '"+exoName+"' in lesson "+lessonName);
-							}
-						}					 
-					}
-				}
-			}
-		});
-		
-		this.addTab(i18n.tr("Mission"), null, new JScrollPane(missionTab),
-				i18n.tr("Description of the work to do"));
-		
-		initJSyntaxPane();
-
-		/* Register to game engine */
-		this.game = Game.getInstance();
-		this.game.addGameListener(this);
-		this.game.addProgLangListener(this);
-		
-		/* add code tabs */
-		currentExerciseHasChanged(game.getCurrentLesson().getCurrentExercise());
-		
-		/* removes keybindings from the JTextField
-		 * Used to permit CTRL-PageUp and CTR-PageDown to change tabs */
-		
-//		this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ctrl pressed PAGE_DOWN"), null );
-//		this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ctrl pressed PAGE_UP" ), null );
-//		this.missionTab.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,InputEvent.CTRL_DOWN_MASK ), null );
-//		this.missionTab.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,InputEvent.CTRL_DOWN_MASK ), null );
-//		System.out.println(showKeys(this, "MissionEditorTabs"));
-//		System.out.println(showKeys(missionTab, "JEditorPane"));
-	}
-	
-	public static String showKeys(JComponent jc, String nom) {
-		String res="";
-		res+=nom+" : "; 
-		
-		KeyStroke[] tab = jc.getInputMap().allKeys();
-		for (int i = 0; i < tab.length-1; i++) {
-			res+=tab[i].toString()+" , ";
-			if(tab[i].toString().contains("PAGE_UP")||tab[i].toString().contains("PAGE_DOWN"))
-				System.err.println(tab[i].toString());
-		}
-		res+=tab[tab.length-1].toString()+"";
-		return res;
-	}
-	@Override
-	public void currentExerciseHasChanged(Lecture lecture) {
-		currentExercise = lecture;		
-
-		currentProgrammingLanguageHasChanged(Game.getProgrammingLanguage()); /* Redo any code panel, and reload the mission */
-		selectedEntityHasChanged();
-		doLayout();
-	}
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-	@Override
-	public void selectedWorldHasChanged(World w) { 
-		selectedEntityHasChanged();
-	}
-	
-	@Override
-	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) { /* Redo any code panel */
-		int tabPosition = getSelectedIndex();
-		/* Remove every tabs, but the mission one */
-		while (getTabCount()>1) {
-			IEditorPanel p = (IEditorPanel) this.getComponentAt(getTabCount()-1);
-			p.clear();
-			removeTabAt(getTabCount()-1);
-		}
-
-		if (currentExercise instanceof Exercise) {
-			/* Add back the right amount of tabs */
-			int publicSrcFileCount = ((Exercise) currentExercise).getSourceFileCount(newLang);
-			for (int i = 0; i < publicSrcFileCount; i++) {
-				/* Create the code editor */
-				SourceFile srcFile = ((Exercise) currentExercise).getSourceFile(newLang, i);
-
-				/* Create the tab with the code editor as content */
-				this.addTab(srcFile.getName(), null, srcFile.getEditorPanel(newLang), i18n.tr("Type your code here")); 
-			}		
-			if (getTabCount()>tabPosition)
-				setSelectedIndex(tabPosition);
-		}
-		/* Change the mission text, because the CSS changed */
-		missionTab.setEditorKit(new JlmHtmlEditorKit(game.getCurrentLesson().getCurrentExercise()));
-		missionTab.setText(this.game.getCurrentLesson().getCurrentExercise().getMission(newLang));
-		missionTab.setCaretPosition(0);
-	}
-
-	@Override
-	public void selectedEntityHasChanged() { /* the code panels may want to know */
-		for (int i=1;i<getTabCount();i++) {
-			Component c = this.getComponentAt(getTabCount()-1);
-			if (c instanceof IEntityStackListener)
-				((IEntityStackListener) c).tracedEntityChanged(game.getSelectedEntity());
-		}
-	}
-	@Override
-	public void selectedWorldWasUpdated() { /* don't care */ }
-
-	/* setup methods */
-	private void initJSyntaxPane() {
-		DefaultSyntaxKit.initKit();
-        Configuration conf = DefaultSyntaxKit.getConfig(DefaultSyntaxKit.class);
-
-
-		//TODO: can be configured through a property file in the new version of jsyntaxpane
-		SyntaxStyles st = SyntaxStyles.getInstance();
-		st.put(TokenType.OPERATOR, new SyntaxStyle(Color.BLACK, false, false)); // black
-		st.put(TokenType.KEYWORD, new SyntaxStyle(new Color(0x8d0056), true, false)); // violet,
-																						// bold
-		st.put(TokenType.TYPE, new SyntaxStyle(Color.BLACK, false, false)); // black
-		st.put(TokenType.COMMENT, new SyntaxStyle(new Color(0x29825e), false, false)); // dark
-																						// green
-		st.put(TokenType.NUMBER, new SyntaxStyle(Color.BLACK, false, false)); // black
-		// st.add(TokenType.REGEX, new SyntaxStyle(new Color(0xcc6600), false, false)); // not used in Java
-		// st.add(TokenType.IDENT, new SyntaxStyle(new Color(0x1300c5), false, false)); // dark blue
-		st.put(TokenType.IDENTIFIER, new SyntaxStyle(Color.black, false, false)); // black
-		st.put(TokenType.STRING, new SyntaxStyle(new Color(0x3600ff), false, false)); // blue
-		st.put(TokenType.DEFAULT, new SyntaxStyle(Color.BLACK, false, false)); // black
-	}
-}
diff --git a/src/jlm/core/ui/OSXAdapter.java b/src/jlm/core/ui/OSXAdapter.java
deleted file mode 100644
index d7af279..0000000
--- a/src/jlm/core/ui/OSXAdapter.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
-
-File: OSXAdapter.java
-
-Abstract: Hooks existing preferences/about/quit functionality from an
-    existing Java app into handlers for the Mac OS X application menu.
-    Uses a Proxy object to dynamically implement the 
-    com.apple.eawt.ApplicationListener interface and register it with the
-    com.apple.eawt.Application object.  This allows the complete project
-    to be both built and run on any platform without any stubs or 
-    placeholders. Useful for developers looking to implement Mac OS X 
-    features while supporting multiple platforms with minimal impact.
-      
-Version: 2.0
-
-Disclaimer: IMPORTANT:  This Apple software is supplied to you by 
-Apple Inc. ("Apple") in consideration of your agreement to the
-following terms, and your use, installation, modification or
-redistribution of this Apple software constitutes acceptance of these
-terms.  If you do not agree with these terms, please do not use,
-install, modify or redistribute this Apple software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, Apple grants you a personal, non-exclusive
-license, under Apple's copyrights in this original Apple software (the
-"Apple Software"), to use, reproduce, modify and redistribute the Apple
-Software, with or without modifications, in source and/or binary forms;
-provided that if you redistribute the Apple Software in its entirety and
-without modifications, you must retain this notice and the following
-text and disclaimers in all such redistributions of the Apple Software. 
-Neither the name, trademarks, service marks or logos of Apple Inc. 
-may be used to endorse or promote products derived from the Apple
-Software without specific prior written permission from Apple.  Except
-as expressly stated in this notice, no other rights or licenses, express
-or implied, are granted by Apple herein, including but not limited to
-any patent rights that may be infringed by your derivative works or by
-other works in which the Apple Software may be incorporated.
-
-The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
-MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
-THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
-OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
-
-IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
-OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
-MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
-AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
-STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-Copyright © 2003-2007 Apple, Inc., All Rights Reserved
-
- */
-
-// http://developer.apple.com/referencelibrary/Java/idxPorting-date.html
-package jlm.core.ui;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-
-public class OSXAdapter implements InvocationHandler {
-
-	protected Object targetObject;
-	protected Method targetMethod;
-	protected String proxySignature;
-
-	static Object macOSXApplication;
-
-	// Pass this method an Object and Method equipped to perform application
-	// shutdown logic
-	// The method passed should return a boolean stating whether or not the quit
-	// should occur
-	public static void setQuitHandler(Object target, Method quitHandler) {
-		setHandler(new OSXAdapter("handleQuit", target, quitHandler));
-	}
-
-	// Pass this method an Object and Method equipped to display application
-	// info
-	// They will be called when the About menu item is selected from the
-	// application menu
-	public static void setAboutHandler(Object target, Method aboutHandler) {
-		boolean enableAboutMenu = (target != null && aboutHandler != null);
-		if (enableAboutMenu) {
-			setHandler(new OSXAdapter("handleAbout", target, aboutHandler));
-		}
-		// If we're setting a handler, enable the About menu item by calling
-		// com.apple.eawt.Application reflectively
-		try {
-			Method enableAboutMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledAboutMenu",
-					new Class[] { boolean.class });
-			enableAboutMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enableAboutMenu) });
-		} catch (Exception ex) {
-			System.err.println("OSXAdapter could not access the About Menu");
-			ex.printStackTrace();
-		}
-	}
-
-	// Pass this method an Object and a Method equipped to display application
-	// options
-	// They will be called when the Preferences menu item is selected from the
-	// application menu
-	public static void setPreferencesHandler(Object target, Method prefsHandler) {
-		boolean enablePrefsMenu = (target != null && prefsHandler != null);
-		if (enablePrefsMenu) {
-			setHandler(new OSXAdapter("handlePreferences", target, prefsHandler));
-		}
-		// If we're setting a handler, enable the Preferences menu item by
-		// calling
-		// com.apple.eawt.Application reflectively
-		try {
-			Method enablePrefsMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledPreferencesMenu",
-					new Class[] { boolean.class });
-			enablePrefsMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enablePrefsMenu) });
-		} catch (Exception ex) {
-			System.err.println("OSXAdapter could not access the About Menu");
-			ex.printStackTrace();
-		}
-	}
-
-	// Pass this method an Object and a Method equipped to handle document
-	// events from the Finder
-	// Documents are registered with the Finder via the CFBundleDocumentTypes
-	// dictionary in the
-	// application bundle's Info.plist
-	public static void setFileHandler(Object target, Method fileHandler) {
-		setHandler(new OSXAdapter("handleOpenFile", target, fileHandler) {
-			// Override OSXAdapter.callTarget to send information on the
-			// file to be opened
-			@Override
-			public boolean callTarget(Object appleEvent) {
-				if (appleEvent != null) {
-					try {
-						Method getFilenameMethod = appleEvent.getClass().getDeclaredMethod("getFilename",
-								(Class[]) null);
-						String filename = (String) getFilenameMethod.invoke(appleEvent, (Object[]) null);
-						this.targetMethod.invoke(this.targetObject, new Object[] { filename });
-					} catch (SecurityException ex) {
-						ex.printStackTrace();
-					} catch (NoSuchMethodException ex) {
-						ex.printStackTrace();
-					} catch (IllegalArgumentException ex) {
-						ex.printStackTrace();
-					} catch (IllegalAccessException ex) {
-						ex.printStackTrace();
-					} catch (InvocationTargetException ex) {
-						ex.printStackTrace();
-					}
-				}
-				return true;
-			}
-		});
-	}
-
-	// setHandler creates a Proxy object from the passed OSXAdapter and adds it
-	// as an ApplicationListener
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	public static void setHandler(OSXAdapter adapter) {
-		try {
-			Class applicationClass = Class.forName("com.apple.eawt.Application");
-			if (macOSXApplication == null) {
-				macOSXApplication = applicationClass.getConstructor((Class[]) null).newInstance((Object[]) null);
-			}
-			Class applicationListenerClass = Class.forName("com.apple.eawt.ApplicationListener");
-			Method addListenerMethod = applicationClass.getDeclaredMethod("addApplicationListener",
-					new Class[] { applicationListenerClass });
-			// Create a proxy object around this handler that can be
-			// reflectively added as an Apple ApplicationListener
-			Object osxAdapterProxy = Proxy.newProxyInstance(OSXAdapter.class.getClassLoader(),
-					new Class[] { applicationListenerClass }, adapter);
-			addListenerMethod.invoke(macOSXApplication, new Object[] { osxAdapterProxy });
-		} catch (ClassNotFoundException cnfe) {
-			System.err
-					.println("This version of Mac OS X does not support the Apple EAWT.  ApplicationEvent handling has been disabled ("
-							+ cnfe + ")");
-		} catch (Exception ex) { // Likely a NoSuchMethodException or an
-			// IllegalAccessException loading/invoking
-			// eawt.Application methods
-			System.err.println("Mac OS X Adapter could not talk to EAWT:");
-			ex.printStackTrace();
-		}
-	}
-
-	// Each OSXAdapter has the name of the EAWT method it intends to listen for
-	// (handleAbout, for example),
-	// the Object that will ultimately perform the task, and the Method to be
-	// called on that Object
-	protected OSXAdapter(String proxySignature, Object target, Method handler) {
-		this.proxySignature = proxySignature;
-		this.targetObject = target;
-		this.targetMethod = handler;
-	}
-
-	// Override this method to perform any operations on the event
-	// that comes with the various callbacks
-	// See setFileHandler above for an example
-	public boolean callTarget(Object appleEvent) throws InvocationTargetException, IllegalAccessException {
-		Object result = targetMethod.invoke(targetObject, (Object[]) null);
-		if (result == null) {
-			return true;
-		}
-		return Boolean.valueOf(result.toString()).booleanValue();
-	}
-
-	// InvocationHandler implementation
-	// This is the entry point for our proxy object; it is called every time an
-	// ApplicationListener method is invoked
-	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-		if (isCorrectMethod(method, args)) {
-			boolean handled = callTarget(args[0]);
-			setApplicationEventHandled(args[0], handled);
-		}
-		// All of the ApplicationListener methods are void; return null
-		// regardless of what happens
-		return null;
-	}
-
-	// Compare the method that was called to the intended method when the
-	// OSXAdapter instance was created
-	// (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
-	protected boolean isCorrectMethod(Method method, Object[] args) {
-		return (targetMethod != null && proxySignature.equals(method.getName()) && args.length == 1);
-	}
-
-	// It is important to mark the ApplicationEvent as handled and cancel the
-	// default behavior
-	// This method checks for a boolean result from the proxy method and sets
-	// the event accordingly
-	protected void setApplicationEventHandled(Object event, boolean handled) {
-		if (event != null) {
-			try {
-				Method setHandledMethod = event.getClass().getDeclaredMethod("setHandled",
-						new Class[] { boolean.class });
-				// If the target method returns a boolean, use that as a hint
-				setHandledMethod.invoke(event, new Object[] { Boolean.valueOf(handled) });
-			} catch (Exception ex) {
-				System.err.println("OSXAdapter was unable to handle an ApplicationEvent: " + event);
-				ex.printStackTrace();
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/jlm/core/ui/ResourcesCache.java b/src/jlm/core/ui/ResourcesCache.java
deleted file mode 100644
index a80a77a..0000000
--- a/src/jlm/core/ui/ResourcesCache.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-import java.net.URL;
-import java.util.Hashtable;
-
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.UIManager;
-
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-
-public class ResourcesCache {
-	private static Hashtable<String, ImageIcon> iconsCache = new Hashtable<String, ImageIcon>();
-
-	private static ImageIcon[] busyIcons;
-
-	public static void loadBusyIconAnimation() {
-		busyIcons = new ImageIcon[30];
-		for (int i=0 ; i<30; i++) {
-			URL url = ResourcesCache.class.getClassLoader().getResource("img/busyicon/anim-"+(i+1)+".png");
-			if (url == null) {
-				busyIcons[i] =  new ImageIcon();
-			} else {
-				busyIcons[i] = new ImageIcon(url);
-			}
-		}
-	}
-	
-	private static Boolean warnedAboutBrokenPath = false;
-	/**
-	 * Lazy loading of ImageIcon resources.
-	 * @param path of the image resource to be loaded.
-	 * @return the ImageIcon or a blank ImageIcon when resource is not found.
-	 */
-	public static ImageIcon getIcon(String path) {
-		return getIcon(path, false);
-	}
-	/**
-	 * Lazy loading of ImageIcon resources.
-	 * @param path of the image resource to be loaded.
-	 * @param okNull : whether it's ok to return null (useful to search for several paths) 
-	 * @return the ImageIcon or a blank ImageIcon when resource is not found.
-	 */
-	public static ImageIcon getIcon(String path, boolean okNull) {
-		if (!iconsCache.containsKey(path)) {
-			URL url = ResourcesCache.class.getClassLoader().getResource(path);
-			if (url == null) {
-				if (okNull) 
-					return null;
-				if (!warnedAboutBrokenPath) {
-					Logger.log("jlm.ui.ResourcesCache.getIcon()", "Cannot find path "+path+": classloader returned null.");
-					warnedAboutBrokenPath = true;
-				}
-				ImageIcon c = (ImageIcon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
-				iconsCache.put(path, c);
-			} else {
-				ImageIcon img = new ImageIcon(url);
-				iconsCache.put(path, img);
-			}
-		}
-		return iconsCache.get(path);
-	}
-
-	public static ImageIcon getIcon(Object basePath, String path) {
-		String name = basePath.getClass().getPackage().getName().replaceAll("\\.", "/") 
-		        +"/"+path;
-		return getIcon(name);
-	}
-
-	public static int getBusyIconsSize() {
-		return ResourcesCache.busyIcons.length;
-	}
-
-
-	public static Icon getBusyIcons(int busyIconIndex) {
-		return ResourcesCache.busyIcons[busyIconIndex];
-	}
-
-	public static ImageIcon getStarredIcon(ImageIcon icon, Exercise exo) {
-		String path = exo.getWorld(0).getView().getClass().getCanonicalName();
-		for (ProgrammingLanguage lang : exo.getProgLanguages()) {
-			if (Game.getInstance().studentWork.getPassed(exo, lang))
-				path += "_"+lang.getLang()+"ok";
-			else 
-				path += "_"+lang.getLang()+"nok";
-		}
-		if (!iconsCache.containsKey(path)) {
-			BufferedImage combined;
-			if (exo.getProgLanguages().contains(Game.LIGHTBOT)) {
-				combined = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
-				Graphics g = combined.getGraphics();
-				g.drawImage(icon.getImage(), 0, 0, null);
-				
-				ImageIcon star = getIcon("resources/star.png");
-				ImageIcon starNo = getIcon("resources/star_white.png");
-				if (Game.getInstance().studentWork.getPassed(exo, Game.LIGHTBOT))  
-					g.drawImage(star.getImage(), 0, 0, null);
-				else 
-					g.drawImage(starNo.getImage(), 0, 0, null);
-				
-			} else {
-				combined = new BufferedImage(icon.getIconWidth()+10, icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
-				Graphics g = combined.getGraphics();
-				g.drawImage(icon.getImage(), 0, 0, null);
-				
-				if (Game.getInstance().studentWork.getPassed(exo, Game.JAVA)) { 
-					g.drawImage(Game.JAVA.getIcon().getImage(), 26, 0, null);
-				} else {
-					//g.drawImage(getIcon("img/lang_java_no.png").getImage(), 26,0,null);
-				}
-				if (Game.getInstance().studentWork.getPassed(exo, Game.PYTHON)) { 
-					g.drawImage(Game.PYTHON.getIcon().getImage(), 26, 16, null);
-				} else {
-					//	g.drawImage(getIcon("img/lang_python_no.png").getImage(), 26,16,null);
-				}
-				
-			}
-			
-			iconsCache.put(path, new ImageIcon(combined));
-		}
-		return iconsCache.get(path);
-	}
-	
-}
diff --git a/src/jlm/core/ui/ResultsPanel.java b/src/jlm/core/ui/ResultsPanel.java
deleted file mode 100644
index c272f21..0000000
--- a/src/jlm/core/ui/ResultsPanel.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package jlm.core.ui;
-
-import jlm.core.model.Game;
-import jlm.core.model.ServerUserData;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.ArrayList;
-import java.util.Map;
-
-/**
- * Panel to display students results from the server
- * You can add a filter of student to display only a list of usernames depending of a criteria (good, bad student...)
- */
-public class ResultsPanel extends JPanel {
-	private static final long serialVersionUID = 1L;
-
-    // all data on students from the server
-    private Map<String, ServerUserData> serverData;
-    // list of students to filter the selection to display (null if all data has to be displayed)
-    private ArrayList<String> userFilter;
-
-    public ResultsPanel(ArrayList<String> userFilter) {
-        this.userFilter = userFilter;
-
-        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
-        setBorder(BorderFactory.createTitledBorder("Results by student"));
-        displayResults();
-    }
-
-    public void displayResults() {
-        this.removeAll();
-        serverData = Game.getInstance().getCurrentCourse().getServerData();
-
-        UIManager.put("ProgressBar.background", Color.RED); //color of the background
-        UIManager.put("ProgressBar.foreground", Color.GREEN);  //color of progress bar
-
-        if (serverData != null) {
-            // Add the results graph of each student to serverDataPanel
-            // if a filter has been set, iterate only through these students
-            // else, iterate through all students of the course
-            for (final String student : (userFilter == null ? serverData.keySet() : userFilter)) {
-                JPanel studentPanel = new JPanel();
-                studentPanel.add(new JLabel(student));
-
-                JProgressBar graph = new JProgressBar(0, serverData.get(student).getExercisesTotal());
-                graph.setValue(serverData.get(student).getExercisesPassed());
-                studentPanel.add(graph);
-                JButton studentButton = new JButton();
-                studentButton.setContentAreaFilled(false);
-                studentButton.add(studentPanel);
-                studentButton.addActionListener(new ActionListener() {
-                    @Override
-                    public void actionPerformed(ActionEvent actionEvent) {
-                        new StudentDetailsDialog(serverData.get(student));
-                    }
-                });
-
-                add(studentButton);
-            }
-
-        } else {
-            add(new JLabel("There is no result yet for this course..."));
-        }
-
-        this.repaint();
-    }
-}
diff --git a/src/jlm/core/ui/SourceFileDocumentSynchronizer.java b/src/jlm/core/ui/SourceFileDocumentSynchronizer.java
deleted file mode 100644
index 3f472c5..0000000
--- a/src/jlm/core/ui/SourceFileDocumentSynchronizer.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package jlm.core.ui;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-import javax.swing.text.EditorKit;
-
-import jlm.core.model.lesson.ISourceFileListener;
-import jlm.core.model.lesson.SourceFile;
-
-
-/*
- * Responsibility: synchronize content between Document instance
- * used by a JEditorPane and the body field of a SourceFile instance.
- * 
- */
-
-public class SourceFileDocumentSynchronizer implements DocumentListener, ISourceFileListener {
-
-	private Document document;
-	private SourceFile sourceFile;
-	private EditorKit editorKit;
-	private boolean propagationInProgress = false;
-
-	public SourceFileDocumentSynchronizer(EditorKit kit) {
-		this.editorKit = kit;
-	}
-
-	public void clear() {
-		document.removeDocumentListener(this);
-		sourceFile.removeListener();
-		this.document = null;
-		this.sourceFile = null;
-		editorKit = null;
-	}
-
-	public void setDocument(Document doc) {
-		this.document = doc;
-	}
-
-	public void setSourceFile(SourceFile srcFile) {
-		this.sourceFile = srcFile;
-	}
-
-	private void copyDocumentContentToSourceFileBody() {
-		if (this.propagationInProgress)
-			return ;
-
-		this.propagationInProgress = true;
-		try {
-			this.sourceFile.setBody(this.document.getText(0, this.document.getLength()));
-		} catch (BadLocationException e1) {
-			e1.printStackTrace();
-		} finally {
-			this.propagationInProgress = false;
-		}
-	}
-
-	private void copySourceFileBodyToDocumentContent() {
-		if (this.propagationInProgress)
-			return ;
-		
-		this.propagationInProgress = true;
-		try {
-			this.document.remove(0, this.document.getLength());
-			String body = this.sourceFile.getBody();
-			if (body == null || body.equals("")) {
-				return;
-			}
-			Reader reader = new StringReader(body);
-			this.editorKit.read(reader, this.document, 0);
-		} catch (IOException e) {
-			e.printStackTrace();
-		} catch (BadLocationException e) {
-			e.printStackTrace();
-		} finally {
-			this.propagationInProgress = false;
-		}
-	}
-
-	@Override
-	public void changedUpdate(DocumentEvent e) {
-		copyDocumentContentToSourceFileBody();
-	}
-
-	@Override
-	public void insertUpdate(DocumentEvent e) {
-		copyDocumentContentToSourceFileBody();
-	}
-
-	@Override
-	public void removeUpdate(DocumentEvent e) {
-		copyDocumentContentToSourceFileBody();
-	}
-
-	@Override
-	public void sourceFileContentHasChanged() {
-		copySourceFileBodyToDocumentContent();
-	}
-}
diff --git a/src/jlm/core/ui/StatusBar.java b/src/jlm/core/ui/StatusBar.java
deleted file mode 100644
index 694dfad..0000000
--- a/src/jlm/core/ui/StatusBar.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.JLabel;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.SwingConstants;
-import javax.swing.Timer;
-
-import jlm.core.GameListener;
-import jlm.core.GameStateListener;
-import jlm.core.ProgLangChangesListener;
-import jlm.core.StatusStateListener;
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.ui.action.SetProgLanguage;
-import jlm.universe.World;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class StatusBar extends JPanel implements GameListener,GameStateListener,StatusStateListener, ProgLangChangesListener {
-
-	private static final long serialVersionUID = 8443305863958273495L;
-	private Game game;
-	private JLabel statusMessageLabel;
-	private JLabel statusAnimationLabel;
-	private JLabel progLangLabel;
-	private JPopupMenu popup = new JPopupMenu();
-	
-	private int busyIconIndex = 0;
-
-	private Timer busyIconTimer;
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	public StatusBar(Game game) {
-		super();
-		this.game = game;
-		this.game.addGameStateListener(this);
-		game.addStatusStateListener(this);
-		game.addProgLangListener(this);
-		game.addGameListener(this);
-		initComponents();
-	}
-	
-	public void initComponents() {
-		this.setBorder(BorderFactory.createEtchedBorder());
-
-		// JSeparator separator = new JSeparator(SwingConstants.VERTICAL);
-		statusMessageLabel = new JLabel("");
-		statusAnimationLabel = new JLabel();
-		statusAnimationLabel.setHorizontalAlignment(SwingConstants.LEFT);
-		statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
-		
-		setupLanguages(Game.getInstance().getCurrentLesson().getCurrentExercise());
-		progLangLabel = new JLabel();
-		progLangLabel.setHorizontalAlignment(SwingConstants.LEFT);
-		progLangLabel.setIcon(Game.getProgrammingLanguage().getIcon());
-		progLangLabel.addMouseListener(new MouseListener() {			
-			public void mouseReleased(MouseEvent e) {
-				maybeShowPopup(e);
-			}
-			public void mousePressed(MouseEvent e) {
-				maybeShowPopup(e);
-			}
-			public void mouseExited(MouseEvent e) {}
-			public void mouseEntered(MouseEvent e) {}
-			public void mouseClicked(MouseEvent e) {
-                popup.show(e.getComponent(),
-                        e.getX(), e.getY());
-			}
-			void maybeShowPopup(MouseEvent e) {
-				if (e.isPopupTrigger())
-					mouseClicked(e);
-			}
-		});
-
-		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
-		this.add(Box.createHorizontalStrut(10));
-		this.add(statusMessageLabel);
-		this.add(Box.createHorizontalGlue());
-		this.add(statusAnimationLabel);
-		this.add(Box.createHorizontalStrut(20));
-		this.add(progLangLabel);
-		this.add(Box.createHorizontalStrut(10));
-
-		ResourcesCache.loadBusyIconAnimation();
-
-		busyIconTimer = new Timer(30, new ActionListener() {
-			public void actionPerformed(ActionEvent e) {
-				busyIconIndex = (busyIconIndex + 1) % ResourcesCache.getBusyIconsSize();
-				statusAnimationLabel.setIcon(ResourcesCache.getBusyIcons(busyIconIndex));
-			}
-		});
-
-	}
-
-	@Override
-	public void stateChanged(Game.GameState type) {
-		switch (type) {
-		case SAVING:
-			statusMessageLabel.setText(i18n.tr("Saving"));
-			busyIconTimer.start();
-			break;
-		case COMPILATION_STARTED:
-			statusMessageLabel.setText(i18n.tr("Compiling"));
-			busyIconTimer.start();
-			break;
-		case LOADING_DONE:
-		case SAVING_DONE:
-		case COMPILATION_ENDED:
-		case DEMO_ENDED:
-		case EXECUTION_ENDED:
-			game.statusRootSet("");
-			game.statusArgEmpty();
-			busyIconTimer.stop();
-			statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
-			break;
-		case EXECUTION_STARTED:
-			game.statusRootSet(i18n.tr("Running "));
-			busyIconTimer.start();
-			break;
-		case DEMO_STARTED:
-			game.statusRootSet(i18n.tr("Playing demo "));
-			busyIconTimer.start();
-			break;		
-		case LOADING:
-			game.statusRootSet(i18n.tr("Loading "));
-			busyIconTimer.start();
-			break;
-		default:
-			statusMessageLabel.setText("");
-			statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
-		}
-	}
-
-	@Override
-	public void stateChanged(final String txt) {
-		statusMessageLabel.setText(txt);
-		//RepaintManager.currentManager(statusMessageLabel).markCompletelyDirty(statusMessageLabel);
-		//RepaintManager.currentManager(statusMessageLabel).paintDirtyRegions();
-	}
-
-	public void setupLanguages(Lecture lecture) {
-		popup.removeAll();
-		Game g = Game.getInstance();
-		if (lecture instanceof Exercise) {
-			Exercise exo = (Exercise) lecture;
-			for (ProgrammingLanguage pl : exo.getProgLanguages()) {
-				JMenuItem item = new JMenuItem(pl.getIcon());
-			    item.addActionListener(new SetProgLanguage(g,pl));
-				popup.add(item);
-			}
-		}
-	}
-	@Override
-	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
-		progLangLabel.setIcon(newLang.getIcon());
-	}
-	@Override
-	public void currentExerciseHasChanged(Lecture lecture) {
-		setupLanguages(lecture);
-	}
-	@Override
-	public void currentLessonHasChanged() {
-		setupLanguages(Game.getInstance().getCurrentLesson().getCurrentExercise());
-	}
-	@Override
-	public void selectedWorldHasChanged(World newWorld) { /* don't care */ }
-	@Override
-	public void selectedEntityHasChanged() { /* tell your mum */ }
-	@Override
-	public void selectedWorldWasUpdated() { /* go away */ }
-}
diff --git a/src/jlm/core/ui/StudentDetailsDialog.java b/src/jlm/core/ui/StudentDetailsDialog.java
deleted file mode 100644
index a38221a..0000000
--- a/src/jlm/core/ui/StudentDetailsDialog.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.core.ui;
-
-import jlm.core.model.ServerExerciseData;
-import jlm.core.model.ServerUserData;
-
-import javax.swing.*;
-import java.awt.*;
-
-/**
- * Dialog to display detailed data about a student in a course
- * For now, it is only text, but it could be graphs of progression, ...
- */
-public class StudentDetailsDialog extends JDialog {
-	private static final long serialVersionUID = 1L;
-
-    public StudentDetailsDialog(ServerUserData userData) {
-        super(MainFrame.getInstance(), "Details on " + userData.getUsername(), false);
-        setLayout(new BorderLayout());
-
-        JPanel infosPanel = new JPanel();
-        infosPanel.setLayout(new BoxLayout(infosPanel, BoxLayout.PAGE_AXIS));
-        infosPanel.setBorder(BorderFactory.createTitledBorder("Infos on " + userData.getUsername()));
-
-        infosPanel.add(new JLabel("Last Join: " + userData.getLastJoin()));
-        infosPanel.add(new JLabel("Last Leave: " + userData.getLastLeave()));
-        infosPanel.add(new JLabel("Last Heartbeat: " + userData.getLastHeartbeat()));
-        infosPanel.add(new JLabel("Total number of exercises passed: " + userData.getExercisesTotal()));
-        infosPanel.add(new JLabel("Total number of exercises passed with success: " + userData.getExercisesPassed()));
-
-        JPanel exercisesPanel = new JPanel();
-        exercisesPanel.setLayout(new BoxLayout(exercisesPanel, BoxLayout.PAGE_AXIS));
-        exercisesPanel.setBorder(BorderFactory.createTitledBorder("Exercises done"));
-        for(ServerExerciseData exo: userData.getExercises()){
-            exercisesPanel.add(new JLabel(exo.getName() + " (" + exo.getLang() + ") " + exo.getPassedTests()
-            + "/" + exo.getTotalTests() + " - " + exo.getDate()));
-        }
-
-        add(infosPanel, BorderLayout.NORTH);
-        add(exercisesPanel, BorderLayout.CENTER);
-
-        pack();
-        setMinimumSize(new Dimension(500, 300));
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(true);
-        setVisible(true);
-        setLocationRelativeTo(getParent());
-    }
-}
diff --git a/src/jlm/core/ui/TeacherConsoleDialog.java b/src/jlm/core/ui/TeacherConsoleDialog.java
deleted file mode 100644
index 96b0f24..0000000
--- a/src/jlm/core/ui/TeacherConsoleDialog.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package jlm.core.ui;
-
-import jlm.core.model.Course;
-import jlm.core.model.Game;
-import jlm.core.model.ServerAnswer;
-import jlm.core.ui.action.CreateCourse;
-import jlm.core.ui.action.DeleteCourse;
-import jlm.core.ui.action.RefreshCourse;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.KeyEvent;
-
-/**
- * Dialog to display all options available to the teacher
- * Once the course selected, he can view its students results in this console
- * He can also manage courses : create or delete
- */
-public class TeacherConsoleDialog extends JDialog {
-	private static final long serialVersionUID = 1L;
-
-    //private Game game;
-    //private Course course;
-    private JLabel courseNameLabel;
-    private ResultsPanel allResultsPanel;
-    private ResultsPanel helpPanel;
-    private ResultsPanel layaboutPanel;
-    private ResultsPanel badPanel;
-    private ResultsPanel goodPanel;
-
-    public TeacherConsoleDialog() {
-        super(MainFrame.getInstance(), "JLM Teacher Console", false);
-
-        Game game = Game.getInstance();
-        Course course = game.getCurrentCourse();
-
-        // automatically refresh the course to display in the teacher console if it's empty
-        if (course.getCourseId() != null && !course.getCourseId().isEmpty()
-                && course.getServerData() == null){
-            String answer = course.refresh();
-            try {
-                if (ServerAnswer.values()[Integer.parseInt(answer)] == ServerAnswer.WRONG_TEACHER_PASSWORD)
-                    JOptionPane.showMessageDialog(this, "Wrong teacher password for the course",
-                            "Server error", JOptionPane.ERROR_MESSAGE);
-            } catch (NumberFormatException nfe) {
-             // the answer was not a status message, it contains course data
-            }
-            // refresh the needing help, layout, bad and good students lists
-            course.refreshStudentsLists();
-        }
-
-        initComponent();
-    }
-
-    public void initComponent() {
-        setLayout(new BorderLayout());
-
-        //Top toolbar
-        JToolBar toolBar = new JToolBar();
-        toolBar.setBorder(BorderFactory.createEtchedBorder());
-
-        Game game = Game.getInstance();
-        
-        courseNameLabel = new JLabel(game.getCourseID().isEmpty() ? "No course selected" : "[" + game.getCourseID() + "]");
-
-        JButton newButton = new JButton(new CreateCourse(game, "New course",
-                ResourcesCache.getIcon("img/console_add.png"), this));
-        newButton.setBorderPainted(false);
-
-        JButton refreshButton = new JButton(new RefreshCourse(game, "Refresh",
-                ResourcesCache.getIcon("img/console_refresh.png"), this));
-        refreshButton.setBorderPainted(false);
-
-        JButton deleteButton = new JButton(new DeleteCourse(game, "Delete",
-                ResourcesCache.getIcon("img/console_delete.png"), this));
-        deleteButton.setBorderPainted(false);
-
-        toolBar.add(courseNameLabel);
-        toolBar.add(newButton);
-        toolBar.add(refreshButton);
-        toolBar.add(deleteButton);
-        
-        add(BorderLayout.NORTH, toolBar);
-        
-        //Center tabbed panel, with the different resultsPanel
-        JTabbedPane tabbedPanel = new JTabbedPane();
-        
-        allResultsPanel = new ResultsPanel(null);
-        tabbedPanel.addTab("All results", new JScrollPane(allResultsPanel));
-        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_A);
-        
-        Course course = game.getCurrentCourse();
-        
-        helpPanel = new ResultsPanel(course.getNeedingHelpStudents());
-        tabbedPanel.addTab("Need help", null,
-                new JScrollPane(helpPanel), "Students requesting help");
-        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_H);
-
-        layaboutPanel = new ResultsPanel(course.getLayaboutStudents());
-        tabbedPanel.addTab("No activity", null,
-                new JScrollPane(layaboutPanel), "Students with no recorded activity");
-        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_L);
-
-        badPanel = new ResultsPanel(course.getBadStudents());
-        tabbedPanel.addTab("Failing", null,
-                new JScrollPane(badPanel), "Students failing completely");
-        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_B);
-
-        goodPanel = new ResultsPanel(course.getGoodStudents());
-        tabbedPanel.addTab("Successful", null,
-                new JScrollPane(goodPanel), "Students doing good");
-        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_G);
-        
-        add(BorderLayout.CENTER, tabbedPanel);
-
-        pack();
-        setMinimumSize(new Dimension(500, 300));
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(true);
-        setVisible(true);
-
-        setLocationRelativeTo(getParent());
-
-    }
-
-    public void refresh() {
-    	Game game = Game.getInstance();
-        courseNameLabel.setText(game.getCourseID().isEmpty() ? "" : "[" + game.getCourseID() + "]");
-        allResultsPanel.displayResults();
-        helpPanel.displayResults();
-        layaboutPanel.displayResults();
-        badPanel.displayResults();
-        goodPanel.displayResults();
-        this.repaint();
-    }
-}
diff --git a/src/jlm/core/ui/TipsDialog.java b/src/jlm/core/ui/TipsDialog.java
deleted file mode 100644
index c342c00..0000000
--- a/src/jlm/core/ui/TipsDialog.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JFrame;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lecture;
-
- at SuppressWarnings("serial")
-public class TipsDialog extends AbstractAboutDialog {
-
-	public TipsDialog(JFrame parent) {
-		super(parent);
-		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
-	}
-
-	@Override
-	public void currentExerciseHasChanged(Lecture lect) {
-		setTitle("Tips");
-		this.area.setText("no tips");
-		this.area.setCaretPosition(0);
-	}
-	
-	public void setText(String txt) {
-		this.area.setText(txt);
-		this.area.setCaretPosition(0);
-	}
-
-}
diff --git a/src/jlm/core/ui/WorldCellRenderer.java b/src/jlm/core/ui/WorldCellRenderer.java
deleted file mode 100644
index 36fedcc..0000000
--- a/src/jlm/core/ui/WorldCellRenderer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.Component;
-
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.ListCellRenderer;
-
-import jlm.universe.World;
-
-
-
-
-public class WorldCellRenderer extends JLabel implements ListCellRenderer {
-
- 	private static final long serialVersionUID = -8332490521368971733L;
-
-	public WorldCellRenderer() {
-		//setOpaque(true);
-	}
-
-	@Override
-	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
-			boolean cellHasFocus) {
-
-		if (value instanceof World) {
-			World w = (World) value;
-			setText(w.getName());
-		} else {
-			setText(value!=null?value.toString():"");
-		}
-       
-        if (isSelected) {
-            setBackground(list.getSelectionBackground());
-            setForeground(list.getSelectionForeground());
-        } else {
-            setBackground(list.getBackground());
-            setForeground(list.getForeground());
-        }
-                     
-        setFont(list.getFont());
-        setOpaque(true);
-        return this;
-	}
-
-}
diff --git a/src/jlm/core/ui/WorldComboListAdapter.java b/src/jlm/core/ui/WorldComboListAdapter.java
deleted file mode 100644
index 0e638c0..0000000
--- a/src/jlm/core/ui/WorldComboListAdapter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.AbstractListModel;
-import javax.swing.ComboBoxModel;
-
-import jlm.core.GameListener;
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.universe.World;
-
-public class WorldComboListAdapter extends AbstractListModel implements ComboBoxModel, GameListener {
-
-	private static final long serialVersionUID = -4669130955472219209L;
-	private Game game;
-	private World selectedWorld;
-	private Exercise currentExercise;
-	
-	public WorldComboListAdapter(Game game) {
-		this.game = game;
-		this.game.addGameListener(this);
-		if (game.getCurrentLesson().getCurrentExercise() instanceof Exercise) {
-			this.currentExercise = (Exercise) this.game.getCurrentLesson().getCurrentExercise();
-			this.selectedWorld = this.game.getSelectedWorld();
-		}
-	}
-
-	@Override
-	public Object getElementAt(int index) {
-		return currentExercise == null?null: this.currentExercise.getWorld(index);
-	}
-
-	@Override
-	public int getSize() {
-		return currentExercise == null?0: currentExercise.getWorldCount();
-	}
-
-	@Override
-	public Object getSelectedItem() {
-		return currentExercise == null?null: selectedWorld;
-	}
-
-	@Override
-	public void setSelectedItem(Object anItem) {
-		if (anItem instanceof World) {
-			World w = (World) anItem;
-			this.selectedWorld = w;
-			this.game.setSelectedWorld(w);
-		} else {
-			Logger.log("WordComboListAdapter:setSelectedItem", "parameter is not a world");
-		}
-	}
-
-	
-	@Override
-	public void currentExerciseHasChanged(Lecture lect) {
-		if (lect instanceof Exercise) {
-			this.currentExercise = (Exercise) lect;
-			this.selectedWorld = game.getSelectedWorld();
-			fireContentsChanged(this, 0, this.currentExercise.getWorldCount()-1);
-		} else {
-			currentExercise = null;
-			selectedWorld = null;
-		}
-	}
-	
-	@Override
-	public void currentLessonHasChanged() { /* don't care */ }
-
-	@Override
-	public void selectedWorldHasChanged(World w) {
-		this.selectedWorld = w;
-		fireContentsChanged(this, 0, this.currentExercise.getWorldCount()-1);		
-	}
-	
-	@Override
-	public void selectedEntityHasChanged() { /* don't care */ }
-	
-	@Override
-	public void selectedWorldWasUpdated() { /* don't care */ }
-}
diff --git a/src/jlm/core/ui/WorldView.java b/src/jlm/core/ui/WorldView.java
deleted file mode 100644
index 22494e8..0000000
--- a/src/jlm/core/ui/WorldView.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package jlm.core.ui;
-
-import javax.swing.JComponent;
-import javax.swing.SwingUtilities;
-
-import jlm.universe.IWorldView;
-import jlm.universe.World;
-
-
-
-public abstract class WorldView extends JComponent  implements IWorldView {
-
-	private static final long serialVersionUID = -4599730915218800968L;
-
-	protected World world;
-	
-	public WorldView(World w) {
-		this.world = w;
-		w.doDelay();
-		this.world.addWorldUpdatesListener(this);
-	}
-	
-	public void setWorld(World w) {
-		this.world.removeWorldUpdatesListener(this);
-		this.world = w;
-		this.world.addWorldUpdatesListener(this);
-		worldHasMoved();
-	}
-
-	@Override
-	public void worldHasMoved() {
-		if (SwingUtilities.isEventDispatchThread()) {
-			repaint();
-		} else {
-			SwingUtilities.invokeLater(new Runnable() {
-				public void run() {
-					repaint();
-				}
-			});			
-		}
-	}
-	
-	@Override
-	public void worldHasChanged() {
-		/* nothing specific to do here since we already react to HasMoved */
-	}
-
-	public boolean isWorldCompatible(World world) {
-		return world.getClass().equals(this.world.getClass());
-	}
-
-	/** Returns what should be added to the tab name */
-	public String getTabName() {
-		return ""; 
-	}
-
-	/** Returns what should be added to the tooltip */
-	public String getTip() {
-		return "";
-	}
-}
diff --git a/src/jlm/core/ui/XMPPDialog.java b/src/jlm/core/ui/XMPPDialog.java
deleted file mode 100644
index 3d0ab6a..0000000
--- a/src/jlm/core/ui/XMPPDialog.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package jlm.core.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.JDialog;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-
-import jlm.core.model.Game;
-
-import org.jivesoftware.smack.Chat;
-import org.jivesoftware.smack.ChatManager;
-import org.jivesoftware.smack.ConnectionConfiguration;
-import org.jivesoftware.smack.MessageListener;
-import org.jivesoftware.smack.XMPPConnection;
-import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.packet.Message;
-import org.jivesoftware.smack.packet.Presence;
-
-public class XMPPDialog extends JDialog {
-
-	private static final long serialVersionUID = 1L;
-	private static String XMPP_HOSTNAME = Game.getProperty("jlm.xmpp.hostname");
-	private static final int XMPP_PORT = Integer.parseInt(Game.getProperty("jlm.xmpp.port"));
-	
-	private String USERNAME = Game.getProperty("jlm.xmpp.username");
-	private String PASSWORD = Game.getProperty("jlm.xmpp.password");
-		
-	private String login;
-	
-	private XMPPConnection xmppConnection;
-	private ChatManager chatManager;
-	private Chat chat;
-		
-	private JTextArea display = new JTextArea();
-	private JTextField input = new JTextField();
-
-	public XMPPDialog() {
-		super(MainFrame.getInstance(), "The JLM XMPP Chat", false);
-		
-		this.login = System.getenv("USER");
-		if (this.login  == null)
-			this.login  = System.getenv("USERNAME");
-		if (this.login  == null)
-			this.login  = "John Doe";	
-		initConnection();
-		initComponent();
-	}
-
-	public void initConnection() {
-        // enable smack's debugging
-		//System.setProperty("smack.debugEnabled", "true");
-        //XMPPConnection.DEBUG_ENABLED = true;
-        
-        ConnectionConfiguration config = new ConnectionConfiguration(XMPP_HOSTNAME, XMPP_PORT);
-        this.xmppConnection = new XMPPConnection(config);
- 
-        try {
-        	this.xmppConnection.connect();
-        	this.xmppConnection.login(USERNAME, PASSWORD, this.login);
-        	this.xmppConnection.sendPacket(new Presence(Presence.Type.available));
-			this.chatManager = xmppConnection.getChatManager();
-			
-			if (this.xmppConnection.isConnected()) {
-		        this.chat = chatManager.createChat(USERNAME, new MessageListener() {
-		            @Override
-					public void processMessage(Chat chat, Message message) {
-		            	String from = message.getFrom().substring(message.getFrom().indexOf("/")+1);
-		                display.append(from+">: "+message.getBody()+"\n");
-		            }
-		        });
-			}
-        } catch (XMPPException ex) {
-        	ex.printStackTrace();
-        }
-	}
-	
-	@Override
-	public void dispose() {
-		if (this.xmppConnection != null) {
-			this.xmppConnection.disconnect();
-			//this.xmppConnection.disconnect(new Presence(Presence.Type.unavailable));
-			this.xmppConnection = null;
-		}
-		super.dispose();
-	}
-
-	public void initComponent() {
-		setLayout(new BorderLayout());
-
-		display.setEditable(false);
-		JScrollPane scrollPane = new JScrollPane(display);
-
-		add(BorderLayout.CENTER, scrollPane);
-
-		JPanel downPanel = new JPanel();
-		downPanel.setLayout(new BorderLayout());
-		downPanel.add(BorderLayout.CENTER, input);
-		
-		add(BorderLayout.SOUTH, downPanel);
-		input.addActionListener(new ActionListener() {
-
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				if (xmppConnection!=null && xmppConnection.isConnected() && chat != null && input.getText().length() > 0) {
-			        try {
-						chat.sendMessage(input.getText());
-					} catch (XMPPException e1) {
-						e1.printStackTrace();
-					}					
-					input.setText("");
-				}
-			}
-		});
-		input.setEditable(true);
-
-		pack();
-		setMinimumSize(new Dimension(500, 300));
-		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-		setResizable(true);
-
-		setLocationRelativeTo(getParent());
-	}
-}
diff --git a/src/jlm/core/ui/action/AbstractGameAction.java b/src/jlm/core/ui/action/AbstractGameAction.java
deleted file mode 100644
index feb6abc..0000000
--- a/src/jlm/core/ui/action/AbstractGameAction.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package jlm.core.ui.action;
-
-import java.util.Locale;
-
-import javax.swing.AbstractAction;
-import javax.swing.ImageIcon;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-import jlm.core.model.Game;
-
-
-public abstract class AbstractGameAction extends AbstractAction {
-
-	private static final long serialVersionUID = -1190103028775831188L;
-	private String descEnabled, descDisabled;
-
-	protected Game game;
-	protected Locale locale;
-	protected I18n i18n;
-
-	public AbstractGameAction(Game game, String text) {
-		super(text);
-		this.game = game;
-	}
-	
-	public AbstractGameAction(Game game, String text, ImageIcon icon) {
-		super(text, icon);
-		this.game = game;
-		this.i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",game.getLocale(), I18nFactory.FALLBACK);
-
-	}
-	
-	protected void setDescription(String descEnabled, String descDisabled) {
-		putValue(SHORT_DESCRIPTION, descEnabled);
-		this.descEnabled = descEnabled;
-		this.descDisabled = descDisabled;		
-	}
-
-	public AbstractGameAction(Game game, String text, ImageIcon icon, Integer mnemonic) {
-		this (game,text,icon);
-		putValue(MNEMONIC_KEY, mnemonic);
-	}
-
-	public Game getGame() {
-		return this.game;
-	}
-
-	@Override
-	public void setEnabled(boolean enabled) {
-		if (enabled)
-			putValue(SHORT_DESCRIPTION, descEnabled);
-		else
-			putValue(SHORT_DESCRIPTION, descDisabled);
-			
-		super.setEnabled(enabled);
-	}
-
-}
diff --git a/src/jlm/core/ui/action/CleanUpSession.java b/src/jlm/core/ui/action/CleanUpSession.java
deleted file mode 100644
index 2a217f8..0000000
--- a/src/jlm/core/ui/action/CleanUpSession.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-
-
-public class CleanUpSession extends AbstractGameAction {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-
-	public CleanUpSession(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		game.clearSession();
-	}
-
-}
diff --git a/src/jlm/core/ui/action/CreateCourse.java b/src/jlm/core/ui/action/CreateCourse.java
deleted file mode 100644
index 9f8765b..0000000
--- a/src/jlm/core/ui/action/CreateCourse.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.ui.CreateCourseDialog;
-import jlm.core.ui.TeacherConsoleDialog;
-
-/**
- * Controller to handle clicks on the create button from the teacher console
- */
-public class CreateCourse extends AbstractGameAction {
-	private static final long serialVersionUID = 1L;
-
-    private TeacherConsoleDialog teacherConsoleDialog;
-
-    public CreateCourse(Game game, String text, TeacherConsoleDialog teacherConsoleDialog) {
-        super(game, text);
-        this.teacherConsoleDialog = teacherConsoleDialog;
-    }
-
-    public CreateCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog teacherConsoleDialog) {
-        super(game, text, icon);
-        this.teacherConsoleDialog = teacherConsoleDialog;
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent actionEvent) {
-        new CreateCourseDialog().setVisible(true);
-        teacherConsoleDialog.refresh();
-    }
-}
diff --git a/src/jlm/core/ui/action/DeleteCourse.java b/src/jlm/core/ui/action/DeleteCourse.java
deleted file mode 100644
index 3885775..0000000
--- a/src/jlm/core/ui/action/DeleteCourse.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-import javax.swing.JOptionPane;
-
-import jlm.core.model.Course;
-import jlm.core.model.CourseAppEngine;
-import jlm.core.model.Game;
-import jlm.core.model.ServerAnswer;
-import jlm.core.ui.MainFrame;
-import jlm.core.ui.TeacherConsoleDialog;
-
-/**
- * Controller to handle clicks on the Delete button from the teacher console
- */
-public class DeleteCourse extends AbstractGameAction {
-	private static final long serialVersionUID = 1L;
-
-    private Course course;
-    private TeacherConsoleDialog parentComponent;
-
-    public DeleteCourse(Game game, String text, TeacherConsoleDialog parentComponent) {
-        super(game, text);
-        course = game.getCurrentCourse();
-        this.parentComponent = parentComponent;
-    }
-
-    public DeleteCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog parentComponent) {
-        super(game, text, icon);
-        course = game.getCurrentCourse();
-        this.parentComponent = parentComponent;
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent actionEvent) {
-        if (course.getCourseId() != null) {
-            int choice = JOptionPane.showConfirmDialog(MainFrame.getInstance(), "Do you really want to delete the course on the server?");
-            if (choice == JOptionPane.OK_OPTION) {
-                String answer = course.delete();
-                ServerAnswer serverAnswer = ServerAnswer.values()[Integer.parseInt(answer)];
-                if (serverAnswer == ServerAnswer.WRONG_TEACHER_PASSWORD)
-                    JOptionPane.showMessageDialog(parentComponent, "Wrong module teacher password", "Server error",
-                            JOptionPane.ERROR_MESSAGE);
-                if(serverAnswer == ServerAnswer.ALL_IS_FINE){
-                    Game.getInstance().setCurrentCourse(new CourseAppEngine());
-                    MainFrame.getInstance().appendToTitle("");
-                    parentComponent.refresh();
-                }
-            }
-        }
-    }
-}
diff --git a/src/jlm/core/ui/action/ExportSession.java b/src/jlm/core/ui/action/ExportSession.java
deleted file mode 100644
index ff7fcd7..0000000
--- a/src/jlm/core/ui/action/ExportSession.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.io.File;
-
-import javax.swing.ImageIcon;
-import javax.swing.JFileChooser;
-
-import jlm.core.model.Game;
-import jlm.core.model.UserAbortException;
-import jlm.core.model.session.ZipSessionKit;
-
-public class ExportSession extends AbstractGameAction {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-	private Component parent;
-
-	public ExportSession(Game game, String text, ImageIcon icon, Component parent) {
-		super(game, text, icon);
-		this.parent = parent;
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		JFileChooser fc = new JFileChooser();
-		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
-		fc.setAcceptAllFileFilterUsed(false);
-		int returnValue = fc.showSaveDialog(this.parent);
-
-		if (returnValue == JFileChooser.APPROVE_OPTION) {
-			File sessionFileToExportTo = fc.getSelectedFile();
-			
-			ZipSessionKit kit = new ZipSessionKit(this.game);
-			try {
-				kit.storeAll(sessionFileToExportTo);
-			} catch (UserAbortException e1) {
-				e1.printStackTrace();
-			}
-		}
-	}
-
-}
diff --git a/src/jlm/core/ui/action/HelpMe.java b/src/jlm/core/ui/action/HelpMe.java
deleted file mode 100644
index 65b4fa5..0000000
--- a/src/jlm/core/ui/action/HelpMe.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-import javax.swing.JToggleButton;
-
-import jlm.core.model.Game;
-import jlm.core.model.HelpAppEngine;
-import jlm.core.model.HelpServer;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.utils.FileUtils;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-/**
- * Class that handle clicks on HELP button
- * It sends a request to the JLM server
- */
-public class HelpMe extends AbstractGameAction {
-	private static final long serialVersionUID = 1L;
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
-
-    private HelpServer helpServer;
-    private boolean isRequestingHelp = false;
-
-    public HelpMe(Game game, String text, ImageIcon icon) {
-        super(game, text, icon);
-        helpServer = new HelpAppEngine();
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-    	isRequestingHelp = ! isRequestingHelp;
-        helpServer.setStatus(isRequestingHelp);
-        ((JToggleButton)e.getSource()).setText(isRequestingHelp ? i18n.tr("Cancel call") : i18n.tr("Call for Help"));
-        ((JToggleButton)e.getSource()).setIcon(ResourcesCache.getIcon("img/btn-alert-"+(isRequestingHelp?"on":"off")+".png"));
-    }
-
-}
diff --git a/src/jlm/core/ui/action/ImportSession.java b/src/jlm/core/ui/action/ImportSession.java
deleted file mode 100644
index 6d16055..0000000
--- a/src/jlm/core/ui/action/ImportSession.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.Component;
-import java.awt.event.ActionEvent;
-import java.io.File;
-
-import javax.swing.ImageIcon;
-import javax.swing.JFileChooser;
-
-import jlm.core.model.Game;
-import jlm.core.model.session.ZipSessionKit;
-
-public class ImportSession extends AbstractGameAction {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-
-	private Component parent;
-
-	public ImportSession(Game game, String text, ImageIcon icon, Component parent) {
-		super(game, text, icon);
-		this.parent = parent;
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		JFileChooser fc = new JFileChooser();
-		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
-		int returnValue = fc.showOpenDialog(this.parent);
-
-		if (returnValue == JFileChooser.APPROVE_OPTION) {
-			File sessionFileToImportFrom = fc.getSelectedFile();
-			
-			ZipSessionKit kit = new ZipSessionKit(this.game);
-			kit.loadAll(sessionFileToImportFrom);
-		}
-	}
-
-}
diff --git a/src/jlm/core/ui/action/OneStep.java b/src/jlm/core/ui/action/OneStep.java
deleted file mode 100644
index 762af8c..0000000
--- a/src/jlm/core/ui/action/OneStep.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-
-
-public class OneStep extends AbstractGameAction {
-
-	private static final long serialVersionUID = 930451111824072175L;
-
-	public OneStep(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		this.game.allowOneStep();		
-	}
-}
diff --git a/src/jlm/core/ui/action/PlayDemo.java b/src/jlm/core/ui/action/PlayDemo.java
deleted file mode 100644
index 59d3146..0000000
--- a/src/jlm/core/ui/action/PlayDemo.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-
-public class PlayDemo extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = 5113775865916404566L;
-
-	public PlayDemo(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		this.game.startExerciseDemoExecution();		
-	}
-	
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Run the demo of what you should code for this exercise"),
-				i18n.tr("Impossible to run the demo right now"));		
-	}
-}
diff --git a/src/jlm/core/ui/action/QuitGame.java b/src/jlm/core/ui/action/QuitGame.java
deleted file mode 100644
index e0df75b..0000000
--- a/src/jlm/core/ui/action/QuitGame.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-
-public class QuitGame extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-
-	public QuitGame(Game game, String text, ImageIcon icon, Integer mnemonic) {
-		super(game, text, icon, mnemonic);
-		game.addHumanLangListener(this);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		game.quit();
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Quit the application"),i18n.tr("Impossible to quit the application right now"));		
-	}
-
-}
diff --git a/src/jlm/core/ui/action/RefreshCourse.java b/src/jlm/core/ui/action/RefreshCourse.java
deleted file mode 100644
index 07bf0ec..0000000
--- a/src/jlm/core/ui/action/RefreshCourse.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package jlm.core.ui.action;
-
-import jlm.core.model.Course;
-import jlm.core.model.Game;
-import jlm.core.model.ServerAnswer;
-import jlm.core.ui.TeacherConsoleDialog;
-
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-
-/**
- * Controller to handle clicks on the refresh button from the teacher console
- * It download updated data from the server and refresh the console ui
- */
-public class RefreshCourse extends AbstractGameAction {
-
-	private static final long serialVersionUID = 1L;
-	
-	private Course course;
-    private TeacherConsoleDialog parentComponent;
-
-    public RefreshCourse(Game game, String text, TeacherConsoleDialog parentComponent) {
-        super(game, text);
-        course = game.getCurrentCourse();
-        this.parentComponent = parentComponent;
-    }
-
-    public RefreshCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog parentComponent) {
-        super(game, text, icon);
-        course = game.getCurrentCourse();
-        this.parentComponent = parentComponent;
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent actionEvent) {
-        if (course.getCourseId() != null) {
-            String answer = course.refresh();
-            try {
-                if (ServerAnswer.values()[Integer.parseInt(answer)] == ServerAnswer.WRONG_TEACHER_PASSWORD)
-                    JOptionPane.showMessageDialog(parentComponent, "Wrong teacher password for the course",
-                            "Server error", JOptionPane.ERROR_MESSAGE);
-            } catch (NumberFormatException nfe) {
-             // the answer was not a status message, it contains course data
-            }
-            // refresh the needing help, layabout, bad and good students lists
-            course.refreshStudentsLists();
-
-            parentComponent.refresh();
-        }
-    }
-}
diff --git a/src/jlm/core/ui/action/Reset.java b/src/jlm/core/ui/action/Reset.java
deleted file mode 100644
index 6c02ac7..0000000
--- a/src/jlm/core/ui/action/Reset.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-
-public class Reset extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = 5113775865916404566L;
-
-	public Reset(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-		game.addHumanLangListener(this);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		this.game.reset();
-	}
-	
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Reset your world to the initial state"),i18n.tr("World cannot be reset right now"));		
-	}
-
-}
diff --git a/src/jlm/core/ui/action/RevertExercise.java b/src/jlm/core/ui/action/RevertExercise.java
deleted file mode 100644
index 70e492a..0000000
--- a/src/jlm/core/ui/action/RevertExercise.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.ImageIcon;
-import javax.swing.JOptionPane;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.Exercise;
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.SourceFile;
-import jlm.core.model.lesson.SourceFileRevertable;
-
-public class RevertExercise extends AbstractGameAction {
-
-	private static final long serialVersionUID = -1509545929438458599L;
-
-	public RevertExercise(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		Object[] options = { "OK", "CANCEL" };
-		int choice = 
-			JOptionPane.showOptionDialog(null, "Reverting this exercise will erase all your work and cannot be undone.\n Are you sure that you want to proceed?", "Warning",
-				JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
-				null, options, options[0]);
-		if (choice != 0) {
-			System.out.println("Revert canceled on user request -- your work was preserved.");
-			return;
-		}
-
-		Lecture lect = game.getCurrentLesson().getCurrentExercise();
-		if (! (lect instanceof Exercise)) 
-			return;
-
-		Exercise ex = (Exercise) lect;
-		for (ProgrammingLanguage lang: ex.getProgLanguages())
-			for (int i=0; i<ex.getSourceFileCount(lang); i++) {
-				SourceFile sf = ex.getSourceFile(lang,i);
-				if (sf instanceof SourceFileRevertable)
-					((SourceFileRevertable) sf).revert();
-			}
-		System.out.println("Exercise reverted");
-	}
-
-}
diff --git a/src/jlm/core/ui/action/SetLanguage.java b/src/jlm/core/ui/action/SetLanguage.java
deleted file mode 100644
index 257c149..0000000
--- a/src/jlm/core/ui/action/SetLanguage.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import jlm.core.model.Game;
-
-public class SetLanguage extends AbstractGameAction {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-
-	private Locale lang;
-
-	public SetLanguage(Game game, String text, Locale lang) {
-		super(game, text, null);
-		this.lang = lang;
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		game.setLocale(lang);
-	}
-
-}
diff --git a/src/jlm/core/ui/action/SetProgLanguage.java b/src/jlm/core/ui/action/SetProgLanguage.java
deleted file mode 100644
index 9bddf33..0000000
--- a/src/jlm/core/ui/action/SetProgLanguage.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-
-public class SetProgLanguage extends AbstractGameAction {
-
-	private static final long serialVersionUID = 5778501209753480269L;
-
-	private ProgrammingLanguage lang;
-
-	public SetProgLanguage(Game game, ProgrammingLanguage lang) {
-		super(game, lang.toString(), null);
-		this.lang = lang;
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		game.setProgramingLanguage(lang);
-	}
-}
diff --git a/src/jlm/core/ui/action/StartExecution.java b/src/jlm/core/ui/action/StartExecution.java
deleted file mode 100644
index fe0a814..0000000
--- a/src/jlm/core/ui/action/StartExecution.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-/** Action launched when the Start button gets hit */
-public class StartExecution extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = -4326617501298324713L;
-	
-	public StartExecution(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-		game.addHumanLangListener(this);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		if (game.getState().equals(Game.GameState.EXECUTION_STARTED) && game.stepModeEnabled()) {
-			game.disableStepMode();
-			game.allowOneStep();
-		} else
-			this.game.startExerciseExecution();		
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Launch the execution of your code"),
-				i18n.tr("Cannot launch the execution right now. Wait a bit, or interrupt current activity with the stop button"));		
-	}
-}
diff --git a/src/jlm/core/ui/action/StepExecution.java b/src/jlm/core/ui/action/StepExecution.java
deleted file mode 100644
index 142e2bd..0000000
--- a/src/jlm/core/ui/action/StepExecution.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-
-public class StepExecution extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = 930451111824072175L;
-
-	public StepExecution(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-		game.addHumanLangListener(this);
-	}
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Execute one step of your code"), 
-				i18n.tr("Impossible to step your code now. Need to stop the execution first?"));
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		if (game.getState().equals(Game.GameState.EXECUTION_STARTED))
-			game.allowOneStep();
-		else			
-			game.startExerciseStepExecution();		
-	}
-}
diff --git a/src/jlm/core/ui/action/StopExecution.java b/src/jlm/core/ui/action/StopExecution.java
deleted file mode 100644
index 86809cf..0000000
--- a/src/jlm/core/ui/action/StopExecution.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-
-public class StopExecution extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = -4563140493957678216L;
-	
-	public StopExecution(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-		game.addHumanLangListener(this);
-	}
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Stop your code"), 
-				i18n.tr("No execution to stop right now"));
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		this.game.stopExerciseExecution();		
-	}
-}
diff --git a/src/jlm/core/ui/action/SwitchExo.java b/src/jlm/core/ui/action/SwitchExo.java
deleted file mode 100644
index bc09cba..0000000
--- a/src/jlm/core/ui/action/SwitchExo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package jlm.core.ui.action;
-
-import java.awt.event.ActionEvent;
-import java.util.Locale;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.ui.ChooseLectureDialog;
-
-
-public class SwitchExo extends AbstractGameAction implements HumanLangChangesListener {
-
-	private static final long serialVersionUID = 5113775865916404566L;
-
-	public SwitchExo(Game game, String text, ImageIcon icon) {
-		super(game, text, icon);
-		game.addHumanLangListener(this);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		new ChooseLectureDialog();
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		setDescription(i18n.tr("Switch to another exercise"),"");
-	}
-
-}
diff --git a/src/jlm/core/ui/action/package-info.java b/src/jlm/core/ui/action/package-info.java
deleted file mode 100644
index 0adac83..0000000
--- a/src/jlm/core/ui/action/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * The action listeners of the UI, calling the right functions of the game singleton.
- */
-package jlm.core.ui.action;
-
diff --git a/src/jlm/core/ui/package-info.java b/src/jlm/core/ui/package-info.java
deleted file mode 100644
index 308a31c..0000000
--- a/src/jlm/core/ui/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * User interface
- */
-package jlm.core.ui;
-
diff --git a/src/jlm/core/utils/ColorMapper.java b/src/jlm/core/utils/ColorMapper.java
deleted file mode 100644
index 9fd15a8..0000000
--- a/src/jlm/core/utils/ColorMapper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.core.utils;
-
-import java.awt.Color;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-public class ColorMapper {
-	static String[] choices = {
-		"white","black","blue","cyan","darkGray","gray","green","lightGray","magenta","orange","pink","red","yellow"};
-	static Color[] colors = {
-		Color.white,Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,Color.red,Color.yellow};
-	static Pattern colorName = Pattern.compile("(\\d+)/(\\d+)/(\\d+)");
-
-	public static Color name2color(String name) throws InvalidColorNameException {
-		for (int i=0; i<choices.length; i++) 
-			if (choices[i].equalsIgnoreCase(name))
-				return colors[i];
-		Matcher m = colorName.matcher(name);
-		if (m.matches()) {
-			try {
-				int r=Integer.parseInt( m.group(1) );
-				int g=Integer.parseInt( m.group(2) );
-				int b=Integer.parseInt( m.group(3) );
-				
-				if (r<0 || r>255) 
-					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Red value is not between 0 and 255");
-				if (g<0 || g>255) 
-					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Green value is not between 0 and 255");
-				if (b<0 || b>255) 
-					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Blue value is not between 0 and 255");
-					
-				return new Color(r,g,b);
-			} catch (NumberFormatException nfe) {
-				throw new InvalidColorNameException("Name "+name+" is not a valid color name since one of its component is not a number",nfe);
-			}
-		} else {
-			throw new InvalidColorNameException("Name "+name+" is not a valid color name");
-		}
-	}
-	
-	public static String color2name(Color c) {
-		for (int i=0; i<choices.length; i++) 
-			if (colors[i].equals(c))
-				return choices[i];
-		return c.getRed()+"/"+c.getGreen()+"/"+c.getBlue();
-	}
-}
diff --git a/src/jlm/core/utils/FileUtils.java b/src/jlm/core/utils/FileUtils.java
deleted file mode 100644
index b75da40..0000000
--- a/src/jlm/core/utils/FileUtils.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package jlm.core.utils;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.util.Locale;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-
-/** This class is in charge of loading the resources from disk into memory
- * 
- * 	It solves 2 main difficulties. The first one is to find the files in any case, be 
- *  them in the distributed jar file, or on the disk (as it happens when we develop JLM: 
- *  we don't build a jar for each run, we directly from our source tree). It also deals 
- *  with the windows/unix incompatibilities about directory separators (/ or \).
- * 
- *  The second problem it deals with is about translations. When looking for a help file, 
- *  it first search for a suitable translated version. If not found, it fallbacks to the 
- *  English version. This is done through the locale static variable. Yeah, that's not 
- *  clean but it just works.
- */
-public class FileUtils {
-	private static Locale locale;
-	
-	private final static String[] directories = { "", "lib/", "src/" };                
-
-	
-	/** Specifies the locale that we have to use when looking for translated files */
-	public static void setLocale(Locale l) {
-		locale = l;
-	}
-	public static Locale getLocale() {
-		return locale==null?new Locale("en"):locale;
-	}
-	
-	public static BufferedReader newFileReader(String file, String extension, boolean translatable) throws FileNotFoundException, UnsupportedEncodingException {
-		/* first check if we can find it unmodified */
-		int i = 0;
-		if (!translatable) { // extension is ignored in this case. That's useful to get it from a file chooser
-			while (i<directories.length) {
-				if ((new File(directories[i] + file)).exists()) {
-					return new BufferedReader(new FileReader(directories[i] + file));
-				} else {
-					i++;
-				}   	
-			}
-		}
-		
-		if (translatable && locale == null)
-			throw new RuntimeException("locale is null: you cannot request for translated material (yet)");
-		
-		/* Build the list of filenames we will iterate (translated if any, and raw) */
-		String[] fileNames;
-		if (translatable && ! locale.getLanguage().equals("en")) {
-			fileNames = new String[] {
-					file.replace('.', '/') + "." + locale.getLanguage(),
-					file.replace('.', '/')
-			};
-		} else { // not translatable, or currently in English: only search for non-translated form
-				fileNames = new String[] {
-						file.replace('.', '/')
-				};
-		}
-		/* Do that iteration */
-		for (String fileName : fileNames ) {        
-			/* change class name to directories */
-			fileName = fileName + (extension != null ? "." + extension : "");
-			
-			i = 0;
-			while (i<directories.length) {
-				if ((new File(directories[i] + fileName)).exists()) {
-					return new BufferedReader(new FileReader(directories[i] + fileName));
-				} else {
-					i++;
-				}   	
-			}
-        
-			// external HTML file of this exercise not found on file system. Try as resource, in case we are in a jar file
-			String resourceName =  "/"+fileName;
-        	resourceName = resourceName.replace('\\', '/'); /* just in case we were passed a windows path */
-
-        	InputStream s = ExerciseTemplated.class.getResourceAsStream(resourceName);
-        	if (s == null) 
-        		continue; // test next name in the list
-
-        	BufferedReader br = null;
-        	try {
-        		br = new BufferedReader(new InputStreamReader(s, "UTF-8"));
-        	} catch (UnsupportedEncodingException e1) {
-        		e1.printStackTrace();
-        		System.err.println("File encoding of " + fileName + " is not supported on this platform (please report this bug)");
-        		//return null;
-        		throw e1;
-        		//throw new FileNotFoundException(file + "with extension " + extension + " is encoded in an unsupported encoding.");
-        	}
-        	if (br != null) 
-				return br;
-        }
-		// file not found, give up. No logs here, as it is ok that some entities do not exist in some languages
-		if (extension == null)
-			throw new FileNotFoundException(file + " (without extension) could not be found.");
-		throw new FileNotFoundException(file + " with extension " + extension + " could not be found.");
-	}	
-	
-	public static StringBuffer readContentAsText(String file, String extension, boolean translatable) throws FileNotFoundException, UnsupportedEncodingException {
-		BufferedReader br = FileUtils.newFileReader(file, extension, translatable);
-		String newLine = System.getProperty("line.separator");
-		
-		StringBuffer sb = new StringBuffer();
-		try {
-			String s;
-			s = br.readLine();
-			while (s != null) {
-				sb.append(s);
-				sb.append(newLine);
-				s = br.readLine();
-			}
-			
-		} catch (IOException e) {
-			e.printStackTrace();			
-		} finally {
-			try {
-				br.close();
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
-		}
-		return sb;
-	}
-}
diff --git a/src/jlm/core/utils/InvalidColorNameException.java b/src/jlm/core/utils/InvalidColorNameException.java
deleted file mode 100644
index ff3fd8a..0000000
--- a/src/jlm/core/utils/InvalidColorNameException.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package jlm.core.utils;
-
-public class InvalidColorNameException extends Exception {
-	private static final long serialVersionUID = 1L;
-	public InvalidColorNameException(String msg){
-		super(msg);
-	}
-	public InvalidColorNameException(String msg, Exception e) {
-		super(msg,e);
-	}
-}
diff --git a/src/jlm/universe/BrokenWorldFileException.java b/src/jlm/universe/BrokenWorldFileException.java
deleted file mode 100644
index 501da6e..0000000
--- a/src/jlm/universe/BrokenWorldFileException.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package jlm.universe;
-
-public class BrokenWorldFileException extends Exception {
-	private static final long serialVersionUID = 1L;
-	
-	public BrokenWorldFileException(String msg) {
-		super(msg);
-	}
-}
diff --git a/src/jlm/universe/Direction.java b/src/jlm/universe/Direction.java
deleted file mode 100644
index 3f3f2b4..0000000
--- a/src/jlm/universe/Direction.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package jlm.universe;
-
-import java.awt.Point;
-
-
-// TODO: rewrite using enumeration
-public class Direction {
-	private int value;
-
-	public static final int NORTH_VALUE = 0;
-
-	public static final int EAST_VALUE = 1;
-
-	public static final int SOUTH_VALUE = 2;
-
-	public static final int WEST_VALUE = 3;
-
-	public static final Direction NORTH = new Direction(NORTH_VALUE);
-
-	public static final Direction EAST = new Direction(EAST_VALUE);
-
-	public static final Direction SOUTH = new Direction(SOUTH_VALUE);
-
-	public static final Direction WEST = new Direction(WEST_VALUE);
-
-	private static final Direction rights[] = { EAST, SOUTH, WEST, NORTH };
-
-	private static final Direction lefts[] = { WEST, NORTH, EAST, SOUTH };
-
-	private static final Direction opposites[] = { SOUTH, WEST, NORTH, EAST };
-
-	private Direction(int d) {
-		value = d;
-	}
-
-	public boolean equals(Direction d) {
-		return value == d.value;
-	}
-	
-	public Direction copy() {
-		return new Direction(value);
-	}
-
-	public Direction right() {
-		return rights[value];
-	}
-
-	public Direction left() {
-		return lefts[value];
-	}
-
-	public Direction opposite() {
-		return opposites[value];
-	}
-
-	@Override
-	public String toString() {
-		switch (value) {
-		case NORTH_VALUE:
-			return "NORTH";
-		case EAST_VALUE:
-			return "EAST";
-		case SOUTH_VALUE:
-			return "SOUTH";
-		case WEST_VALUE:
-			return "WEST";
-		default:
-			return "Unknown direction";
-		}
-	}
-
-	public Point toPoint() {
-		switch (value) {
-		case NORTH_VALUE:
-			return new Point(0, -1);
-		case EAST_VALUE:
-			return new Point(1, 0);
-		case SOUTH_VALUE:
-			return new Point(0, 1);
-		case WEST_VALUE:
-			return new Point(-1, 0);
-		default:
-			return null;
-		}
-	}
-	
-	public int intValue() {
-		return this.value;
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + value;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		final Direction other = (Direction) obj;
-		if (value != other.value)
-			return false;
-		return true;
-	}
-}
diff --git a/src/jlm/universe/Entity.java b/src/jlm/universe/Entity.java
deleted file mode 100644
index 0f05255..0000000
--- a/src/jlm/universe/Entity.java
+++ /dev/null
@@ -1,326 +0,0 @@
-package jlm.universe;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.universe.lightbot.LightBotEntity;
-
-import org.python.core.PyException;
-import org.python.core.PyTraceback;
-
-/* Entities cannot have their own org.xnap.commons.i18n.I18n, use the static Game.i18n instead.
- * 
- * This is because we have to pass the classname to the I18nFactory, but it seems to break 
- * stuff that our code generate new package names. This later case being forced by our use 
- * of the compiler, we cannot initialize an I18n stuff. 
- * 
- * Instead, the solution is to use the static field Game.i18n, as it is done in AbstractBuggle::diffTo().
- */
-
-public abstract class Entity {
-	protected String name;
-	protected World world;
-
-	private Semaphore oneStepSemaphore = new Semaphore(0);
-
-	public Entity() {}
-
-	public Entity(String name) {
-		this.name=name;
-	}
-	public Entity(String name, World w) {
-		this.name=name;
-		if (w != null) {
-			this.world = w;
-			world.addEntity(this);
-		}
-	}
-
-	public String getName() {
-		return this.name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}	
-
-	public World getWorld() {
-		return world;
-	}
-
-	public void setWorld(World world) {
-		this.world = world;
-	}
-
-	/* This is to allow exercise to forbid the use by students of some functions 
-	 * which are mandatory for core mechanism. See welcome.ArrayBuggle to see how it forbids setPos(int,int)  
-	 */
-	private boolean inited = false;
-	public boolean isInited() {
-		return inited;
-	}
-	public void initDone() {
-		inited = true;		
-	}
-
-	public void allowOneStep() {
-		this.oneStepSemaphore.release();
-	}
-
-	/** Delays the entity to let the user understand what's going on.
-	 *  
-	 * Calls to this function should be placed in important operation of the entity. There e.g. one such call in BuggleEntity.forward().  
-	 */
-	protected void stepUI() {		
-		fireStackListener();
-		world.notifyWorldUpdatesListeners();
-		if (world.isDelayed()) {
-			if (Game.getInstance().stepModeEnabled()) {
-				this.oneStepSemaphore.acquireUninterruptibly();
-			} else {	
-				try {
-					if (world.getDelay()>0) // seems that sleep(0) takes time (yield thread?)
-						Thread.sleep(world.getDelay());
-				} catch (InterruptedException e) {
-					e.printStackTrace();
-				}
-			}
-		}		
-	}
-
-	/** Copy fields of the entity passed in argument */
-	public void copy(Entity other) {
-		setName(other.getName());
-		setWorld(other.getWorld());
-	}
-	/** Copy constructor */
-	public abstract Entity copy();
-
-
-	/* Stuff related to tracing mechanism.
-	 * 
-	 * This is the ability to highlight the current instruction in step-by-step execution. 
-	 * 
-	 * Right now, this is only used for LightBot because I'm not sure of how to retrieve the current point of execution in java or scripting
-	 */
-	ArrayList<IEntityStackListener> stackListeners = new ArrayList<IEntityStackListener>();
-	public void addStackListener(IEntityStackListener l) {
-		stackListeners.add(l);
-	}
-	public void removeStackListener(IEntityStackListener l) {
-		stackListeners.remove(l);
-	}
-	public void fireStackListener() {
-		StackTraceElement[] trace = getCurrentStack();
-		for (IEntityStackListener l:stackListeners)
-			l.entityTraceChanged(this, trace);		
-	}
-	public StackTraceElement[] getCurrentStack() {
-		return Thread.currentThread().getStackTrace();
-	}
-
-	/** Retrieve one parameter from the world */
-	public Object getParam(int i) {
-		return world.parameters[i];
-	}	
-	protected int getParamsAmount() {
-		return world.parameters.length;
-	}
-	
-	/** Returns whether this is the entity selected in the interface */
-	public boolean isSelected() {
-		return this == Game.getInstance().getSelectedEntity();
-	}
-
-	/** Run this specific entity, encoding the student logic to solve a given exercise. 
-	 * 
-	 *  This method is redefined by the leafs of the inheritance tree (the entities involved in exercises)   
-	 *   
-	 *  @see #runIt() that execute an entity depending on the universe and programming language
-	 *    
-	 */
-	protected abstract void run() throws Exception;
-
-	/** Make the entity run, according to the used universe and programming language.
-	 * 
-	 * This task is not trivial given that it depends on the universe and the programming language:
-	 *  * In most universes, the active part is the entity itself. But in the Bat universe, the 
-	 *    student-provided method (that is not a real entity but part of the world directly) 
-	 *    is run against all testcase, that are not real worlds either.
-	 *    
-	 *  * Java entities are launched by just executing their {@link #run()} method that 
-	 *    was redefined by the student (possibly with some templating)
-	 *  * LightBot entities are launched by executing the {@link LightBotEntity#run()} method, 
-	 *    that is NOT defined by the student, but interprets the code of the students.
-	 *  * Python (and other scripting language) entities are launched by injecting the 
-	 *    student-provided code within a {@link ScriptEngine}. 
-	 *    In this later case, the java entity is injected within the scripting world so that it 
-	 *    can forward the student commands to the world. 
-	 * 
-	 *  @see #run() that encodes the student logic in Java
-	 */
-	public void runIt(ExecutionProgress progress) {
-		ProgrammingLanguage progLang = Game.getProgrammingLanguage();
-		ScriptEngine engine ;
-		if (progLang.equals(Game.JAVA)||progLang.equals(Game.LIGHTBOT)) {
-			try {
-				run();
-			} catch (Exception e) {
-				String msg = Game.i18n.tr("The execution of your program raised an exception: {0}\n" + 
-						" Please fix your code.\n",e.getLocalizedMessage());
-
-				System.err.println(msg);
-				progress.setCompilationError(msg);
-				e.printStackTrace();
-			}
-		} else {
-			try {
-				/* We could try to optimize here by not starting one engine for each entity but only one per language, in which the entities would be in separate contexts. 
-				 * On the other hand, the garbage collection would be harder this way and it works as is... */
-				ScriptEngineManager manager = new ScriptEngineManager();       
-				engine = manager.getEngineByName(progLang.getLang().toLowerCase());
-				if (engine==null) 
-					throw new RuntimeException(Game.i18n.tr("Failed to start an interpreter for {0}",progLang.getLang().toLowerCase()));
-
-				/* Inject the entity into the scripting world so that it can forward script commands to the world */
-				engine.put("entity", this);
-				/* Inject commands' wrappers that forward the calls to the entity */
-				this.getWorld().setupBindings(progLang,engine);
-
-				if (progLang.equals(Game.PYTHON)) 
-					engine.eval(
-							/* getParam is in every Entity, so put it here to not request the universe to call super.setupBinding() */
-							"def getParam(i):\n"+
-							"  return entity.getParam(i)\n" +
-							"def isSelected():\n" +
-							"  return entity.isSelected()\n");									
-
-
-				String script = getScript(progLang);
-
-				if (Game.getInstance().isDebugEnabled())
-					System.err.println("Here is the script >>>>"+script+"<<<<");
-
-				if (script == null) 
-					System.err.println(Game.i18n.tr("No {0} script source for entity {1}. Please report that bug against JLM.",progLang,this));
-				else {
-					/* that's not really clean to get the output working when we 
-					 * redirect to the graphical console, but it works. */
-					setScriptOffset(progLang, getScriptOffset(progLang)+7);
-					engine.eval(
-							"import sys;\n" +
-									"import java.lang;\n" +
-									"class JLMOut:\n" +
-									"  def write(obj,msg):\n" +
-									"    java.lang.System.out.print(str(msg))\n" +
-									"sys.stdout = JLMOut()\n"+
-									"sys.stderr = JLMOut()\n"+
-									script);
-				}
-			} catch (ScriptException e) {
-				if (e.getCause() instanceof PyException) { // This seem to be all exceptions raised by python
-					PyException cause = (PyException) e.getCause();
-
-					StringBuffer msg = new StringBuffer();
-
-					if (cause.type.toString().equals("<type 'exceptions.SyntaxError'>")) {
-						msg.append(Game.i18n.tr("Syntax error at line {0}: {1}\n" +
-								"In doubt, check your indentation, and that you don't mix tabs and spaces\n",
-								((cause.value.__findattr__("lineno").asInt())-getScriptOffset(Game.PYTHON)),
-								cause.value.__findattr__("msg")));
-
-					} else { /* It makes sense to display a backtrace for any errors but syntax ones */
-
-						if (cause.type.toString().equals("<type 'exceptions.NameError'>")) {
-							msg.append(Game.i18n.tr("NameError raised: You seem to use a non-existent identifier; Please check for typos\n"));
-							msg.append(cause.value+"\n");
-						} else if (cause.type.toString().equals("<type 'exceptions.TypeError'>")) {
-							msg.append(Game.i18n.tr("TypeError raised: you are probably misusing a function or something.\n"));
-							msg.append(cause.value+"\n");
-						} else if (cause.type.toString().equals("<type 'exceptions.UnboundLocalError'>")) {
-							msg.append(Game.i18n.tr("UnboundLocalError raised: you are probably using a global variable that is not declared as such.\n"));
-							msg.append(cause.value+"\n");
-
-
-							/* FIXME: how could we factorize the world's error? */ 
-						} else if (cause.type.toString().equals("<type 'jlm.universe.bugglequest.exception.NoBaggleUnderBuggleException'>")) {
-							msg.append(Game.i18n.tr("Error: there is no baggle to pickup under the buggle"));
-						} else if (cause.type.toString().equals("<type 'jlm.universe.bugglequest.exception.AlreadyHaveBaggleException'>")) {
-							msg.append(Game.i18n.tr("Error: a buggle cannot carry more than one baggle at the same time"));
-						} else if (cause.type.toString().equals("<type 'jlm.universe.bugglequest.exception.BuggleInOuterSpaceException'>")) {
-							msg.append(Game.i18n.tr("Error: your buggle just teleported to the outer space..."));
-						} else if (cause.type.toString().equals("<type 'jlm.universe.bugglequest.exception.BuggleWallException'>")) {
-							msg.append(Game.i18n.tr("Error: your buggle just hit a wall. That hurts."));
-
-						} else {
-							msg.append(Game.i18n.tr("Unknown error (please report): {0}\nIts value is: {1}",
-									cause.type.toString(),cause.value+"\n"));
-
-						}
-
-
-						/* The following is very inspired from <jython>/src/org/python/core/PyTraceback.java, 
-						 * even if we cannot reuse directly this implementation since we want to change all linenos on the fly. 
-						 */
-						PyTraceback tb = cause.traceback;
-						while (tb != null) {
-							tb.tb_lineno-= getScriptOffset(Game.PYTHON);
-							if (tb.tb_frame == null || tb.tb_frame.f_code == null) {
-								msg.append(String.format("  (no code object) at line %s\n", tb.tb_lineno));
-							} else {
-								msg.append(String.format("  File \"%.500s\", line %d, in %.500s\n",
-										tb.tb_frame.f_code.co_filename, tb.tb_lineno, tb.tb_frame.f_code.co_name));
-							}
-							tb = (PyTraceback) tb.tb_next;
-						}
-					}				
-
-					if (Game.getInstance().isDebugEnabled()) {
-						System.err.println("CAUSE: "+cause.value.toString());
-						System.err.println("MSG: "+e.getMessage());
-						System.err.println("BT: "+msg);
-					}
-
-					progress.setCompilationError(msg.toString());
-				}
-			} catch (Exception e) {
-				String msg = Game.i18n.tr("Script evaluation raised an exception that is not a ScriptException but a {0}.\n"+
-						" Please report this as a bug against JLM, with all details allowing to reproduce it.\n" +
-						"Exception message: {1}",e.getClass(),e.getLocalizedMessage());
-				for (StackTraceElement elm : e.getStackTrace()) 
-					msg += elm.toString();
-				
-				System.err.println(msg);
-				progress.setCompilationError(msg);
-				e.printStackTrace();
-			}
-		}
-
-	}
-
-	private Map<ProgrammingLanguage,String> script = new HashMap<ProgrammingLanguage, String>(); /* What to execute when running a scripting language */
-	public void setScript(ProgrammingLanguage lang, String s) {
-		script.put(lang,  s);
-	}
-	public String getScript(ProgrammingLanguage lang) {
-		return script.get(lang);
-	}
-
-	private Map<ProgrammingLanguage,Integer> scriptOffset = new HashMap<ProgrammingLanguage, Integer>(); /* the offset to apply to error messages */
-	public void setScriptOffset(ProgrammingLanguage lang, int offset) {
-		scriptOffset.put(lang,  offset);
-	}
-	public Integer getScriptOffset(ProgrammingLanguage lang) {
-		Integer res = scriptOffset.get(lang);
-		return res == null ? 0:res;
-	}
-}
diff --git a/src/jlm/universe/EntityControlPanel.java b/src/jlm/universe/EntityControlPanel.java
deleted file mode 100644
index 7d457b2..0000000
--- a/src/jlm/universe/EntityControlPanel.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package jlm.universe;
-
-import java.util.Locale;
-
-import javax.swing.JPanel;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public abstract class EntityControlPanel extends JPanel implements HumanLangChangesListener {
-	private static final long serialVersionUID = 1L;
-	public abstract void setEnabledControl(boolean enabled);
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
-	
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",newLang, I18nFactory.FALLBACK);
-	}
-}
diff --git a/src/jlm/universe/GridWorld.java b/src/jlm/universe/GridWorld.java
deleted file mode 100644
index 4d349ef..0000000
--- a/src/jlm/universe/GridWorld.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package jlm.universe;
-
-
-
-
-
-
-public abstract class GridWorld extends World {
-
-	protected GridWorldCell[][] cells;
-	protected int sizeX;
-	protected int sizeY;
-	protected boolean visibleGrid=true;
-
-	public GridWorld(String name, int x, int y) {
-		super(name);
-		create(x, y);
-	}
-
-	public GridWorld(GridWorld world2) {
-		super(world2);
-		sizeX = world2.getWidth();
-		sizeY = world2.getHeight();
-		visibleGrid = world2.visibleGrid;
-		this.cells = new GridWorldCell[sizeX][sizeY];
-		for (int i = 0; i < sizeX; i++)
-			for (int j = 0; j < sizeY; j++) {
-				cells[i][j] = world2.getCell(i, j).copy(this);
-			}
-	}
-
-	protected void create(int width, int height) {
-		this.sizeX = width;
-		this.sizeY = height;
-		this.cells = new GridWorldCell[sizeX][sizeY];
-		for (int i = 0; i < sizeX; i++)
-			for (int j = 0; j < sizeY; j++)
-				setCell(newCell(i, j), i, j) ;
-	}
-	protected abstract GridWorldCell newCell(int x, int y);
-	
-	public void setWidth(int width) {
-		GridWorldCell[][] oldCells = cells;
-		this.cells = new GridWorldCell[width][sizeY];
-		for (int i = 0; i< Math.min(width, sizeX); i++) 
-			for (int j = 0; j < sizeY; j++)
-				cells[i][j] = oldCells[i][j];
-		
-		if (width>sizeX) // need to increase the table size
-			for (int i = sizeX; i< width; i++) 
-				for (int j = 0; j < sizeY; j++)
-					cells[i][j] = newCell(i, j);
-			
-		sizeX = width;
-	}
-
-	public void setHeight(int height) {
-		GridWorldCell[][] oldCells = cells;
-		this.cells = new GridWorldCell[sizeX][height];
-		for (int i = 0; i< sizeX; i++)  {
-			for (int j = 0; j < Math.min(height, sizeY); j++)
-				cells[i][j] = oldCells[i][j];
-			if (height>sizeY) // need to increase the table size
-				for (int j = sizeY; j < height; j++)
-					cells[i][j] = newCell(i, j);
-		}
-		
-		sizeY = height;
-	}
-
-	
-	public GridWorldCell getCell(int x, int y) {
-		return this.cells[x][y];
-	}
-
-	public void setCell(GridWorldCell c, int x, int y) {
-		this.cells[x][y] = c;
-		notifyWorldUpdatesListeners();
-	}
-
-	public int getWidth() {
-		return this.sizeX;
-	}
-
-	public int getHeight() {
-		return this.sizeY;
-	}
-	public boolean getVisibleGrid() {
-		return visibleGrid;
-	}
-	public void setVisibleGrid(boolean s) {
-		visibleGrid=s;
-	}
-}
diff --git a/src/jlm/universe/GridWorldCell.java b/src/jlm/universe/GridWorldCell.java
deleted file mode 100644
index ec8e917..0000000
--- a/src/jlm/universe/GridWorldCell.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package jlm.universe;
-
-
-
-
-public abstract class GridWorldCell {
-
-	protected GridWorld world;
-	protected int x;
-	protected int y;
-
-	public GridWorldCell(GridWorld w, int x, int y) {
-		world = w;
-		this.x = x;
-		this.y = y;
-	}
-	public abstract GridWorldCell copy(GridWorld world);
-
-	public GridWorld getWorld() {
-		return this.world;
-	}
-
-	public int getX() {
-		return this.x;
-	}
-
-	public void setX(int newX) {
-		this.x = newX;
-	}
-
-	public int getY() {
-		return this.y;
-	}
-
-	public void setY(int newY) {
-		this.y = newY;
-	}
-
-	public void setWorld(GridWorld w) {
-		this.world = w;
-	}
-}
diff --git a/src/jlm/universe/IEntityStackListener.java b/src/jlm/universe/IEntityStackListener.java
deleted file mode 100644
index eb377de..0000000
--- a/src/jlm/universe/IEntityStackListener.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package jlm.universe;
-
-public interface IEntityStackListener {
-	public void entityTraceChanged(Entity e, StackTraceElement[] trace);
-
-	public void tracedEntityChanged(Entity selectedEntity);
-}
diff --git a/src/jlm/universe/IWorldView.java b/src/jlm/universe/IWorldView.java
deleted file mode 100644
index 4dae3fd..0000000
--- a/src/jlm/universe/IWorldView.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package jlm.universe;
-
-public interface IWorldView {
-
-	/**
-	 * Called every time something changes: entity move, new entity, entity gets destroyed, etc.
-	 */
-	public void worldHasMoved();
-	
-	/**
-	 * Called when entities are created or destroyed, not when they move
-	 */
-	public void worldHasChanged(); 
-
-}
\ No newline at end of file
diff --git a/src/jlm/universe/World.java b/src/jlm/universe/World.java
deleted file mode 100644
index a837c28..0000000
--- a/src/jlm/universe/World.java
+++ /dev/null
@@ -1,328 +0,0 @@
-package jlm.universe;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.model.Logger;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.ui.JlmHtmlEditorKit;
-import jlm.core.ui.WorldView;
-import jlm.core.utils.FileUtils;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public abstract class World {
-	private boolean isDelayed = false; // whether we display interactively or not
-	private int delay = 100; // delay between two instruction executions of an entity.
-
-	protected ArrayList<Entity> entities = new ArrayList<Entity>();
-
-	private String name;
-
-	public I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
-
-	public World(String name) {
-		this.name = name;
-	}
-
-	public World(World w2) {
-		this(w2.getName());
-		reset(w2);
-	}
-
-	public World copy() {
-		World res=null;
-		try {
-			res = this.getClass().getConstructor(this.getClass()).newInstance(this);
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw new RuntimeException(e);
-		}
-		return res;
-	}
-
-	/**
-	 * Reset the content of a world to be the same than the one passed as
-	 * argument
-	 * 
-	 * @param initialWorld
-	 */
-	public void reset(World initialWorld) {
-		entities = new ArrayList<Entity>();
-		for (Entity b : initialWorld.entities) {
-			Entity br = b.copy();
-			br.setWorld(this);
-			entities.add(br);
-		}
-		this.isDelayed = initialWorld.isDelayed;
-		this.delay = initialWorld.delay;
-		this.parameters = (initialWorld.parameters!=null?initialWorld.parameters.clone():null);
-		notifyEntityUpdateListeners();
-		notifyWorldUpdatesListeners();
-	}
-
-	public String getName() {
-		return this.name;
-	}
-
-	public void setName(String n) {
-		name = n;
-	}
-
-	public boolean isDelayed() {
-		return isDelayed;
-	}
-	/** returns the delay to apply */
-	public int getDelay() {
-		return this.delay;
-	}
-	/** set the value of the UI delay which will be used on doDelay() */
-	public void setDelay(int d) {
-		this.delay = d;
-		notifyWorldUpdatesListeners(); // notify the speed slider model
-	}
-	/** set current UI delay to what was defined as max UI delay with setDelayUI() */
-	public void doDelay() {
-		isDelayed = true;
-	}
-	/** set current UI delay to 0 */
-	public void doneDelay() {
-		isDelayed = false;
-	}
-
-	public void addEntity(Entity b) {
-		entities.add(b);
-		notifyEntityUpdateListeners();
-	}
-	public void removeEntity(Entity b) {
-		if (!entities.remove(b)) 
-			System.out.println("Ignoring a request to remove an unknown entity");
-		notifyEntityUpdateListeners();		
-	}
-
-	public void emptyEntities() {
-		entities = new ArrayList<Entity>();
-		notifyEntityUpdateListeners();
-	}
-
-	public void setEntities(ArrayList<Entity> l) {
-		entities = l;
-		notifyEntityUpdateListeners();
-	}
-
-	public int getEntityCount() {
-		return entities.size();
-	}
-
-	public Entity getEntity(int i) {
-		return entities.get(i);
-	}
-	public List<Entity> getEntities() {
-		return entities;
-	}
-	
-	public void runEntities(List<Thread> runnerVect, final ExecutionProgress progress) {
-		if (Game.getInstance().isDebugEnabled())
-			Logger.log("World:runEntities","Programming language: "+Game.getProgrammingLanguage());
-		
-		for (final Entity b : entities) {
-			Thread runner = new Thread(new Runnable() {
-				public void run() {
-					Game.getInstance().statusArgAdd(getName());
-					b.runIt(progress);
-					Game.getInstance().statusArgRemove(getName());
-				}
-			});
-
-			// So that we can still stop it from the AWT Thread, even if an infinite loop occures
-			runner.setPriority(Thread.MIN_PRIORITY);
-
-			runner.start();
-			runnerVect.add(runner);
-		}
-	}
-
-	/* who's interested in every details of the world changes */
-	private ArrayList<IWorldView> worldUpdatesListeners = new ArrayList<IWorldView>();
-
-	/* who's only interested in entities creation and destructions */
-	private ArrayList<IWorldView> entitiesUpdateListeners = new ArrayList<IWorldView>();
-
-	public void addWorldUpdatesListener(IWorldView v) {
-		synchronized (this.worldUpdatesListeners) {
-			this.worldUpdatesListeners.add(v);
-		}
-	}
-
-	public void removeWorldUpdatesListener(IWorldView v) {
-		synchronized (this.worldUpdatesListeners) {
-			this.worldUpdatesListeners.remove(v);
-		}
-	}
-
-	public void notifyWorldUpdatesListeners() {
-		synchronized (this.worldUpdatesListeners) {
-			for (IWorldView v : this.worldUpdatesListeners) {
-				v.worldHasMoved();
-			}
-		}
-	}
-
-	public void addEntityUpdateListener(IWorldView v) {
-		synchronized (this.entitiesUpdateListeners) {
-			this.entitiesUpdateListeners.add(v);
-		}
-	}
-
-	public void removeEntityUpdateListener(IWorldView v) {
-		synchronized (this.entitiesUpdateListeners) {
-			this.entitiesUpdateListeners.remove(v);
-		}
-	}
-
-	public void notifyEntityUpdateListeners() {
-		synchronized (this.entitiesUpdateListeners) {
-			for (IWorldView v : this.entitiesUpdateListeners) {
-				v.worldHasChanged();
-			}
-		}
-	}
-
-	/* IO related */
-	/** Returns whether this universe implements world I/O */
-	public boolean haveIO() { 
-		return false; 
-	}
-	public World readFromFile(String path) throws IOException, BrokenWorldFileException {
-		throw new RuntimeException("This universe does not implement world I/O");
-	}
-
-	public void writeToFile(BufferedWriter f) throws IOException {}
-
-	public void writeToFile(File outputFile) throws IOException {
-		BufferedWriter bw = null;
-		FileWriter fw = null;
-		try {
-			fw = new FileWriter(outputFile);
-			bw = new BufferedWriter(fw);
-			this.writeToFile(bw);
-		} catch (IOException e) {
-			throw e;
-		} finally {
-			if (bw != null)
-				bw.close();
-		}
-	}
-
-	/* Find my UI */
-	public WorldView getView() {
-		return new WorldView(this) {
-			private static final long serialVersionUID = 1L;
-			@Override
-			public boolean isWorldCompatible(World world) {
-				return false;
-			}
-		};
-	}
-	public EntityControlPanel getEntityControlPanel() {
-		return new EntityControlPanel() {
-			private static final long serialVersionUID = 1L;
-			@Override
-			public void setEnabledControl(boolean enabled) {
-			}
-		};
-	}
-	public abstract ImageIcon getIcon();
-
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((entities == null) ? 0 : entities.hashCode());
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if ( !(obj instanceof World))
-			return false;
-		World other = (World) obj;
-		if (entities == null) {
-			if (other.entities != null)
-				return false;
-		} else if (!entities.equals(other.entities))
-			return false;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		return true;
-	}
-
-	String about = null;
-
-	public String getAbout() {
-		if (about == null) {
-			String filename = getClass().getCanonicalName().replace('.', File.separatorChar);
-			StringBuffer sb = null;
-			try {
-				sb = FileUtils.readContentAsText(filename, "html", true);
-			} catch (IOException ex) {
-				about = "File "+filename+".html not found.";
-				return about;
-			}
-			/* read it */
-			about = sb.toString();
-		}
-		return "<html>\n" + JlmHtmlEditorKit.getCSS(Game.getProgrammingLanguage()) + "<body>\n" + about + "</body>\n</html>\n";
-	}
-	
-	/**
-	 * Set about to null in order to allows it to be reloaded in the right language
-	 */
-	public void resetAbout() {
-		this.about = null ;
-	}
-
-	protected Object[] parameters = null;
-	public void setParameter(Object[] parameters) {
-		this.parameters = parameters;		
-	}
-	public Object[] getParameters() {
-		return parameters;
-	}
-	public Object getParameter(int i){
-		return parameters[i];
-	}
-
-	public void setSelectedEntity(Entity e) {
-		notifyWorldUpdatesListeners();//EntityUpdateListeners();
-	}
-	/** Returns the script except that must be injected within the environment before running user code
-	 * 
-	 * It should pass all order to the java entity, which were injected independently  
-	 * @throws ScriptException 
-	 */
-	public abstract void setupBindings(ProgrammingLanguage lang,ScriptEngine engine) throws ScriptException;
-
-	/** Returns a textual representation of the differences from the receiver world to the one in parameter*/
-	public abstract String diffTo(World world);
-}
diff --git a/src/jlm/universe/bat/BatEntity.java b/src/jlm/universe/bat/BatEntity.java
deleted file mode 100644
index 4b331e1..0000000
--- a/src/jlm/universe/bat/BatEntity.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package jlm.universe.bat;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-public class BatEntity extends Entity {
-	
-	public BatEntity() {
-		super();
-	}
-	
-	public BatEntity(String name, World w) {
-		super(name,w);
-	}
-	
-	public BatEntity(BatEntity other) {
-		super();
-		copy(other);
-	}
-
-	@Override
-	public Entity copy() {
-		return new BatEntity(this);
-	}
-	
-	
-	@Override
-	public void copy(Entity o) {
-		super.copy(o);
-	}
-	
-
-	@Override
-	public boolean equals(Object o) {
-		if (!(o instanceof BatEntity)) {
-			return false;
-		}
-		return (super.equals(o));
-	}
-	
-	@Override
-	protected void run() {
-		throw new RuntimeException ("I thought this method was useless. Please report.");
-	}
-
-	protected void run(BatTest t) {
-		// To be overriden by child classes
-	}
-	
-	@Override 
-	public void runIt(ExecutionProgress progress) {
-		ProgrammingLanguage pl = Game.getProgrammingLanguage();
-		if (pl.equals(Game.JAVA)) {
-			for (BatTest t:((BatWorld) world).getTests())
-				try {
-					run(t);
-				} catch (Exception e) {
-					t.setResult("this test raised an exception: "+e.getMessage());
-				}
-		} else if (pl.equals(Game.PYTHON)) {
-			ScriptEngine engine ;
-
-			ScriptEngineManager manager = new ScriptEngineManager();       
-			engine = manager.getEngineByName("python");
-			if (engine==null) 
-				throw new RuntimeException("Failed to start an interpreter for python");
-			
-			try {
-				engine.eval(
-						"import java.lang.System.err\n"+
-						"def log(a):\n"+
-						"  java.lang.System.err.print(\"%s: %s\" %(entity.getName(),a))\n");
-				String script = getScript(Game.PYTHON);
-				if (script == null)
-					throw new RuntimeException("No script found for "+Game.getInstance().getCurrentLesson().getCurrentExercise());
-				engine.eval(script);
-			} catch (ScriptException e1) {
-				progress.setCompilationError( e1.getCause().toString() );
-				e1.printStackTrace();
-			}									
-
-			for (BatTest t:((BatWorld) getWorld()).getTests())
-				try {
-					engine.put("thetest",t);
-					engine.eval("thetest.setResult("+t.getName()+")");
-				} catch (Exception e) {
-					t.setResult("this test raised an exception: "+e.getMessage());
-				}
-
-		}
-	}
-
-}
diff --git a/src/jlm/universe/bat/BatExercise.java b/src/jlm/universe/bat/BatExercise.java
deleted file mode 100644
index 28dfb7d..0000000
--- a/src/jlm/universe/bat/BatExercise.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package jlm.universe.bat;
-
-import java.util.List;
-import java.util.Vector;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.ExerciseTemplatingEntity;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-
-public abstract class BatExercise extends ExerciseTemplatingEntity {
-	public static final boolean INVISIBLE = false;
-	public static final boolean VISIBLE = true;
-	
-	public BatExercise(Lesson lesson) {
-		super(lesson);
-	}
-
-	protected void setup(World[] ws) {
-		if (ws.length > 1)
-			throw new RuntimeException("Bat exercises must have at most one world");
-		
-		String entName="no name";
-		entName = ws[0].getName();
-		
-		/* Install the corrections: the first time setResult is called, it set 'expected' instead */
-		for (BatTest t : ((BatWorld)ws[0]).tests)
-			run(t);
-		
-		super.setup(ws,entName,
-				"import jlm.universe.bat.BatEntity; "+
-		        "import jlm.universe.bat.BatWorld; "+
-		        "import jlm.universe.bat.BatTest; "+
-		        "import jlm.universe.World; "+
-		        "public class "+entName+" extends BatEntity { ");
-	}
-	
-	@Override
-	public void runDemo(List<Thread> runnerVect){
-		/* No demo in bat exercises */
-	}
-
-	public abstract void run(BatTest t);
-	
-	@Override 
-	public void mutateCorrection(WorldKind kind) {
-		Vector<World> worlds;
-		switch (kind) {
-		case INITIAL: worlds = initialWorld; break;
-		case CURRENT: worlds = currentWorld; break;
-		case ANSWER:  worlds = answerWorld;  break;
-		default: throw new RuntimeException("kind is invalid: "+kind);
-		}
-
-		for (ProgrammingLanguage pl : getProgLanguages()) {
-			if (!pl.equals(Game.JAVA)) 
-				worlds.get(0).getEntity(0).setScript(pl, corrections.get(pl));
-		}
-		
-		for (BatTest t : ((BatWorld)worlds.get(0)).tests) 
-			t.objectiveTest = true;
-	}
-}
diff --git a/src/jlm/universe/bat/BatTest.java b/src/jlm/universe/bat/BatTest.java
deleted file mode 100644
index 7f85eb6..0000000
--- a/src/jlm/universe/bat/BatTest.java
+++ /dev/null
@@ -1,206 +0,0 @@
-package jlm.universe.bat;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-
-public class BatTest {
-	Object[] parameters;
-	
-	protected Object result;
-	protected Object expected;
-	
-	private boolean visible;
-	private boolean correct,answered;
-	public boolean objectiveTest=false; // ExoTest messes with it, sorry
-	private String funName;
-	
-	public BatTest(String funName, boolean visible,Object parameters) {
-		this.funName = funName;
-		this.visible = visible;
-		this.correct = false;
-		this.answered = false;
-		
-		/* Cast parameters into an array on need */
-		if (parameters.getClass().isArray()) {
-			this.parameters = (Object[]) parameters;
-		} else {
-			this.parameters = new Object[] {parameters};
-		}
-	}
-	public BatTest copy() {
-		BatTest res = new BatTest(funName,visible,parameters.clone());
-		res.result = result;
-		res.expected = expected;
-		return res;
-	}
-	
-	public boolean isVisible() {
-		return visible;
-	}
-	
-	@Override
-	public boolean equals(Object o) {  
-		if (!(o instanceof BatTest)) 
-			return false;
-		BatTest other = (BatTest) o;
-		if (other.parameters.length != parameters.length) {
-			//System.out.println("While comparing a Bat test, the amount of parameters differs: "+parameters.length+" != "+other.parameters.length);
-			return false;
-		}
-		for (int i=0;i<parameters.length;i++)
-			if (!parameters[i].equals(other.parameters[i])) {
-				//System.out.println("While comparing a Bat test, the parameter "+i+" differs: "+parameters[i]+" != "+other.parameters[i]);
-				return false;
-			}
-		if (isObjective() && !other.isObjective()) {
-			/* We seem to be called as answer.equals(current) from the check() method. 
-			 * Act accordingly by comparing our expected to their result
-			 */
-			if (expected == null && other.result != null) {
-				return false;			
-			}
-			if (expected !=null && !expected.equals(other.result)) {
-				return false;
-			}
-		} else if (!isObjective() && other.isObjective()) {
-			/* We seem to be called as current.equals(answer). Weird I thought it was impossible. Anyway. */
-			if (result == null && other.expected != null) {
-				return false;			
-			}
-			if (result !=null && !result.equals(other.expected)) {
-				return false;
-			}
-		} else {
-			/* Act as an usual equal method as we don't seem to be called from check(). From the UI maybe? */
-			if (result == null && other.result != null) {
-				//System.out.println("While comparing a Bat test, the result differs: null != "+other.result);
-				return false;			
-			}
-			if (result !=null && !result.equals(other.result)) {
-				//System.out.println("While comparing a Bat test, the result differs: "+result+" != "+other.result);
-				return false;
-			}
-			if (expected == null && other.result != null) {
-				return false;			
-			}
-			if (expected != null && !expected.equals(other.expected)) {
-				//System.out.println("While comparing a Bat test, the expected value differs: "+expected+" != "+other.expected);
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public Object getParameter(int i) {
-		return parameters[i];
-	}
-
-	public boolean isAnswered() {
-		return answered;
-	}
-	public boolean isCorrect() {
-		return correct;
-	}
-	
-	private String name = null;
-
-	private void displayParameter(Object o, StringBuffer sb, ProgrammingLanguage pl) {
-		if (o == null) {
-			sb.append("null");
-		} else if (o instanceof String[]) {
-			sb.append("{");
-			String[]a = (String[]) o;
-			for (String i:a) {
-				sb.append(i+",");
-			}
-			sb.deleteCharAt(sb.length()-1);
-			sb.append("}");					
-		} else if (o.getClass().isArray()){
-			if (pl.equals(Game.JAVA)) {
-				sb.append("{");
-			} else { // Python
-				sb.append("[");
-			}
-			if (o.getClass().getComponentType().equals(Integer.TYPE)) {
-				int[]a = (int[]) o;
-				for (int i:a) 
-					sb.append(i+",");
-				
-				if (a.length > 0) // Don't kill the last comma if there is none
-					sb.deleteCharAt(sb.length()-1);
-			} else {
-				throw new RuntimeException("Unhandled internal type (only integer arrays are handled so far)");
-			}
-			if (pl.equals(Game.JAVA)) {
-				sb.append("}");
-			} else { // Python
-				sb.append("]");
-			}
-		} else if (o instanceof Boolean && pl.equals(Game.PYTHON)){
-			Boolean b = (Boolean) o;
-			if (b) {
-				sb.append("True");
-			} else {
-				sb.append("False");
-			}
-		} else if (o instanceof String && pl.equals(Game.PYTHON)) {
-			sb.append("\""+o+"\"");
-		} else {
-			sb.append(o.toString());
-		}		
-	}
-	public String getName() {
-		ProgrammingLanguage pl = Game.getProgrammingLanguage();
-		if (name == null) {
-			StringBuffer sb=new StringBuffer(funName+"(");
-			
-			for (Object o:parameters) {
-				displayParameter(o, sb, pl);
-				sb.append(",");
-			}
-			
-			sb.deleteCharAt(sb.length()-1);
-			sb.append(")");					
-			name=sb.toString();
-
-		}
-		return name;
-	}
-	public boolean isObjective() {
-		return objectiveTest;
-	}
-	
-	public String toString() {
-		ProgrammingLanguage pl = Game.getProgrammingLanguage();
-		StringBuffer res = new StringBuffer(getName());
-		res.append("=");
-		displayParameter(result, res, pl);
-		res.append(" (expected: ");
-		displayParameter(expected, res, pl);
-		res.append("; isObjective: "+isObjective()+")");
-		return res.toString();
-	}
-	public String getResult() {
-		Object o = result;
-		if (isObjective())
-			o = expected;
-		
-		if (o != null) {
-			StringBuffer sb = new StringBuffer();
-			displayParameter(o, sb, Game.getProgrammingLanguage());
-			return sb.toString();
-		} else {
-			return "(null)";
-		}
-	}
-	public void setResult(Object r) {
-		result = r;
-		if (expected == null) {
-			expected = r; // The first time we're set, that's an answer which comes in
-		} else {
-			if (expected != null)
-				correct = expected.equals(result);
-			answered = true;
-		}
-	}
-}
diff --git a/src/jlm/universe/bat/BatWorld.java b/src/jlm/universe/bat/BatWorld.java
deleted file mode 100644
index 61177ac..0000000
--- a/src/jlm/universe/bat/BatWorld.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package jlm.universe.bat;
-
-import java.util.List;
-import java.util.Vector;
-
-import javax.script.ScriptEngine;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
-
-public class BatWorld extends World {
-	public List<BatTest> tests = new Vector<BatTest>();
-	
-	public BatWorld(String funName) {
-		super(funName);
-		
-		BatEntity e = new BatEntity();
-		addEntity(e);
-		e.setWorld(this);
-	}
-	public BatWorld(BatWorld w2) {
-		super(w2);
-		this.tests = new Vector<BatTest>();
-		for (BatTest t:w2.tests) 
-			tests.add(t.copy());
-	}
-	
-	@Override
-	public void reset(World w) {
-		BatWorld anotherWorld = (BatWorld) w;
-		this.tests = new Vector<BatTest>();
-		for (BatTest t:anotherWorld.tests) 
-			tests.add(t.copy());
-		super.reset(anotherWorld);		
-	}
-	@Override
-	public boolean equals(Object o){
-		if (!(o instanceof BatWorld)) {
-			return false;
-		}
-		BatWorld other = (BatWorld) o;
-		if (other.tests.size() != tests.size()) {
-			//System.out.println("Amount of tests differ between worlds: "+tests.size()+" != "+other.tests.size());
-			return false;
-		}
-		for (int i=0;i<tests.size();i++)
-			if (!tests.get(i).equals(other.tests.get(i))) {
-				//throw new RuntimeException("Test "+i+" differs: "+tests.get(i)+" != "+other.tests.get(i));
-				return false;
-			}
-		return true;
-	}
-	@Override
-	public WorldView getView() {
-		return new BatWorldView(this);
-	}
-	@Override
-	public ImageIcon getIcon() {
-		return ResourcesCache.getIcon("img/world_bat.png");
-	}
-	
-	/* So that the view can display them */
-	protected List<BatTest> getTests() {
-		return tests;
-	}
-
-	/* World logic */
-	public void addTest(boolean visible, Object...params) {
-		tests.add(new BatTest(getName(),visible, params));
-	}
-	@Override
-	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) {
-		/* No need of any binding for this world */
-	}
-	@Override
-	public String diffTo(World w) {
-		BatWorld other = (BatWorld) w;
-		StringBuffer sb = new StringBuffer();
-		boolean foundError = false;
-		for (int i=0;i<tests.size();i++) {
-			if (foundError && !tests.get(i).isVisible() && !Game.getInstance().isDebugEnabled()) 
-				return sb.toString();
-					
-			if (!tests.get(i).equals(other.tests.get(i))) { 
-				sb.append(other.tests.get(i).getName()+" returned "+other.tests.get(i).getResult()+
-						                               " while "+         tests.get(i).getResult()+" were expected.\n");
-				foundError = true;
-			}
-		}
-		return sb.toString();
-	}
-}
diff --git a/src/jlm/universe/bat/BatWorldView.java b/src/jlm/universe/bat/BatWorldView.java
deleted file mode 100644
index 8700672..0000000
--- a/src/jlm/universe/bat/BatWorldView.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package jlm.universe.bat;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.Rectangle2D;
-import java.util.List;
-
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
-
-public class BatWorldView extends WorldView {
-
-	private static final long serialVersionUID = 1L;
-
-	public BatWorldView(World w) {
-		super(w);
-	}
-
-	@Override
-	public boolean isWorldCompatible(World world) {
-		return world instanceof BatWorld;
-	}
-
-	@Override
-	public void paintComponent(Graphics g) {
-
-		super.paintComponent(g);
-
-		Graphics2D g2 = (Graphics2D) g;
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setColor(Color.white);
-		g2.fill(new Rectangle2D.Double(0.,0.,(double)getWidth(),(double)getHeight()));
-
-		List<BatTest> tests = ((BatWorld) world).getTests();
-		boolean foundError=false;
-		for (int i=0;i<tests.size();i++) {
-			BatTest currTest = tests.get(i);
-			if (!currTest.isVisible() && foundError) 
-				break;
-
-			if (currTest.isObjective()) {
-				if (currTest.isVisible()) 
-					g2.setColor(Color.black);
-				else 
-					g2.setColor(Color.white);
-			} else {
-				if (currTest.isAnswered()) {
-
-					if (currTest.isCorrect()) 
-						g2.setColor(Color.blue);
-					else { 
-						g2.setColor(Color.red);
-						foundError = true;
-					}
-				} else {
-					if (currTest.isVisible()) 
-						g2.setColor(Color.black);
-					else 
-						g2.setColor(Color.white);						
-				}
-			}
-			g2.drawString(currTest.getName()+"="+currTest.getResult()
-					+(currTest.isAnswered() && !currTest.isCorrect() ?" (expected: "+currTest.expected+")":"")
-					, 0, (i+1)*20);
-		}
-
-	}
-}
diff --git a/src/jlm/universe/bat/package-info.java b/src/jlm/universe/bat/package-info.java
deleted file mode 100644
index 1e6c26c..0000000
--- a/src/jlm/universe/bat/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Universe aiming at exercising tactical programming through simple exercises imported from JavaBat.
- */
-package jlm.universe.bat;
diff --git a/src/jlm/universe/bugglequest/AbstractBuggle.java b/src/jlm/universe/bugglequest/AbstractBuggle.java
deleted file mode 100644
index 488067b..0000000
--- a/src/jlm/universe/bugglequest/AbstractBuggle.java
+++ /dev/null
@@ -1,446 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-import java.awt.Point;
-
-import jlm.core.model.Game;
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.GridWorld;
-import jlm.universe.World;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-import jlm.universe.bugglequest.exception.BuggleInOuterSpaceException;
-import jlm.universe.bugglequest.exception.BuggleWallException;
-import jlm.universe.bugglequest.exception.NoBaggleUnderBuggleException;
-
-public abstract class AbstractBuggle extends Entity {
-	int k_val = 0;
-	int[] k_seq = {0,0, 1,1, 2,3, 2,3, 4,5};
-	
-	Color color;
-	
-	Color brushColor;
-
-	private int x;
-	private int y;
-
-	Direction direction;
-
-	boolean brushDown;
-
-	private Baggle baggle;
-
-	/* This is for the simple buggle to indicate that it did hit a wall, and is thus not a valid
-	 * candidate for exercise completion.
-	 */
-	private boolean seenError = false;
-	public void seenError() {
-		this.seenError = true;
-	}
-	public void seenError(String msg) {
-		System.err.println(msg);
-		this.seenError = true;
-	}
-	public boolean haveSeenError() {
-		return seenError;
-	}	
-	
-	/**
-	 * Constructor with no argument so that child classes can avoid declaring a
-	 * constructor. But it should not be used as most methods assert on world
-	 * being not null. After using it, {@link Entity#setWorld(BuggleWorld)} must be used
-	 * ASAP.
-	 */
-	public AbstractBuggle() {
-		this(null, "John Doe", 0, 0, Direction.NORTH, Color.red, Color.red);
-	}
-
-	public AbstractBuggle(BuggleWorld w) {
-		this(w, "John Doe", 0, 0, Direction.NORTH, Color.red, Color.red);
-	}
-
-	public AbstractBuggle(BuggleWorld world, String name, int x, int y, Direction direction, Color c) {
-		this(world, name, 0, 0, Direction.NORTH, c, c);
-	}
-
-	public AbstractBuggle(World world, String name, int x, int y, Direction direction, Color color, Color brushColor) {
-		super(name,world);
-		this.color = color;
-		this.brushColor = brushColor;
-		this.x = x;
-		this.y = y;
-		this.direction = direction;
-	}
-	@Override
-	public void copy(Entity e) {
-		super.copy(e);
-		AbstractBuggle other = (AbstractBuggle)e;
-		this.color = other.color;
-		this.brushColor = other.brushColor;
-		this.x = other.x;
-		this.y = other.y;
-		this.direction = other.direction;
-	}
-	@Override
-	public Entity copy() {
-		return new Buggle(this);
-	}
-
-	public boolean isBrushDown() {
-		return brushDown;
-	}
-
-	public void brushDown() {
-		this.brushDown = true;
-		BuggleWorldCell cell = (BuggleWorldCell) ((BuggleWorld)world).getCell(x, y);
-		cell.setColor(brushColor);
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public void brushUp() {
-		if (k_seq[k_val]==4) k_val++; else k_val = 0;
-		this.brushDown = false;
-	}
-
-	public Color getGroundColor() {
-		return getCell().getColor();
-	}
-
-	public Color getBrushColor() {
-		return brushColor;
-	}
-
-	public void setBrushColor(Color c) {
-		if (c != null)
-			brushColor = c;
-	}
-
-	public Color getColor() {
-		return color;
-	}
-
-	public void setColor(Color c) {
-		if (c != null) {
-			this.color = c;
-			world.notifyWorldUpdatesListeners();
-		}
-	}
-
-	public Direction getDirection() {
-		return direction;
-	}
-
-	public void setDirection(Direction direction) {
-		if (direction != null) {
-			this.direction = direction;
-			stepUI();
-		}
-	}
-
-	public void turnLeft() {
-		if (k_seq[k_val]==2) k_val++; else k_val = 0;
-		setDirection(direction.left());
-	}
-
-	public void turnRight() {
-		if (k_seq[k_val]==3) k_val++; else k_val = 0;
-		setDirection(direction.right());
-	}
-
-	public void turnBack() {
-		setDirection(direction.opposite());
-	}
-	
-	public int getWorldHeight() {
-		return ((GridWorld) world).getHeight();
-	}
-	
-	public int getWorldWidth() {
-		return ((GridWorld) world).getWidth();
-	}
-	protected BuggleWorldCell getCell(){
-		return (BuggleWorldCell) ((GridWorld)world).getCell(x, y);
-	}
-	protected BuggleWorldCell getCell(int u, int v) throws BuggleInOuterSpaceException{
-		BuggleWorld bw = (BuggleWorld) world;
-		if (y>=bw.getHeight())
-			throw new BuggleInOuterSpaceException("You tried to access a cell with Y="+y+", but the maximal Y in this world is "+(bw.getHeight()-1));
-		if (x>=bw.getWidth())
-			throw new BuggleInOuterSpaceException("You tried to access a cell with X="+x+", but the maximal X in this world is "+(bw.getWidth()-1));
-
-		return (BuggleWorldCell) ((GridWorld)world).getCell(u, v);
-	}
-	protected BuggleWorldCell getCellFromLesson(int u, int v) {
-		try {
-			return getCell(u,v);
-		} catch (BuggleInOuterSpaceException e) {
-			throw new RuntimeException("Broken lesson: you accessed a cell in outer space",e);
-		}
-	}
-
-	public int getX() {
-		return x;
-	}
-
-	public void setX(int x) throws BuggleInOuterSpaceException {
-		BuggleWorld bw = (BuggleWorld) world;
-		if (x>=bw.getWidth())
-			throw new BuggleInOuterSpaceException("You tried to set X to "+x+", but the maximal X in this world is "+(bw.getWidth()-1));
-		this.x = x;
-		stepUI();
-	}
-	public void setXFromLesson(int x)  {
-		try {
-			setX(x);
-		} catch (BuggleInOuterSpaceException e) {
-			throw new RuntimeException("Broken lesson: you moved to outer space",e);
-		}
-	}
-
-	public int getY() {
-		return y;
-	}
-
-	public void setY(int y) throws BuggleInOuterSpaceException  {
-		BuggleWorld bw = (BuggleWorld) world;
-		if (y>=bw.getHeight())
-			throw new BuggleInOuterSpaceException("You tried to set Y to "+y+", but the maximal Y in this world is "+(bw.getHeight()-1));
-		this.y = y;
-		stepUI();
-	}
-	public void setYFromLesson(int y)  {
-		try {
-			setY(y);
-		} catch (BuggleInOuterSpaceException e) {
-			throw new RuntimeException("Broken lesson: you moved to outer space",e);
-		}
-	}
-
-	public void setPos(int x, int y) throws BuggleInOuterSpaceException {
-		BuggleWorld bw = (BuggleWorld) world;
-		if (y>=bw.getHeight())
-			throw new BuggleInOuterSpaceException("You tried to set Y to "+y+", but the maximal Y in this world is "+(bw.getHeight()-1));
-		if (x>=bw.getWidth())
-			throw new BuggleInOuterSpaceException("You tried to set X to "+x+", but the maximal X in this world is "+(bw.getWidth()-1));
-		this.x = x;
-		this.y = y;
-		stepUI();
-	}
-	public void setPosFromLesson(int x, int y)  {
-		try {
-			setPos(x,y);
-		} catch (BuggleInOuterSpaceException e) {
-			throw new RuntimeException("Broken lesson: you moved to outer space",e);
-		}
-	}
-
-	public void forward() throws BuggleWallException {
-		if (k_seq[k_val]==0) k_val++; else k_val = 0;
-		move(direction.toPoint());
-	}
-
-	public void forward(int count) throws BuggleWallException {
-		for (int i = 0; i < count; i++)
-			forward();
-	}
-
-	public void backward() throws BuggleWallException {
-		if (k_seq[k_val]==1) k_val++; else k_val = 0;
-		move(direction.opposite().toPoint());
-	}
-
-	public void backward(int count) throws BuggleWallException {
-		for (int i = 0; i < count; i++)
-			backward();
-	}
-
-	private boolean lookAtWall(boolean forward) {
-		Direction delta;
-		if (forward)
-			delta = getDirection();
-		else
-			delta = getDirection().opposite();
-
-		BuggleWorldCell cell;
-		switch (delta.intValue()) {
-		case Direction.NORTH_VALUE: /* looking up is easy */
-			cell = getCell();
-			return cell.hasTopWall();
-
-		case Direction.WEST_VALUE: /* looking to the left also */
-			cell = getCell();
-			return cell.hasLeftWall();
-
-		case Direction.SOUTH_VALUE: /* if looking down, look to the top of one cell lower */
-			cell = getCellFromLesson(getX(),                        (getY()+1) % getWorldHeight());
-			return cell.hasTopWall();
-
-		case Direction.EAST_VALUE: /* if looking right, look to the left of one next cell */
-			cell = getCellFromLesson((getX()+1) % getWorldWidth(), getY());
-			return cell.hasLeftWall();
-
-		default: throw new RuntimeException("Invalid direction: "+delta);
-		}
-	}
-	public boolean isFacingWall() {
-		return lookAtWall(true);
-	}
-	public boolean isBackingWall() {
-		return lookAtWall(false);
-	}
-
-	private void move(Point delta) throws BuggleWallException {
-		if (delta == null)
-			return;
-		
-		int newx = (x + delta.x) % getWorldWidth();
-		if (newx < 0)
-			newx += getWorldWidth();
-		int newy = (y + delta.y) % getWorldHeight();
-		if (newy < 0)
-			newy += getWorldHeight();
-
-		if (delta.equals(direction.toPoint())            && isFacingWall() ||
-				delta.equals(direction.opposite().toPoint()) && isBackingWall())	
-
-			throw new BuggleWallException();
-
-		x = newx;
-		y = newy;
-
-		if (brushDown) {
-			getCell().setColor(brushColor);
-		}
-
-		stepUI();
-	}
-
-	public boolean isOverBaggle() {
-		return getCellFromLesson(this.x, this.y).hasBaggle();
-	}
-
-	public boolean isCarryingBaggle() {
-		return this.baggle != null;
-	}
-
-	@Deprecated
-	public void pickUpBaggle() throws NoBaggleUnderBuggleException, AlreadyHaveBaggleException {
-		pickupBaggle();
-	}
-	public void pickupBaggle() throws NoBaggleUnderBuggleException, AlreadyHaveBaggleException {
-		if (k_seq[k_val]==5) k_val++; else k_val = 0;
-		if (k_val>k_seq.length-1) {
-			setName("Easter "+name);
-			System.out.println("EASTEEEER");
-			((BuggleWorld)world).easter= true;
-			k_val=0;
-			return;
-		}
-
-		if (!isOverBaggle())
-			throw new NoBaggleUnderBuggleException("There is no baggle to pick up");
-		if (isCarryingBaggle())
-			throw new AlreadyHaveBaggleException("Your buggle is already carrying a baggle");
-		baggle = getCellFromLesson(this.x, this.y).pickupBaggle();
-	}
-
-	public void dropBaggle() throws AlreadyHaveBaggleException {
-		getCellFromLesson(this.x, this.y).setBaggle(this.baggle);
-		baggle = null;
-	}
-
-	public boolean isOverMessage() {
-		return getCell().hasContent();
-	}
-
-	public void writeMessage(String msg) {
-		getCell().addContent(msg);
-	}
-	public void writeMessage(int nb) {
-		writeMessage(""+nb);
-	}
-
-	public String readMessage() {
-		return getCell().getContent();
-	}
-
-	public void clearMessage() {
-		getCell().emptyContent();
-	}
-
-
-
-	@Override
-	public String toString() {
-		return "Buggle (" + this.getClass().getName() + "): x=" + x + " y=" + y + " Direction:" + direction + " Color:"
-		+ color;
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((brushColor == null) ? 0 : brushColor.hashCode());
-		result = PRIME * result + (brushDown ? 1231 : 1237);
-		result = PRIME * result + ((color == null) ? 0 : color.hashCode());
-		result = PRIME * result + ((direction == null) ? 0 : direction.hashCode());
-		result = PRIME * result + x;
-		result = PRIME * result + y;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (!(obj instanceof AbstractBuggle))
-			return false;
-		
-		final AbstractBuggle other = (AbstractBuggle) obj;
-		if (color == null) {
-			if (other.color != null)
-				return false;
-		} else if (!color.equals(other.color))
-			return false;
-		if (direction == null) {
-			if (other.direction != null)
-				return false;
-		} else if (!direction.equals(other.direction))
-			return false;
-		if (seenError != other.seenError)
-			return false;
-		if (x != other.x)
-			return false;
-		if (y != other.y)
-			return false;
-		return true;
-	}
-	public String diffTo(AbstractBuggle other) {
-		if (other == null) 
-			return Game.i18n.tr("Its value is 'null', which is never good.");
-		/* We cannot use a i18n defined in our class, as we have to pass the classname to the initialization of i18n, 
-		 *    but gettext don't seem to like the fact that we generate at runtime some package names that it does not know at compile time.
-		 * So, use Game.i18n instead.
-		 */
-		StringBuffer sb = new StringBuffer();
-		if (getX() != other.getX() || getY() != other.getY()) 
-			sb.append(Game.i18n.tr("    Its position is ({0},{1}); expected: ({2},{3}).\n",other.getX(),other.getY(),getX(),getY()));
-		if (getDirection() != other.getDirection()) 
-			sb.append(Game.i18n.tr("    Its direction is {0}; expected: {1}.\n",other.getDirection(),getDirection()));
-		if (getColor() != other.getColor()) 
-			sb.append(Game.i18n.tr("    Its color is {0}; expected: {1}.\n",other.getColor(),getColor()));
-		if (getBrushColor() != other.getBrushColor())
-			sb.append(Game.i18n.tr("    The color of its brush is {0}; expected: {1}.\n",other.getBrushColor(),getBrushColor()));
-		if (isCarryingBaggle() && !other.isCarryingBaggle())
-			sb.append(Game.i18n.tr("    It should not carry that baggle.\n"));
-		if (!isCarryingBaggle() && other.isCarryingBaggle())
-			sb.append(Game.i18n.tr("    It is not carrying any baggle.\n"));
-		if (haveSeenError() && !other.haveSeenError())
-			sb.append(Game.i18n.tr("    It encountered an issue, such as bumping into a wall.\n"));
-		if (!haveSeenError() && other.haveSeenError())
-			sb.append(Game.i18n.tr("    It didn't encounter any issue, such as bumping into a wall.\n"));
-		return sb.toString();
-	}
-}
diff --git a/src/jlm/universe/bugglequest/Baggle.java b/src/jlm/universe/bugglequest/Baggle.java
deleted file mode 100644
index 5ed0184..0000000
--- a/src/jlm/universe/bugglequest/Baggle.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-
-public class Baggle {
-
-	private Color color;
-	private BuggleWorldCell cell;
-
-	public static final Color DEFAULT_COLOR = new Color(0.82f,0.41f,0.12f);
-	
-	
-	public Baggle(BuggleWorldCell c) {
-		this(c, DEFAULT_COLOR);
-	}
-
-	public Baggle(BuggleWorldCell cell, Color c) {
-		this.cell = cell;
-		this.color = c;
-	}
-	
-	public Baggle(Baggle b) {
-		this.color = b.color;
-		this.cell = b.cell;
-	}
-	
-	public void setCell(BuggleWorldCell c) {
-		this.cell = c;
-	}
-		
-	@Override
-	public String toString() {
-		return "Baggle ("+this.getClass().getName()+"): Color:" + color;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((color == null) ? 0 : color.hashCode());
-		//result = prime * result + ((cell == null) ? 0 : cell.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		Baggle other = (Baggle) obj;
-		if (color == null) {
-			if (other.color != null)
-				return false;
-		} else if (!color.equals(other.color))
-			return false;
-//		if (cell == null) {
-//			if (other.cell != null)
-//				return false;
-//		} //else if (!cell.equals(other.cell))
-		//	return false;
-		return true;
-	}
-
-	
-
-}
diff --git a/src/jlm/universe/bugglequest/Buggle.java b/src/jlm/universe/bugglequest/Buggle.java
deleted file mode 100644
index ae68480..0000000
--- a/src/jlm/universe/bugglequest/Buggle.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-
-import jlm.universe.Direction;
-
-
-public final class Buggle extends AbstractBuggle {
-
-	public Buggle(AbstractBuggle b){
-		super();
-		setWorld(b.getWorld());
-		setName(b.getName());
-		setColor(b.color);
-		setBrushColor(b.brushColor);
-		setPosFromLesson(b.getX(), b.getY());
-		setDirection(b.direction);
-		brushDown = b.brushDown;
-	}
-
-	public Buggle(BuggleWorld world, String name, int i, int j, Direction north, Color color, Color brush) {
-		super(world, name, i, j, north, color, brush);
-	}
-
-	public Buggle(BuggleWorld world) {
-		super(world);
-	}
-
-	@Override
-	public void run() {
-		// nothing by default
-	}
-}
diff --git a/src/jlm/universe/bugglequest/BuggleWorld.fr.html b/src/jlm/universe/bugglequest/BuggleWorld.fr.html
deleted file mode 100644
index 0c8de7a..0000000
--- a/src/jlm/universe/bugglequest/BuggleWorld.fr.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<h1>Le monde des Buggles</h1>
-Ce monde a été inventé par Lyn Turbak, du Wellesley College. Il est peuplé
-de Buggles, petites bêtes qui comprennent des ordres simples, et offre de
-nombreuses possibilités d'interaction avec le monde: prendre ou poser des
-objets, colorier le sol, se cogner à des murs, etc.
-
-<h2>Méthodes comprises par les buggles</h2>
-<table border=1>
-<tr><td colspan=2 align=center><b>Bouger</b><br/> (voir aussi la note sur les exceptions, plus bas)</td></tr>
-  <tr><td><b>Tourner à gauche<br/>Tourner à droite<br/>Se retourner<br/>Avancer<br/>Reculer</b></td>
-      <td><div class="Java">void turnLeft()</div><div class="python">turnLeft()</div>
-          <div class="Java">void turnRight()</div><div class="python">turnRight()</div>
-          <div class="Java">void turnBack()</div><div class="python">turnBack()</div>
-          <div class="Java">void forward() ou void forward(nbPas)</div><div class="python">forward() ou forward(nbPas)</div>
-          <div class="Java">void backward() ou void backward(nbPas)</div><div class="python">backward() ou backward(nbPas)</div></td></tr>
-  <tr><td><b>Obtenir l'abcisse<br/>Obtenir l'ordonnée<br/>Changer l'abcisse<br/>Changer l'ordonnée<br/>Changer la position</b></td>
-      <td><div class="Java">int getX()</div><div class="python">getX()</div>
-          <div class="Java">int getY()</div><div class="python">getY()</div>
-          <div class="Java">void setX(int x)</div><div class="python">setX(x)</div>
-          <div class="Java">void setY(int y)</div><div class="python">setY(y)</div>
-          <div class="Java">void setPos(int x,int y)</div><div class="python">setPos(x,y)</div></td></tr>
-
-<tr><td colspan=2 align=center><b>Informations sur la buggle</b></td></tr>
-  <tr><td><b>Obtenir la couleur<br/>Changer la couleur</b></td>
-      <td><div class="Java">Color getColor()</div><div class="python">getColor()</div>
-          <div class="Java">void setColor(Color c)</div><div class="python">setColor(color)</div></td></tr>				
-  <tr><td><b>Chercher un mur devant<br/>Chercher un mur derriere</b></td>
-      <td><div class="Java">boolean isFacingWall()</div><div class="python">isFacingWall()</div>
-          <div class="Java">boolean isBackingWall()</div><div class="python">isBackingWall()</div></td></tr>				
-  <tr><td><b>Obtenir la direction<br/>Changer la direction</b><br/>Les directions valides sont :</td>
-      <td><div class="Java">Direction getDirection()</div><div class="python">getDirection()</div>
-          <div class="Java">void setDirection(Direction dir)</div><div class="python">setDirection(direction)</div>
-          Direction.NORTH, Direction.EAST, Direction.SOUTH et Direction.WEST</td></tr>
-  <tr><td>Renvoi si la buggle est actuellement <b>sélectionnée dans l'interface</b></td>
-      <td><div class="Java">boolean isSelected()</div><div class="python">isSelected()</div></td></tr>
- 
-<tr><td colspan=2 align=center><b>À propos de la brosse</b></td></tr>
-  <tr><td><b>Baisser la brosse<br/>Lever la brosse<br/>Obtenir la position de la brosse</b></td>
-      <td><div class="Java">void brushUp()</div><div class="python">brushUp()</div>
-          <div class="Java">void brushDown()</div><div class="python">brushDown()</div>
-          <div class="Java">boolean isBrushDown()</div><div class="python">isBrushDown()</div></td></tr>
-  <tr><td><b>Modifier la couleur de la brosse<br/>Obtenir la couleur de la brosse</b></td>
-      <td><div class="Java">void setBrushColor(Color c)</div><div class="python">setBrushColor(color)</div>
-          <div class="Java">Color getBrushColor()</div><div class="python">getBrushColor()</div></td></tr>
-
-<tr><td colspan=2 align=center><b>Interagir avec le monde</b></td></tr>
-  <tr><td><b>Obtenir la couleur du sol</b></td>
-      <td><div class="Java">Color getGroundColor()</div><div class="python">getGroundColor()</div></td></tr>
-
-  <tr><td><b>Chercher un baggle par terre<br/>Chercher un baggle dans ses poches<br/>Prendre un baggle<br/>Poser un baggle</b><br/>
-      (voir la note sur les exceptions)</td>
-      <td><div class="Java">boolean isOverBaggle()</div><div class="python">isOverBaggle()</div>
-          <div class="Java">boolean isCarryingBaggle()</div><div class="python">isCarryingBaggle()</div>
-          <div class="Java">void pickupBaggle()</div><div class="python">pickupBaggle()</div>
-          <div class="Java">void dropBaggle()</div><div class="python">dropBaggle()</div></td></tr>
-
-  <tr><td><b>Chercher un message<br/>Ajouter un message<br/>Lire le message<br/>Effacer le message</b></td>
-      <td><div class="Java">boolean isOverMessage()</div><div class="python">isOverMessage()</div>
-          <div class="Java">void writeMessage(String msg)</div><div class="python">writeMessage(msg)</div>
-          <div class="Java">String readMessage()</div><div class="python">readMessage()</div>
-          <div class="Java">void clearMessage()</div><div class="python">clearMessage()</div></td></tr>
-</table>
-
-<h2>Note sur les exceptions</h2>
-Les buggles normales lèvent une exception BuggleWallException si on cherche
-à leur faire traverser un mur.
-Elles lèvent une exception NoBaggleUnderBuggleException si vous cherchez à
-prendre un baggle dans une case qui n'en contient pas, ou une exception
-AlreadyHaveBaggleException si vous portez déjà un baggel.
-Tenter de déposer un baggel sur une case qui en contient déjà lève une
-exception AlreadyHaveBaggleException.
-<p>Les "SimpleBuggles" (ie, celles utilisées dans les premiers exercices)
-affiche un message d'erreur sans que vous ayez à vous soucier de ce qu'est
-une exception.</p>
diff --git a/src/jlm/universe/bugglequest/BuggleWorld.html b/src/jlm/universe/bugglequest/BuggleWorld.html
deleted file mode 100644
index af653f0..0000000
--- a/src/jlm/universe/bugglequest/BuggleWorld.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<h1>BuggleWorld</h1>
-This world was invented by Lyn Turbak, at Wellesley College. It is full of
-Buggles, little animals understanding simple orders, and offers numerous
-possibilities of interaction with the world: taking or dropping objects,
-paint the ground, hit walls, etc.
-
-<h2>Methods understood by buggles</h2>
-<table border=1>
-<tr><td colspan=2 align=center><b>Moving</b><br/> (See also the note on exceptions, below)</td></tr>
-  <tr><td><b>Turn left<br/>Turn right<br/>Turn back<br/>Moving forward<br/>Moving back</b></td>
-      <td><div class="Java">void turnLeft()</div><div class="python">turnLeft()</div>
-          <div class="Java">void turnRight()</div><div class="python">turnRight()</div>
-          <div class="Java">void turnBack()</div><div class="python">turnBack()</div>
-          <div class="Java">void forward() or void forward(int steps)</div><div class="python">forward() or forward(steps)</div>
-          <div class="Java">void backward() or void backward(int steps)</div><div class="python">backward() or backward(steps)</div></td></tr>
-  <tr><td><b>Get X coordinate<br/>Get Y coordinate<br/>Set X coordinate<br/>Set Y coordinate<br/>Set position</b></td>
-      <td><div class="Java">int getX()</div><div class="python">getX()</div>
-          <div class="Java">int getY()</div><div class="python">getY()</div>
-          <div class="Java">void setX(int x)</div><div class="python">setX(x)</div>
-          <div class="Java">void setY(int y)</div><div class="python">setY(y)</div>
-          <div class="Java">void setPos(int x,int y)</div><div class="python">setPos(x,y)</div></td></tr>
-
-<tr><td colspan=2 align=center><b>Information on the buggle</b></td></tr>
-  <tr><td><b>Get the color<br/>Set the color</b></td>
-      <td><div class="Java">Color getColor()</div><div class="python">getColor()</div>
-          <div class="Java">void setColor(Color c)</div><div class="python">setColor(color)</div></td></tr>				
-  <tr><td><b>Look for a wall forward<br/>Look for a wall backward</b></td>
-      <td><div class="Java">boolean isFacingWall()</div><div class="python">isFacingWall()</div>
-          <div class="Java">boolean isBackingWall()</div><div class="python">isBackingWall()</div></td></tr>				
-  <tr><td><b>Get heading<br/>Set heading</b><br/>valid directions are:</td>
-      <td><div class="Java">Direction getDirection()</div><div class="python">getDirection()</div>
-          <div class="Java">void setDirection(Direction dir)</div><div class="python">setDirection(direction)</div>
-          Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST</td></tr>
-  <tr><td>Check whether the buggle is currently <b>selected in the interface</b></td>
-      <td><div class="Java">boolean isSelected()</div><div class="python">isSelected()</div></td></tr>
- 
-<tr><td colspan=2 align=center><b>About the brush</b></td></tr>
-  <tr><td><b>Brush down<br/>Brush up<br/>Get brush position</b></td>
-      <td><div class="Java">void brushUp()</div><div class="python">brushUp()</div>
-          <div class="Java">void brushDown()</div><div class="python">brushDown()</div>
-          <div class="Java">boolean isBrushDown()</div><div class="python">isBrushDown()</div></td></tr>
-  <tr><td><b>Change the brush color<br/>Get the color of the brush</b></td>
-      <td><div class="Java">void setBrushColor(Color c)</div><div class="python">setBrushColor(color)</div>
-          <div class="Java">Color getBrushColor()</div><div class="python">getBrushColor()</div></td></tr>
-
-<tr><td colspan=2 align=center><b>Interacting with the world</b></td></tr>
-  <tr><td><b>Get the color of the ground</b></td>
-      <td><div class="Java">Color getGroundColor()</div><div class="python">getGroundColor()</div></td></tr>
-
-  <tr><td><b>Look for a baggle on the ground<br/>Look for a baggle in bag<br/>Pickup a baggle<br/>Drop a baggle</b><br/>
-      (see the note on exceptions)</td>
-      <td><div class="Java">boolean isOverBaggle()</div><div class="python">isOverBaggle()</div>
-          <div class="Java">boolean isCarryingBaggle()</div><div class="python">isCarryingBaggle()</div>
-          <div class="Java">void pickupBaggle()</div><div class="python">pickupBaggle()</div>
-          <div class="Java">void dropBaggle()</div><div class="python">dropBaggle()</div></td></tr>
-
-  <tr><td><b>Look for a message<br/>Add a message<br/>Read the message<br/>Erase the message</b></td>
-      <td><div class="Java">boolean isOverMessage()</div><div class="python">isOverMessage()</div>
-          <div class="Java">void writeMessage(String msg)</div><div class="python">writeMessage(msg)</div>
-          <div class="Java">String readMessage()</div><div class="python">readMessage()</div>
-          <div class="Java">void clearMessage()</div><div class="python">clearMessage()</div></td></tr>
-</table>
-
-<h2>Note on exceptions</h2>
-Regular buggles throw a BuggleWallException exception if you ask them to
-traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you
-ask them to pickup a baggle from an empty cell, or a
-AlreadyHaveBaggleException exception if they already carry a baggle.  Trying
-to drop a baggle on a cell already containing one throws an
-AlreadyHaveBaggleException exception.
-<p>SimpleBuggles (ie, the one used in first exercises) display an error message
-on problem so that you don't need to know what an exception is.</p>
diff --git a/src/jlm/universe/bugglequest/BuggleWorld.java b/src/jlm/universe/bugglequest/BuggleWorld.java
deleted file mode 100644
index 322deda..0000000
--- a/src/jlm/universe/bugglequest/BuggleWorld.java
+++ /dev/null
@@ -1,493 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.utils.ColorMapper;
-import jlm.core.utils.FileUtils;
-import jlm.core.utils.InvalidColorNameException;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.GridWorld;
-import jlm.universe.GridWorldCell;
-import jlm.universe.World;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-import jlm.universe.bugglequest.ui.BuggleButtonPanel;
-import jlm.universe.bugglequest.ui.BuggleWorldView;
-
-
-public class BuggleWorld extends GridWorld {
-
-	public BuggleWorld(String name, int x, int y) {
-		super(name,x,y);
-	}
-	@Override
-	protected GridWorldCell newCell(int x, int y) {
-		return new BuggleWorldCell(this, x, y);
-	}
-	/** 
-	 * Create a new world being almost a copy of the first one. Beware, all the buggles of the copy are changed to BuggleRaw. 
-	 * @param world2
-	 */
-	public BuggleWorld(BuggleWorld world2) {
-		super(world2);
-	}
-
-	/**
-	 * Reset the content of a world to be the same than the one passed as argument
-	 * does not affect the name of the initial world.
-	 */
-	@Override
-	public void reset(World iw) {
-		BuggleWorld initialWorld = (BuggleWorld)iw;
-		for (int i = 0; i < sizeX; i++)
-			for (int j = 0; j < sizeY; j++) {
-				BuggleWorldCell c = (BuggleWorldCell) initialWorld.getCell(i, j);
-				cells[i][j] = new BuggleWorldCell(c, this);
-			}
-		easter=false;
-
-		super.reset(initialWorld);
-	}	
-	@Override
-	public void setWidth(int w) {
-		super.setWidth(w);
-		if (selectedCell != null && selectedCell.getX()>=w)
-			selectedCell = null;
-		for (int i=0; i<entities.size();i++) {
-			AbstractBuggle b = (AbstractBuggle) entities.get(i);
-			if (b.getX()>w)
-				entities.remove(i--); // -- to counter the effect of ++ at the  end of body loop
-		}
-	}
-	@Override
-	public void setHeight(int h) {
-		super.setHeight(h);
-		if (selectedCell != null && selectedCell.getY()>=h)
-			selectedCell = null;
-		for (int i=0; i<entities.size();i++) {
-			AbstractBuggle b = (AbstractBuggle) entities.get(i);
-			if (b.getY()>h)
-				entities.remove(i--); // -- to counter the effect of ++ at the  end of body loop
-		}
-	}
-
-	@Override
-	public BuggleWorldView getView() {
-		return new BuggleWorldView(this);
-	}
-	@Override
-	public EntityControlPanel getEntityControlPanel() {
-		return new BuggleButtonPanel();
-	}
-	@Override
-	public ImageIcon getIcon() {
-		return ResourcesCache.getIcon("img/world_buggle.png");
-	}
-
-	public boolean easter = false;
-	/* IO related */
-	@Override
-	public boolean haveIO() {
-		return true;
-	}
-	public static World newFromFile(String path) throws IOException, BrokenWorldFileException {
-		BuggleWorld res = new BuggleWorld("toto", 1, 1);
-		return res.readFromFile(path);
-	}
-	@Override
-	public World readFromFile(String path) throws IOException, BrokenWorldFileException {
-		BuggleWorld res = new BuggleWorld("toto", 1, 1);
-
-		return readFromFile(path,"BuggleWorld",res);
-	}
-	
-	public World readFromFile(String path, String classname, BuggleWorld res) throws IOException, BrokenWorldFileException {
-		String name;
-		BufferedReader reader = FileUtils.newFileReader(path, "map", false);
-		
-		/* Get the world name from the first line */
-		String line = reader.readLine();
-		if (line == null)
-			throw new BrokenWorldFileException(Game.i18n.tr(
-					"{0}.map: this file does not seem to be a serialized BuggleWorld (the file is empty!)",path));
-		
-		Pattern p = Pattern.compile("^"+classname+": ");
-		Matcher m = p.matcher(line);
-		if (!m.find())
-			throw new RuntimeException(Game.i18n.tr(
-					"{0}.map: This file does not seem to be a serialized BuggleWorld (malformated first line: {1})", path, line));
-		name = m.replaceAll("");
-		
-		/* Get the dimension from the second line that is eg "Size: 20x20" */
-		line = reader.readLine();
-		if (line == null)
-			throw new RuntimeException(Game.i18n.tr("" +
-					"{0}.map: End of file reached before world size specification",path));
-		p = Pattern.compile("^Size: (\\d+)x(\\d+)$");
-		m = p.matcher(line);
-		if (!m.find()) 
-			throw new RuntimeException(Game.i18n.tr("{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''", line));
-		int width = Integer.parseInt(m.group(1)); 
-		int height = Integer.parseInt(m.group(2));
-
-		res.setName(name);
-		res.setWidth(width);
-		res.setHeight(height);
-		
-		line = reader.readLine();
-		
-		Pattern bugglePattern = Pattern.compile("^Buggle\\((\\d+),(\\d+)\\): (\\w+),([^,]+),([^,]+),(.+)$"); // direction, color, brush, name
-		Matcher buggleMatcher = bugglePattern.matcher(line);
-		String cellFmt = "^Cell\\((\\d+),(\\d+)\\): ([^,]+?),(\\w+),(\\w+),(\\w+),(.*)$";
-		Pattern cellPattern = Pattern.compile(cellFmt);
-		Matcher cellMatcher = cellPattern.matcher(line);
-
-		do {
-			cellMatcher = cellPattern.matcher(line);
-			buggleMatcher = bugglePattern.matcher(line);
-
-			if (buggleMatcher.matches()) { 
-				int x=Integer.parseInt( buggleMatcher.group(1) );
-				int y=Integer.parseInt( buggleMatcher.group(2) );
-
-				if (x<0 || x > width || y<0 || y>height)
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Cannot put a buggle on coordinate {0},{1}: that''s out of the world",x,y));
-
-				String dirName = buggleMatcher.group(3);
-				Direction direction;
-				if (dirName.equalsIgnoreCase("north"))
-					direction = Direction.NORTH;
-				else if (dirName.equalsIgnoreCase("south"))
-					direction = Direction.SOUTH;
-				else if (dirName.equalsIgnoreCase("east"))
-					direction = Direction.EAST;
-				else if (dirName.equalsIgnoreCase("west"))
-					direction = Direction.WEST;
-				else 
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Invalid buggle''s direction: {0}", buggleMatcher.group(3)));
-
-				Color color;
-				try {
-					color = ColorMapper.name2color( buggleMatcher.group(4));
-				} catch (InvalidColorNameException e) {
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Invalid buggle''s color name: {0}", buggleMatcher.group(4)));
-				}
-				Color brushColor;
-				try {
-					brushColor = ColorMapper.name2color( buggleMatcher.group(5));
-				} catch (InvalidColorNameException e) {
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Invalid buggle''s color name: {0}", buggleMatcher.group(5)));
-				}
-				String buggleName = buggleMatcher.group(6);
-
-				new Buggle(res, buggleName, x, y, direction, color, brushColor);
-			} else if (cellMatcher.matches()) {
-				/* Get the info */
-				int x=Integer.parseInt( cellMatcher.group(1) );
-				int y=Integer.parseInt( cellMatcher.group(2) );
-
-				if (x<0 || x > width || y<0 || y>height)
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Cannot define a cell on coordinate {0},{1}: that''s out of the world",x,y));
-
-
-				String colorName = cellMatcher.group(3);
-				Color color;
-				String baggleFlag = cellMatcher.group(4);
-				String topWallFlag = cellMatcher.group(5);
-				String leftWallFlag = cellMatcher.group(6);
-				String content = cellMatcher.group(7);
-
-				try {
-					color = ColorMapper.name2color(colorName);
-				} catch (InvalidColorNameException e) {
-					throw new BrokenWorldFileException(Game.i18n.tr("Invalid color name: {0}",colorName));
-				}
-
-				/* Make sure that this info makes sense */
-				if (!baggleFlag.equalsIgnoreCase("baggle") && !baggleFlag.equalsIgnoreCase("nobaggle"))
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Expecting ''baggle'' or ''nobaggle'' but got {0} instead",baggleFlag));
-
-				if (!topWallFlag.equalsIgnoreCase("topwall") && !topWallFlag.equalsIgnoreCase("notopwall"))
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Expecting ''topwall'' or ''notopwall'' but got {0} instead",topWallFlag));
-
-				if (!leftWallFlag.equalsIgnoreCase("leftwall") && !leftWallFlag.equalsIgnoreCase("noleftwall"))
-					throw new BrokenWorldFileException(Game.i18n.tr(
-							"Expecting ''leftwall'' or ''noleftwall'' but got {0} instead",leftWallFlag));
-
-				/* Use the info */
-				BuggleWorldCell cell = new BuggleWorldCell(res, x, y);
-
-				if (baggleFlag.equalsIgnoreCase("baggle"))
-					try {
-						cell.setBaggle(new Baggle(cell));
-					} catch (AlreadyHaveBaggleException e) {
-						throw new BrokenWorldFileException(Game.i18n.tr(
-								"The cell {0},{1} seem to be defined more than once. At least, there is two baggles here, which is not allowed.",x,y));
-					}
-
-				if (topWallFlag.equalsIgnoreCase("topwall"))
-					cell.putTopWall();
-				if (leftWallFlag.equalsIgnoreCase("leftwall"))
-					cell.putLeftWall();		
-
-				cell.setColor(color);
-
-				if (content.length()>0)
-					cell.setContent(content);
-
-				res.setCell(cell, x, y);
-			} else {
-				throw new BrokenWorldFileException(Game.i18n.tr(
-						"Parse error. I was expecting a cell or a buggle description but got: {0}",line));					
-			}
-
-			line = reader.readLine();
-		} while (line != null);
-
-		return res;
-	}
-
-	@Override
-	public void writeToFile(BufferedWriter writer) throws IOException {
-
-		writer.write("BuggleWorld: "+getName() + "\n");
-		writer.write("Size: "+getWidth() + "x"+ getHeight() + "\n");
-
-		for (Entity e : getEntities()) {
-			AbstractBuggle b = (AbstractBuggle) e;
-			writer.write("Buggle("+b.getX()+","+b.getY()+"): ");
-			
-			if (b.getDirection().equals(Direction.NORTH)) 
-				writer.write("north,");
-			if (b.getDirection().equals(Direction.SOUTH)) 
-				writer.write("south,");
-			if (b.getDirection().equals(Direction.EAST)) 
-				writer.write("east,");
-			if (b.getDirection().equals(Direction.WEST)) 
-				writer.write("west,");
-			
-			writer.write(ColorMapper.color2name(b.getColor())+",");
-			writer.write(ColorMapper.color2name(b.getBrushColor())+",");
-			writer.write(b.getName());
-			writer.write("\n");
-		}
-			
-		
-		for (int x = 0; x < getWidth(); x++) {
-			for (int y = 0; y < getHeight(); y++) {
-				BuggleWorldCell cell = (BuggleWorldCell) getCell(x, y);
-
-				if ((!cell.getColor().equals(Color.white)) || cell.hasBaggle() || 
-						cell.hasLeftWall() || cell.hasTopWall() || cell.hasContent()
-						) {
-					
-					writer.write("Cell("+x+","+y+"): ");
-					writer.write(ColorMapper.color2name(cell.getColor())+",");
-					
-					if (cell.hasBaggle()) 
-						writer.write("baggle,");
-					else 
-						writer.write("nobaggle,");
-					
-					if (cell.hasTopWall()) 
-						writer.write("topwall,");
-					else 
-						writer.write("notopwall,");
-
-					if (cell.hasLeftWall()) 
-						writer.write("leftwall,");
-					else 
-						writer.write("noleftwall,");
-					
-					if (cell.hasContent())
-						writer.write(cell.getContent());
-					writer.write("\n");
-				}
-			}
-		}
-	}
-
-	@Override
-	public String toString() {
-		return super.toString(); 
-	}
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		//result = PRIME * result + ((entities == null) ? 0 : entities.hashCode());
-		result = PRIME * result + sizeX;
-		result = PRIME * result + sizeY;
-		result = PRIME * result + Arrays.hashCode(cells);
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if ( !(obj instanceof BuggleWorld) )
-			return false;
-		final BuggleWorld other = (BuggleWorld) obj;
-		if (sizeX != other.sizeX)
-			return false;
-		if (sizeY != other.sizeY)
-			return false;
-		for (int x=0; x<getWidth(); x++) 
-			for (int y=0; y<getHeight(); y++) 
-				if (!getCell(x, y).equals(other.getCell(x, y)))
-					return false;
-
-		return super.equals(obj);
-	}
-
-	/* Cell selection is particularly important to world edition */
-	BuggleWorldCell selectedCell=null;
-	public BuggleWorldCell getSelectedCell() {
-		return selectedCell;
-	}
-	public void setSelectedCell(int x, int y) {
-		selectedCell = getCell(x,y);
-	}
-	public void unselectCell() {
-		selectedCell = null;
-	}
-	
-	/* adapters to the cells */
-	public BuggleWorldCell getCell(int x, int y) {
-		return (BuggleWorldCell) super.getCell(x, y);
-	}
-	public void setColor(int x, int y, Color c) {
-		getCell(x, y).setColor(c);
-	}
-	public void addContent(int x, int y, String string) {
-		getCell(x, y).addContent(string);
-	}
-
-	public void putTopWall(int x, int y) {
-		getCell(x, y).putTopWall();		
-	}
-
-	public void putLeftWall(int x, int y) {
-		getCell(x, y).putLeftWall();		
-	}
-	public void newBaggle(int x, int y) throws AlreadyHaveBaggleException {
-		getCell(x, y).newBaggle();		
-	}
-	@Override
-	public void setupBindings(ProgrammingLanguage lang,ScriptEngine engine) throws ScriptException {
-		if (lang.equals(Game.PYTHON)) {
-			engine.put("Direction", Direction.class);
-			engine.put("Color", Color.class);
-			engine.eval(
-				"def forward(steps=1):\n"+
-				"	entity.forward(steps)\n"+
-				"def backward(steps=1):\n"+
-				"	entity.backward(steps)\n"+
-				"def turnLeft():\n"+
-				"	entity.turnLeft()\n"+
-				"def turnBack():\n"+
-				"	entity.turnBack()\n"+
-				"def turnRight():\n"+
-				"	entity.turnRight()\n"+
-				"\n"+
-				"def getWorldHeight():\n"+
-				"	return entity.getWorldHeight()\n"+
-				"def getWorldWidth():\n"+
-				"	return entity.getWorldWidth()\n"+
-				"def getX():\n"+
-				"	return entity.getX()\n"+
-				"def getY():\n"+
-				"	return entity.getY()\n"+
-				"def setX(x):\n"+
-				"	entity.setX(x)\n"+
-				"def setY(y):\n"+
-				"	entity.setY(y)\n"+
-				"def setPos(x,y):\n"+
-				"	entity.setPos(x,y)\n"+
-				"def setDirection(d):\n"+
-				"	entity.setDirection(d)\n"+
-				"def brushDown():\n"+
-				"   entity.brushDown()\n"+
-				"def brushUp():\n"+
-				"   entity.brushUp()\n" +
-				"def isFacingWall():" +
-				"	return entity.isFacingWall()\n"+
-				"def getGroundColor():\n"+
-				"   return entity.getGroundColor()\n"+
-				
-				"def errorMsg(str):\n"+
-				"  entity.seenError(str)\n"+
-				
-				"def isOverBaggle():\n"+
-				"	return entity.isOverBaggle()\n"+
-				"def isCarryingBaggle():\n"+
-				"	return entity.isCarryingBaggle()\n"+
-				"def pickupBaggle():\n"+
-				"	return entity.pickupBaggle()\n"+
-				"def dropBaggle():\n"+
-				"	return entity.dropBaggle()\n"+
-				
-				"def isOverMessage():\n"+
-				"	return entity.isOverMessage()\n"+
-				"def readMessage():\n"+
-				"	return entity.readMessage()\n"+
-				"def clearMessage():\n"+
-				"   entity.clearMessage()\n"+
-				"def writeMessage(msg):\n"+
-				"   entity.writeMessage(msg)\n"+
-				
-				"def getDirection():\n"+
-				"   return entity.getDirection()\n"+
-				
-				"def setBrushColor(c):\n"+
-				"    entity.setBrushColor(c)\n"+
-				"def getBrushColor():\n"+
-				"    return entity.getBrushColor()\n"
-						);		
-		} else {
-			throw new RuntimeException("No binding of BuggleWorld for "+lang);
-		}
-	}
-	@Override
-	public String diffTo(World world) {
-		BuggleWorld other = (BuggleWorld) world;
-		StringBuffer sb = new StringBuffer();
-		if (! other.getName().equals(getName()))
-			sb.append(i18n.tr("  The world''s name is {0}",other.getName()));
-		for (int x=0; x<getWidth(); x++) 
-			for (int y=0; y<getHeight(); y++) 
-				if (!getCell(x, y).equals(other.getCell(x, y))) 
-					sb.append(i18n.tr("  In ({0},{1})",x,y)+  getCell(x, y).diffTo(other.getCell(x, y))+".\n");
-		for (int i=0; i<entities.size(); i++)  
-			if (! entities.get(i).equals(other.entities.get(i))) 
-				sb.append(i18n.tr("  Something is wrong about buggle ''{0}'':\n",entities.get(i).getName())+
-						((AbstractBuggle) entities.get(i)).diffTo((AbstractBuggle) other.entities.get(i)));
-		return sb.toString();
-	}
-
-}
diff --git a/src/jlm/universe/bugglequest/BuggleWorldCell.java b/src/jlm/universe/bugglequest/BuggleWorldCell.java
deleted file mode 100644
index 2a1ac9f..0000000
--- a/src/jlm/universe/bugglequest/BuggleWorldCell.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-
-import jlm.universe.GridWorld;
-import jlm.universe.GridWorldCell;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-
-
-public class BuggleWorldCell extends GridWorldCell {
-	private Color color;
-
-	private Color msgColor = DEFAULT_MSG_COLOR; 
-	
-	public static final Color DEFAULT_COLOR = Color.white;
-	public static final Color DEFAULT_MSG_COLOR = new Color(0.5f,0.5f,0.9f);
-
-	private Baggle baggle;
-	
-	private String content = "";
-	
-	private boolean leftWall;
-
-	private boolean topWall;
-
-	public BuggleWorldCell(BuggleWorld w, int x, int y) {
-		this(w, x, y, DEFAULT_COLOR, false, false, null, "");
-	}
-
-	public BuggleWorldCell(BuggleWorldCell c, GridWorld w) {
-		this((BuggleWorld) w, c.x, c.y, c.color, c.leftWall, c.topWall, null, null);
-		if (c.hasBaggle()) {
-			Baggle b = new Baggle(c.getBaggle());
-			b.setCell(this);
-			this.baggle = b;
-		}
-		this.content = c.content;
-	}
-	public BuggleWorldCell copy(GridWorld w) {
-		return new BuggleWorldCell(this,w);
-	}
-
-	public BuggleWorldCell(BuggleWorld w, int x, int y, Color color, boolean leftWall, boolean topWall) {
-		this(w, x, y, color, leftWall, topWall, null, "");
-	}
-
-	public BuggleWorldCell(BuggleWorld w, int x, int y, Color c, boolean leftWall, boolean topWall, Baggle baggle, String content) {
-		super(w,x,y);
-		this.color = c;
-		this.leftWall = leftWall;
-		this.topWall = topWall;
-		this.baggle = baggle;
-		this.content = content;
-	}
-
-	public void setColor(Color c) {
-		this.color = c;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public Color getColor() {
-		return this.color;
-	}
-	
-	public void setMsgColor(Color c) {
-		this.msgColor = c;
-		world.notifyWorldUpdatesListeners();
-	}
-	
-	public Color getMsgColor() {
-		return this.msgColor;
-	}
-
-	public void putTopWall() {
-		this.topWall = true;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public void removeTopWall() {
-		this.topWall = false;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public void putLeftWall() {
-		this.leftWall = true;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public void removeLeftWall() {
-		this.leftWall = false;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	@Override
-	public String toString() {
-		String cell;
-		if (hasContent()) 
-			cell = this.content;
-		if (hasBaggle())
-			cell = "o";
-		else if (color.equals(DEFAULT_COLOR))
-			cell = " ";
-		else
-			cell = "?";
-		return cell;
-	}
-
-	public boolean hasTopWall() {
-		return this.topWall;
-	}
-
-	public boolean hasLeftWall() {
-		return this.leftWall;
-	}
-
-	public boolean hasBaggle() {
-		return this.baggle != null;
-	}
-
-	public Baggle getBaggle() {
-		return this.baggle;
-	}
-
-	public void newBaggle() throws AlreadyHaveBaggleException {
-		//Logger.log("WorldCell:newBaggle", "");
-		if (this.baggle != null) 
-			throw new AlreadyHaveBaggleException("This cell already contains a baggle");
-		this.baggle = new Baggle(this);
-		world.notifyWorldUpdatesListeners();		
-	}
-	
-	public void newBaggle(Color c) throws AlreadyHaveBaggleException {
-		if (this.baggle != null) 
-			throw new AlreadyHaveBaggleException("This cell already contains a baggle");
-		this.baggle = new Baggle(this,c);
-		world.notifyWorldUpdatesListeners();
-	}
-	
-	public void setBaggle(Baggle b) throws AlreadyHaveBaggleException {
-		if (this.baggle != null && b != null) 
-			throw new AlreadyHaveBaggleException("This cell already contains a baggle");
-		this.baggle = b;
-		world.notifyWorldUpdatesListeners();
-	}
-
-	public Baggle pickupBaggle() {
-		Baggle b = this.baggle;
-		this.baggle.setCell(null);
-		baggle = null;		
-		world.notifyWorldUpdatesListeners();
-		return b;
-	}
-	
-	public boolean hasContent() {
-		return (!this.content.equals(""));
-	}
-
-	public String getContent() {
-		return this.content;
-	}
-	
-	public void setContent(String c) {
-		this.content = c;
-		world.notifyWorldUpdatesListeners();
-	}
-	
-	public void addContent(String c) {
-		this.content += c;
-		world.notifyWorldUpdatesListeners();
-	}
-	public void emptyContent() {
-		this.content = "";
-		world.notifyWorldUpdatesListeners();		
-	}
-			
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		//result = prime * result + ((baggle == null) ? 0 : baggle.hashCode());
-		result = prime * result + ((color == null) ? 0 : color.hashCode());
-		result = prime * result + ((content == null) ? 0 : content.hashCode());
-		result = prime * result + (leftWall ? 1231 : 1237);
-		result = prime * result + (topWall ? 1231 : 1237);
-		result = prime * result + ((world == null) ? 0 : world.hashCode());
-		result = prime * result + x;
-		result = prime * result + y;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		BuggleWorldCell other = (BuggleWorldCell) obj;
-		//if (hasBaggle() != other.hasBaggle())
-		//	return false;
-		if (baggle == null) {
-			if (other.baggle != null)
-				return false;
-		} else if (!baggle.equals(other.baggle))
-			return false;
-		if (color == null) {
-			if (other.color != null)
-				return false;
-		} else if (!color.equals(other.color))
-			return false;
-		if (!content.equals(other.content))
-			return false;
-		if (leftWall != other.leftWall)
-			return false;
-		if (topWall != other.topWall)
-			return false;
-		if (x != other.x)
-			return false;
-		if (y != other.y)
-			return false;
-		return true;
-	}
-
-	/* This function is called as answer.diffTo(current) */
-	public String diffTo(BuggleWorldCell current) {
-		StringBuffer sb = new StringBuffer();
-		if (baggle == null && current.baggle != null) 
-			sb.append(this.world.i18n.tr(", there shouldn't be this baggle"));
-		if (baggle != null && current.baggle == null)
-			sb.append(this.world.i18n.tr(", there should be a baggle"));
-		if (baggle != null && current.baggle != null && !baggle.equals(current.baggle))
-			sb.append(this.world.i18n.tr(", the baggle differs"));
-		if (color == null) {
-			if (current.color != null)
-				sb.append(this.world.i18n.tr(", the ground should not be {0}",current.color));
-		} else if (!color.equals(current.color))
-			sb.append(this.world.i18n.tr(", the ground is expected to be {0}, but it is {1}", color, current.color));
-		if (!content.equals(current.content))
-			sb.append(this.world.i18n.tr(", the ground reads ''{0}'' (expected: ''{1}'')", current.content, content));
-		if (leftWall != current.leftWall)
-			if (current.leftWall)
-				sb.append(this.world.i18n.tr(", there shouldn't be any wall at west"));
-			else
-				sb.append(this.world.i18n.tr(", there should be a wall at west"));
-		if (topWall != current.topWall)
-			if (current.topWall)
-				sb.append(this.world.i18n.tr(", there shouldn't be any wall at north"));
-			else
-				sb.append(this.world.i18n.tr(", there should be a wall at north"));
-		return sb.toString();
-	}
-}
diff --git a/src/jlm/universe/bugglequest/SimpleBuggle.java b/src/jlm/universe/bugglequest/SimpleBuggle.java
deleted file mode 100644
index b136665..0000000
--- a/src/jlm/universe/bugglequest/SimpleBuggle.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package jlm.universe.bugglequest;
-
-import java.awt.Color;
-
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-import jlm.universe.bugglequest.exception.BuggleInOuterSpaceException;
-import jlm.universe.bugglequest.exception.BuggleWallException;
-import jlm.universe.bugglequest.exception.NoBaggleUnderBuggleException;
-
-
-
-public abstract class SimpleBuggle extends AbstractBuggle  {
-	public SimpleBuggle(BuggleWorld w, String name, int i, int j, Direction dir, Color c, Color bc) {
-		super(w,name,i,j,dir,c,bc);
-	}
-
-	public SimpleBuggle() {
-		super();
-	}
-
-	@Override
-	public void forward()  {
-		try { 
-			super.forward(); 
-		} catch (BuggleWallException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You hit a wall.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-
-	@Override
-	public void forward(int count)  {
-		try { 
-			super.forward(count); 
-		} catch (BuggleWallException e) { 
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You hit a wall.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-
-	@Override
-	public void backward()  {
-		try { 
-			super.backward(); 
-		} catch (BuggleWallException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You hit a wall.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-
-	@Override
-	public void backward(int count)  {
-		try { 
-			super.backward(count); 
-		} catch (BuggleWallException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You hit a wall.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-
-	@Deprecated
-	@Override
-	public void pickUpBaggle () { 
-		pickupBaggle();
-	}
-	@Override
-	public void pickupBaggle () { 
-		try { 
-			super.pickupBaggle(); 
-		} catch (NoBaggleUnderBuggleException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "No baggle here.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		} catch (AlreadyHaveBaggleException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You are already carrying a baggle.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-
-	@Override
-	public void dropBaggle () { 
-		try { 
-			super.dropBaggle(); 
-		} catch (AlreadyHaveBaggleException e) { 
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "Buggle already carry a baggle.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}	
-	@Override 
-	public void setX(int x) {
-		try {
-			super.setX(x);
-		} catch (BuggleInOuterSpaceException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "The buggle moved to the outer space.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-	@Override 
-	public void setY(int y) {
-		try {
-			super.setY(y);
-		} catch (BuggleInOuterSpaceException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "The buggle moved to the outer space.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-	@Override 
-	public void setPos(int x,int y) {
-		try {
-			super.setPos(x,y);
-		} catch (BuggleInOuterSpaceException e) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "The buggle moved to the outer space.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-	}
-}
\ No newline at end of file
diff --git a/src/jlm/universe/bugglequest/exception/AlreadyHaveBaggleException.java b/src/jlm/universe/bugglequest/exception/AlreadyHaveBaggleException.java
deleted file mode 100644
index f1fff08..0000000
--- a/src/jlm/universe/bugglequest/exception/AlreadyHaveBaggleException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package jlm.universe.bugglequest.exception;
-
-import jlm.core.JLMException;
-
-
-public class AlreadyHaveBaggleException extends JLMException {
-
-	private static final long serialVersionUID = -4857249506281940595L;
-
-	public AlreadyHaveBaggleException(String msg) {
-		super(msg);
-	}
-}
diff --git a/src/jlm/universe/bugglequest/exception/BuggleInOuterSpaceException.java b/src/jlm/universe/bugglequest/exception/BuggleInOuterSpaceException.java
deleted file mode 100644
index d249bc2..0000000
--- a/src/jlm/universe/bugglequest/exception/BuggleInOuterSpaceException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package jlm.universe.bugglequest.exception;
-
-import jlm.core.JLMException;
-
-
-public class BuggleInOuterSpaceException extends JLMException {
-
-	public BuggleInOuterSpaceException(String msg) {
-		super(msg);
-	}
-
-	private static final long serialVersionUID = -7246709356730960089L;
-
-}
diff --git a/src/jlm/universe/bugglequest/exception/BuggleWallException.java b/src/jlm/universe/bugglequest/exception/BuggleWallException.java
deleted file mode 100644
index 33100ed..0000000
--- a/src/jlm/universe/bugglequest/exception/BuggleWallException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package jlm.universe.bugglequest.exception;
-
-import jlm.core.JLMException;
-
-
-public class BuggleWallException extends JLMException {
-
-	public BuggleWallException() {
-		super("Buggles cannot traverse walls");
-	}
-
-	private static final long serialVersionUID = -7246709356730960089L;
-
-}
diff --git a/src/jlm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java b/src/jlm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java
deleted file mode 100644
index 3522f52..0000000
--- a/src/jlm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package jlm.universe.bugglequest.exception;
-
-import jlm.core.JLMException;
-
-
-public class NoBaggleUnderBuggleException extends JLMException {
-
-	private static final long serialVersionUID = 8112061605322303567L;
-
-	public NoBaggleUnderBuggleException(String msg) {
-		super(msg);
-	}
-
-}
diff --git a/src/jlm/universe/bugglequest/exception/package-info.java b/src/jlm/universe/bugglequest/exception/package-info.java
deleted file mode 100644
index 5885c0c..0000000
--- a/src/jlm/universe/bugglequest/exception/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Exceptions possibly raised to students in this universe
- */
-package jlm.universe.bugglequest.exception;
-
diff --git a/src/jlm/universe/bugglequest/mapeditor/EditionListener.java b/src/jlm/universe/bugglequest/mapeditor/EditionListener.java
deleted file mode 100644
index cdcc5c9..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/EditionListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-public interface EditionListener {
-	/** 
-	 * Inform the listener that the edited world just changed 
-	 * @param w the new world to edit
-	 */
-	void setWorld(World w);
-	/** 
-	 * Event fired each time that something changes in the edited world. That's quite often, actually
-	 */
-	void worldEdited();
-	/**
-	 * Event fired when the currently selection changes
-	 * @param x x-coordinate of selection
-	 * @param y y-coordinate of selection
-	 * @param ent new entity under radar. May be null if there is no entity in selected cell
-	 */
-	void selectedChanged(int x, int y, Entity ent);
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/Editor.java b/src/jlm/universe/bugglequest/mapeditor/Editor.java
deleted file mode 100644
index e63db46..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/Editor.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import java.awt.Color;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.Entity;
-import jlm.universe.World;
-import jlm.universe.bugglequest.AbstractBuggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class Editor {
-
-	private BuggleWorld world;
-	private ArrayList<EditionListener> editionListeners = new ArrayList<EditionListener>();
-	private String command = "topwall";
-	private Color selectedColor = Color.blue;
-	private int selectedColorNumber = 1;
-	public I18n	i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages", new Locale("fr"), I18nFactory.FALLBACK); // FIXME: ugly: french is hardcoded!!!!!
-
-	
-	public Editor() {
-		createNewMap(10, 10);
-		world.setSelectedCell(0, 0);
-	}
-
-	public void createNewMap(int width, int height) {
-		this.world = new BuggleWorld("Brave new world",width, height);
-		
-		for (EditionListener v : this.editionListeners) {
-			v.setWorld(this.world);
-		}
-				
-		notifySetWorld(world);
-	}
-
-	public void saveMap(File file) {
-		try {
-			this.world.writeToFile(file);
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void loadMap(String file) throws IOException {
-		try {
-			world = (BuggleWorld) BuggleWorld.newFromFile(file); 
-		} catch (BrokenWorldFileException e) {
-			e.printStackTrace();
-		}
-		notifySetWorld(world);
-	}
-
-	public BuggleWorld getWorld() {
-		return this.world;
-	}
-	
-	public void addEditionListener(EditionListener v) {
-		this.editionListeners.add(v);
-	}
-
-	public void removeEditionListener(EditionListener v) {
-		this.editionListeners.remove(v);
-	}
-
-	public void notifySetWorld(World w) {
-		for (EditionListener v : this.editionListeners) 
-			v.setWorld(w);
-	}
-	public void notifyWorldEdited(){
-		for (EditionListener el : editionListeners)
-			el.worldEdited();		
-	}
-
-	public void setCommand(String cmd) {
-		command = cmd;
-	}
-	public String getCommand() {
-		return command;
-	}
-
-	public void setSelectedColor(Color c) {
-		selectedColor = c;
-	}
-	public Color getSelectedColor() {
-		return selectedColor;
-	}
-
-	public int getSelectedColorNumber() {
-		return selectedColorNumber ;
-	}
-
-	public void setSelectedColorNumber(int i) {
-		selectedColorNumber = i;		
-	}
-
-	public void setSelectedCell(int x, int y) {
-		AbstractBuggle buggle = null;
-		for (Entity e : getWorld().getEntities()) {
-			AbstractBuggle b = (AbstractBuggle) e;
-			if (b.getX() == x && b.getY() == y)
-				buggle = b;
-		}
-		getWorld().setSelectedCell(x, y);
-		
-		for (EditionListener el : editionListeners)
-			el.selectedChanged(x, y, buggle);
-	}
-	public void setSelectedEntity(AbstractBuggle buggle) {
-		int x = getWorld().getSelectedCell().getX();
-		int y = getWorld().getSelectedCell().getY();
-		
-		getWorld().setSelectedEntity(buggle);
-		for (EditionListener el : editionListeners)
-			el.selectedChanged(x, y, buggle);
-		
-	}
-
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/MainFrame.java b/src/jlm/universe/bugglequest/mapeditor/MainFrame.java
deleted file mode 100644
index 045bcb6..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/MainFrame.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.io.File;
-import java.io.IOException;
-
-import javax.swing.AbstractAction;
-import javax.swing.ButtonGroup;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JSplitPane;
-import javax.swing.JToggleButton;
-import javax.swing.JToolBar;
-import javax.swing.KeyStroke;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
-import jlm.core.ui.ResourcesCache;
-import jlm.core.utils.ColorMapper;
-import jlm.core.utils.InvalidColorNameException;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-
-public class MainFrame extends JFrame {
-
-	private static final long serialVersionUID = -7243431953648987489L;
-
-	private Editor editor;
-	private ButtonGroup tools;
-	private String path;	
-	
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-	
-	public MainFrame(Editor editor) {
-		super("BuggleQuest - MapEditor");
-		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-		this.editor = editor;
-		initComponents();
-		setSize(800, 600);
-		setVisible(true);
-	}
-
-	public void initComponents() {
-
-		JMenuBar menuBar = new JMenuBar();
-
-		JMenu fileMenu = new JMenu("File");
-		JMenuItem mi;
-		
-		mi = new JMenuItem(new NewMapAction());
-		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
-		fileMenu.add(mi);
-		
-		mi = new JMenuItem(new OpenMapAction());
-		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
-		fileMenu.add(mi);
-		
-		mi = new JMenuItem(new SaveMapAction());
-		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
-		fileMenu.add(mi);
-
-		mi = new JMenuItem(new QuitAction());
-		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
-		fileMenu.add(mi);
-
-		menuBar.add(fileMenu);
-		this.setJMenuBar(menuBar);
-
-		getContentPane().setLayout(new BorderLayout());
-
-		JToolBar toolBar = new JToolBar();
-
-		JToggleButton topButton = createButton("topwall"); 
-		JToggleButton leftButton = createButton("leftwall"); 
-		JToggleButton baggleButton = createButton("baggle");
-		JToggleButton buggleButton = createButton("buggle");
-		JToggleButton nobuggleButton = createButton("nobuggle");
-		JToggleButton textButton = createButton("text");
-		JToggleButton colorButton = createButton("colors",new ActionListener() {
-			public void actionPerformed(ActionEvent e) {
-				editor.setCommand("colors");
-				Object[] choices = {
-						"custom", "black","blue","cyan","darkGray","gray","green","lightGray","magenta","orange","pink","red","yellow"};
-				Color[] colors = {
-						new Color(42,42,42), Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,Color.red,Color.yellow};
-				
-				Object selectedValue = JOptionPane.showInputDialog(null,
-						"Choose a color", "Change color",
-						JOptionPane.INFORMATION_MESSAGE, null,
-						choices, choices[editor.getSelectedColorNumber()]);
-				
-				if (selectedValue == null) // cancel pressed
-					return;
-					
-				if (selectedValue.equals("custom")) {
-					String name = JOptionPane.showInputDialog("What color you want (r/g/b)", 
-							colors[0].getRed()+"/"+colors[0].getGreen()+"/"+colors[0].getBlue());
-					try {
-						Color c = ColorMapper.name2color(name);
-						colors[0] = c;
-					} catch (InvalidColorNameException icne) {
-						/* Ignore */
-					}
-				}
-				for (int i=0; i<choices.length;i++) 
-					if (selectedValue.equals(choices[i])) {
-						editor.setSelectedColorNumber(i);
-						editor.setSelectedColor(colors[i]);
-					}					
-			}	
-		});
-
-		topButton.setSelected(true);
-
-
-		toolBar.add(topButton);
-		toolBar.add(leftButton);
-		toolBar.add(baggleButton);
-		toolBar.add(buggleButton);
-		toolBar.add(nobuggleButton);
-		toolBar.add(colorButton);
-		toolBar.add(textButton);
-
-		tools = new ButtonGroup();
-		tools.add(topButton);
-		tools.add(leftButton);
-		tools.add(baggleButton);
-		tools.add(buggleButton);
-		tools.add(nobuggleButton);
-		tools.add(colorButton);
-		tools.add(textButton);
-
-		getContentPane().add(toolBar, BorderLayout.NORTH);
-
-		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
-		sp.setOneTouchExpandable(false);
-
-		MapView mapView = new MapView(editor);
-		editor.addEditionListener(mapView);
-		sp.setLeftComponent(mapView);
-		sp.setRightComponent(new PropertiesEditor(editor));
-		sp.setResizeWeight(.6);
-		
-		getContentPane().add(sp, BorderLayout.CENTER);
-	}
-
-	private JToggleButton createButton(final String name) {
-		ActionListener l = new ActionListener() {
-			public void actionPerformed(ActionEvent e) {
-				editor.setCommand(name);
-			}	
-		};
-		return createButton(name,l); 
-	}
-	private JToggleButton createButton(final String name, ActionListener l) {
-		JToggleButton bt = new JToggleButton(ResourcesCache.getIcon("img/edit_"+name+".png"));
-		bt.setActionCommand(name);
-		bt.setBorderPainted(false);
-		bt.addActionListener(l);
-		return bt;
-	}
-
-	class NewMapAction extends AbstractAction {
-		private static final long serialVersionUID = 1L;
-
-		public NewMapAction() {
-			super(i18n.tr("Create New Map"));
-		}
-
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			int w = 10;
-			int h = 10;
-
-			String wString = null;
-			String hString = null;
-
-			wString = JOptionPane.showInputDialog("Enter desired map width", Integer.toString(w));
-			if (wString != null)
-				hString = JOptionPane.showInputDialog("Enter desired map height", Integer.toString(h));
-
-			if (hString != null) {
-				w = Integer.parseInt(wString);
-				h = Integer.parseInt(hString);
-				editor.createNewMap(w, h);
-				MainFrame.this.path = null;
-			}
-		}
-
-	}
-
-	class SaveMapAction extends AbstractAction {
-		private static final long serialVersionUID = 1L;
-
-		public SaveMapAction() {
-			super("Save As...");
-		}
-
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			JFileChooser fc;
-			if (MainFrame.this.path != null)
-				fc = new JFileChooser(MainFrame.this.path);
-			else
-				fc = new JFileChooser();
-			int status = fc.showSaveDialog(MainFrame.this);
-
-			if (status == JFileChooser.APPROVE_OPTION) {
-				File file = fc.getSelectedFile();
-				editor.saveMap(file);
-			}
-		}
-	}
-
-	class OpenMapAction extends AbstractAction {
-		private static final long serialVersionUID = 1L;
-
-		public OpenMapAction() {
-			super(i18n.tr("Open Map..."));
-		}
-
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			JFileChooser fc = new JFileChooser();
-			fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("JLM map files"), "map"));
-			int status = fc.showOpenDialog(MainFrame.this);
-
-			if (status == JFileChooser.APPROVE_OPTION) {
-				MainFrame.this.path = fc.getSelectedFile().getAbsolutePath();
-				try {
-					editor.loadMap(MainFrame.this.path);
-				} catch (IOException e1) {
-					JOptionPane.showMessageDialog(null, e1.getLocalizedMessage(),i18n.tr("Error while reading {0}",path), JOptionPane.ERROR_MESSAGE);
-				}
-			}
-		}
-
-	}
-
-	class QuitAction extends AbstractAction {
-		private static final long serialVersionUID = 1L;
-
-		public QuitAction() {
-			super("Quit Map Editor");
-		}
-
-		@Override
-		public void actionPerformed(ActionEvent e) {
-			dispose();
-		}
-
-	}
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/MapEditorApp.java b/src/jlm/universe/bugglequest/mapeditor/MapEditorApp.java
deleted file mode 100644
index 80dfa89..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/MapEditorApp.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import java.io.IOException;
-
-
-public class MapEditorApp {
-
-	public static void main(String[] args) {
-		Editor editor = new Editor();
-		new MainFrame(editor);
-		if (args.length>0)
-			try {
-				editor.loadMap(args[0]);
-			} catch (IOException e) {
-				
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-	}
-
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/MapView.java b/src/jlm/universe/bugglequest/mapeditor/MapView.java
deleted file mode 100644
index 4866dae..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/MapView.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-
-import javax.swing.JOptionPane;
-
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorldCell;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-import jlm.universe.bugglequest.ui.BuggleWorldView;
-
-
-public class MapView extends BuggleWorldView implements EditionListener {
-
-	private static final long serialVersionUID = -8303474674104829723L;
-	private Editor editor;
-	private int buggleCount = 0;
-	
-	public MapView(Editor e) {
-		super(e.getWorld());
-		this.editor = e;
-
-		MouseListener mouseListener = new MouseAdapter() {
-			@Override
-			public void mouseClicked(MouseEvent e) {
-				handleMouseEvt(e);
-			}
-			void handleMouseEvt(MouseEvent e) {
-				int x = (int) ((e.getX() - getPadX()) / getCellWidth());
-				int y = (int) ((e.getY() - getPadY()) / getCellWidth());
-				
-				editor.setSelectedCell(x, y);
-				BuggleWorldCell cell = (BuggleWorldCell) editor.getWorld().getSelectedCell();
-				String cmd = editor.getCommand();
-
-				if (cmd.equals("topwall")) {
-					if (cell.hasTopWall()) 
-						cell.removeTopWall();
-					else
-						cell.putTopWall();
-				} else if (cmd.equals("leftwall")) {
-					if (cell.hasLeftWall()) 
-						cell.removeLeftWall();
-					else
-						cell.putLeftWall();
-				} else if (cmd.equals("baggle")) {
-					if (cell.hasBaggle()) 
-						cell.pickupBaggle();
-					else
-						try {
-							cell.newBaggle();
-						} catch (AlreadyHaveBaggleException e1) {
-							System.out.println("The impossible did happen (yet again)");
-							e1.printStackTrace();
-						}
-				} else if (cmd.equals("colors")) {
-					if (cell.getColor().equals(editor.getSelectedColor())) 
-						cell.setColor(Color.white);
-					else
-						cell.setColor(editor.getSelectedColor());
-				} else if (cmd.equals("text")) {
-					String inputValue = (String)JOptionPane.showInputDialog(null,
-							"Choose a new message", "Change message",
-							JOptionPane.QUESTION_MESSAGE, null,
-							null,cell.getContent());
-					
-					if (inputValue == null) // cancel pressed
-						return;
-					cell.emptyContent();
-					cell.addContent(inputValue);
-					
-				} else if (cmd.equals("buggle")) {
-					Buggle thebuggle = null;
-					for (Entity ent:editor.getWorld().getEntities()) {
-						Buggle b = (Buggle) ent;
-						if (b.getX() == x && b.getY() == y) {
-							thebuggle = b;
-							break;
-						}
-					}
-					if (thebuggle == null) {
-						thebuggle = new Buggle(editor.getWorld(),"buggle"+(++buggleCount), x,y,Direction.NORTH,Color.black, Color.black);
-					} 
-					editor.setSelectedEntity(thebuggle);
-				} else if (cmd.equals("nobuggle")) {
-					Buggle thebuggle = null;
-					for (Entity ent:editor.getWorld().getEntities()) {
-						Buggle b = (Buggle) ent;
-						if (b.getX() == x && b.getY() == y) {
-							thebuggle = b;
-							break;
-						}
-					}
-					if (thebuggle != null) {
-						editor.getWorld().removeEntity(thebuggle);
-						if (editor.getWorld().getEntities().contains(thebuggle))
-							System.err.println("The entity is still in "+editor.getWorld().getEntities().indexOf(thebuggle)+"!!");
-
-					}
-					editor.setSelectedEntity(null);
-				}
-			}
-		};
-		addMouseListener(mouseListener);
-	}
-
-	@Override
-	public void worldEdited() {
-		worldHasChanged();// use the callbacks of the regular view -- not really clean but efficient
-	}
-
-	@Override
-	public void selectedChanged(int x, int y, Entity ent) {
-		/* I'm too lazy to react to this */
-		this.repaint();
-	}
-	
-	@Override
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-		BuggleWorldCell selection = editor.getWorld().getSelectedCell();
-		if (selection != null) {
-			int padx = (int) getPadX();
-			int pady = (int) getPadY();
-			int ox = (int) (selection.getX()*getCellWidth()); // x-offset of the cell
-			int oy = (int) ((selection.getY())*getCellWidth()); // y-offset of the cell
-			int cellW = (int) getCellWidth();
-
-			g.setColor(Color.RED);
-			g.drawRoundRect(padx+ox+2, pady+oy+2, cellW-4,cellW-4, cellW/10, cellW/10);
-			g.setColor(Color.WHITE);
-			g.drawRoundRect(padx+ox+3, pady+oy+3, cellW-6,cellW-6, cellW/10, cellW/10);
-			g.setColor(Color.RED);
-			g.drawRoundRect(padx+ox+4, pady+oy+4, cellW-8,cellW-8, cellW/10, cellW/10);
-		}
-	}
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java b/src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java
deleted file mode 100644
index 7e39b3f..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/PropertiesEditor.java
+++ /dev/null
@@ -1,389 +0,0 @@
-package jlm.universe.bugglequest.mapeditor;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.util.Vector;
-
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
-import javax.swing.event.TableModelEvent;
-import javax.swing.event.TableModelListener;
-import javax.swing.table.DefaultTableModel;
-
-import jlm.core.utils.ColorMapper;
-import jlm.core.utils.InvalidColorNameException;
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.World;
-import jlm.universe.bugglequest.AbstractBuggle;
-import jlm.universe.bugglequest.Baggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.BuggleWorldCell;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-public class PropertiesEditor extends JComponent implements EditionListener {
-	private static final long serialVersionUID = 3904327915735497696L;
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-	
-	private AbstractBuggle selectedBuggle;
-
-	private DefaultTableModel model = new DefaultTableModel() {
-		private static final long serialVersionUID = 1L;
-
-		public boolean isCellEditable(int rowIndex, int colIndex) {
-			return colIndex>0;
-		}
-	};
-	private JTable table = new JTable(model);
-
-	private Editor editor; 
-	private int selectedXRank,selectedYRank,topRank,leftRank,baggleRank;
-
-	Vector<JLMProperty> properties = new Vector<JLMProperty>();
-	
-	public PropertiesEditor(Editor _editor) {
-		editor = _editor;
-		editor.addEditionListener(this);
-
-		setLayout(new BorderLayout());
-		add(new JScrollPane(table), BorderLayout.CENTER);
-
-		model.setColumnCount(2);
-		model.setColumnIdentifiers(new Object[] {i18n.tr("Property"), i18n.tr("Value")});
-		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-		repopulateTable();
-		setVisible(true);
-		setPreferredSize(new Dimension(100, 500));
-
-		model.addTableModelListener(new MyTableModelListener(editor,table,properties));
-	}
-	private void repopulateTable() {
-		while (model.getRowCount()>0)
-			model.removeRow(0);
-		properties.removeAllElements();
-
-		/* The editor for the name */
-		model.insertRow(0, new Object[] {i18n.tr("World name"), new JLMProperty(properties) { 
-			@Override
-			public void setValue(String value) {
-				editor.getWorld().setName(value);
-			}
-			@Override
-			public String toString() {
-				return editor.getWorld().getName();
-			}
-		}});
-
-		/*---------- world width ---------------*/
-		model.addRow(new Object[] {i18n.tr("World width"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				return ""+editor.getWorld().getWidth();
-			}
-			@Override
-			public void setValue(String value) {
-				Integer i;
-				try {
-					i = Integer.parseInt(value);
-				} catch (NumberFormatException nfe) {
-					table.setValueAt(""+editor.getWorld().getWidth(),rank,1);
-					return; // silently ignore invalid values
-				}
-				editor.getWorld().setWidth(i);
-				editor.getWorld().notifyWorldUpdatesListeners();
-			}
-		}});
-		
-		/*---------- world height ---------------*/
-		model.addRow(new Object[] {i18n.tr("World height"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				return ""+editor.getWorld().getHeight();
-			}
-			@Override
-			public void setValue(String value) {
-				Integer i;
-				try {
-					i = Integer.parseInt(value);
-				} catch (NumberFormatException nfe) {
-					table.setValueAt(""+editor.getWorld().getHeight(),rank,1);
-					return; // silently ignore invalid values
-				}
-				editor.getWorld().setHeight(i);
-				editor.getWorld().notifyWorldUpdatesListeners();
-			}
-		}});
-
-		/*---------- selected cell ---------------*/
-		model.addRow(new Object[] {i18n.tr("Selected cell X"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				selectedXRank = rank;
-				return ""+editor.getWorld().getSelectedCell().getX();
-			}
-			@Override
-			public void setValue(String value) {
-				Integer x;
-				try {
-					x = Integer.parseInt(value);
-					if (x>=editor.getWorld().getWidth() || x<0)
-						throw new NumberFormatException("out of world");
-				} catch (NumberFormatException nfe) {
-					table.setValueAt(""+editor.getWorld().getSelectedCell().getX(),rank,1);
-					return; // silently ignore invalid values
-				}
-				editor.setSelectedCell(x, editor.getWorld().getSelectedCell().getY());
-			}
-		}});
-
-		/*---------- selected cell ---------------*/
-		model.addRow(new Object[] {i18n.tr("Selected cell Y"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				selectedYRank = rank;
-				return ""+editor.getWorld().getSelectedCell().getY();
-			}
-			@Override
-			public void setValue(String value) {
-				Integer y;
-				try {
-					y = Integer.parseInt(value);
-					if (y>=editor.getWorld().getHeight() || y<0)
-						throw new NumberFormatException("out of world");
-				} catch (NumberFormatException nfe) {
-					table.setValueAt(""+editor.getWorld().getSelectedCell().getY(),rank,1);
-					return; // silently ignore invalid values
-				}
-				editor.setSelectedCell(editor.getWorld().getSelectedCell().getX(),y);
-			}
-		}});
-		/*---------- Ground color ---------------*/
-		model.addRow(new Object[] {i18n.tr("Ground color (name or r/g/b)"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				return ColorMapper.color2name( editor.getWorld().getSelectedCell().getColor() );
-			}
-			@Override
-			public void setValue(String value) {
-				try {
-					Color c = ColorMapper.name2color(value);
-					editor.getWorld().getSelectedCell().setColor(c);
-				} catch (InvalidColorNameException icn) {
-					table.setValueAt(ColorMapper.color2name(editor.getWorld().getSelectedCell().getColor()),rank,1);
-				}
-			}
-		}});
-
-		/*---------- top wall cell ---------------*/
-		model.addRow(new Object[] {i18n.tr("Top wall?"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				topRank = rank;
-				return editor.getWorld().getSelectedCell().hasTopWall()?"Y":"N";
-			}
-			@Override
-			public void setValue(String value) {
-				if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
-					table.setValueAt(editor.getWorld().getSelectedCell().hasTopWall()?"Y":"N",rank,1);
-					return;
-					
-				} else if (value.equalsIgnoreCase("Y")) {
-					if (!editor.getWorld().getSelectedCell().hasTopWall()) // only update if needed
-						editor.getWorld().getSelectedCell().putTopWall();
-				} else {
-					if (editor.getWorld().getSelectedCell().hasTopWall()) // only update if needed
-						editor.getWorld().getSelectedCell().removeTopWall();
-				}
-			}
-		}});
-		/*---------- left wall cell ---------------*/
-		model.addRow(new Object[] {i18n.tr("Left wall?"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				leftRank = rank;
-				return editor.getWorld().getSelectedCell().hasLeftWall()?"Y":"N";
-			}
-			@Override
-			public void setValue(String value) {
-				if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
-					table.setValueAt(editor.getWorld().getSelectedCell().hasLeftWall()?"Y":"N",rank,1);
-					return;
-					
-				} else if (value.equalsIgnoreCase("Y")) {
-					if (!editor.getWorld().getSelectedCell().hasLeftWall()) // only update if needed
-						editor.getWorld().getSelectedCell().putLeftWall();
-				} else {
-					if (editor.getWorld().getSelectedCell().hasLeftWall()) // only update if needed
-						editor.getWorld().getSelectedCell().removeLeftWall();
-				}
-			}
-		}});
-		/*---------- have baggle ---------------*/
-		model.addRow(new Object[] {i18n.tr("Baggle?"), new JLMProperty(properties) {
-			@Override
-			public String toString() {
-				baggleRank = rank;
-				return editor.getWorld().getSelectedCell().hasBaggle()?"Y":"N";
-			}
-			@Override
-			public void setValue(String value) {
-				BuggleWorldCell selected = editor.getWorld().getSelectedCell();
-				
-				try {
-					if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
-						table.setValueAt(editor.getWorld().getSelectedCell().hasBaggle()?"Y":"N",rank,1);
-						return;
-
-					} else if (value.equalsIgnoreCase("Y")) {
-						if (!selected.hasBaggle()) // only update if needed
-							selected.setBaggle(new Baggle(selected));
-					} else {
-						if (selected.hasBaggle()) // only update if needed
-							selected.setBaggle(null);
-					}
-				} catch (AlreadyHaveBaggleException e) { 
-					System.err.println("The impossible happened (yet again)");
-					e.printStackTrace();
-				}
-			}
-		}});
-		
-		if (selectedBuggle != null) {
-			/*---------- Buggle name ---------------*/
-			model.addRow(new Object[] {i18n.tr("Buggle name"), new JLMProperty(properties) {
-				@Override
-				public String toString() {
-					return selectedBuggle.getName();
-				}
-				@Override
-				public void setValue(String value) {
-					selectedBuggle.setName(value);
-				}
-			}});
-			/*---------- Buggle direction ---------------*/
-			model.addRow(new Object[] {i18n.tr("Buggle direction (N|S|E|W)"), new JLMProperty(properties) {
-				@Override
-				public String toString() {
-					if (selectedBuggle.getDirection().equals(Direction.NORTH)) 
-						return "N";
-					if (selectedBuggle.getDirection().equals(Direction.SOUTH))
-						return "S";
-					if (selectedBuggle.getDirection().equals(Direction.EAST))
-						return "E";
-					if (selectedBuggle.getDirection().equals(Direction.WEST))
-						return "W";
-					return "?";
-				}
-				@Override
-				public void setValue(String value) {
-					if (value.equalsIgnoreCase("N"))
-						selectedBuggle.setDirection(Direction.NORTH);
-					if (value.equalsIgnoreCase("S"))
-						selectedBuggle.setDirection(Direction.SOUTH);
-					if (value.equalsIgnoreCase("E"))
-						selectedBuggle.setDirection(Direction.EAST);
-					if (value.equalsIgnoreCase("W"))
-						selectedBuggle.setDirection(Direction.WEST);
-					else {
-						table.setValueAt(this.toString(),rank,1);
-					}
-				}
-			}});
-			/*---------- Buggle color ---------------*/
-			model.addRow(new Object[] {i18n.tr("Buggle color (name or r/g/b)"), new JLMProperty(properties) {
-				@Override
-				public String toString() {
-					return ColorMapper.color2name( selectedBuggle.getColor() );
-				}
-				@Override
-				public void setValue(String value) {
-					try {
-						Color c = ColorMapper.name2color(value);
-						selectedBuggle.setColor(c);
-					} catch (InvalidColorNameException icn) {
-						table.setValueAt(ColorMapper.color2name(selectedBuggle.getColor()),rank,1);
-					}
-				}
-			}});
-			/*---------- Buggle color ---------------*/
-			model.addRow(new Object[] {i18n.tr("Brush color (name or r/g/b)"), new JLMProperty(properties) {
-				@Override
-				public String toString() {
-					return ColorMapper.color2name( selectedBuggle.getBrushColor() );
-				}
-				@Override
-				public void setValue(String value) {
-					try {
-						Color c = ColorMapper.name2color(value);
-						selectedBuggle.setBrushColor(c);
-					} catch (InvalidColorNameException icn) {
-						table.setValueAt(ColorMapper.color2name(selectedBuggle.getBrushColor()),rank,1);
-					}
-				}
-			}});
-		}
-	}
-	@Override
-	public void setWorld(World w) {
-		if (((BuggleWorld) w).getSelectedCell() == null)
-			((BuggleWorld) w).setSelectedCell(0,0);
-		repopulateTable();		
-		
-	}
-	@Override
-	public void worldEdited() {
-		BuggleWorldCell selected = editor.getWorld().getSelectedCell();
-		
-		table.setValueAt(""+selected.getX(),selectedXRank,1);
-		table.setValueAt(""+selected.getY(),selectedYRank,1);
-		table.setValueAt(selected.hasTopWall() ?"Y":"N", topRank, 1);
-		table.setValueAt(selected.hasLeftWall()?"Y":"N", leftRank,1);
-		table.setValueAt(selected.hasBaggle()?"Y":"N", baggleRank,1);
-	}
-	@Override
-	public void selectedChanged(int x, int y, Entity ent) {
-		selectedBuggle = (AbstractBuggle) ent;
-		repopulateTable();
-	}
-}
-
-class MyTableModelListener implements TableModelListener {
-	private JTable table;
-	private Vector<JLMProperty> properties;
-
-	private boolean ongoing = false;
-	
-	MyTableModelListener(Editor e, JTable t, Vector<JLMProperty> props) {
-		table = t;
-		properties = props;
-	}
-	public void tableChanged(TableModelEvent e) {
-		if (ongoing) 
-			return;
-		
-		ongoing = true;
-		int row = e.getFirstRow(); // selections are SINGLE_SELECTION anyway, so ignore getLastRow
-
-		if (e.getType() == TableModelEvent.UPDATE) 
-			for (JLMProperty p : properties) 
-				if (p.rank == row) 
-					p.setValue(""+ table.getModel().getValueAt(row, 1));
-		ongoing = false;
-	}
-}
-
-abstract class JLMProperty {
-	public int rank;
-	public JLMProperty(Vector<JLMProperty> props) {
-		rank = props.size();
-		props.add(this);
-	}
-	public abstract void setValue(String value);
-	public abstract String toString();
-}
diff --git a/src/jlm/universe/bugglequest/mapeditor/package-info.java b/src/jlm/universe/bugglequest/mapeditor/package-info.java
deleted file mode 100644
index 5a6b81f..0000000
--- a/src/jlm/universe/bugglequest/mapeditor/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * This package contains another binary, which can be used to edit BuggleWorld maps
- */
-package jlm.universe.bugglequest.mapeditor;
-
diff --git a/src/jlm/universe/bugglequest/package-info.java b/src/jlm/universe/bugglequest/package-info.java
deleted file mode 100644
index f185a20..0000000
--- a/src/jlm/universe/bugglequest/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Universe of the buggles, allowing simple control yet rich interactions with the environment.
- */
-package jlm.universe.bugglequest;
-
diff --git a/src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java b/src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java
deleted file mode 100644
index b874945..0000000
--- a/src/jlm/universe/bugglequest/ui/BuggleButtonPanel.java
+++ /dev/null
@@ -1,240 +0,0 @@
-package jlm.universe.bugglequest.ui;
-
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.GridLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.util.Locale;
-
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JToggleButton;
-
-import jlm.core.model.Game;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.bugglequest.AbstractBuggle;
-import jlm.universe.bugglequest.exception.BuggleWallException;
-
-public class BuggleButtonPanel extends EntityControlPanel {
-
-	private static final long serialVersionUID = 1L;
-	private JButton fButton;
-	private JButton bButton;
-	private JButton rButton;
-	private JButton lButton;
-	private JToggleButton brushButton;
-	private JComboBox buggleColorComboBox;
-	private JComboBox brushColorComboBox;
-	private JLabel lBuggleColor;
-	private JLabel lBrushColor;
-	
-	public BuggleButtonPanel() {
-		setLayout(new FlowLayout());
-		
-		initializeButtons();
-		initializeColorsBoxes();
-
-		add(createButtonsPanel());
-		add(createColorsBoxes());
-
-		Game.getInstance().addHumanLangListener(this);
-	}
-
-	/**
-	 * Initialize fButton, bButton, rButton, lButton and brushButton
-	 */
-	private void initializeButtons() {
-		fButton = new JButton(i18n.tr("forward"));
-		fButton.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				try {
-					((AbstractBuggle)Game.getInstance().getSelectedEntity()).forward();
-				} catch (BuggleWallException e) {
-					showWallHuggingErrorMessageDialog();
-					// e.printStackTrace();
-					//game.getOutputWriter().log(e);
-				}
-			}
-		});
-		fButton.setMnemonic(KeyEvent.VK_UP);
-
-		bButton = new JButton(i18n.tr("backward"));
-		bButton.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				try {
-					((AbstractBuggle)Game.getInstance().getSelectedEntity()).backward();
-				} catch (BuggleWallException e) {
-					showWallHuggingErrorMessageDialog();
-					// e.printStackTrace();
-					// Game.getInstance().getOutputWriter().log(e);
-				}
-			}
-		});
-		bButton.setMnemonic(KeyEvent.VK_DOWN);
-
-		lButton = new JButton(i18n.tr("turn left"));
-		lButton.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				((AbstractBuggle)Game.getInstance().getSelectedEntity()).turnLeft();
-			}
-		});
-		lButton.setMnemonic(KeyEvent.VK_LEFT);
-
-		rButton = new JButton(i18n.tr("turn right"));
-		rButton.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				((AbstractBuggle)Game.getInstance().getSelectedEntity()).turnRight();
-			}
-		});
-		rButton.setMnemonic(KeyEvent.VK_RIGHT);
-
-		brushButton = new JToggleButton(i18n.tr("mark"));
-		brushButton.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				AbstractBuggle b = (AbstractBuggle)Game.getInstance().getSelectedEntity();
-				if (b.isBrushDown()) {
-					b.brushUp();
-				} else {
-					b.brushDown();
-				}
-			}
-		});
-		brushButton.setMnemonic(KeyEvent.VK_SPACE);
-		brushButton.setSelected(((AbstractBuggle)(Game.getInstance().getSelectedEntity())).isBrushDown());
-	}
-
-	/**
-	 * Initialize buggleColorComboBox and brushColorComboBox
-	 */
-	private void initializeColorsBoxes() {
-		Color[] colors = {Color.BLUE, Color.BLACK, Color.CYAN, Color.DARK_GRAY,
-				  Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, 
-				  Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW};
-		
-		brushColorComboBox=new JComboBox (colors);
-		brushColorComboBox.setRenderer(new BuggleColorCellRenderer());
-		brushColorComboBox.setSelectedItem(((AbstractBuggle)Game.getInstance().getSelectedEntity()).getBrushColor());
-		brushColorComboBox.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				JComboBox cb = (JComboBox) event.getSource();
-				Color c = (Color) cb.getSelectedItem();
-				cb.setSelectedItem(c);
-				((AbstractBuggle)Game.getInstance().getSelectedEntity()).setBrushColor(c);
-			}
-		});
-		
-		buggleColorComboBox=new JComboBox (colors);
-		buggleColorComboBox.setRenderer(new BuggleColorCellRenderer());
-		buggleColorComboBox.setSelectedItem(((AbstractBuggle)Game.getInstance().getSelectedEntity()).getColor());
-		buggleColorComboBox.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				JComboBox cb = (JComboBox) event.getSource();
-				Color c = (Color) cb.getSelectedItem();
-				cb.setSelectedItem(c);
-				((AbstractBuggle)Game.getInstance().getSelectedEntity()).setColor(c);
-			}
-		});
-	}
-
-	/**
-	 * Add the five buttons to a JPanel and return the JPanel
-	 * @return a JPanel where the five buttons have been added
-	 */
-	private JPanel createButtonsPanel() {
-		JPanel buttonsPanel = new JPanel();
-		
-		GridBagLayout gdLayout = new GridBagLayout();
-		buttonsPanel.setLayout(gdLayout);
-
-		GridBagConstraints c = new GridBagConstraints();
-		c.insets = new Insets(3, 3, 3, 3);
-
-		c.gridy = 1;
-		c.gridx = 1;
-		c.gridwidth = 1;
-		gdLayout.setConstraints(fButton, c);
-		buttonsPanel.add(fButton);
-
-		c.gridy = 2;
-		c.gridx = 0;
-		gdLayout.setConstraints(lButton, c);
-		buttonsPanel.add(lButton);
-
-		c.gridy = 2;
-		c.gridx = 1;
-		c.fill = GridBagConstraints.HORIZONTAL;
-		gdLayout.setConstraints(brushButton, c);
-		buttonsPanel.add(brushButton);
-
-		c.gridy = 2;
-		c.gridx = 2;
-		gdLayout.setConstraints(rButton, c);
-		buttonsPanel.add(rButton);
-
-		c.gridy = 3;
-		c.gridx = 1;
-		gdLayout.setConstraints(bButton, c);
-		buttonsPanel.add(bButton);
-		
-		return buttonsPanel;
-	}
-
-	/**
-	 * Add the two combo boxes to a JPanel and return the JPanel
-	 * @return a JPanel where the two combo boxes have been added
-	 */
-	private JPanel createColorsBoxes() {
-		JPanel colorsPanel = new JPanel();
-		colorsPanel.setLayout(new GridLayout(4,1));
-		
-		lBrushColor = new JLabel("Brush Color");
-		colorsPanel.add(lBrushColor);
-		colorsPanel.add(brushColorComboBox);
-		
-		lBuggleColor = new JLabel("Buggle Color");
-		colorsPanel.add(lBuggleColor);
-		colorsPanel.add(buggleColorComboBox);
-		
-		return colorsPanel;
-	}
-	
-	@Override
-	public void setEnabledControl(boolean enabled) {
-		fButton.setEnabled(enabled);
-		bButton.setEnabled(enabled);
-		lButton.setEnabled(enabled);
-		rButton.setEnabled(enabled);
-		brushButton.setEnabled(enabled);
-		buggleColorComboBox.setEnabled(enabled);
-		brushColorComboBox.setEnabled(enabled);
-	}
-	
-	public void showWallHuggingErrorMessageDialog() {
-		String message ;
-		String title = i18n.tr("Wall hugging error");
-		message = i18n.tr("Your buggle has collided with a wall, it hurts a lot ! ='(");
-		JOptionPane.showMessageDialog(null, message,title, JOptionPane.ERROR_MESSAGE);
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n.setLocale(newLang);
-		
-		bButton.setText(i18n.tr("backward"));
-		fButton.setText(i18n.tr("forward"));
-		lButton.setText(i18n.tr("turn left"));
-		rButton.setText(i18n.tr("turn right"));
-		brushButton.setText(i18n.tr("mark"));
-		lBrushColor.setText(i18n.tr("Brush Color"));
-		lBuggleColor.setText(i18n.tr("Buggle Color"));
-	}
-	
-}
diff --git a/src/jlm/universe/bugglequest/ui/BuggleColorCellRenderer.java b/src/jlm/universe/bugglequest/ui/BuggleColorCellRenderer.java
deleted file mode 100644
index 8b1d2af..0000000
--- a/src/jlm/universe/bugglequest/ui/BuggleColorCellRenderer.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package jlm.universe.bugglequest.ui;
-
-import java.awt.Color;
-import java.awt.Component;
-
-import javax.swing.JButton;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.ListCellRenderer;
-
-/**
- * This cell renderer is used by the combo boxes from BuggleButtonPanel in order to show some fancy colored rectangles.
- * @see ListCellRenderer
- * @see BuggleButtonPanel
- */
-public class BuggleColorCellRenderer extends JPanel implements ListCellRenderer{
-
-	private static final long serialVersionUID = 1L;
-
-    private JButton cell;	// The container of the colored rectangle
-    
-    /**
-     * Constructor of BuggleColorCellRenderer
-     * It initializes the cell and add it to the BuggleColorCellRenderer
-     */
-    public BuggleColorCellRenderer() {
-        super();
-        this.cell = new JButton();
-        this.add(this.cell);
-    }
-    
-    /**
-     * Change the color of the cell according to the selected value
-     * @return The BuggleColorCellRenderer with the cell's background of color "value" 
-     * @param list Unused here
-     * @param value The color that we will assign to our cell. Since it's sure that value is an instance of Color, it's not necessary to check it.
-     * @param index Unused here
-     * @param isSelected Unused here
-     * @param cellHasFocus Unused here
-     */
-    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
-        this.cell.setBackground((Color) value);
-        this.cell.setOpaque(true);
-        this.cell.setBorderPainted(false);
-        return this;
-    }
-
-}
\ No newline at end of file
diff --git a/src/jlm/universe/bugglequest/ui/BuggleWorldView.java b/src/jlm/universe/bugglequest/ui/BuggleWorldView.java
deleted file mode 100644
index c68ee77..0000000
--- a/src/jlm/universe/bugglequest/ui/BuggleWorldView.java
+++ /dev/null
@@ -1,318 +0,0 @@
-package jlm.universe.bugglequest.ui;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.imageio.ImageIO;
-import javax.swing.ImageIcon;
-
-import jlm.core.ui.WorldView;
-import jlm.universe.Entity;
-import jlm.universe.World;
-import jlm.universe.bugglequest.AbstractBuggle;
-import jlm.universe.bugglequest.Baggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.BuggleWorldCell;
-
-
-
-public class BuggleWorldView extends WorldView {
-
-	private static final long serialVersionUID = -7164642270965762239L;
-
-
-	private static Color DARK_CELL_COLOR = new Color(0.93f,0.93f,0.93f);
-	private static Color LIGHT_CELL_COLOR = new Color(0.95f,0.95f,0.95f);
-	private static Color GRID_COLOR = new Color(0.8f,0.8f,0.8f);
-	private static Color WALL_COLOR = new Color(0.0f,0.0f,0.5f);
-	
-	public BuggleWorldView (World w) {
-		super(w);
-	}
-		
-	protected double getCellWidth() {
-		return (double) Math.min(getHeight() / ((BuggleWorld)world).getHeight() , getWidth() /  ((BuggleWorld)world).getWidth());
-	}
-	
-	protected double getPadX() {
-		return (getWidth() - getCellWidth() * ((BuggleWorld)world).getWidth()) / 2;
-	}
-	protected double getPadY() {
-		return (getHeight() - getCellWidth() * ((BuggleWorld)world).getHeight()) / 2;
-	}
-
-
-	@Override
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-		Graphics2D g2 = (Graphics2D) g;
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
-		drawBackground(g2);
-		
-		for (Entity ent: world.getEntities()) {
-			AbstractBuggle b = (AbstractBuggle)ent;  	
-			drawBuggle(g2, b);
-		}
-		
-		drawWalls(g2);
-	}
-	
-	// return the color of the cell located at position (x,y)
-	private Color getCellColor(int x, int y) {
-		BuggleWorldCell cell = (BuggleWorldCell) ((BuggleWorld)world).getCell(x, y);
-
-		if (BuggleWorldCell.DEFAULT_COLOR.equals(cell.getColor())) {
-			if (((BuggleWorld) world).getVisibleGrid()) { 
-				if ((x+y)%2==0)
-					return DARK_CELL_COLOR;	
-				else
-					return LIGHT_CELL_COLOR;
-			} else {
-				return Color.WHITE;
-			}
-		} else {
-			return cell.getColor();
-		}		
-	}
-	
-	private void drawBackground(Graphics2D g) {
-		double cellW = getCellWidth();
-		double padx = getPadX();
-		double pady = getPadY();
-		BuggleWorld w = (BuggleWorld)world;
-
-		if (w.getVisibleGrid() == false) {
-			g.setColor(Color.white);
-			g.fill(new Rectangle2D.Double(padx,pady ,(w.getWidth()-1)*cellW,(w.getHeight()-1)*cellW));				
-		}
-		for (int x=0; x<w.getWidth(); x++) {
-			for (int y=0; y<w.getHeight(); y++) {
-				g.setColor(getCellColor(x, y));
-				
-				BuggleWorldCell cell = (BuggleWorldCell) w.getCell(x, y);
-
-				g.fill(new Rectangle2D.Double(padx+x*cellW, pady+y*cellW, cellW, cellW));	
-				
-				if (cell.hasBaggle())
-					drawBaggle(g, cell, cell.getBaggle());
-				if (cell.hasContent())
-					drawMessage(g, cell, cell.getContent());
-			}
-		}
-
-		if (((BuggleWorld) world).getVisibleGrid()) {
-			g.setColor(GRID_COLOR);
-			for (int x=0; x<=w.getWidth(); x++) {
-				g.draw(new Line2D.Double(padx+x*cellW, pady, padx+x*cellW, pady+w.getHeight()*cellW));
-			}
-			for (int y=0; y<=w.getHeight(); y++) {
-				g.draw(new Line2D.Double(padx+0, pady+y*cellW, padx+w.getWidth()*cellW, pady+y*cellW));						
-			}
-		}
-	}
-	
-	private void drawWalls(Graphics2D g) {
-		double cellW = getCellWidth();
-		double padx = getPadX();
-		double pady = getPadY();
-		BuggleWorld w = (BuggleWorld)world;
-
-		int width = w.getWidth();
-		int height = w.getHeight();
-		
-		g.setColor(WALL_COLOR);
-		
-		for (int x = 0; x < width; x++) {
-			for (int y = 0; y < height; y++) {
-				BuggleWorldCell cell = (BuggleWorldCell) w.getCell(x, y);
-
-				if (cell.hasTopWall()) {
-					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW-1, padx+(x+1)*cellW, pady+y*cellW-1));						
-					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW, padx+(x+1)*cellW, pady+y*cellW));						
-					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW+1, padx+(x+1)*cellW, pady+y*cellW+1));						
-				}
-				
-				if (cell.hasLeftWall()) {
-					g.draw(new Line2D.Double(padx+x*cellW-1, pady+y*cellW, padx+x*cellW-1, pady+(y+1)*cellW));
-					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW, padx+x*cellW, pady+(y+1)*cellW));
-					g.draw(new Line2D.Double(padx+x*cellW+1, pady+y*cellW, padx+x*cellW+1, pady+(y+1)*cellW));
-				}
-			}
-		}
-
-		// frontier walls (since the world is a torus)
-		for (int y = 0; y < height; y++) {
-			if (((BuggleWorldCell) w.getCell(0, y)).hasLeftWall()) {
-				g.draw(new Line2D.Double(padx+width*cellW-1, pady+y*cellW, padx+width*cellW-1, pady+(y+1)*cellW));
-				g.draw(new Line2D.Double(padx+width*cellW, pady+y*cellW, padx+width*cellW, pady+(y+1)*cellW));
-				g.draw(new Line2D.Double(padx+width*cellW+1, pady+y*cellW, padx+width*cellW+1, pady+(y+1)*cellW));				
-			}
-		}
-
-		for (int x = 0; x < width; x++) {
-			if (((BuggleWorldCell) w.getCell(x, 0)).hasTopWall()) {
-				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW-1, padx+(x+1)*cellW, pady+height*cellW-1));						
-				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW, padx+(x+1)*cellW, pady+height*cellW));						
-				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW+1, padx+(x+1)*cellW, pady+height*cellW+1));						
-			}
-		}	
-	}
-	
-	private void drawBuggle(Graphics2D g, AbstractBuggle b) {
-		double scaleFactor = 0.6; // to scale the sprite
-		double pixW = scaleFactor * getCellWidth() / INVADER_SPRITE_SIZE;  // fake pixel width
-		double pad = 0.5*(1.0-scaleFactor)*getCellWidth(); // padding to center sprite in the cell
-		double padx = getPadX();
-		double pady = getPadY();
-	
-		double ox = b.getX()*getCellWidth(); // x-offset of the cell
-		double oy = b.getY()*getCellWidth(); // y-offset of the cell
-		
-		if (b.isBrushDown()) {
-			if (Color.BLACK.equals(b.getBrushColor())) 
-				g.setColor(Color.WHITE);
-			else
-				g.setColor(Color.BLACK);
-		} else
-			g.setColor(b.getColor());
-
-		if (((BuggleWorld)world).easter) {
-			try {
-				InputStream is = getClass().getResourceAsStream("/jlm/universe/bugglequest/ui/rabbit.png");
-				ImageIcon ic = new ImageIcon(ImageIO.read(is));
-				g.drawImage(ic.getImage(), (int)(padx+ox),(int)(pady+oy), (int)getCellWidth(),(int)getCellWidth(),null);
-			} catch (IOException e) {
-				// Forget it
-				((BuggleWorld)world).easter = false;
-				return;
-			}
-			
-		} else {
-			for (int dy=0; dy<INVADER_SPRITE_SIZE; dy++) {
-				for (int dx=0; dx<INVADER_SPRITE_SIZE; dx++) {
-					int direction = b.getDirection().intValue();
-					if (INVADER_SPRITE[direction][dy][dx] == 1) {
-						g.fill(new Rectangle2D.Double(padx+pad+ox+dx*pixW, pady+pad+oy+dy*pixW, pixW, pixW));
-					}
-				}				
-			}
-		}
-	}
-	
-	private void drawBaggle(Graphics2D g, BuggleWorldCell cell, Baggle b) {
-		double padx = getPadX();
-		double pady = getPadY();
-	
-		double scaleFactor = 0.8; // to scale the sprite
-
-		double d = scaleFactor*getCellWidth();
-		double pad = 0.5*(1.0-scaleFactor)*getCellWidth(); // padding to center sprite in the cell
-
-		double scaleFactor2 = 0.5; // to scale the sprite
-
-		double d2 = scaleFactor2*scaleFactor*getCellWidth();
-		double pad2 = 0.5*(1.0-scaleFactor*scaleFactor2)*getCellWidth(); // padding to center sprite in the cell
-		
-		double ox = cell.getX()*getCellWidth(); // x-offset of the cell
-		double oy = cell.getY()*getCellWidth(); // y-offset of the cell
-		
-		if (((BuggleWorld)world).easter) {
-			try {
-				InputStream is = getClass().getResourceAsStream("/jlm/universe/bugglequest/ui/egg.png");
-				ImageIcon ic = new ImageIcon(ImageIO.read(is));
-				g.drawImage(ic.getImage(), (int)(padx+ox),(int)(pady+oy), (int)getCellWidth(),(int)getCellWidth(),null);
-			} catch (IOException e) {
-				// Forget it
-				((BuggleWorld)world).easter = false;
-				return;
-			}
-			
-		} else {
-			g.setColor(Baggle.DEFAULT_COLOR);
-			g.fill(new Arc2D.Double(padx+ox+pad, pady+oy+pad, d, d, 0, 360, Arc2D.CHORD));
-			g.setColor(getCellColor(cell.getX(), cell.getY()));
-			g.fill(new Arc2D.Double(padx+ox+pad2, pady+oy+pad2, d2, d2, 0, 360, Arc2D.CHORD));
-
-			g.setColor(Baggle.DEFAULT_COLOR.darker().darker());
-			g.draw(new Arc2D.Double(padx+ox+pad, pady+oy+pad, d, d, 0, 360, Arc2D.CHORD));
-			g.draw(new Arc2D.Double(padx+ox+pad2, pady+oy+pad2, d2, d2, 0, 360, Arc2D.CHORD));
-		}
-	}
-	
-	private void drawMessage(Graphics2D g, BuggleWorldCell cell, String msg) {
-		double padx = getPadX();
-		double pady = getPadY();
-		double ox = cell.getX()*getCellWidth(); // x-offset of the cell
-		double oy = (cell.getY()+1)*getCellWidth(); // y-offset of the cell
-
-		
-		g.setColor(cell.getMsgColor());
-		g.drawString(msg, (float) (padx+ox)+1, (float) (pady+oy)-4);	
-	}
-
-	
-
-	// old style ;b
-	private static int INVADER_SPRITE_SIZE = 11;
-	private static int[][][] INVADER_SPRITE = {
-	{
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-		{ 0,0,1,0,0,0,0,0,1,0,0 },
-		{ 0,0,0,1,0,0,0,1,0,0,0 },
-		{ 0,0,1,1,1,1,1,1,1,0,0 },
-		{ 0,1,1,0,1,1,1,0,1,1,0 },
-		{ 1,1,1,1,1,1,1,1,1,1,1 },
-		{ 1,0,1,1,1,1,1,1,1,0,1 },
-		{ 1,0,1,0,0,0,0,0,1,0,1 },
-		{ 0,0,0,1,1,0,1,1,0,0,0 },
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-	},
-	{
-	    { 0,0,0,1,1,1,0,0,0,0,0 },
-		{ 0,0,0,0,0,1,1,0,0,0,0 },
-		{ 0,0,0,1,1,1,1,1,0,1,0 },
-		{ 0,0,1,0,1,1,0,1,1,0,0 },
-		{ 0,0,1,0,1,1,1,1,0,0,0 },
-		{ 0,0,0,0,1,1,1,1,0,0,0 },
-		{ 0,0,1,0,1,1,1,1,0,0,0 },
-		{ 0,0,1,0,1,1,0,1,1,0,0 },
-		{ 0,0,0,1,1,1,1,1,0,1,0 },
-		{ 0,0,0,0,0,1,1,0,0,0,0 },
-		{ 0,0,0,1,1,1,0,0,0,0,0 }
-	},
-	{
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-		{ 0,0,0,1,1,0,1,1,0,0,0 },
-		{ 1,0,1,0,0,0,0,0,1,0,1 },
-		{ 1,0,1,1,1,1,1,1,1,0,1 },
-		{ 1,1,1,1,1,1,1,1,1,1,1 },
-		{ 0,1,1,0,1,1,1,0,1,1,0 },
-		{ 0,0,1,1,1,1,1,1,1,0,0 },
-		{ 0,0,0,1,0,0,0,1,0,0,0 },
-		{ 0,0,1,0,0,0,0,0,1,0,0 },
-		{ 0,0,0,0,0,0,0,0,0,0,0 },
-	},
-	{
-		{ 0,0,0,0,0,1,1,1,0,0,0 },
-		{ 0,0,0,0,1,1,0,0,0,0,0 },
-		{ 0,1,0,1,1,1,1,1,0,0,0 },
-		{ 0,0,1,1,0,1,1,0,1,0,0 },
-		{ 0,0,0,1,1,1,1,0,1,0,0 },
-		{ 0,0,0,1,1,1,1,0,0,0,0 },
-		{ 0,0,0,1,1,1,1,0,1,0,0 },
-		{ 0,0,1,1,0,1,1,0,1,0,0 },
-		{ 0,1,0,1,1,1,1,1,0,0,0 },
-		{ 0,0,0,0,1,1,0,0,0,0,0 },
-		{ 0,0,0,0,0,1,1,1,0,0,0 }
-	}};
-}
diff --git a/src/jlm/universe/bugglequest/ui/package-info.java b/src/jlm/universe/bugglequest/ui/package-info.java
deleted file mode 100644
index 76fecfa..0000000
--- a/src/jlm/universe/bugglequest/ui/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * User interface elements of the buggle world
- */
-package jlm.universe.bugglequest.ui;
-
diff --git a/src/jlm/universe/lightbot/LightBotEditorPanel.java b/src/jlm/universe/lightbot/LightBotEditorPanel.java
deleted file mode 100644
index e13afd4..0000000
--- a/src/jlm/universe/lightbot/LightBotEditorPanel.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package jlm.universe.lightbot;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.BorderFactory;
-import javax.swing.Icon;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.border.BevelBorder;
-
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.ISourceFileListener;
-import jlm.core.ui.IEditorPanel;
-import jlm.core.ui.ResourcesCache;
-import jlm.universe.Entity;
-import jlm.universe.IEntityStackListener;
-import net.miginfocom.swing.MigLayout;
-
-public class LightBotEditorPanel extends JScrollPane implements IEditorPanel,ISourceFileListener,IEntityStackListener {
-	private static final long serialVersionUID = 1L;
-	LightBotSourceFile srcFile;
-	Map<String,InstructionChooser> choosers=new HashMap<String, InstructionChooser>();
-	InstructionChooser selectedChooser = null;
-	Entity tracedEntity;
-	private Map<String,Icon> iconsByNames = new HashMap<String, Icon>();
-	private Map<Icon,String> iconNameByIcons = new HashMap<Icon,String>();
-	private Icon[] iconList;
-
-	public LightBotEditorPanel(LightBotSourceFile srcFile) {
-		super();
-		
-		iconList = new Icon[LightBotInstruction.instructionNames.length];
-		int i=0;
-		for (String n:LightBotInstruction.instructionNames) {
-			iconList[i] =ResourcesCache.getIcon("img/lightbot_"+n+".png");
-			iconNameByIcons.put(iconList[i],n);
-			iconsByNames.put(n,iconList[i]);
-			i++;
-		}
-		
-		this.srcFile = srcFile;
-		srcFile.setListener(this);
-		sourceFileContentHasChanged();
-		tracedEntity = Game.getInstance().getSelectedEntity();
-		tracedEntity.addStackListener(this);
-	}
-	@Override
-	public void clear() {
-		srcFile.removeListener();
-		if (tracedEntity != null)
-			tracedEntity.removeStackListener(this);
-	}
-	@Override
-	public void sourceFileContentHasChanged() {
-
-		/* Main function */
-		JPanel mainPanel = new JPanel();
-		mainPanel.setBorder(BorderFactory.createTitledBorder("Main"));
-		mainPanel.setLayout(new MigLayout("wrap 4, fill"));
-		for (int i=0;i<srcFile.getMain().length;i++) {
-			InstructionChooser chooser = new InstructionChooser(srcFile.getMain(),i);
-			choosers.put("main:"+i, chooser);
-			mainPanel.add(chooser, "grow");
-		}
-
-		/* Func 1 */
-		JPanel func1Panel = new JPanel();
-		func1Panel.setBorder(BorderFactory.createTitledBorder("Function 1"));
-		func1Panel.setLayout(new MigLayout("wrap 4, fill"));
-		for (int i=0;i<srcFile.getFunc1().length;i++) { 
-			InstructionChooser chooser = new InstructionChooser(srcFile.getFunc1(),i);
-			choosers.put("func1:"+i, chooser);
-			func1Panel.add(chooser, "grow");
-		}
-
-		/* Func 2 */
-		JPanel func2Panel = new JPanel();
-		func2Panel.setBorder(BorderFactory.createTitledBorder("Function 2"));
-		func2Panel.setLayout(new MigLayout("wrap 4, fill"));
-		for (int i=0;i<srcFile.getFunc2().length;i++) {
-			InstructionChooser chooser = new InstructionChooser(srcFile.getFunc2(),i); 
-			choosers.put("func2:"+i, chooser);
-			func2Panel.add(chooser, "grow");
-		}
-		for (InstructionChooser ic:choosers.values()) 
-			ic.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
-
-		/* Put everything together */
-		JPanel global = new JPanel();
-		global.setLayout(new MigLayout("wrap 1, fill"));
-		global.add(mainPanel,"grow");
-		global.add(func1Panel,"grow");
-		global.add(func2Panel,"grow");
-		setViewportView(global);
-		doLayout();
-	}
-
-	private class InstructionChooser extends JComboBox {
-		public InstructionChooser(final LightBotInstruction[] func, final int pos) {
-			super(iconList);
-			this.addActionListener(new ActionListener() {
-				@Override
-				public void actionPerformed(ActionEvent arg0) {
-					func[pos] = new LightBotInstruction(iconNameByIcons.get((Icon) InstructionChooser.this.getSelectedItem()));
-				}				
-			});
-			setSelectedItem(iconsByNames.get(func[pos].toString()));
-		}
-
-		private static final long serialVersionUID = 7308818147531552628L;
-
-	}
-
-	@Override
-	public void entityTraceChanged(Entity e, StackTraceElement[] trace) {
-		if (selectedChooser != null)
-			selectedChooser.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
-		if (trace != null && trace[0]!=null) {
-			selectedChooser = choosers.get(trace[0].getMethodName()+":"+trace[0].getLineNumber());
-			if (selectedChooser!=null)
-				selectedChooser.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
-		}
-	}
-
-	@Override
-	public void tracedEntityChanged(Entity e) {
-		if (tracedEntity != null)
-			tracedEntity.removeStackListener(this);
-		tracedEntity =  e;
-		tracedEntity.addStackListener(this);
-		entityTraceChanged(e, tracedEntity.getCurrentStack());
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotEntity.java b/src/jlm/universe/lightbot/LightBotEntity.java
deleted file mode 100644
index 519a93c..0000000
--- a/src/jlm/universe/lightbot/LightBotEntity.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package jlm.universe.lightbot;
-
-import java.awt.Point;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Exercise;
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.GridWorld;
-import jlm.universe.World;
-
-
-
-public class LightBotEntity extends Entity  {
-	private int x;
-	private int y;
-
-	Direction direction;
-	
-	StackTraceElement[] tracedStack = new StackTraceElement[1];
-	
-	/**
-	 * Constructor with no argument so that child classes can avoid declaring a
-	 * constructor. But it should not be used as most methods assert on world
-	 * being not null. After using it, {@link jlm.universe.Entity#setWorld(LightBotWorld)} must be used
-	 * ASAP.
-	 */
-	public LightBotEntity() {
-		this(null, "John Doe", 0, 0, Direction.NORTH);
-	}
-
-	public LightBotEntity(GridWorld w) {
-		this(w, "John Doe", 0, 0, Direction.NORTH);
-	}
-
-	public LightBotEntity(World world, String name, int x, int y, Direction direction2) {
-		super(name,world);
-		this.setX(x);
-		this.setY(y);
-		this.direction = direction2;
-	}
-	@Override
-	public void copy(Entity e) {
-		super.copy(e);
-		LightBotEntity other = (LightBotEntity)e;
-		this.setX(other.getX());
-		this.setY(other.getY());
-		this.direction = other.direction;
-	}
-	@Override
-	public Entity copy() {
-		LightBotEntity lb = new LightBotEntity();
-		lb.setWorld(getWorld());
-		lb.setName(getName());
-		lb.setPos(getX(), getY());
-		lb.setDirection(direction);
-		return lb;
-	}
-
-
-	public void setDirection(Direction d) {
-		direction=d;
-	}
-	public Direction getDirection() {
-		return direction;
-	}
-
-	public int getWorldHeight() {
-		return ((GridWorld)world).getHeight();
-	}
-
-	public int getWorldWidth() {
-		return ((GridWorld)world).getWidth();
-	}
-	public LightBotWorldCell getCell(){
-		return (LightBotWorldCell) ((GridWorld) world).getCell(getX(), getY());
-	}
-	protected LightBotWorldCell getCell(int u, int v){
-		return (LightBotWorldCell) ((GridWorld) world).getCell(u, v);
-	}
-	private int bounded(int x,int max) {
-		if (x<0)
-			return 0;
-		if (x>=max)
-			return max-1;
-		return x;
-	}
-	
-	private LightBotWorldCell getCellNeighbor(Point delta) {
-		return getCell( bounded((getX()+delta.x),getWorldWidth()) , bounded((getY()+delta.y),getWorldHeight()));
-	}
-
-
-	public void setPos(int x, int y) {
-		this.setX(x);
-		this.setY(y);
-	}
-	public void forward() {
-		if (getCellNeighbor(getDirection().toPoint()).getHeight() == getCell().getHeight())
-			move();
-		else 
-			System.out.println("facing wall");
-	}
-	public void jump(){
-		int heightHere = getCell().getHeight();
-		int heightThere = getCellNeighbor(getDirection().toPoint()).getHeight();
-		
-		if ( (heightThere - heightHere  == 1 /*jump one up*/) || 
-		     (heightHere > heightThere /*jump down*/))
-			move();
-		else 
-			System.out.println("cannot jump here");
-	}
-
-	private void move() {
-		int newx = bounded(getX() + getDirection().toPoint().x , getWorldWidth());
-		int newy = bounded(getY() + getDirection().toPoint().y , getWorldHeight());
-		setX(newx);
-		setY(newy);
-	}
-
-	public void left() {
-		direction=getDirection().left();
-	}
-	public void right() {
-		direction=getDirection().right();
-	}
-	public void light() {
-		((LightBotWorld) world).switchLight(getX(),getY());
-	}
-	
-
-	@Override
-	public String toString() {
-		return "LightBot (" + this.getClass().getName() + "): x=" + getX() + " y=" + getY() + " Direction:" + direction;
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((direction == null) ? 0 : direction.hashCode());
-		result = PRIME * result + getX();
-		result = PRIME * result + getY();
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (!(obj instanceof LightBotEntity))
-			return false;
-
-		final LightBotEntity other = (LightBotEntity) obj;
-		if (direction == null) {
-			if (other.direction != null)
-				return false;
-		} else if (!direction.equals(other.direction))
-			return false;
-		if (getX() != other.getX())
-			return false;
-		if (getY() != other.getY())
-			return false;
-		return true;
-	}
-
-
-
-	LightBotSourceFile sf;
-	@Override
-	public void run() {
-		sf = (LightBotSourceFile) ((Exercise) Game.getInstance().getCurrentLesson().getCurrentExercise()).getSourceFile(Game.LIGHTBOT,0);
-				
-		/* Run main */
-		run("main",sf.getMain());
-		tracedStack[0] = new StackTraceElement("LightbotEntity","main","main",1);
-		fireStackListener();
-	}
-	public void runF1(){
-		run("func1",sf.getFunc1());
-	}
-	public void runF2(){
-		run("func2",sf.getFunc2());
-	}
-
-	private void run(String fileName,LightBotInstruction[] file) {
-		if (file == null)
-			return;
-		int line=0;
-		for (LightBotInstruction i: file) {
-			tracedStack[0] = new StackTraceElement("LightbotEntity",fileName,fileName,line++);
-			fireStackListener();
-			if (i!=null && !i.isNoop())
-			stepUI();
-			if (i!=null)
-				i.run(this);
-		}
-	}
-
-	public void setX(int x) {
-		this.x = x;
-	}
-	public int getX() {
-		return x;
-	}
-	public void setY(int y) {
-		this.y = y;
-	}
-	public int getY() {
-		return y;
-	}
-
-	@Override
-	public StackTraceElement[] getCurrentStack() {
-		return tracedStack;
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotExercise.java b/src/jlm/universe/lightbot/LightBotExercise.java
deleted file mode 100644
index 702a4db..0000000
--- a/src/jlm/universe/lightbot/LightBotExercise.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package jlm.universe.lightbot;
-
-import java.util.List;
-import java.util.Vector;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-
-public class LightBotExercise extends ExerciseTemplated {
-	public LightBotExercise(Lesson lesson) {
-		super(lesson);
-		addProgLanguage(Game.LIGHTBOT);
-		if (getProgLanguages().size()>1) 
-			throw new RuntimeException("More than one language defined in a LightbotExercise. Please report this bug.");
-		getSourceFilesList(Game.LIGHTBOT).add(new LightBotSourceFile("Code"));
-	}
-
-	@Override
-	protected void setup(World[] ws) {
-		for (World w : ws) 
-			((LightBotWorld) w).rotateLeft();
-		
-		setupWorlds(ws);
-		/* remove entities from the answer world: we don't care of where the bot is at the end */
-		for (World w :answerWorld)
-			w.emptyEntities();
-		computeAnswer();
-	}
-
-	@Override
-	protected void computeAnswer() {
-		for (int w=0;w<answerWorld.size();w++) {
-			LightBotWorld.CellIterator ci = ((LightBotWorld)answerWorld.get(w)).new CellIterator();
-			while (ci.hasNext()) {
-				ci.next().setLightOn();
-			}
-		}
-	}
-	@Override
-	public void check() {
-		lastResult = new ExecutionProgress();
-		for (int w=0;w<currentWorld.size();w++) {
-			LightBotWorld.CellIterator ci = ((LightBotWorld)currentWorld.get(w)).new CellIterator();
-			while (ci.hasNext()) {
-				LightBotWorldCell cell = ci.next();
-				if (cell.isLight()) {
-					lastResult.totalTests++;
-					if (cell.isLightOn())
-						lastResult.passedTests++;
-				}
-			}
-			int stillOff = lastResult.totalTests - lastResult.passedTests;
-			if (stillOff == 1) 
-				lastResult.details = "The light is still off";
-			if (stillOff > 1)
-				lastResult.details = stillOff + " lights (out of "+lastResult.totalTests+") are still off";
-
-		}
-	}
-	@Override
-	public void run(List<Thread> runnerVect){ // FIXME: that's a redefinition to the same, right?
-		reset();
-
-		for (int i=0; i<currentWorld.size(); i++)
-			currentWorld.get(i).doDelay();
-
-		for (int i=0; i<currentWorld.size(); i++)
-			currentWorld.get(i).runEntities(runnerVect, lastResult);
-	}
-
-	@Override
-	public void runDemo(List<Thread> runnerVect){		
-		/* No demo for lightbot: this is a puzzle game, you have to search for the answer by yourself */
-	}
-	
-	@Override
-	final protected void mutateEntities(Vector<World> worlds, String newClassName) {
-		throw new RuntimeException("Why are you trying to mutate Lightbot entities, you weirdo?! super.mutateEntities() is not ready for that.");
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotInstruction.java b/src/jlm/universe/lightbot/LightBotInstruction.java
deleted file mode 100644
index 7da64a5..0000000
--- a/src/jlm/universe/lightbot/LightBotInstruction.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package jlm.universe.lightbot;
-
-
-
-public class LightBotInstruction {
-	/* instructionNames must match what toString says, and what the string constructor expects, or comboboxes of editor won't work */
-	public final static String[] instructionNames = { "noop","forward", "jump", "left", "right", "light", "f1","f2" };
-
-	private enum InstructionKind {
-		NOOP,FORWARD,JUMP,LIGHT,LEFT,RIGHT,F1,F2;		
-	}
-
-	InstructionKind kind;
-	public LightBotInstruction(InstructionKind kind) {
-		this.kind = kind;
-	}
-	public LightBotInstruction(char c) {
-		switch (c) {
-		case 'F': kind=InstructionKind.FORWARD; break;
-		case 'J': kind=InstructionKind.JUMP; break;
-		case 'L': kind=InstructionKind.LEFT; break;
-		case 'R': kind=InstructionKind.RIGHT; break;
-		case 'O': kind=InstructionKind.LIGHT; break;
-		case '1': kind=InstructionKind.F1; break;
-		case '2': kind=InstructionKind.F2; break;
-		case ' ': kind=InstructionKind.NOOP; break;
-		default:
-			throw new RuntimeException("Char '"+c+"' does not match any known symbol");
-		}
-	}
-	public LightBotInstruction(String str) {
-		/* must match instructionNames, or the comboboxes in the editor won't work */
-		if (str.equalsIgnoreCase("forward")) {
-			kind=InstructionKind.FORWARD;
-		} else if (str.equalsIgnoreCase("jump")) {
-			kind=InstructionKind.JUMP;
-		} else if (str.equalsIgnoreCase("light")) {
-			kind=InstructionKind.LIGHT;
-		} else if (str.equalsIgnoreCase("left")) {
-			kind=InstructionKind.LEFT;
-		} else if (str.equalsIgnoreCase("right")) {
-			kind=InstructionKind.RIGHT;
-		} else if (str.equalsIgnoreCase("f1")) {
-			kind=InstructionKind.F1;
-		} else if (str.equalsIgnoreCase("f2")) {
-			kind=InstructionKind.F2;
-		} else {
-			kind=InstructionKind.NOOP; 
-		}
-	}
-	public void run(LightBotEntity lb) {
-//		System.out.println("exec "+toString());
-		switch (kind) {
-		case FORWARD: lb.forward(); break;
-		case JUMP: lb.jump(); break;
-		case LEFT: lb.left(); break;
-		case RIGHT: lb.right(); break;
-		case LIGHT: lb.light(); break;
-		case F1: lb.runF1(); break;
-		case F2: lb.runF2(); break;
-		case NOOP: /* nothing to do for NOOP :) */
-			break;
-		}
-	}
-	public char toChar() {
-		switch (kind) {
-		case FORWARD: return 'F'; 
-		case JUMP: return 'J'; 
-		case LEFT: return 'L'; 
-		case RIGHT: return 'R';
-		case LIGHT: return 'O';
-		case F1: return '1'; 
-		case F2: return '2'; 
-		case NOOP: 
-		}
-		return ' ';
-	}
-	public static LightBotInstruction noop() {
-		return new LightBotInstruction(InstructionKind.NOOP);
-	}
-	
-	public String toString() {
-		switch (kind) { /* must match instructionNames, or the comboboxes in the editor won't work */
-		case NOOP: return "noop";
-		case FORWARD: return "forward"; 
-		case JUMP: return "jump"; 
-		case LEFT: return "left"; 
-		case RIGHT: return "right";
-		case LIGHT: return "light";
-		case F1: return "f1"; 
-		case F2: return "f2"; 
-		}
-		return "noop";
-	}
-	public boolean isNoop() {
-		return kind == InstructionKind.NOOP;
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotSourceFile.java b/src/jlm/universe/lightbot/LightBotSourceFile.java
deleted file mode 100644
index 643d5a4..0000000
--- a/src/jlm/universe/lightbot/LightBotSourceFile.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package jlm.universe.lightbot;
-
-import javax.swing.JScrollPane;
-
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.model.lesson.SourceFileRevertable;
-
-public class LightBotSourceFile extends SourceFileRevertable {
-	private LightBotInstruction[] main;
-	private LightBotInstruction[] func1;
-	private LightBotInstruction[] func2;
-
-	public LightBotSourceFile(String name) {
-		super(name, "");
-		resetBody();
-	}
-	@Override
-	public String getBody(){
-		StringBuffer sb = new StringBuffer();
-		for (int i=0;i<main.length;i++)
-			sb.append(main[i].toChar());
-		sb.append('\n');
-		for (int i=0;i<func1.length;i++)
-			sb.append(func1[i].toChar());
-		sb.append('\n');
-		for (int i=0;i<func2.length;i++)
-			sb.append(func2[i].toChar());
-		sb.append('\n');
-		return sb.toString();
-	}
-
-	private void resetBody() {
-		main = new LightBotInstruction[12];
-		for (int i=0;i<main.length;i++)
-			main[i]=LightBotInstruction.noop();
-		func1 = new LightBotInstruction[8];
-		for (int i=0;i<func1.length;i++)
-			func1[i]=LightBotInstruction.noop();
-		func2 = new LightBotInstruction[8];
-		for (int i=0;i<func2.length;i++)
-			func2[i]=LightBotInstruction.noop();	
-	}
-	
-	@Override
-	public void setBody(String newBody){
-		/* reset everything to noop */
-		resetBody();
-		
-		/* parse content */
-		String[] lines = newBody.split("\n");
-		int pos=0;
-		if (lines.length>0)
-			for (char c : lines[0].toCharArray()) 
-				main[pos++]=new LightBotInstruction(c);
-		pos=0;
-		if (lines.length>1)
-			for (char c : lines[1].toCharArray()) 
-				func1[pos++]=new LightBotInstruction(c);
-		pos=0;
-		if (lines.length>2)
-			for (char c : lines[2].toCharArray()) 
-				func2[pos++]=new LightBotInstruction(c);
-	}
-
-	@Override
-	public JScrollPane getEditorPanel(ProgrammingLanguage lang){
-		return new LightBotEditorPanel(this);
-	}
-	public LightBotInstruction[] getMain() {
-		return main;
-	}
-	public LightBotInstruction[] getFunc1() {
-		return func1;
-	}
-	public LightBotInstruction[] getFunc2() {
-		return func2;
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotWorld.fr.html b/src/jlm/universe/lightbot/LightBotWorld.fr.html
deleted file mode 100644
index b63fe01..0000000
--- a/src/jlm/universe/lightbot/LightBotWorld.fr.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<h1>LightBotWorld</h1>
-
-Ce monde introduit un petit puzzle de programmation qui peut être utilisé
-pour introduire la programmation aux enfants ne sachant pas lire. En effet,
-il est programmé de manière graphique. L'objectif de chaque niveau est
-d'allumer toutes les lumières du plateau en utilisant le petit
-robot. Celui-ci comprend les ordres suivants :
-
-<table border=1>
- <tr><td><b>Ordre</b></td><td><b>Signification</b></td></tr>
- <tr><td><img src="img/lightbot_forward.png" /></td><td><b>Avancer</b><br />Ne peut être utilisé si la case d'arrivée n'est pas à la même altitude que
-la case de départ.</td></tr>
- <tr><td><img src="img/lightbot_jump.png" /></td><td><b>Sauter en avant</b><br />Ne peut être utilisé que si la case d'arrivée est un étage plus haute que la
-case de départ, ou si l'arrivée est plus basse que le départ. Ne peut être
-utilisée pour des déplacements à plat.</td></tr> 
- <tr><td><img src="img/lightbot_left.png" /></td><td><b>Tourner à gauche</b>.</td></tr>  
- <tr><td><img src="img/lightbot_right.png" /></td><td><b>Tourner à droite</b>.</td></tr>   
- <tr><td><img src="img/lightbot_light.png" /></td><td><b>Allumer ou éteindre</b><br />Allumer l'ampoule si elle était éteinte, et éteindre si elle était
-allumée. Sans effet s'il n'y a pas d'ampoule dans la case courante.</td></tr>    
- <tr><td><img src="img/lightbot_f1.png" /></td><td><b>Appeller la fonction 1</b>.</td></tr>
- <tr><td><img src="img/lightbot_f2.png" /></td><td><b>Appeller la fonction 2</b>.</td></tr>
-</table>
-
-<p>Veuillez noter que ce jeu n'est pas vraiment adapté aux jeunes enfants
-puisque la principale difficulté vient de la limitation du nombre
-d'instructions utilisable dans chaque programme. Les niveaux avancés ne
-peuvent être résolus sans écrire des fonctions pour factoriser le code, ce
-qui est souvent au delà des capacités des jeunes enfants.</p>
-
-<p>Ce jeu est très largement inspiré d'un jeu en flash du même nom, que l'on
-peut par exemple trouver sur kongregate.com. Il a été écrit par Danny
-Yaroslavski (Coolio-Niato), d'après une idée originale de Matt Chase.</p>      
\ No newline at end of file
diff --git a/src/jlm/universe/lightbot/LightBotWorld.html b/src/jlm/universe/lightbot/LightBotWorld.html
deleted file mode 100644
index 3aa9770..0000000
--- a/src/jlm/universe/lightbot/LightBotWorld.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<h1>LightBotWorld</h1>
-
-This world introduces a little programming puzzle which can somehow be used to introduce programmation to non-reading kids since it is programmed graphically. 
-The goal of each board is to light up all the lights. Your robot understands the following orders:
-
-<table border=1>
- <tr><td><b>Order</b></td><td><b>Meaning</b></td></tr>
- <tr><td><img src="img/lightbot_forward.png" /></td><td><b>Move forward</b><br />Cannot be done if the destination cell is of another height than source cell</td></tr>
- <tr><td><img src="img/lightbot_jump.png" /></td><td><b>Jump forward</b><br />Can only be done if the destination cell is one step higher than source cell, or if destination is lower than source. Cannot be used for plain moves.</td></tr> 
- <tr><td><img src="img/lightbot_left.png" /></td><td><b>Turn left</b>.</td></tr>  
- <tr><td><img src="img/lightbot_right.png" /></td><td><b>Turn right</b>.</td></tr>   
- <tr><td><img src="img/lightbot_light.png" /></td><td><b>Switch the light</b>.<br />Turn it on if it was off, and off if it was on. No effect if the cell does not contain any light.</td></tr>    
- <tr><td><img src="img/lightbot_f1.png" /></td><td><b>Call function 1</b>.</td></tr>
- <tr><td><img src="img/lightbot_f2.png" /></td><td><b>Call function 2</b>.</td></tr>
-</table>
-
-<p>Please note that this world is not completely suited to small kids since the main difficulty comes from the fact that your are highly limited in the amount of instructions you can give to your robot. Advanced levels thus require to write sound functions, and are often above the capacities of small kids.</p>
-
-<p>This game is heavily inspirated from a flash game of the same name, which can for example be played on kongregate.com. It was written by Danny Yaroslavski (Coolio-Niato), the original idea being of Matt Chase.</p>      
\ No newline at end of file
diff --git a/src/jlm/universe/lightbot/LightBotWorld.java b/src/jlm/universe/lightbot/LightBotWorld.java
deleted file mode 100644
index b8c9bee..0000000
--- a/src/jlm/universe/lightbot/LightBotWorld.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package jlm.universe.lightbot;
-
-import java.util.Arrays;
-import java.util.Iterator;
-
-import javax.script.ScriptEngine;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.Entity;
-import jlm.universe.GridWorld;
-import jlm.universe.World;
-
-public class LightBotWorld extends jlm.universe.GridWorld implements Iterable<LightBotWorldCell> {
-
-	public LightBotWorld(String name, int x, int y) {
-		super(name,x,y);
-		setDelay(200);
-	}
-	protected LightBotWorldCell newCell(int x, int y) {
-		return new LightBotWorldCell(this, x, y);
-	}
-
-	/**
-	 * Create a new world being almost a copy of the first one.
-	 * 
-	 * @param world2
-	 */
-	public LightBotWorld(LightBotWorld world2) {
-		super(world2);
-	}
-
-	/**
-	 * Reset the content of a world to be the same than the one passed as
-	 * argument. Does not affect the name of the initial world.
-	 */
-	@Override
-	public void reset(World iw) {
-		GridWorld initialWorld = (GridWorld) iw;
-		for (int i = 0; i < sizeX; i++)
-			for (int j = 0; j < sizeY; j++) {
-				LightBotWorldCell c = (LightBotWorldCell) initialWorld.getCell(i, j);
-				cells[i][j] = new LightBotWorldCell(c,this);
-			}
-
-		super.reset(initialWorld);
-	}
-
-	public void rotateRight() {	
-		LightBotWorldCell[][] newWorld = new LightBotWorldCell[this.sizeY][this.sizeX];
-		for (int y=0; y<this.sizeY; y++)
-			for (int x=0; x<this.sizeX; x++) {
-				LightBotWorldCell cell = (LightBotWorldCell) this.cells[x][y];
-				cell.setX(this.sizeX-(y+1));
-				cell.setY(x);
-				newWorld[this.sizeX-(y+1)][x] = cell;
-			}
-		this.cells = newWorld;
-		int oldSizeX = this.sizeX;
-		this.sizeX = this.sizeY;
-		this.sizeY = oldSizeX;
-		
-		for (Entity entity : this.entities) {
-			LightBotEntity bot = (LightBotEntity) entity;
-			int x = bot.getX();
-			int y = bot.getY();
-			
-			bot.setX(this.sizeX-(y+1));
-			bot.setY(x);
-			bot.right();
-		}
-		
-		notifyWorldUpdatesListeners();
-	}
-	
-	public void rotateLeft() {
-		LightBotWorldCell[][] newWorld = new LightBotWorldCell[this.sizeY][this.sizeX];
-		for (int y=0; y<this.sizeY; y++)
-			for (int x=0; x<this.sizeX; x++) {
-				LightBotWorldCell cell = (LightBotWorldCell) this.cells[x][y];
-				cell.setX(y);
-				cell.setY(this.sizeX-(x+1));
-				newWorld[y][this.sizeX-(x+1)] = cell;
-			}
-		this.cells = newWorld;
-		int oldSizeX = this.sizeX;
-		this.sizeX = this.sizeY;
-		this.sizeY = oldSizeX;
-		
-		for (Entity entity : this.entities) {
-			LightBotEntity bot = (LightBotEntity) entity;
-			int x = bot.getX();
-			int y = bot.getY();
-			
-			bot.setX(y);
-			bot.setY(this.sizeX-(x+1));
-			bot.left();
-		}
-		
-		notifyWorldUpdatesListeners();		
-	}
-	
-	
-	
-	@Override
-	public WorldView getView() {
-//		return new LightBotWorldView2D(this);
-		return new LightBotWorldViewIsometric(this);
-	}
-	@Override
-	public ImageIcon getIcon() {
-		return ResourcesCache.getIcon("img/world_lightbot.png");
-	}
-	
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + sizeX;
-		result = PRIME * result + sizeY;
-		result = PRIME * result + Arrays.hashCode(cells);
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		final GridWorld other = (GridWorld) obj;
-		if (getWidth() != other.getWidth())
-			return false;
-		if (getHeight() != other.getHeight())
-			return false;
-		for (int x = 0; x < getWidth(); x++)
-			for (int y = 0; y < getHeight(); y++)
-				if (!getCell(x, y).equals(other.getCell(x, y)))
-					return false;
-
-		return super.equals(obj);
-	}
-
-	public class CellIterator implements Iterator<LightBotWorldCell> {
-		private int x = 0;
-		private int y = 0;
-
-		@Override
-		public boolean hasNext() {
-			return x <= LightBotWorld.this.sizeX - 1 && y <= LightBotWorld.this.sizeY - 1;
-		}
-
-		@Override
-		public LightBotWorldCell next() {
-			LightBotWorldCell res = (LightBotWorldCell) LightBotWorld.this.getCell(x, y);
-			if (x >= LightBotWorld.this.sizeX - 1) {
-				x = 0;
-				y++;
-			} else {
-				x++;
-			}
-			return res;
-		}
-
-		@Override
-		public void remove() {
-			throw new RuntimeException("Method not implemented (and not implementable");
-		}
-
-	}
-
-	public void setHeight(int x, int y, int h) {
-		((LightBotWorldCell) getCell(x, y)).setHeight(h);
-	}
-
-	public void addLight(int x, int y) {
-		((LightBotWorldCell) getCell(x, y)).addLight();
-	}
-
-	public void removeLight(int x, int y) {
-		((LightBotWorldCell) getCell(x, y)).removeLight();
-	}
-
-	public void switchLight(int x, int y) {
-		((LightBotWorldCell) getCell(x, y)).lightSwitch();
-	}
-
-	@Override
-	public Iterator<LightBotWorldCell> iterator() {
-		return new CellIterator();
-	}
-	@Override
-	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) {
-		throw new RuntimeException("No binding of LightbotWorld for "+lang);
-	}
-	@Override
-	public String diffTo(World other) {
-		return "null";
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotWorldCell.java b/src/jlm/universe/lightbot/LightBotWorldCell.java
deleted file mode 100644
index ec0b858..0000000
--- a/src/jlm/universe/lightbot/LightBotWorldCell.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package jlm.universe.lightbot;
-
-import jlm.universe.GridWorld;
-import jlm.universe.GridWorldCell;
-
-
-
-
-public class LightBotWorldCell extends GridWorldCell {
-	private boolean light=false; /* whether we have a light */
-	private boolean lightOn=false; /* if we have a light, whether it's on or off */
-
-	private int height;
-
-	public LightBotWorldCell(GridWorld w, int x, int y) {
-		this(w, x, y, false, false, 0);
-	}
-
-	public LightBotWorldCell(LightBotWorldCell c, GridWorld w) {
-		this(w, c.x, c.y, c.light, c.lightOn, c.height);
-	}
-	@Override
-	public GridWorldCell copy(GridWorld world) {
-		return new LightBotWorldCell(this,world);
-	}
-
-	public LightBotWorldCell(GridWorld w, int x, int y, boolean light, boolean lightOn, int height) {
-		super(w,x,y);
-		this.light = light;
-		this.lightOn = lightOn;
-		this.height = height;
-	}
-
-	public void addLight() {
-		this.light = true;
-		this.lightOn = false;
-		world.notifyWorldUpdatesListeners();
-	}
-	public void removeLight() {
-		this.light = false;
-		world.notifyWorldUpdatesListeners();
-	}
-	public void lightSwitch() {
-		lightOn = !lightOn;
-		world.notifyWorldUpdatesListeners();
-	}
-	public void setLightOn() {
-		lightOn = true;
-		world.notifyWorldUpdatesListeners();
-	}
-	public void setLightOff() {
-		lightOn = false;
-		world.notifyWorldUpdatesListeners();
-	}
-	/** Returns true if the light is on, or if there is no light */
-	public boolean getLightOnOrNone(){
-		return (!light) || lightOn;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + (light ? 1231 : 1237);
-		result = prime * result + (lightOn ? 1231 : 1237);
-		result = prime * result + ((world == null) ? 0 : world.hashCode());
-		result = prime * result + x;
-		result = prime * result + y;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		LightBotWorldCell other = (LightBotWorldCell) obj;
-		if (light != other.light)
-			return false;
-		if (lightOn != other.lightOn)
-			return false;
-		if (x != other.x)
-			return false;
-		if (y != other.y)
-			return false;
-		return true;
-	}
-
-	public int getHeight() {
-		return height;
-	}
-
-	public void setHeight(int h) {
-		height = h;
-	}
-
-	public boolean isLight() {
-		return light;
-	}
-
-	public boolean isLightOn() {
-		return lightOn;
-	}
-	
-	@Override
-	public String toString() {
-		return "LBCell[x:"+this.x+";y:"+this.y+";z:"+this.height+";light:"+(light?(lightOn?"on":"off"):"none")+"]";
-	}	
-	
-}
diff --git a/src/jlm/universe/lightbot/LightBotWorldView2D.java b/src/jlm/universe/lightbot/LightBotWorldView2D.java
deleted file mode 100644
index 241679d..0000000
--- a/src/jlm/universe/lightbot/LightBotWorldView2D.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/* This file is not used anymore: it displays a stupid 2D view of the world.
- * Its main interest were to be able to test the world before the 3D isometric were functional.
- * I don't kill it so that we have a backup in case the 3D view breaks at some point.
- */
-
-package jlm.universe.lightbot;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.Arc2D;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-
-import jlm.core.ui.WorldView;
-import jlm.universe.Direction;
-import jlm.universe.Entity;
-import jlm.universe.GridWorld;
-import jlm.universe.GridWorldCell;
-import jlm.universe.World;
-
-public class LightBotWorldView2D extends WorldView {
-	private static final long serialVersionUID = 1674820378395646693L;
-
-	private static Color GRID_COLOR = new Color(0.8f, 0.8f, 0.8f);
-	private static Color DARK_CELL_COLOR = new Color(0.93f, 0.93f, 0.93f);
-	private static Color LIGHT_CELL_COLOR = new Color(0.95f, 0.95f, 0.95f);
-	private static Color LIGHT_OFF_COLOR = Color.BLACK;
-	private static Color LIGHT_ON_COLOR = Color.YELLOW;
-	private static Color BOT_COLOR = Color.BLUE;
-
-	private static final double CELL_WIDTH = 50.;
-	
-	public LightBotWorldView2D(World w) {
-		super(w);
-	}
-
-	@Override
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-		Graphics2D g2 = (Graphics2D) g;
-
-		GridWorld tw = (GridWorld) this.world;
-
-		double ratio = Math.min(((double) getWidth()) / (tw.getWidth()*LightBotWorldView2D.CELL_WIDTH), ((double) getHeight()) / (tw.getHeight()*LightBotWorldView2D.CELL_WIDTH));
-		g2.translate(Math.abs((getWidth() - ratio * tw.getWidth()*LightBotWorldView2D.CELL_WIDTH) / 2.), Math.abs((getHeight() - ratio * tw.getHeight()*LightBotWorldView2D.CELL_WIDTH) / 2.));
-		g2.scale(ratio, ratio);
-		
-
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setColor(Color.white);
-		g2.fill(new Rectangle2D.Double(0., 0., (double) tw.getWidth()*LightBotWorldView2D.CELL_WIDTH, (double) tw.getHeight()*LightBotWorldView2D.CELL_WIDTH));
-
-		
-		// draw background
-		drawWorld2D(g2);
-		
-		// draw lights (and elevation)
-		for (int x = 0; x < tw.getWidth(); x++) {
-			for (int y = 0; y < tw.getHeight(); y++) {
-				LightBotWorldCell cell = (LightBotWorldCell) tw.getCell(x, y);
-				if (cell.isLight()) {
-					drawLight2D(g2, cell, cell.isLightOn());
-				}
-				
-				
-				g2.setColor(Color.RED);
-				if (cell.getHeight() != 0)
-					g2.drawString(Integer.toString(cell.getHeight()), (int) (x*LightBotWorldView2D.CELL_WIDTH), (int) ((y+1)*LightBotWorldView2D.CELL_WIDTH));
-			}
-		}
-		
-		// draw lightBots
-		for (Entity ent: world.getEntities())
-			drawBot2D(g2, (LightBotEntity) ent);
-	}
-
-	private void drawWorld2D(Graphics2D g) {
-		GridWorld w = (GridWorld) world;
-
-		for (int x = 0; x < w.getWidth(); x++) {
-			for (int y = 0; y < w.getHeight(); y++) {
-				Color cellColor = Color.white;
-				if ((x + y) % 2 == 0)
-					cellColor = LightBotWorldView2D.DARK_CELL_COLOR;
-				else
-					cellColor = LightBotWorldView2D.LIGHT_CELL_COLOR;
-				g.setColor(cellColor);
-				g.fill(new Rectangle2D.Double(x*LightBotWorldView2D.CELL_WIDTH, y*LightBotWorldView2D.CELL_WIDTH, LightBotWorldView2D.CELL_WIDTH, LightBotWorldView2D.CELL_WIDTH));
-			}
-		}
-
-		g.setColor(GRID_COLOR);
-		for (int x = 0; x <= w.getWidth(); x++)
-			g.draw(new Line2D.Double(x*LightBotWorldView2D.CELL_WIDTH, 0., x*LightBotWorldView2D.CELL_WIDTH, w.getHeight()*LightBotWorldView2D.CELL_WIDTH));
-		for (int y = 0; y <= w.getHeight(); y++)
-			g.draw(new Line2D.Double(0., y*LightBotWorldView2D.CELL_WIDTH, w.getWidth()*LightBotWorldView2D.CELL_WIDTH, y*LightBotWorldView2D.CELL_WIDTH));
-	}
-
-	private void drawLight2D(Graphics2D g, GridWorldCell cell, boolean lightOn) {
-		if (lightOn)
-			g.setColor(LightBotWorldView2D.LIGHT_ON_COLOR);
-		else
-			g.setColor(LightBotWorldView2D.LIGHT_OFF_COLOR);
-		g.fill(new Arc2D.Double(cell.getX()*LightBotWorldView2D.CELL_WIDTH + 0.1*LightBotWorldView2D.CELL_WIDTH, cell.getY()*LightBotWorldView2D.CELL_WIDTH + 0.1*LightBotWorldView2D.CELL_WIDTH, 0.8*LightBotWorldView2D.CELL_WIDTH, 0.8*LightBotWorldView2D.CELL_WIDTH, 0, 360, Arc2D.OPEN));
-	}
-
-	private void drawBot2D(Graphics2D g, LightBotEntity bot) {
-		GridWorldCell cell = bot.getCell();
-
-		double width = LightBotWorldView2D.CELL_WIDTH;
-		double height = LightBotWorldView2D.CELL_WIDTH;
-		double cx = cell.getX();
-		double cy = cell.getY();
-		
-		double angle = 0.;
-		switch (bot.getDirection().intValue()) {
-		case Direction.NORTH_VALUE:
-			angle = Math.PI;
-			break;
-		case Direction.SOUTH_VALUE:
-			angle = 0.;
-			break;
-		case Direction.EAST_VALUE:
-			angle = -Math.PI/2.;
-			break;
-		case Direction.WEST_VALUE:
-			angle = Math.PI/2;
-			break;
-		}
-		g.rotate(angle, cx*LightBotWorldView2D.CELL_WIDTH+width/2., cy*LightBotWorldView2D.CELL_WIDTH+height/2.);
-		
-		g.setColor(LightBotWorldView2D.BOT_COLOR);
-		g.fill(new Arc2D.Double((cx-0.25)*LightBotWorldView2D.CELL_WIDTH,(cy+0.1)*LightBotWorldView2D.CELL_WIDTH,1.5*width,1.5*height,60,60, Arc2D.PIE));		
-	}
-}
diff --git a/src/jlm/universe/lightbot/LightBotWorldViewIsometric.java b/src/jlm/universe/lightbot/LightBotWorldViewIsometric.java
deleted file mode 100644
index 1c44725..0000000
--- a/src/jlm/universe/lightbot/LightBotWorldViewIsometric.java
+++ /dev/null
@@ -1,312 +0,0 @@
-package jlm.universe.lightbot;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GridLayout;
-import java.awt.RenderingHints;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Arc2D;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import javax.swing.JButton;
-import javax.swing.JPanel;
-
-import jlm.core.model.Game;
-import jlm.core.ui.WorldView;
-import jlm.universe.Direction;
-import jlm.universe.GridWorld;
-import jlm.universe.GridWorldCell;
-import jlm.universe.World;
-
-public class LightBotWorldViewIsometric extends WorldView {
-
-	private static final long serialVersionUID = -697923562790202622L;
-
-	private static final Color GRID_COLOR = new Color(0.2f, 0.2f, 0.2f);
-	private static final Color DARK_CELL_COLOR = new Color(0.9f, 0.9f, 0.9f);
-	private static final Color LIGHT_CELL_COLOR = new Color(0.93f, 0.93f, 0.93f);
-
-	private static final Color DARK_WALL_COLOR = new Color(0.7f, 0.7f, 0.7f);
-	private static final Color LIGHT_WALL_COLOR = new Color(0.8f, 0.8f, 0.8f);
-
-	private static final Color LIGHT_OFF_COLOR = Color.BLACK;
-	private static final Color LIGHT_ON_COLOR = Color.YELLOW;
-	private static final Color BOT_COLOR = Color.BLUE;
-
-	private static final double CELL_WIDTH = 40.;
-	private static final double CELL_HEIGHT = 15.;
-
-	private static final double verticalIsometricScaleFactor = 2.;
-	private static final double isometricAngle = Math.PI / 4.;
-
-	private List<LightBotWorldCell> cellsZOrdered = new ArrayList<LightBotWorldCell>();
-
-	public LightBotWorldViewIsometric(World w) {
-		super(w);
-		initComponents();
-		computeZOrders();
-		if (world.getEntityCount() > 1)
-			throw new RuntimeException("Multiple entities in lightbot world not supported");
-	}
-
-	private synchronized void computeZOrders() {
-		this.cellsZOrdered.clear();
-		for (LightBotWorldCell c : ((LightBotWorld) this.world))
-			cellsZOrdered.add(c);
-
-		Collections.sort(cellsZOrdered, new Comparator<LightBotWorldCell>() {
-			@Override
-			public int compare(LightBotWorldCell c1, LightBotWorldCell c2) {
-				return LightBotWorldViewIsometric.computeZOrder(c1) - LightBotWorldViewIsometric.computeZOrder(c2);
-			}
-		});
-	}
-
-	@Override
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-
-		Graphics2D g2 = (Graphics2D) g;
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
-		AffineTransform originalTransform = g2.getTransform();
-		
-		
-		GridWorld tw = (GridWorld) this.world;
-
-		double componentWidth = (double) getWidth();
-		double componentHeight = (double) getHeight();
-		double boardWidth = tw.getWidth() * CELL_WIDTH;
-		double boardHeight = tw.getHeight() * CELL_WIDTH;
-		double diagWidth = Math.sqrt(boardWidth * boardWidth + boardHeight * boardHeight);
-		double diagHeight = diagWidth;
-
-		double ratio = Math.min(componentWidth / (diagWidth), (componentHeight * verticalIsometricScaleFactor)
-				/ (1.5 * diagHeight));
-
-		double marginW = (componentWidth - ratio * diagWidth) / 2.;
-		double marginH = (componentHeight - ((1.5 * ratio * diagHeight) / verticalIsometricScaleFactor)) / 2.;
-		double paddingW = (diagWidth - boardWidth) / 2.;
-		double paddingH = (2 * diagHeight - boardHeight) / 2.;
-
-		// center drawing in the middle of the component
-		g2.translate(marginW, marginH);
-
-		// scale to component size + half-size for height
-		g2.scale(ratio, ratio / verticalIsometricScaleFactor);
-
-		// draw bounding-box
-		// g2.setColor(Color.RED);
-		// g2.draw(new Rectangle2D.Double(0., 0., diagWidth, 1.5*diagHeight));
-
-		GradientPaint skyGradient = new GradientPaint((float) (diagWidth / 2.), 0.f, new Color(0.0f, 0.0f, 0.6f),
-				(float) ((2. * diagWidth) / 3.), (float) (diagHeight), Color.BLACK, false);
-		g2.setPaint(skyGradient);
-		g2.fill(new Rectangle2D.Double(0., 0., diagWidth, 1.5 * diagHeight));
-
-		// shift drawing in order to be centered after it has been rotated
-		g2.translate(paddingW, paddingH);
-		g2.rotate(isometricAngle, boardWidth / 2., boardHeight / 2.);
-
-		// draw world and lights
-		drawWorld3D(g2);
-		
-		g2.setTransform(originalTransform);		
-	}
-
-	public static int computeZOrder(GridWorldCell cell) {
-		final int tx = cell.getWorld().getWidth();
-		final int ty = cell.getWorld().getHeight();
-
-		final int x = cell.getY();
-		final int y = cell.getX();
-
-		int val = (x + y) * (x + y + 1) / 2 + x + 1;
-		if (x + y > ty - 1)
-			val -= ((x + y - ty + 1) * (x + y - ty + 2)) / 2;
-		if (x + y > tx)
-			val -= ((x + y - tx) * (x + y - tx + 1)) / 2;
-
-		return val;
-	}
-
-	private synchronized void drawWorld3D(Graphics2D g) {
-		LightBotEntity bot = null;
-		if (world.getEntityCount() > 0)
-			bot = (LightBotEntity) world.getEntity(0);
-
-		for (LightBotWorldCell cell : this.cellsZOrdered) {
-			int x = cell.getX();
-			int y = cell.getY();
-
-			Color cellColor = Color.white;
-			if ((x + y) % 2 == 0)
-				cellColor = DARK_CELL_COLOR;
-			else
-				cellColor = LIGHT_CELL_COLOR;
-			g.setColor(cellColor);
-
-			double cw = CELL_WIDTH;
-			double dx = x * cw;
-			double dy = y * cw;
-			double dz = cell.getHeight() * CELL_HEIGHT;
-
-			GeneralPath face1 = new GeneralPath();
-			face1.moveTo(dx, dy + cw);
-			face1.lineTo(dx - dz, dy + cw - dz);
-			face1.lineTo(dx + cw - dz, dy + cw - dz);
-			face1.lineTo(dx + cw, dy + cw);
-			face1.lineTo(dx, dy + cw);
-
-			GeneralPath face2 = new GeneralPath();
-			face2.moveTo(dx + cw, dy + cw);
-			face2.lineTo(dx + cw - dz, dy + cw - dz);
-			face2.lineTo(dx + cw - dz, dy - dz);
-			face2.lineTo(dx + cw, dy);
-			face2.lineTo(dx + cw, dy + cw);
-
-			// floor
-			g.setColor(GRID_COLOR);
-			g.draw(new Rectangle2D.Double(dx, dy, cw, cw));
-
-			// face 1
-			g.setColor(DARK_WALL_COLOR);
-			g.fill(face1);
-			g.setColor(GRID_COLOR);
-			g.draw(face1);
-
-			// face 2
-			g.setColor(LIGHT_WALL_COLOR);
-			g.fill(face2);
-			g.setColor(GRID_COLOR);
-			g.draw(face2);
-
-			// steps on faces
-			for (int h = 0; h<cell.getHeight(); h++) {
-				g.setColor(GRID_COLOR);
-				double z = h * CELL_HEIGHT;
-				g.draw(new Line2D.Double(dx - z, dy + cw - z, dx + cw - z, dy + cw - z));
-				g.draw(new Line2D.Double(dx + cw -z , dy + cw - z, dx + cw -z , dy - z));
-			}
-	
-			// roof
-			g.setColor(cellColor);
-			g.fill(new Rectangle2D.Double(dx - dz, dy - dz, cw, cw));
-			g.setColor(GRID_COLOR);
-			g.draw(new Rectangle2D.Double(dx - dz, dy - dz, cw, cw));
-
-			if (cell.isLight()) {
-				drawLight2D(g, cell);
-			}
-
-			// print elevation
-			// g.setColor(Color.RED);
-			// g.drawString(Integer.toString(cell.getHeight()), (int) (dx - dz),
-			// (int) (dy + cw - ch));
-
-			// print z-order
-			// g.setColor(Color.BLUE);
-			// g.drawString(Integer.toString(computeZOrder(cell)), (int) (dx +
-			// cw - cw / 3 - dz), (int) (dy + cw - dz));
-
-			// print cell coord
-			//g.setColor(Color.BLACK);
-			//g.drawString(("" + x + ":" + y), (int) (dx + cw - cw / 2. - dz),
-			//(int) (dy + cw / 2. - dz));
-
-			if (bot != null && cell == bot.getCell()) {
-				drawBot2D(g, bot);
-			}
-		}
-
-	}
-
-	private void drawLight2D(Graphics2D g, LightBotWorldCell cell) {
-		final double dx = cell.getX() * CELL_WIDTH;
-		final double dy = cell.getY() * CELL_WIDTH;
-		final double dz = cell.getHeight() * CELL_HEIGHT;
-
-		g.setColor(cell.isLightOn()?LIGHT_ON_COLOR:LIGHT_OFF_COLOR);
-		g.fill(new Arc2D.Double(dx + 0.1 * CELL_WIDTH - dz, dy + 0.1 * CELL_WIDTH - dz, 0.8 * CELL_WIDTH,
-				0.8 * CELL_WIDTH, 0, 360, Arc2D.OPEN));
-	}
-
-	private void drawBot2D(Graphics2D g, LightBotEntity bot) {
-		LightBotWorldCell cell = bot.getCell();
-
-		double width = CELL_WIDTH;
-		double height = CELL_WIDTH;
-		double cx = cell.getX();
-		double cy = cell.getY();
-
-		double angle = 0.;
-		switch (bot.getDirection().intValue()) {
-		case Direction.NORTH_VALUE:
-			angle = Math.PI;
-			break;
-		case Direction.SOUTH_VALUE:
-			angle = 0.;
-			break;
-		case Direction.EAST_VALUE:
-			angle = -Math.PI / 2.;
-			break;
-		case Direction.WEST_VALUE:
-			angle = Math.PI / 2;
-			break;
-		}
-
-		double rx = cx * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT + width / 2.;
-		double ry = cy * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT + height / 2.;
-		g.rotate(angle, rx, ry);
-
-		g.setColor(BOT_COLOR);
-		g.fill(new Arc2D.Double((cx - 0.25) * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT, (cy + 0.1) * CELL_WIDTH
-				- cell.getHeight() * CELL_HEIGHT, 1.5 * width, 1.5 * height, 60, 60, Arc2D.PIE));
-
-		g.rotate(-angle, rx, ry);
-
-	}
-
-	@Override
-	public void worldHasMoved() {
-		computeZOrders();
-		super.worldHasMoved();
-	}	
-	
-	public void initComponents() {
-		JButton rotateLeft = new JButton("left");
-		rotateLeft.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				for (World w : Game.getInstance().getSelectedWorlds())
-					((LightBotWorld) w).rotateLeft();
-			}
-		});
-	
-		JButton rotateRight = new JButton("right");
-		rotateRight.addActionListener(new ActionListener() {
-			public void actionPerformed(ActionEvent event) {
-				for (World w : Game.getInstance().getSelectedWorlds())
-					((LightBotWorld) w).rotateRight();
-			}
-		});
-		
-		JPanel buttonsPanel = new JPanel();
-		buttonsPanel.setLayout(new GridLayout(1,2));
-		buttonsPanel.add(rotateLeft);
-		buttonsPanel.add(rotateRight);
-		
-		setLayout(new BorderLayout());
-		add(BorderLayout.NORTH, buttonsPanel);
-	}
-}
diff --git a/src/jlm/universe/lightbot/package-info.java b/src/jlm/universe/lightbot/package-info.java
deleted file mode 100644
index e22360a..0000000
--- a/src/jlm/universe/lightbot/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Little programming game universe where you must program a robot to 
- * light up some lights. You do so graphically and not in java. 
- */
-package jlm.universe.lightbot;
-
diff --git a/src/jlm/universe/package-info.java b/src/jlm/universe/package-info.java
deleted file mode 100644
index abba5da..0000000
--- a/src/jlm/universe/package-info.java
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * Constituting elements of each specialized universes.
- * 
- * The class defined directly in this class act as ancestors 
- * to the specialized versions defined in subpackages.
- */
-package jlm.universe;
-
diff --git a/src/jlm/universe/sort/CopyVal.java b/src/jlm/universe/sort/CopyVal.java
deleted file mode 100644
index 2230136..0000000
--- a/src/jlm/universe/sort/CopyVal.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package jlm.universe.sort;
-
-public class CopyVal extends Operation {
-	
-	/**
-	 * Constructor of the class CopyVal
-	 * @param source : the source of the operation
-	 * @param destination : the destination of the operation
-	 */
-	public CopyVal(int source, int destination){
-		super(source,destination);
-	}
-
-	/**
-	 * Compute an operation on init
-	 * @param init the values on which compute the operation 
-	 * @return the array of values after the operation
-	 */
-	@Override
-	public int[] run(int[] init) {
-		init[destination] = init[source];
-		return init;
-	}
-	
-}
diff --git a/src/jlm/universe/sort/GetVal.java b/src/jlm/universe/sort/GetVal.java
deleted file mode 100644
index fe64f18..0000000
--- a/src/jlm/universe/sort/GetVal.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package jlm.universe.sort;
-
-public class GetVal extends Operation {
-	
-	public int position;
-
-	/**
-	 * Constructor of the class SetVal
-	 * @param position the source of the operation
-	 * @param destination the destination of the operation
-	 */
-	public GetVal(int position){
-		super(-1,-1);
-		this.position = position; 
-	}
-
-	/**
-	 * Compute an operation on init
-	 * @param init the values on which compute the operation
-	 * @return the array passed as parameter, once the operation is applied to it
-	 */
-	@Override
-	public int[] run(int[] init) {
-		return init;
-	}
-	
-	
-}
diff --git a/src/jlm/universe/sort/Operation.java b/src/jlm/universe/sort/Operation.java
deleted file mode 100644
index 18fd94c..0000000
--- a/src/jlm/universe/sort/Operation.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package jlm.universe.sort;
-
-
-public abstract class Operation {
-	
-	protected int source;	// the source of the operation
-	protected int destination;	// the destination of the operation
-	
-	/**
-	 * Constructor of the class Operation
-	 * @param source the source of the operation
-	 * @param destination the destination of the operation
-	 */
-	public Operation(int source, int destination){
-		this.source = source;
-		this.destination = destination;
-	}
-	
-	/**
-	 * Indicate whether some other object is "equal to" this one
-	 * @param o the reference object with which to compare
-	 */
-	public boolean equals(Object o) {
-		if (o == null || !(o instanceof Operation))
-			return false;
-		
-		Operation other = (Operation) o;
-		if (destination != other.destination)
-			return false;
-		if (!getClass().equals(o.getClass()))
-			return false;
-		if (source != other.source)
-			return false;
-		return true;
-	}
-
-	/**
-	 * Returns the source of the operation
-	 */
-	public int getSource() {
-		return this.source;
-	}
-
-	/**
-	 * Returns the destination of the operation
-	 */
-	public int getDestination() {
-		return this.destination;
-	}
-		
-	/**
-	 * Compute an operation on init
-	 * @param init the values on which compute the operation
-	 * @return a new array of values equals to init where the operation had been computed
-	 */
-	public abstract int[] run(int[] init);	
-}
diff --git a/src/jlm/universe/sort/SetVal.java b/src/jlm/universe/sort/SetVal.java
deleted file mode 100644
index 722a6c8..0000000
--- a/src/jlm/universe/sort/SetVal.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package jlm.universe.sort;
-
-public class SetVal extends Operation {
-	
-	int value;
-
-	/**
-	 * Constructor of the class SetVal
-	 * @param position the source of the operation
-	 * @param destination the destination of the operation
-	 */
-	public SetVal(int position, int value){
-		super(position,-1);
-		this.value = value; 
-	}
-
-	/**
-	 * Compute an operation on init
-	 * @param init the values on which compute the operation
-	 * @return the array passed as parameter, once the operation is applied to it
-	 */
-	@Override
-	public int[] run(int[] init) {
-		init[source] = value;
-		
-		return init;
-	}
-	
-	
-}
diff --git a/src/jlm/universe/sort/SortingButtonPanel.java b/src/jlm/universe/sort/SortingButtonPanel.java
deleted file mode 100644
index 962ef54..0000000
--- a/src/jlm/universe/sort/SortingButtonPanel.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package jlm.universe.sort;
-
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-
-import jlm.core.model.Game;
-import jlm.universe.EntityControlPanel;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-/**
- * The control panel for the sorting world. 
- * It allows you to use the copy, setValue and swap methods interactively.
- * @see EntityControlPanel
- * @see SortingWorld
- */
-public class SortingButtonPanel extends EntityControlPanel {
-
-	private static final long serialVersionUID = 1L;
-	private JButton validateButton;	// a validate button
-	private JComboBox operationsComboBox;	// the available operations on the array ( setValue, copy and swap )
-	private JComboBox leftValueComboBox;	// the value for the first parameter of the selected operation
-	private JComboBox rightValueComboBox;	// the value for the second parameter of the selected operation
-	
-	private I18n i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
-
-	/**
-     * Constructor of SortingButtonPanel
-     * It initializes the command panel
-     */
-	public SortingButtonPanel() {
-		super();
-		SortingEntity se = (SortingEntity) Game.getInstance().getSelectedEntity();
-		this.add(this.createCommandPanel(se));
-	}
-	
-	/**
-	 * Initialize the command panel of the SortingButtonPanel
-	 * @param se The current sorting Entity
-	 * @return a JPanel containing the command panel
-	 */
-	private JPanel createCommandPanel(SortingEntity se) {
-		JPanel commandPane = new JPanel();
-		commandPane.setLayout(new FlowLayout());
-		
-		String operationsAvailable[] = { "swap","setValue","copy"};
-		this.operationsComboBox = new JComboBox(operationsAvailable);
-		
-		int n = se.getValueCount();
-		Integer index[] = new Integer[n];
-		for ( int i = 0 ; i < n ; i++) {
-			index[i] = i; 
-		}
-		this.leftValueComboBox = new JComboBox(index) ;
-		this.rightValueComboBox = new JComboBox(index) ;
-		
-		this.validateButton = new JButton(i18n.tr("go"));
-		this.validateButton.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				int i = leftValueComboBox.getSelectedIndex();
-				int j = rightValueComboBox.getSelectedIndex();
-				int selectedOperation = operationsComboBox.getSelectedIndex();
-				SortingEntity se = (SortingEntity) Game.getInstance().getSelectedEntity();
-				switch (selectedOperation)
-				{
-					case 0:
-						se.swap(i,j);
-						break;
-					case 1:
-						se.setValue(i,j);
-						break;
-					case 2:
-						se.copy(i, j);
-						break;
-					default:
-						System.err.println("Unknown operation index: "+selectedOperation);
-				}
-			}
-		}
-		);
-		
-		commandPane.add(this.operationsComboBox);
-		commandPane.add(this.leftValueComboBox);
-		commandPane.add(this.rightValueComboBox);
-		commandPane.add(this.validateButton);
-		
-		return commandPane;
-	}
-
-	@Override
-	public void setEnabledControl(boolean enabled) {
-		this.validateButton.setEnabled(enabled);
-		this.operationsComboBox.setEnabled(enabled);
-		this.leftValueComboBox.setEnabled(enabled);
-		this.rightValueComboBox.setEnabled(enabled);
-	}
-}
diff --git a/src/jlm/universe/sort/SortingEntity.java b/src/jlm/universe/sort/SortingEntity.java
deleted file mode 100644
index eafc352..0000000
--- a/src/jlm/universe/sort/SortingEntity.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package jlm.universe.sort;
-
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-public class SortingEntity extends Entity {
-
-	public SortingEntity() {
-		super("Sorting Entity");
-	}
-
-	/** Part of the copy process; Must call super(name) */
-	public SortingEntity(String name) {
-		super(name);
-	}
-	
-	/** Instantiation Constructor (used by exercises to setup the world) */
-	public SortingEntity(String name, World world) {
-		super(name,world);
-	}
-
-	/** A copy constructor needed by the JLM */
-	public Entity copy() {
-		return new SortingEntity(this.name);
-	}
-
-	public void copy(int from,int to) {
-		((SortingWorld) this.world).copy(from,to);
-		stepUI();
-	}
-
-	public int getValue(int i) {
-		return ((SortingWorld) this.world).getValue(i);
-	}
-	
-	public int getValueCount() {
-		return ((SortingWorld) this.world).getValueCount();
-	}
-	
-	public boolean isSmaller(int i, int j) {
-		return ((SortingWorld) this.world).isSmaller(i,j);
-	}
-	
-	public boolean isSmallerThan(int i, int val) {
-		return ((SortingWorld) this.world).isSmallerThan(i,val);
-	}
-	
-	public void run() {
-		// Child implement this
-	}
-	
-	public void setValue(int i,int val) {
-		((SortingWorld) this.world).setValue(i,val);
-		stepUI();
-	}
-	
-	public void swap(int i, int j) {
-		((SortingWorld) this.world).swap(i,j);
-		stepUI();
-	}
-
-}
diff --git a/src/jlm/universe/sort/SortingWorld.fr.html b/src/jlm/universe/sort/SortingWorld.fr.html
deleted file mode 100644
index c5e1541..0000000
--- a/src/jlm/universe/sort/SortingWorld.fr.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<h1>Monde des tris </h1>
-Ce monde vous donne les outils pour expérimenter les algorithmes de tris. On
-peut l'utiliser de deux manières différentes : la première est bien sûr
-d'écrire les algorithmes de tri demandés. Mais on peut aussi se contenter
-dans un premier temps de lancer la démo de chaque exercice et observer les
-algorithmes de tri fonctionner. Cela permet de mieux se rendre compte des
-différences d'efficacité entre eux.
-
-<h2>Méthodes disponibles pour les algorithmes de tri</h2>
-<table border=1>
-<tr><td><b>Méthode</b></td><td><b>Action</b></td><td><b>Coût</b></td></tr>
-<tr><td><div class="Java">int getValueCount()</div>
-        <div class="python">getValueCount()</div></td>
-    <td>Retourne le nombre de valeurs dans le tableau</td><td>aucun</td></tr>
-
-<tr><td><div class="Java">boolean isSmaller(int i, int j)</div>
-        <div class="python">isSmaller(i, j)</div></td>
-    <td>Retourne vrai ssi le contenu de la case i est strictement inférieur à celui
-de la case j</td><td>deux lectures</td></tr>
-<tr><td><div class="Java">boolean isSmallerThan(int i, int val)</div>
-        <div class="python">isSmallerThan(i, val)</div></td>
-    <td>Retourne vrai ssi le contenu de la case i est strictement inférieur à la
-valeur val</td><td>une lecture</td></tr>
-
-<tr><td><div class="Java">void swap(int i, int j)</div>
-        <div class="python">swap(i, j)</div></td>
-     <td>Echange le contenu de la case i avec celui de la case j</td><td>deux lectures, deux écritures</td></tr>
-<tr><td><div class="Java">void copy(int from, int to)</div>
-        <div class="python">copy(from, to)</div></td>
-    <td>Copie le contenu de la case 'from' dans la case 'to'</td><td>une lecture, une écriture</td></tr>
-
-<tr><td><div class="Java">int getValue(int idx)</div>
-        <div class="python">getValue(idx)</div></td>
-    <td>Retourne la valeur de la case idx</td><td>une lecture</td></tr>
-<tr><td><div class="Java">void setValue(int idx, int val)</div>
-        <div class="python">setValue(idx, val)</div></td>
-    <td>Affecte la valeur 'val' à la case 'idx'</td><td>une écriture</td></tr>
-
-<tr><td><div class="Java">boolean isSelected()</div>
-        <div class="python">isSelected()</div></td>
-    <td>Renvoi si le monde actuel est sélectionné dans l'interface graphique.</td><td>aucun</td></tr>
-
-</table>
-
-<h2>Vue de l'historique du monde</h2>
-<p>Il ne suffit pas de trier le tableau pour passer les exercices. Votre
-solution doit suivre scrupuleusement le comportement attendu de chaque
-exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et
-d'écriture sur le tableau effectuées lors de ce tri. En cas de problème, il
-est souvent assez difficile de comprendre la différence entre le
-comportement attendu et le comportement effectif.</p>
-
-<p>Pour cela, il est possible d'explorer graphiquement l'historique de
-n'importe quel monde de tri. Passez par exemple au monde Objectif et
-utilisez son menu contextuel (clic droit) pour choisir entre la vue de
-l'état courant du monde et la vue de son histoire.</p>
-
-<p>La vue de l'historique n'est pas aussi complexe qu'elle en a l'air à
-première vue. Le temps s'écoule de gauche à droite, et les cases du tableau
-sont représentée de haut en bas. Les lignes de différentes couleurs qui
-serpentent représentent les différentes valeurs contenues dans le
-tableau. Quand deux lignes se croises, cela signifie que les valeurs du
-tableau ont été échangées à ce moment de l'historique; un embranchement
-signifie que la valeur a été copiée; une valeur en violet suivie d'un point
-d'interrogation a été lue avec getValue() et une valeur en rouge suivie d'un
-point d'exclamation a été écrite avec setValue().</p>
-
-<p>Cette vue, inspirée d'Aldo Cortesi, est très pratique pour comprendre le
-comportement des algorithmes de tri.</p> 
diff --git a/src/jlm/universe/sort/SortingWorld.html b/src/jlm/universe/sort/SortingWorld.html
deleted file mode 100644
index a1a8b50..0000000
--- a/src/jlm/universe/sort/SortingWorld.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<h1>Sorting World </h1>
-This world provides tools to experiment with the sorting algorithms. It can
-be used in two different ways: the first one is naturally to write the
-required sorting algorithms. But it is also possible to simply use the demo
-mode of each exercise to observe the behavior of sorting algorithms. It
-helps understanding the differences between each of them.
-
-<h2>Methods available to sorting algorithms</h2>
-<table border=1>
-<tr><td><b>Method</b></td><td><b>Action</b></td><td><b>Cost</b></td></tr>
-<tr><td><div class="Java">int getValueCount()</div>
-        <div class="python">getValueCount()</div></td>
-    <td>Returns the amount of values in the array</td><td>none</td></tr>
-
-<tr><td><div class="Java">boolean isSmaller(int i, int j)</div>
-        <div class="python">isSmaller(i, j)</div></td>
-    <td>Returns true if the content of cell i is strictly smaller than the one of cell j</td><td>two reads</td></tr>
-<tr><td><div class="Java">boolean isSmallerThan(int i, int val)</div>
-        <div class="python">isSmallerThan(i, val)</div></td>
-    <td>Returns true if the content of cell i is strictly smaller than value <code>val</code></td><td>one read</td></tr>
-
-<tr><td><div class="Java">void swap(int i, int j)</div>
-        <div class="python">swap(i, j)</div></td>
-     <td>Swaps the content of cell i and the one of cell j</td><td>two reads, two writes</td></tr>
-<tr><td><div class="Java">void copy(int from, int to)</div>
-        <div class="python">copy(from, to)</div></td>
-    <td>Copy the content of cell 'from' into the cell 'to'</td><td>one read, one write</td></tr>
-
-<tr><td><div class="Java">int getValue(int idx)</div>
-        <div class="python">getValue(idx)</div></td>
-    <td>Returns the value of cell idx</td><td>one read</td></tr>
-<tr><td><div class="Java">void setValue(int idx, int val)</div>
-        <div class="python">setValue(idx, val)</div></td>
-    <td>Sets cell 'idx' to the value 'val'</td><td>one write</td></tr>
-
-<tr><td><div class="Java">boolean isSelected()</div>
-        <div class="python">isSelected()</div></td>
-    <td>Returns whether the current world is selected in the graphical interface.</td><td>none</td></tr>
-
-</table>
-
-<h2>History view</h2>
-<p>It is not enough to sort the array to pass the exercises. Your solution 
-must strictly follow the expected behavior of each exercise. This is
-enforced by checking that your algorithm needs the same amount of read
-and write operations to sort the array. When they don't match,
-understanding the difference between your code and the expected
-solution can reveal very difficult.</p>
-
-<p>To help in this process, it is possible to graphically explore the
-history of your sorting algorithm. Switch to the Objective view and
-use the contextual menu (right click) to switch from the the view of
-the current state to the view of its history.</p>
-
-<p>The history view is a bit hairly at the first glance, but actually rather
-simple: The time flows from left to right on this graph, and each row
-is a cell of your array. The curved lines that go navigate between
-rows represent a given data value. When two lines cross, this means
-that two values were swapped at this time stamp; A line fork represent a 
-value copy; When a value is magenta and followed by an interrogation 
-mark (?), it was read using getValue(); If the value is red and followed with 
-an exclamation point (!), it was written using setValue().</p>
-
-<p>This view, inspired from Aldo Cortesi, reveals very helpful understand the inner
-behavior of sorting algorithms.</p> 
diff --git a/src/jlm/universe/sort/SortingWorld.java b/src/jlm/universe/sort/SortingWorld.java
deleted file mode 100644
index 60207ac..0000000
--- a/src/jlm/universe/sort/SortingWorld.java
+++ /dev/null
@@ -1,348 +0,0 @@
-package jlm.universe.sort;
-
-import java.util.ArrayList;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
-
-public class SortingWorld extends World {
-	private int[] values;	// the values as they are sorted in the array
-	private int[] initValues;	// needed by the chronoview
-	private int readCount = 0;	// the count of the read made
-	private int writeCount = 0;	// the count of the write made
-	/*
-	 * It's needed by the chronoview
-	 * This list contains all the operations ( SetVal, CopyVal or Swap ) made on the world since 
-	 * the moment where it has been shown to the user
-	 */
-	private ArrayList<Operation> operations = new ArrayList<Operation>(1) ;	
-
-	/** Copy constructor used by the JLM internals */
-	public SortingWorld(SortingWorld world) {
-		super(world);
-	}
-
-	/** Constructor used in the exercises */
-	public SortingWorld(String name, int nbValues) {
-		super(name);
-		setDelay(50);
-		this.values = new int[nbValues];
-		for (int i=0 ; i< this.values.length ; i++) 
-		{
-			this.values[i] = i;
-		}
-		scramble();
-		this.initValues = this.values;
-	}
-
-	private void scramble() {
-		while( this.isSorted() )
-		{
-			for ( int caseNumber = 0 ; caseNumber < this.values.length ; caseNumber++)
-			{
-				// Swapping time !
-				if ( Math.random() > 0.5)
-				{
-					this.exchangeValues(caseNumber,(int)(Math.random()*this.values.length));
-				}
-			}
-		}
-	}
-
-	public boolean equals(Object o) {
-		if (o == null || !(o instanceof SortingWorld))
-			return false;
-
-		SortingWorld other = (SortingWorld) o;
-		if (values.length != other.values.length)
-			return false;
-		for (int i = 0 ; i < this.values.length ; i++) 
-			if ( this.values[i] != other.values[i] )
-				return false;
-		
-		if (operations.size() != other.operations.size())
-			return false;
-		for (int i = 0 ; i < this.operations.size() ; i++) 
-			if (! operations.get(i).equals( other.operations.get(i)) )
-				return false;
-		
-		if (! (this.readCount == other.readCount) )
-			return false;
-		if (! (this.writeCount == other.writeCount) )
-			return false;
-		
-		return true;
-	}
-
-	/**
-	 * Tells if the array is Sorted or not
-	 */
-	private boolean isSorted() {
-		boolean sw = true;
-		for ( int i = 0 ; i < this.values.length && sw ; i++ )
-		{
-			if ( this.values[i] != i )
-			{
-				sw = false ;
-			}
-		}
-		return sw;
-	}
-
-	/**
-	 * Copy the value from the cell of index from into the cell of index to<br>
-	 * It costs one read and one write.
-	 * @param from The index of the cell to copy
-	 * @param to The index of the cell where copy the value
-	 */
-	public void copy(int from,int to) {
-		if (from<0) throw new RuntimeException("Out of bounds in copy("+from+","+to+"): "+from+"<0");
-		if (to<0) throw new RuntimeException("Out of bounds in copy("+from+","+to+"): "+to+"<0");
-		if (from>=getValueCount()) throw new RuntimeException("Out of bounds in copy("+from+","+to+"), "+from+">= value count");
-		if (to>=getValueCount()) throw new RuntimeException("Out of bounds in copy("+from+","+to+"), "+to+">= value count");
-
-		this.operations.add(new CopyVal(from, to));
-
-		this.readCount++;
-		this.writeCount++;
-		this.values[to] = this.values[from];
-	}
-
-	/**
-	 * Make a textual description of the differences between the caller and world
-	 * @param world : the world with which you want to compare your world
-	 * @return A textual description of the differences between the caller and world
-	 */
-	@Override
-	public String diffTo(World world) {
-		String s ;
-		if (world == null || !(world instanceof SortingWorld)) {
-			s="This is not a world of sorting :(";
-		} else {
-			SortingWorld other = (SortingWorld) world;
-			StringBuffer sb = new StringBuffer();
-			if ( this.readCount != other.readCount )
-				sb.append("Invalid read count : expected "+this.readCount+" found "+other.readCount+"\n");
-			
-			if ( this.writeCount != other.writeCount )
-				sb.append("Invalid write count : expected "+this.writeCount+" found "+other.writeCount+"\n");
-			
-			for (int i = 0 ; i < this.values.length ; i++) 
-				if ( this.values[i] != other.values[i] )
-					sb.append("Index "+i+": expected "+this.values[i]+" found "+other.values[i]+"\n");
-					
-			s = sb.toString();
-		}
-		return s;
-	}
-
-
-	/** Returns the panel which let the user to interact dynamically with the world */
-	@Override
-	public EntityControlPanel getEntityControlPanel() {
-		return new SortingButtonPanel();
-	}
-	/** Returns the icon of the universe */
-	@Override
-	public ImageIcon getIcon() {
-		return ResourcesCache.getIcon("img/world_sorting.png");
-	}
-
-	/**
-	 * Returns the initial state of the array
-	 */
-	public int[] getInitValues() {
-		return initValues;
-	}
-
-	/**
-	 * Return the list of all the operations made on the world since its initialization/last reset
-	 */
-	public ArrayList<Operation> getOperations() {
-		return this.operations;
-	}
-
-	/**
-	 * Return the read counter
-	 */
-	public int getReadCount() {
-		return this.readCount;
-	}
-
-	/** Returns the amount of values in the array */
-	public int getValueCount() {
-		return values.length;
-	}
-
-	/** Returns the array of values that need to be sorted */
-	public int[] getValues() {
-		return this.values;
-	}
-
-	/** Returns a component able at displaying the world */
-	@Override
-	public WorldView getView() {
-		return new SortingWorldView(this);
-	}
-	
-	/** Returns the write counter */
-	public int getWriteCount() {
-		return this.writeCount;
-	}
-
-	/**
-	 * Tell if the value at the index i is smaller than the value at index j<br>
-	 * It costs two reads.
-	 * @param i the index of the first cell that we want to check
-	 * @param j the index of the second cell that we want to check
-	 * @return if the content of the cell of index i is smaller than the content of the cell of index j
-	 */
-	public boolean isSmaller(int i, int j) {
-		if (i<0) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"): "+i+"<0");
-		if (j<0) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"): "+j+"<0");
-		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"), "+i+">= value count");
-		if (j>=getValueCount()) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"), "+j+">= value count");
-
-		this.readCount+=2;
-		return this.values[i]< this.values[j];
-	}
-	
-	/**
-	 * Tell if the value at the index i is smaller than val<br>
-	 * It costs one read.
-	 * @param i the index of case that we want to check
-	 * @param val the value with which compare the cell
-	 * @return if the case of index i is smaller than val
-	 */
-	public boolean isSmallerThan(int i, int val) {
-		if (i<0) throw new RuntimeException("Out of bounds in isSmallerThan("+i+","+val+"): "+i+"<0");
-		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in isSmallerThan("+i+","+val+"), "+i+">= value count");
-
-		this.readCount+=1;
-		return this.values[i]<val;
-	}
-	
-	/** 
-	 * Reset the state of the current world to the one passed in argument
-	 * @param w the world which must be the new start of your current world
-	 */
-	@Override
-	public void reset(World w) {
-		super.reset(w);
-		SortingWorld world = (SortingWorld)w;
-		
-		this.values = world.values.clone();
-		this.initValues = world.initValues.clone();
-		this.readCount = world.readCount ;
-		this.writeCount = world.writeCount;
-		this.operations = new ArrayList<Operation>(1);
-		for ( Operation o: world.operations)
-		{
-			this.operations.add(o);
-		}
-	}
-
-	/**
-	 * Setup the engine so that it's ready to host the user code
-	 *
-	 * @param lang the programming language used
-	 * @throws ScriptException some error reported by the scripting engine itself
-	 */
-	@Override
-	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) throws ScriptException {
-		if (lang.equals(Game.PYTHON)) {
-			e.eval(
-					"def getValueCount():\n" +
-					"  return entity.getValueCount()\n" +
-					"def compare(i,j):\n" +
-					"  return entity.compare(i,j)\n" +
-					"def compareTo(i,j):\n"+
-					"  return entity.compareTo(i,j)\n" +
-					"def swap(i,j):\n" +
-					"  entity.swap(i,j)\n" +
-					"def copy(i,j):\n" +
-					"  entity.copy(i,j)\n" +
-					"def getValue(i):\n" +
-					"  return entity.getValue(i)\n" +
-					"def setValue(i,j):\n" +
-					"  entity.setValue(i,j)\n" +
-					"def isSmaller(i,j):\n"+
-					"  return entity.isSmaller(i,j)\n"+
-					"def isSmallerThan(i,j):\n"+
-					"  return entity.isSmallerThan(i,j)\n"
-			);
-		} else {
-			throw new RuntimeException("No binding of SortingWorld for "+lang);
-		}
-	}
-
-	/**
-	 * Return the value of index i in the array
-	 * @param i the index wanted in the array
-	 * @return the value of index i in the array
-	 */
-	public int getValue(int i) {
-		if (i<0) throw new RuntimeException("Out of bounds in getValue("+i+"): "+i+"<0");
-		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in getValue("+i+"), "+i+">= value count");
-		this.operations.add(new GetVal(i));
-		readCount++;
-		return values[i];
-	}
-
-	/**
-	 * Set the value of the case number i of the array at val<br>
-	 * It costs only one write.
-	 * @param i the index of the cell
-	 * @param val the value that you want to set
-	 */
-	public void setValue(int i,int val) {
-		if (i<0) throw new RuntimeException("Out of bounds in setValue("+i+"): "+i+"<0");
-		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in setValue("+i+"), "+i+">= value count");
-
-		this.operations.add(new SetVal(i, val));
-
-		this.writeCount++;
-		this.values[i]=val;
-	}
-
-	/**
-	 * Swap the value of the case number i with the value of the case number j<br>
-	 * It costs two reads and two writes
-	 * @param i the index of the first cell concerned
-	 * @param j the index of the second cell concerned
-	 */
-	public void swap(int i, int j) {
-		if (i<0) throw new RuntimeException("Out of bounds in swap("+i+","+j+"): "+i+"<0");
-		if (j<0) throw new RuntimeException("Out of bounds in swap("+i+","+j+"): "+j+"<0");
-		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in swap("+i+","+j+"), "+i+">= value count");
-		if (j>=getValueCount()) throw new RuntimeException("Out of bounds in swap("+i+","+j+"), "+j+">= value count");
-
-		this.operations.add(new Swap(i, j));
-
-		this.readCount+=2;
-		this.writeCount+=2;
-
-		exchangeValues(i,j);
-	}
-
-	/**
-	 * Exchange the value of the case number i with the value of the case number j<br>
-	 * It doesn't increase the read or the write counters.
-	 * @param i the index of the first cell concerned
-	 * @param j the index of the second cell concerned
-	 */
-	private void exchangeValues(int i, int j) {
-		int tmp = this.values[i];
-		this.values[i] = this.values[j];
-		this.values[j] = tmp;
-	}
-
-}
diff --git a/src/jlm/universe/sort/SortingWorldView.java b/src/jlm/universe/sort/SortingWorldView.java
deleted file mode 100644
index c7e9274..0000000
--- a/src/jlm/universe/sort/SortingWorldView.java
+++ /dev/null
@@ -1,335 +0,0 @@
-package jlm.universe.sort;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.geom.Rectangle2D;
-import java.util.Locale;
-
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
-
-import org.xnap.commons.i18n.I18n;
-import org.xnap.commons.i18n.I18nFactory;
-
-class SortingViewActionListener implements ActionListener, HumanLangChangesListener {
-	private JMenuItem item;
-	private SortingWorldView view;
-	private I18n i18n;
-
-	public SortingViewActionListener(JMenuItem i, SortingWorldView v) {
-		item=i;
-		view=v;
-		Game.getInstance().addHumanLangListener(this);
-		currentHumanLanguageHasChanged(item.getLocale());
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		view.setUseStateView(!view.isUseStateView());
-		currentHumanLanguageHasChanged(item.getLocale());
-		view.repaint();
-	}
-
-	@Override
-	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages", newLang, I18nFactory.FALLBACK);
-		if (view.isUseStateView()) {
-			item.setText(i18n.tr("Switch to time view"));
-		} else {
-			item.setText(i18n.tr("Switch to state view"));
-		}
-	}
-	
-	
-}
-
-
-public class SortingWorldView extends WorldView {
-	private static final long serialVersionUID = 1L;
-	private JPopupMenu popup = new JPopupMenu();
-	private boolean useStateView = true; // chronoView if false
-
-	public SortingWorldView(World w) {
-		super(w);
-		JMenuItem menuItem;
-
-		//Create the popup menu allowing to switch between views
-		menuItem = new JMenuItem("Switch to time view");
-		menuItem.addActionListener(new SortingViewActionListener(menuItem,this));
-		popup.add(menuItem);
-
-		//Connect it as contextual menu to this pane
-		MouseListener popupListener = new MouseAdapter() {
-			private void maybeShowPopup(MouseEvent e) {
-				if (e.isPopupTrigger()) {
-					popup.show(e.getComponent(),
-							e.getX(), e.getY());
-				}
-			}
-
-			public void mousePressed(MouseEvent e) {
-				maybeShowPopup(e);
-			}
-
-			public void mouseReleased(MouseEvent e) {
-				maybeShowPopup(e);
-			}
-		};
-		this.addMouseListener(popupListener);
-	}
-
-	/**
-	 * Draw the Chrono view
-	 * @param g2 some 2D graphics
-	 * @param we the sorting world considered
-	 */
-	private void drawAlgoChrono(Graphics2D g2, SortingWorld we) {
-		int operationsAmount = we.getOperations().size();	// little optimization
-		/* getWidth()-12 to keep the room to display the very left value. Do that even if we don't depict them */
-		float stepX = ((float)getWidth()-12) / ((float)(Math.max(operationsAmount, 1)));
-		float stepY = ((float)getHeight()) / ((float)(we.getValueCount()));
-		int x1, y1, x2, y2, tone;
-
-		// If the array is small enough, we print the values
-		boolean drawStr = (stepX > 12) && (stepY>12);
-		
-		// Case without any operation to draw: initial view
-		if (operationsAmount == 0) {
-
-			for (int valueIdx = 0; valueIdx < we.getValueCount(); valueIdx++) { 
-				y1 = (int) (valueIdx * stepY + stepY/2.);
-
-				tone = (int) ((((float) we.getValues()[valueIdx]) / ((float) we.getValueCount())) * 255.);
-				g2.setColor(new Color(tone, tone, 128));
-
-				g2.drawLine(0, y1, (int)stepX, y1);
-
-				//If the array is small enough, we print the values
-				if (drawStr) 
-					g2.drawString("" + we.getValues()[valueIdx], 0, y1);
-			}
-			return;
-		}
-
-		// Draw the values at the very left of the figure (in any case)
-		for (int valueIdx = 0; valueIdx < we.getValueCount(); valueIdx++) { 
-			y1 = (int) (valueIdx * stepY + stepY/2);
-			tone = getValueColor(we.getInitValues()[valueIdx],we.getValueCount());
-			g2.setColor(new Color(tone, tone, 128));
-			g2.drawString("" + we.getInitValues()[valueIdx], 0, y1);
-		}
-		
-		int[] valuesAfter = new int[we.getInitValues().length];
-		int[] valuesBefore = new int[we.getInitValues().length];
-		for (int i = 0; i < we.getInitValues().length; i++) { 
-			valuesBefore[i] = we.getInitValues()[i];
-			valuesAfter[i] = valuesBefore[i];
-		}
-		
-		// Case with several operations
-		for (int opIdx = 0; opIdx < operationsAmount; opIdx++) {
-			Operation op = we.getOperations().get(opIdx);
-
-			valuesAfter = op.run(valuesAfter);
-			
-			x1 = (int) (opIdx * stepX);
-			x2 = (int) (x1 + stepX);
-
-			/* Draw straight lines for unmodified values */
-			for (int valIdx=0; valIdx<we.getValueCount();valIdx++) {
-				y1 = (int) (valIdx * stepY + stepY/2);
-				
-				if ( op.getSource() != valIdx && op.getDestination() != valIdx) {							
-					tone = getValueColor(valuesAfter[valIdx],we.getValueCount());
-					g2.setColor(new Color(tone, tone, 128));
-					
-					g2.drawLine(x1, y1, x2, y1);
-				}
-			}
-			/* Write the values in their new position (if there is not too much values) */
-			if (drawStr) 
-				for (int valIdx=0; valIdx<we.getValueCount();valIdx++) { 
-					y1 = (int) (valIdx * stepY + stepY/2);
-					
-					tone = getValueColor(valuesAfter[valIdx],we.getValueCount());
-					g2.setColor(new Color(tone, tone, 128));
-					g2.drawString("" + valuesAfter[valIdx], x2, y1);		
-				}
-			
-			/* Draw the lines depicting the current operation */
-			if (op instanceof Swap ) { // op is a Swap
-//				System.out.println("Swap "+op.source+" <-> "+op.destination);
-				
-				// draw source->dest
-				y1 = (int) (op.getSource() * stepY + stepY/2);
-				y2 = (int) (op.getDestination() * stepY + stepY/2);
-				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
-				g2.setColor(new Color(tone, tone, 128));
-				g2.drawLine(x1, y1, x2, y2);
-
-				// draw dest->source
-				y1 = (int) (op.getDestination() * stepY + stepY/2);
-				y2 = (int) (op.getSource() * stepY + stepY/2);
-				tone = getValueColor(valuesAfter[op.getSource()],we.getValueCount());
-				g2.setColor(new Color(tone, tone, 128));
-				g2.drawLine(x1, y1, x2, y2);
-
-			} else if (op instanceof CopyVal) {
-//				System.out.println("Copy "+op.source+" -> "+op.destination);
-				
-				// draw the value being copied over
-				y1 = (int) (op.getSource() * stepY + stepY/2);
-				y2 = (int) (op.getDestination() * stepY + stepY/2);
-				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
-				g2.setColor(new Color(tone, tone, 128));
-				g2.drawLine(x1, y1, x2, y2);
-				
-				// draw the old value remaining the same
-				y1 = (int) (op.getSource() * stepY + stepY/2);
-				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
-				g2.setColor(new Color(tone, tone, 128));
-				g2.drawLine(x1, y1, x2, y1);
-				
-			} else if (op instanceof SetVal) {
-//				System.out.println("Set "+op.source+" (to "+((SetVal)op).value+")");
-				if (drawStr || true) {
-					y1 = (int) (op.source * stepY + stepY/2);
-				
-					tone = getValueColor(valuesAfter[op.source],we.getValueCount());
-					g2.setColor(Color.red);
-					g2.drawString("" + valuesAfter[op.source]+"!", x2, y1);
-				}
-
-				/* Don't draw a line for the modified value, actually */
-			} else if (op instanceof GetVal) {
-//				System.out.println("Get "+((GetVal)op).position);
-				if (drawStr || true) {
-					int pos = ((GetVal) op).position;
-					y1 = (int) (pos * stepY + stepY/2);
-				
-					tone = getValueColor(valuesAfter[pos],we.getValueCount());
-					g2.setColor(Color.MAGENTA);
-					g2.drawString("" + valuesAfter[pos]+"?", x2, y1);
-				}
-			} else {
-				System.out.println("This operation is not depicted because that's a "+op.toString()+"; please report this bug.");
-			}
-			
-
-			for (int k = 0; k < valuesAfter.length; k++) 
-				valuesBefore[k] = valuesAfter[k];
-		}
-	}
-
-	/**
-	 * Draw the state view
-	 * @param g2 some graphics 2D 
-	 * @param world the sorting world considered
-	 * @param maxSize the max size for a rectangle ( which represents a data in the array ) 
-	 */
-	private void drawAlgoState(Graphics2D g2, SortingWorld world, int maxSize) {
-		double scale = ((double)getWidth())/world.getValues().length;
-		int[] values = world.getValues() ;
-		for (int i=0;i< values.length;i++) 
-		{
-			double height = ((double)values[i])*((double)maxSize)/ ((double)(world.getValueCount()-1));
-			Shape rect = new Rectangle2D.Double(scale*i, ((double)maxSize)- height,scale, height);
-
-			g2.setColor( values[i]==i ? Color.GREEN : Color.RED) ;
-
-			g2.fill(rect);
-
-			g2.setColor(Color.black);
-			g2.draw(rect);
-			if (scale > 20) 
-				g2.drawString(""+values[i], (int)scale*i+(int)scale/2, maxSize-2);
-		}
-		g2.setColor(Color.black);
-		g2.drawString(world.getName()+" ("+world.getWriteCount()+" write, "+world.getReadCount()+" read)", 0, 15);
-	}
-
-	/**
-	 * Decide which view we must draw ( state or chrono )
-	 */
-	public void paintComponent(Graphics g) {
-		if (useStateView) { // myExo is null during initialization
-			paintComponentState(g);
-		} else {
-			paintComponentChrono(g);			
-		}
-	}
-
-	/**
-	 * Paint the chrono view into a rectangle
-	 * @param g some graphics indicating where to draw
-	 */
-	private void paintComponentChrono(Graphics g) {
-		super.paintComponent(g);
-		Graphics2D g2 = (Graphics2D) g;
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-				RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setColor(Color.white);
-		g2.fill(new Rectangle2D.Double(0., 0., (double) getWidth(),
-				(double) getHeight()));
-
-		g2.setColor(Color.black);
-		g2.setFont(new Font("Monaco", Font.PLAIN, 12));
-
-		drawAlgoChrono(g2, (SortingWorld) world);
-	}
-
-	/**
-	 * Draw the state view into a rectangle
-	 * @param g some graphics indicating where to draw
-	 */
-	private void paintComponentState(Graphics g) {
-		super.paintComponent(g);
-		Graphics2D g2 = (Graphics2D) g;
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setColor(Color.white);
-		g2.fill(new Rectangle2D.Double(0.,0.,(double)getWidth(),(double)getHeight()));
-
-		g2.setFont(new Font("Monaco", Font.PLAIN, 12));
-
-		if (world.getEntityCount() > 1) 
-			System.err.println("Sorting World does not accept more than one entity anymore. Please fix your exercise.");
-		
-		int maxSize = getHeight();
-
-		drawAlgoState(g2, (SortingWorld) this.world, maxSize);
-	}
-
-	/**
-	 * Return the tone of the value. This tone is used by the chrono view, it's the color of a line.
-	 * @param value the value from which get the tone
-	 * @param valueCount the total amount of values in the array
-	 * @return the tone of the value 
-	 */
-	private int getValueColor(int value,int valueCount) {
-		return (int) ((((float) value) / ((float) valueCount)) * 255.);
-	}
-
-
-	/** Returns if we must use the state view ( else we must use the chrono view ) */
-	protected boolean isUseStateView() {
-		return useStateView;
-	}
-	protected void setUseStateView(boolean useStateView) {
-		this.useStateView = useStateView;
-	}
-
-}
diff --git a/src/jlm/universe/sort/Swap.java b/src/jlm/universe/sort/Swap.java
deleted file mode 100644
index 9e4e36c..0000000
--- a/src/jlm/universe/sort/Swap.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package jlm.universe.sort;
-
-public class Swap extends Operation {
-	
-	/**
-	 * Constructor of the class Swap
-	 * @param source the source of the operation
-	 * @param destination the destination of the operation
-	 */
-	public Swap(int source, int destination){
-		super(source,destination);
-	}
-
-	/**
-	 * Compute an operation on init
-	 * @param init the values on which compute the operation
-	 * @return the array passed as parameter, once the operation has been applied to it
-	 */
-	@Override
-	public int[] run(int[] init) {
-		int src = init[source];
-		int dest = init[destination];
-		init[source] = dest;
-		init[destination] = src;
-		
-		return init;
-	}
-	
-	
-}
diff --git a/src/jlm/universe/sort/package-info.java b/src/jlm/universe/sort/package-info.java
deleted file mode 100644
index 9f8f65e..0000000
--- a/src/jlm/universe/sort/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Universe to explore the classical sorting algorithms
- */
-
-package jlm.universe.sort;
-
diff --git a/src/jlm/universe/turtles/Direction.java b/src/jlm/universe/turtles/Direction.java
deleted file mode 100644
index d008279..0000000
--- a/src/jlm/universe/turtles/Direction.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package jlm.universe.turtles;
-
-public enum Direction {
-
-	EAST, NORTH, WEST, SOUTH;
-
-}
diff --git a/src/jlm/universe/turtles/Line.java b/src/jlm/universe/turtles/Line.java
deleted file mode 100644
index e170e1f..0000000
--- a/src/jlm/universe/turtles/Line.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package jlm.universe.turtles;
-
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.geom.Line2D;
-
-
-public class Line {
-	public double x1, y1,  x2, y2;
-	public Color color;
-	
-	public Line(double x1, double y1, double x2, double y2, Color color) {
-		this.x1 = x1;
-		this.y1 = y1;
-		this.x2 = x2;
-		this.y2 = y2;
-		this.color = color;
-	}
-	
-	public void draw(Graphics2D g){
-		g.setColor(color);
-		g.draw(new Line2D.Double(x1,y1,x2,y2));
-	}
-
-	public Line copy() {
-		return new Line(x1,y1,x2,y2,color);
-	}
-	private boolean doubleEqual(double a, double b) {
-		return (Math.abs(a-b)<0.000001);
-	}
-	
-	@Override
-	public boolean equals(Object obj) {
-		if (! (obj instanceof Line))
-			return false;
-		
-		Line other = (Line) obj;
-		if (!doubleEqual(x1,other.x1))
-			return false;
-		if (!doubleEqual(x2,other.x2))
-			return false;
-		if (!doubleEqual(y1,other.y1))
-			return false;
-		if (!doubleEqual(y2,other.y2))
-			return false;
-				
-		return true;
-	}
-	public String diffTo(Line o) {
-		Line other = (Line) o;
-		if (!doubleEqual(x1,other.x1))
-			return "x1 differs";
-		if (!doubleEqual(x2,other.x2))
-			return "x2 differs";
-		if (!doubleEqual(y1,other.y1))
-			return "y1 differs";
-		if (!doubleEqual(y2,other.y2))
-			return "y2 differs";
-		return "I dont see the difference";
-	}
-	
-	@Override
-	public String toString(){
-		return "Line ("+x1+","+y1+";"+x2+","+y2+";"+color+")";
-	}
-}
diff --git a/src/jlm/universe/turtles/Turtle.java b/src/jlm/universe/turtles/Turtle.java
deleted file mode 100644
index 59971be..0000000
--- a/src/jlm/universe/turtles/Turtle.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package jlm.universe.turtles;
-
-import java.awt.Color;
-
-import jlm.universe.Entity;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class Turtle extends Entity {
-
-	public final static int DEGREE = 1;
-	public final static int RADIAN = 2;
-	public static final double EPSILON = .0000001;
-
-	private Color color;
-
-	private double x = 0.;
-	private double y = 0.;
-
-	private double heading = 0.;
-	private boolean penDown = true;
-	private int angularUnit = Turtle.DEGREE;
-
-	/**
-	 * Constructor with no argument so that child classes can avoid declaring a
-	 * constructor. But it should not be used as most methods assert on world
-	 * being not null. After using it, {@link Entity#setWorld(BuggleWorld)} must be
-	 * used ASAP.
-	 */
-	public Turtle() {
-		this(null, "John Doe", 0., 0., 0., Color.red);
-	}
-
-	public Turtle(World w) {
-		this(w, "John Doe", 0., 0., 0., Color.red);
-	}
-
-	public Turtle(World w, String name) {
-		this(w, name, 0., 0., 0., Color.red);
-	}
-
-	public Turtle(World w, String name, double x, double y) {
-		this(w, name, x, y, 0., Color.red);
-	}
-
-	public Turtle(World world, String name, double x, double y, double heading, Color c) {
-		super(name, world);
-		this.color = c;
-		this.x = x;
-		this.y = y;
-		this.heading = heading;
-		setHeading(heading);
-	}
-
-	public Turtle(Turtle t) {
-		super();
-		setName(t.getName());
-		setWorld(t.getWorld());
-		this.color = t.color;
-		this.x = t.x;
-		this.y = t.y;
-		this.heading = t.heading;
-		//this.angularUnit = t.angularUnit;
-		this.penDown = t.penDown;
-	}
-
-	@Override
-	public void copy(Entity e) {
-		super.copy(e);
-		Turtle other = (Turtle) e;
-		this.color = other.color;
-		this.x = other.x;
-		this.y = other.y;
-		this.heading = other.heading;
-		//this.angularUnit = other.angularUnit;
-		this.penDown = other.penDown;
-	}
-
-	@Override
-	public Entity copy() {
-		return new Turtle(this);
-	}
-
-	public void forward(double dist) {
-		moveTo(x + dist * Math.cos(heading), y + dist * Math.sin(heading));
-	}
-
-	public void backward(double dist) {
-		moveTo(x + dist * Math.cos(heading + Math.PI), y + dist * Math.sin(heading + Math.PI));
-	}	
-	
-	public Direction getHeadingDirection() {
-		final double w = getWorld().getWidth();
-		final double h = getWorld().getHeight();
-		final double angleHeading = 2*Math.PI - this.heading;
-		
-		if (this.heading >=0 && this.heading < Math.PI) {
-			// bottom semi-circle
-			final double tangenteAngleToBottomLeftCorner = (this.x>EPSILON)?((h-this.y) / this.x):Double.POSITIVE_INFINITY;
-			final double angleToBottomLeftCorner = Math.PI+Math.atan(tangenteAngleToBottomLeftCorner);
-			final double tangenteAngleToBottomRightCorner = ((w-this.x)>EPSILON)?((h-this.y) / (w-this.x)):Double.POSITIVE_INFINITY;
-			final double angleToBottomRightCorner = 2*Math.PI-Math.atan(tangenteAngleToBottomRightCorner);
-
-			if (angleHeading < angleToBottomLeftCorner) {
-				return Direction.WEST;
-			} else if (angleHeading < angleToBottomRightCorner) {
-				return Direction.SOUTH;
-			} else {
-				return Direction.EAST;
-			}
-		} else {
-			// bottom semi-circle			
-			final double tangenteAngleToTopRightCorner = ((w-this.x)>EPSILON)?((this.y) / (w-this.x)):Double.POSITIVE_INFINITY;
-			final double angleToTopRightCorner = Math.atan(tangenteAngleToTopRightCorner);
-			final double tangenteAngleToTopLeftCorner = (this.x>EPSILON)?(this.y / this.x):Double.POSITIVE_INFINITY;
-			final double angleToTopLeftCorner = Math.PI-Math.atan(tangenteAngleToTopLeftCorner);
-					
-			if (angleHeading < angleToTopRightCorner) {
-				return Direction.EAST;
-			} else if (angleHeading < angleToTopLeftCorner) {
-				return Direction.NORTH;
-			} else {
-				return Direction.WEST;
-			}
-		}
-	}
-	
-	public void moveTo(double newX, double newY) {
-		final double w = this.getWorld().getWidth();
-		final double h = this.getWorld().getHeight();
-		
-		double nX = newX;
-		double nY = newY;
-		
-		while (nX < 0 || nX >= w || nY < 0 || nY >= h) { // need to clip			
-			// line equation y = y1+m(x-x1)
-			// where m=(y2-y1)/(x2-x1)
-			final double m = (nY - y) / (nX - x);
-	
-			switch (this.getHeadingDirection()) {
-			case EAST:
-				// intersection with the right boundary (x=r)
-				// x=r and y=y1+m(r-x1)
-				{
-					final double xc = w;
-					final double yc = y + m * (w - x);
-
-					if (this.penDown) {
-						this.getWorld().addLine(x, y, xc, yc, color);
-					}
-					setPos(0., yc);
-					nX = nX - w;
-				}
-				break;
-			case NORTH:
-				// intersection with the top boundary (y=t)
-				// x=(1/m)(t-y1)+x1 and y=t
-				{
-					final double xc = (0 - this.y) / m + this.x;
-					final double yc = 0;
-
-					if (this.penDown) {
-						this.getWorld().addLine(x, y, xc, yc, color);
-					}
-					setPos(xc, h);
-					nY = nY + h;
-				}
-				break;
-			case WEST:
-				// intersection with the left boundary (x=l)
-				// x=l and y=y1+m(l-x1)
-				{
-					final double xc = 0;
-					final double yc = y + m * (0 - x);
-
-					if (this.penDown) {
-						this.getWorld().addLine(x, y, xc, yc, color);
-					}
-					setPos(w, yc);
-					nX = nX + w;
-				}
-				break;
-			case SOUTH:
-				// intersection with the top boundary (y=t)
-				// x=(1/m)(t-y1)+x1 and y=t
-				{
-					final double xc = (h - this.y) / m + this.x;
-					final double yc = h;
-
-					if (this.penDown) {
-						this.getWorld().addLine(x, y, xc, yc, color);
-					}
-					setPos(xc, 0.);
-					nY = nY - h;
-				}
-				break;			
-			}	
-		} 
-		
-		if (this.penDown) {
-			this.getWorld().addLine(x, y, nX, nY, color);
-		}			
-		this.x = nX;
-		this.y = nY;		
-		
-		stepUI();
-	}
-
-	public void turnLeft(double angle) {
-		setHeadingRadian(heading - fromAngularUnit(angle));
-	}
-
-	public void turnRight(double angle) {
-		setHeadingRadian(heading + fromAngularUnit(angle));
-	}
-
-	public boolean isPenDown() {
-		return penDown;
-	}
-
-	public void penDown() {
-		this.penDown = true;
-	}
-
-	public void penUp() {
-		this.penDown = false;
-	}
-
-	private double fromAngularUnit(double angle) {
-		switch (angularUnit) {
-		case Turtle.DEGREE:
-			return Math.toRadians(angle);
-		case Turtle.RADIAN:
-			return angle;
-		}
-		throw new RuntimeException("Unknown angular unit:" + angularUnit + " (please report this bug)");
-	}
-
-	private final double toAngularUnit(double angle) {
-		switch (angularUnit) {
-		case Turtle.DEGREE:
-			return Math.toDegrees(angle);
-		case Turtle.RADIAN:
-			return angle;
-		}
-		throw new RuntimeException("Unknown angular unit:" + angularUnit + " (please report this bug)");
-	}
-
-	public double getHeading() {
-		return toAngularUnit(heading);
-	}
-
-	public void setHeading(double heading) {
-		setHeadingRadian(fromAngularUnit(heading));
-	}
-
-	protected void setHeadingRadian(double heading) {
-		this.heading = ((2. * Math.PI) + heading) % (2. * Math.PI);
-		if (world != null)
-			world.notifyWorldUpdatesListeners();
-	}
-	
-	protected double getHeadingRadian() {
-		return this.heading;
-	}
-
-	@Override
-	public TurtleWorld getWorld() {
-		return (TurtleWorld) super.getWorld();
-	}
-	
-	public Color getColor() {
-		return color;
-	}
-
-	public void setColor(Color c) {
-		color = c;
-	}
-
-	public double getX() {
-		return x;
-	}
-
-	public void setX(double x) {
-		this.x = x;
-		stepUI();
-	}
-
-	public double getY() {
-		return y;
-	}
-
-	public void setY(double y) {
-		this.y = y;
-		stepUI();
-	}
-
-	public void setPos(double x, double y) {
-		this.x = x;
-		this.y = y;
-		stepUI();
-	}
-
-	/* let's accept integers as arguments, too */
-	public void forward(int steps) {
-		forward((double) steps);
-	}
-
-	public void backward(int steps) {
-		backward((double) steps);
-	}
-
-	public void turnLeft(int a) {
-		turnLeft((double) a);
-	}
-
-	public void turnRight(int a) {
-		turnRight((double) a);
-	}
-
-	public void setHeading(int heading) {
-		setHeading((double) heading);
-	}
-
-	public void setX(int x) {
-		setX((double) x);
-	}
-
-	public void setY(int y) {
-		setY((double) y);
-	}
-
-	public void setPos(int x, int y) {
-		setPos((double) x, (double) y);
-	}
-
-	public void setPos(double x, int y) {
-		setPos((double) x, (double) y);
-	}
-
-	public void setPos(int x, double y) {
-		setPos((double) x, (double) y);
-	}
-	
-	@Override
-	public String toString() {
-		return "Turtle (" + this.getClass().getName() + "): x=" + x + " y=" + y + " Heading:" + heading + " Color:"
-				+ color;
-	}
-
-	@Override
-	public int hashCode() {
-		final int PRIME = 31;
-		int result = 1;
-		result = PRIME * result + ((color == null) ? 0 : color.hashCode());
-		result = PRIME * result + (penDown ? 1231 : 1237);
-		result = PRIME * result + (int) heading;
-		result = PRIME * result + (int) x;
-		result = PRIME * result + (int) y;
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (!(obj instanceof Turtle))
-			return false;
-
-		final Turtle other = (Turtle) obj;
-		if (color == null) {
-			if (other.color != null)
-				return false;
-		} else if (!color.equals(other.color))
-			return false;
-		if (Math.abs(heading-other.heading) > Turtle.EPSILON)
-			return false;
-		if (Math.abs(x-other.x) > Turtle.EPSILON)
-			return false;
-		if (Math.abs(y-other.y) > Turtle.EPSILON)
-			return false;
-		return true;
-	}
-
-	@Override
-	public void run() {
-		// Overriden by childs
-	}
-
-}
diff --git a/src/jlm/universe/turtles/TurtleButtonPanel.java b/src/jlm/universe/turtles/TurtleButtonPanel.java
deleted file mode 100644
index f26ef19..0000000
--- a/src/jlm/universe/turtles/TurtleButtonPanel.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package jlm.universe.turtles;
-
-import javax.swing.JLabel;
-import javax.swing.JTextArea;
-
-import jlm.universe.EntityControlPanel;
-import net.miginfocom.swing.MigLayout;
-
-public class TurtleButtonPanel extends EntityControlPanel {
-
-	private static final long serialVersionUID = 1L;
-	JLabel lForward;
-	JTextArea taForward;
-	
-	public TurtleButtonPanel() {
-		setLayout(new MigLayout());
-		//lForward = new JLabel("Forward");
-		//taForward = new JTextArea();
-		//add(lForward);
-		//add(taForward,"wrap");	
-	}
-
-	@Override
-	public void setEnabledControl(boolean enabled) {
-		//lForward.setEnabled(enabled);
-		//taForward.setEnabled(enabled);
-	}
-}
diff --git a/src/jlm/universe/turtles/TurtleWorld.fr.html b/src/jlm/universe/turtles/TurtleWorld.fr.html
deleted file mode 100644
index 694ca9e..0000000
--- a/src/jlm/universe/turtles/TurtleWorld.fr.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<h1>Monde des tortues</h1>
-
-<p>Cet univers est une adaptation de LOGO pour la Java Learning Machine.</p>
-
-<p>Il est directement inspiré des travaux du mathématicien Seymour Papert dans
-les années 60. Inspiré par le psychologue suisse Jean Piaget, il a inventé
-une méthode d'apprentissage de la programmation accessible aux jeunes
-enfants nommée LOGO. Le monde est peuplé de tortues qui laissent une trace
-là où elles marchent et à qui on peut donner des ordres simples.</p>
-
-<h2>Fonctions pour déplacer la tortue</h2>
-
-<pre class="Java">void forward(double nbPas)
-void backward(double nbPas)</pre>
-<pre class="python">forward(nbPas)
-backward(nbPas)</pre>
-Avance (forward) ou recule (backward) du nombre de pas demandés.
-
-<pre class="Java">void turnRight(double angle)
-void turnLeft(double angle)</pre>
-<pre class="python">turnRight(angle)
-turnLeft(angle)</pre>
-Tourne à gauche (left) ou à droite (right) du nombre de l'angle indiqué (en
-degrés).
-
-<pre class="Java">double getX()
-double getY()</pre>
-<pre class="python">getX()
-getY()</pre>
-Retourne la position acutelle de la tortue.
-
-<pre class="Java">void setX(double x)
-void setY(double y)
-void setPos(double x, double y)</pre>
-<pre class="python">setX(x)
-setY(y)
-setPos(x,y)</pre>
-Téléporte la tortue à une nouvelle position.
-
-<pre class="Java">double getHeading()</pre>
-<pre class="python">getHeading()</pre>
-Retourne le cap actuel de la tortue (en degrés).
-
-<pre class="Java">void getHeading(double angle)</pre>
-<pre class="python">getHeading(angle)</pre>
-Change le cap de la tortue à l'angle indiqué (en degrés).
-
-<h2>Fonctions à propos du stylo</h2>
-
-<pre class="Java">void penUp()</pre>
-<pre class="python">penUp()</pre>
-Remonte le stylo de la tortue (les tortues ont des stylos, pas des brosses
-comme les buggles). La tortue ne laissera plus de trace lors de ses
-déplacements suivants.
-
-<pre class="Java">void penDown()</pre>
-<pre class="python">penDown()</pre>
-Descend le stylo. La tortue laissera une trace lors de ses prochains
-déplacements.
-
-<pre class="Java">boolean isPenDown()</pre>
-<pre class="python">isPenDown()</pre>
-Retourne si le stylo est actuellement baissé ou non.
-
-<pre class="Java">Color getColor()</pre>
-<pre class="python">getColor()</pre>
-Retourne la couleur actuelle du stylo.
-
-<pre class="Java">void setColor(Color color)</pre>
-<pre class="python">getColor(color)</pre>
-Modifier la couleur du stylo.
-
-<h2>Autres fonctions</h2>
-
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
-Renvoie si la tortue actuelle est sélectionnée dans l'interface graphique.
diff --git a/src/jlm/universe/turtles/TurtleWorld.html b/src/jlm/universe/turtles/TurtleWorld.html
deleted file mode 100644
index 0c78def..0000000
--- a/src/jlm/universe/turtles/TurtleWorld.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<h1>TurtleWorld</h1>
-
-<p>This universe is an adaptation of LOGO for the Java Learning Machine.</p>
-
-<p>It is directly inspired from the work of the mathematician Seymour
-Papert in the 60's. Inspired from the swiss psycholog Jean Piaget, he came
-up with a learning method called LOGO to teach programming to young
-childs. The world is full of turtles which leave a painting where they go
-and which respond to simple orders.</p>
-
-<h2>Functions to move the turtle</h2>
-
-<pre class="Java">void forward(double steps)
-void backward(double steps)</pre>
-<pre class="python">forward(steps)
-backward(steps)</pre>
-Moves forward or backward of the requested amount of steps.
-
-<pre class="Java">void turnRight(double angle)
-void turnLeft(double angle)</pre>
-<pre class="python">turnRight(angle)
-turnLeft(angle)</pre>
-Turns left or right of the given angle (in degrees).
-
-<pre class="Java">double getX()
-double getY()</pre>
-<pre class="python">getX()
-getY()</pre>
-Returns the current position of the turtle.
-
-<pre class="Java">void setX(double x)
-void setY(double y)
-void setPos(double x, double y)</pre>
-<pre class="python">setX(x)
-setY(y)
-setPos(x,y)</pre>
-Teleports the turtle to a new position.
-
-<pre class="Java">double getHeading()</pre>
-<pre class="python">getHeading()</pre>
-Returns the current heading of the turtle (in degrees).
-
-<pre class="Java">void getHeading(double angle)</pre>
-<pre class="python">getHeading(angle)</pre>
-Sets a new heading to the turtle (in degrees).
-
-<h2>Functions about the pen</h2>
-
-<pre class="Java">void penUp()</pre>
-<pre class="python">penUp()</pre>
-Moves the pen up (turtles have pens, not brushes as buggles). The
-turtle will not leave any trace during its subsequent moves.
-
-<pre class="Java">void penDown()</pre>
-<pre class="python">penDown()</pre>
-Moves the pen down. The turtle will leave a trace during its subsequent moves.
-
-<pre class="Java">boolean isPenDown()</pre>
-<pre class="python">isPenDown()</pre>
-Returns the current pen position as a boolean.
-
-<pre class="Java">Color getColor()</pre>
-<pre class="python">getColor()</pre>
-Returns the current pen color.
-
-<pre class="Java">void setColor(Color color)</pre>
-<pre class="python">getColor(color)</pre>
-Changes the pen color.
-
-<h2>Other functions</h2>
-
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
-Returns whether the current turtle is selected in the graphical interface.
diff --git a/src/jlm/universe/turtles/TurtleWorld.java b/src/jlm/universe/turtles/TurtleWorld.java
deleted file mode 100644
index 7c2e48c..0000000
--- a/src/jlm/universe/turtles/TurtleWorld.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package jlm.universe.turtles;
-
-import java.awt.Color;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Iterator;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptException;
-import javax.swing.ImageIcon;
-
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
-
-public class TurtleWorld extends World {
-
-	ArrayList<Line> shapes = new ArrayList<Line>(); 
-
-	private double width;
-	private double height;
-	
-	public TurtleWorld(String name) {
-		super(name);
-	}
-
-	public TurtleWorld(String name, int width, int height) {
-		super(name);
-		this.width = width;
-		this.height = height;
-	}
-	
-	public TurtleWorld(TurtleWorld world2) {
-		super(world2);
-	}
-
-	@Override
-	public void reset(World w) {
-		TurtleWorld initialWorld = (TurtleWorld)w;
-		shapes = new ArrayList<Line>();
-		this.height = initialWorld.height;
-		this.width = initialWorld.width;
-
-		Iterator<Line> it = initialWorld.shapes();
-		while (it.hasNext()) 
-			shapes.add(it.next().copy());
-		
-		super.reset(w);		
-	}
-	
-	public void addLine(double x, double y, double newX, double newY, Color color) {
-		synchronized (shapes) {
-			//ShapeLine line =new ShapeLine(width/2+x,height/2+y,width/2+newX,height/2+newY,color); 
-			Line line =new Line(x,y,newX,newY,color); 
-			shapes.add(line);
-			notifyWorldUpdatesListeners();
-		}
-	}
-	public Iterator<Line> shapes() {
-		return shapes.iterator();
-	}
-	
-
-	public double getHeight() {
-		return height;
-	}
-	public double getWidth() {
-		return width;
-	}
-	
-	@Override
-	public EntityControlPanel getEntityControlPanel() {
-		return new TurtleButtonPanel();
-	}
-
-	@Override
-	public WorldView getView() {
-		return new TurtleWorldView(this);
-	}
-	@Override
-	public ImageIcon getIcon() {
-		return ResourcesCache.getIcon("img/world_turtle.png");
-	}
-	
-	@Override
-	public boolean equals(Object obj) {
-		if (! (obj instanceof TurtleWorld))
-			return false;
-		if (! super.equals(obj))
-			return false;
-		
-		TurtleWorld other = (TurtleWorld) obj;
-		if (shapes.size() != other.shapes.size())
-			return false;
-		Collections.sort(shapes, new LineComparator());
-		Collections.sort(other.shapes, new LineComparator());
-		for (int i=0;i<shapes.size();i++)
-			if (! shapes.get(i).equals(other.shapes.get(i)))
-				return false;
-		
-		return true;
-	}
-	
-	// TODO implement world IO	
-	
-	@Override
-	public String toString(){
-		String res = "TurtleWorld: name="+getName()+
-			", size="+width+"x"+height+
-			", parameters: " +parameters+
-			", shapes=[";
-		Iterator<Line> it = shapes();
-		while (it.hasNext()) 
-			res += it.next().toString();
-		res += "]";
-		return res;
-	}
-	@Override
-	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) throws ScriptException {
-		if (lang.equals(Game.PYTHON)) {
-			e.put("Color", Color.class);
-			e.eval( "def backward(i):\n"+
-					"  entity.backward(i)\n"+
-					"def forward(i):\n"+
-					"  entity.forward(i)\n"+
-					"def penUp():\n"+
-					"  entity.penUp()\n"+
-					"def penDown():\n"+
-					"  entity.penDown()\n"+
-					"def turnLeft(i):\n"+
-					"  entity.turnLeft(i)\n"+
-					"def turnRight(i):\n"+
-					"  entity.turnRight(i)\n"+
-					"def setColor(c):\n"+
-					"  entity.setColor(c)\n" +
-					"def setPos(x,y):\n" +
-					"  entity.setPos(x,y)\n" +
-					"def moveTo(x,y):\n" +
-					"  entity.moveTo(x,y)\n"
-					);
-		} else {
-			throw new RuntimeException("No binding of TurtleWorld for "+lang);
-		}
-	}
-
-	@Override
-	public String diffTo(World world) {
-		StringBuffer sb = new StringBuffer();
-		TurtleWorld other = (TurtleWorld) world;
-		if (shapes.size() != other.shapes.size())
-			sb.append("  There is only "+other.shapes.size()+" lines where "+shapes.size()+" were expected.\n");
-		for (int i=0;i<other.shapes.size();i++)
-			if (! other.shapes.get(i).equals(shapes.get(i)))
-				sb.append("  Got "+other.shapes.get(i)+" where "+shapes.get(i)+" were expected ("+
-						((Line) other.shapes.get(i)).diffTo(shapes.get(i))+")\n");
-		
-		return sb.toString();
-	}
-}
-
-class LineComparator implements Comparator<Line> {
-
-	public LineComparator() {
-		super();
-	}
-
-	@Override
-	public int compare(Line l1, Line l2) {
-		if (l1.x1 < l2.x1)
-			return -1;
-		if (l1.x1 > l2.x1)
-			return 1;
-
-		if (l1.x2 < l2.x2)
-			return -1;
-		if (l1.x2 > l2.x2)
-			return 1;
-
-		if (l1.y1 < l2.y1)
-			return -1;
-		if (l1.y1 > l2.y1)
-			return 1;
-
-		if (l1.y2 < l2.y2)
-			return -1;
-		if (l1.y2 > l2.y2)
-			return 1;
-		
-		return 0;
-	}
-	
-}
\ No newline at end of file
diff --git a/src/jlm/universe/turtles/TurtleWorldView.java b/src/jlm/universe/turtles/TurtleWorldView.java
deleted file mode 100644
index 0f473bb..0000000
--- a/src/jlm/universe/turtles/TurtleWorldView.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package jlm.universe.turtles;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Rectangle2D;
-import java.util.Iterator;
-
-import javax.swing.ImageIcon;
-
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.Entity;
-import jlm.universe.World;
-
-public class TurtleWorldView extends WorldView {
-	private static final long serialVersionUID = 1674820378395646693L;
-	
-	public TurtleWorldView(World w) {
-		super(w);
-	}
-	
-	@Override
-	public void paintComponent(Graphics g) {
-		super.paintComponent(g);
-		Graphics2D g2 = (Graphics2D) g;
-		
-		TurtleWorld tw = (TurtleWorld) this.world;
-		
-		double ratio = Math.min(((double) getWidth())/tw.getWidth(), ((double)getHeight())/tw.getHeight());
-		g2.translate(Math.abs((getWidth()-ratio*tw.getWidth())/2.), Math.abs((getHeight()-ratio*tw.getHeight())/2.));
-		g2.scale(ratio, ratio);
-
-		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setColor(Color.white);
-		g2.fill(new Rectangle2D.Double(0.,0.,(double)tw.getWidth(),(double)tw.getHeight()));
-		
-		synchronized (((TurtleWorld) world).shapes) {
-			Iterator<Line> it2 = ((TurtleWorld) world).shapes();
-			while (it2.hasNext())
-				it2.next().draw(g2);			
-		}
-		for (Entity ent : world.getEntities())
-			drawTurtle(g2, (Turtle)ent);
-		
-		
-	}
-
-	private void drawTurtle(Graphics2D g, Turtle b) {
-		ImageIcon ic = ResourcesCache.getIcon("img/world_turtle.png");
-		AffineTransform t = new AffineTransform(1.0, 0, 0, 1.0, b.getX()-ic.getIconWidth()/2., b.getY()-ic.getIconHeight()/2.);
-		t.rotate(b.getHeadingRadian(), ic.getIconWidth()/2., ic.getIconHeight()/2.);
-		g.drawImage(ic.getImage(), t, null);
-	}
-}
diff --git a/src/jlm/universe/turtles/package-info.java b/src/jlm/universe/turtles/package-info.java
deleted file mode 100644
index fd95216..0000000
--- a/src/jlm/universe/turtles/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Universe inspired from the LOGO language, mainly used to experiment with recursion. 
- */
-
-package jlm.universe.turtles;
-
diff --git a/src/lessons/backtracking/BacktrackingEntity.java b/src/lessons/backtracking/BacktrackingEntity.java
index 6acb6dd..b64de98 100644
--- a/src/lessons/backtracking/BacktrackingEntity.java
+++ b/src/lessons/backtracking/BacktrackingEntity.java
@@ -1,7 +1,7 @@
 package lessons.backtracking;
 
-import jlm.universe.Entity;
-import jlm.universe.World;
+import plm.universe.Entity;
+import plm.universe.World;
 
 public class BacktrackingEntity extends Entity {
 	/** Instantiation Constructor (used by exercises to setup the world) 
diff --git a/src/lessons/backtracking/BacktrackingExercise.java b/src/lessons/backtracking/BacktrackingExercise.java
index 4de6e01..e788365 100644
--- a/src/lessons/backtracking/BacktrackingExercise.java
+++ b/src/lessons/backtracking/BacktrackingExercise.java
@@ -1,11 +1,11 @@
 package lessons.backtracking;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.ExecutionProgress;
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.core.model.lesson.NoSuchEntityException;
-import jlm.universe.World;
+import plm.core.model.Game;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.core.model.lesson.NoSuchEntityException;
+import plm.universe.World;
 
 public abstract class BacktrackingExercise extends ExerciseTemplated {
 	public BacktrackingExercise(Lesson lesson) {
diff --git a/src/lessons/backtracking/BacktrackingWorld.java b/src/lessons/backtracking/BacktrackingWorld.java
index 05d89c1..ff17caf 100644
--- a/src/lessons/backtracking/BacktrackingWorld.java
+++ b/src/lessons/backtracking/BacktrackingWorld.java
@@ -3,10 +3,10 @@ package lessons.backtracking;
 import javax.script.ScriptEngine;
 import javax.swing.ImageIcon;
 
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.World;
 
 public class BacktrackingWorld extends World {	
 	/** A copy constructor (mandatory for the internal compilation mechanism to work)
@@ -25,7 +25,7 @@ public class BacktrackingWorld extends World {
 	
 	/** Reset the state of the current world to the one passed in argument
 	 * 
-	 * This is mandatory for the JLM good working. Even if the prototype says that the passed object can be 
+	 * This is mandatory for the PLM good working. Even if the prototype says that the passed object can be 
 	 * any kind of world, you can be sure that it's of the same type than the current world. So, there is 
 	 * no need to check before casting your argument.
 	 * 
diff --git a/src/lessons/backtracking/BacktrackingWorldView.java b/src/lessons/backtracking/BacktrackingWorldView.java
index 457aa5f..b789ab3 100644
--- a/src/lessons/backtracking/BacktrackingWorldView.java
+++ b/src/lessons/backtracking/BacktrackingWorldView.java
@@ -6,8 +6,8 @@ import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.geom.Rectangle2D;
 
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
+import plm.core.ui.WorldView;
+import plm.universe.World;
 
 public class BacktrackingWorldView extends WorldView {
 	private static final long serialVersionUID = 1L;
diff --git a/src/lessons/backtracking/ExKnapsack.java b/src/lessons/backtracking/ExKnapsack.java
index b41c1ac..4d096eb 100644
--- a/src/lessons/backtracking/ExKnapsack.java
+++ b/src/lessons/backtracking/ExKnapsack.java
@@ -1,7 +1,7 @@
 package lessons.backtracking;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
 
 public class ExKnapsack extends BacktrackingExercise {
 
diff --git a/src/lessons/backtracking/KnapsackSolver.java b/src/lessons/backtracking/KnapsackSolver.java
index c9ca76d..c1cc282 100644
--- a/src/lessons/backtracking/KnapsackSolver.java
+++ b/src/lessons/backtracking/KnapsackSolver.java
@@ -1,9 +1,5 @@
 package lessons.backtracking;
 
-import lessons.backtracking.BacktrackingEntity;
-import lessons.backtracking.BacktrackingPartialSolution;
-import lessons.backtracking.KnapsackPartialSolution;
-import lessons.backtracking.KnapsackSolver;
 
 public class KnapsackSolver extends BacktrackingEntity {
 	public KnapsackSolver copy(){
diff --git a/src/lessons/backtracking/Main.fr.html b/src/lessons/backtracking/Main.fr.html
index c2e73dc..4b36e06 100644
--- a/src/lessons/backtracking/Main.fr.html
+++ b/src/lessons/backtracking/Main.fr.html
@@ -61,7 +61,7 @@ DrJava. Cela semble être une bonne idée parce qu'il dispose de plusieurs
 interfaces d'aide pour le débuggage et la compilation. Il y a aussi un bon
 éditeur que l'on pourrait réutiliser. Finallement, ils ont un infrastructure
 solide de tests avec junit assurant que leur outil fonctionne toujours après
-modifications ( c'est quelquechose qui manque sérieusement dans la JLM). Je
+modifications ( c'est quelquechose qui manque sérieusement dans la PLM). Je
 pense vraiment que les deux outils devriaent fusionner en quelquechose de
 plus fort. Le seul argument pour ne pas le faire ( en plus de la quantité de
 travail nécessaire ) est que chacun d'entre nous reçoit les honneurs pour
@@ -91,7 +91,7 @@ d'envoyer un email à martin.quinson#loria.fr.</p>
 Cela me donne lesactions à faire suivantes: * Vérifier quel tools.jar donne
 un package com.sun.jdi qui fonctionne * Trouver le bug de DrJava au niveau
 du débuggage pour les aider, et ainsi je pourrai réutiliser des parties de
-leur code à ce propos dans la JLM ( c'est un projet BSD tandis que ja JLM
+leur code à ce propos dans la PLM ( c'est un projet BSD tandis que ja PLM
 est majoritairement GPL jusqu'à présent -- il faudra que je leur demande de
 faire une exception). Cela serait mieux puisque leur interface d'aide semble
 être capable de travailler avec différents débuggers (eclipse, sun ou
@@ -99,9 +99,9 @@ openjdk ). C'est une quantité importante de travail que j'aimerai éviter
 d'avoir à dupliquer. * Trouver comment je peux obtenir les informations de
 traçage d'ASM. Cela semble être plus robuste aux variations de la JVM que
 l'approchage via débuggage. D'un autre côté, le débuggage est une
-fonctionnalité bien tenue dans la JLM.* Travailler sur la fusion entre JLM
+fonctionnalité bien tenue dans la PLM.* Travailler sur la fusion entre PLM
 et DrJava. En plus du problème de license, cela compliquera l'intégration
-actuelle de JLM dans Debian puisque DrJava est composé de [[5 modules
+actuelle de PLM dans Debian puisque DrJava est composé de [[5 modules
 séparés|http://drjava.org/docs/developer/ch02s03.html]] qui peuvent
 seulement être intégré en tant que source package distincts. Comme tout
 package java, aucune source n'est distribuée et ils doivent les récupérer
diff --git a/src/lessons/backtracking/Main.html b/src/lessons/backtracking/Main.html
index 61081f7..bad7679 100644
--- a/src/lessons/backtracking/Main.html
+++ b/src/lessons/backtracking/Main.html
@@ -57,7 +57,7 @@ looks like a good idea because they have several helper interfaces for
 debugging and compiling. Also, they have a good editor that we could
 reuse. Finally, they have a strong testing infrastructure with junit
 ensuring that their tool still work after modifications (that's
-something we are seriously missing in JLM). I'm really thinking that
+something we are seriously missing in PLM). I'm really thinking that
 the two tools should converge to something stronger. The only argument
 for not doing so (beside the amount of work it'll take) is that each
 of us get the credit for each tool where things would be more fuzzy on
@@ -84,17 +84,17 @@ hint (or patch!), please email martin.quinson#loria.fr.</p>
 This gives me the following todo actions:
 * Check whether tools.jar gives a working com.sun.jdi package
 * Find the DrJava bug around debugging to help them, and so that I can
-steal parts of their code about it for JLM (it's BSD'ed while JLM is
+steal parts of their code about it for PLM (it's BSD'ed while PLM is
 mainly GPL'ed for now -- I'll have to ask them for an exception). That
 would be better since their helper interface seem to be able to deal
 with several debuggers (eclipse, sun or openjdk). That's quite a large
 amount of work I'd like to avoid duplicating.
 * Check wheter I can get tracing info from ASM. It may be more
 robust to JVM variants than the debugging approach. On the other hand,
-debugging is a neat feature for JLM as is.
+debugging is a neat feature for PLM as is.
 
-* Work on the convergence of JLM and DrJava. Beside of the licencing
-issue, it will also complicate the ongoing integration of JLM within
+* Work on the convergence of PLM and DrJava. Beside of the licencing
+issue, it will also complicate the ongoing integration of PLM within
 Debian, since DrJava is composed of [[5 separated
 modules|http://drjava.org/docs/developer/ch02s03.html]] that can only
 be integrated as separated source packages. As every java package, no
diff --git a/src/lessons/backtracking/Main.java b/src/lessons/backtracking/Main.java
index dcbbf63..72e7356 100644
--- a/src/lessons/backtracking/Main.java
+++ b/src/lessons/backtracking/Main.java
@@ -1,6 +1,6 @@
 package lessons.backtracking;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 	@Override
diff --git a/src/lessons/bat/string1/AltPairs.fr.html b/src/lessons/bat/string1/AltPairs.fr.html
index eb4a68a..5eeb177 100644
--- a/src/lessons/bat/string1/AltPairs.fr.html
+++ b/src/lessons/bat/string1/AltPairs.fr.html
@@ -3,4 +3,4 @@ Soit une chaîne de caractères, renvoyez la chaîne composée des caractères
 aux index 0,1,4,5,8,9 ... par exemple "kittens" devient "kien".
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/AltPairs.html b/src/lessons/bat/string1/AltPairs.html
index afb4524..c8cbd81 100644
--- a/src/lessons/bat/string1/AltPairs.html
+++ b/src/lessons/bat/string1/AltPairs.html
@@ -1,4 +1,4 @@
 <h1>AltPairs</h1>
 Given a string, return a string made of the chars at indexes 0,1, 4,5, 8,9 ... so "kittens" yields "kien".
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/AltPairs.java b/src/lessons/bat/string1/AltPairs.java
index 4a2be97..19567c1 100644
--- a/src/lessons/bat/string1/AltPairs.java
+++ b/src/lessons/bat/string1/AltPairs.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class AltPairs extends BatExercise {
 	public AltPairs(Lesson lesson) {
@@ -19,20 +18,27 @@ public class AltPairs extends BatExercise {
 		myWorld.addTest(INVISIBLE, "") ;
 		myWorld.addTest(INVISIBLE, "ThisThatTheOther") ;
 
-		langTemplate(Game.PYTHON, "altPairs", 
+		templatePython("altPairs", 
 				"def altPairs(str):\n",
 				"  res = ''\n" +
 				"  for i in range(0,len(str),4):\n" +
 				"    res += str[i:i+2]\n" +
 				"  return res\n");
+		templateScala("altPairs",new String[]{"String"}, 
+				"def altPairs(str:String):String={\n",
+				"  var res = \"\"\n" +
+				"  for (i <- 0 to (str.length-1) by 4)\n" +
+				"    res ++= str.substring(i, Math.min(i+2,str.length))\n" +
+				"  return res\n"+
+				"}\n");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( altPairs((String)t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String altPairs(String str) {
diff --git a/src/lessons/bat/string1/FrontTimes.fr.html b/src/lessons/bat/string1/FrontTimes.fr.html
index 2e3ed52..25737a6 100644
--- a/src/lessons/bat/string1/FrontTimes.fr.html
+++ b/src/lessons/bat/string1/FrontTimes.fr.html
@@ -5,4 +5,4 @@ caractères, ou tout ce qu'il y a si la chaîne a une longueur de moins de 3.
 Renvoyez n copies du début de la chaîne.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/FrontTimes.html b/src/lessons/bat/string1/FrontTimes.html
index ac0a90c..7f7270e 100644
--- a/src/lessons/bat/string1/FrontTimes.html
+++ b/src/lessons/bat/string1/FrontTimes.html
@@ -4,4 +4,4 @@ string and a non-negative int n, we'll say that the front of the string
 is the first 3 chars, or whatever is there if the string is less than
 length 3. Return n copies of the front;
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/FrontTimes.java b/src/lessons/bat/string1/FrontTimes.java
index 52954b8..1a7b566 100644
--- a/src/lessons/bat/string1/FrontTimes.java
+++ b/src/lessons/bat/string1/FrontTimes.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class FrontTimes extends BatExercise {
 	public FrontTimes(Lesson lesson) {
@@ -18,7 +17,7 @@ public class FrontTimes extends BatExercise {
 		myWorld.addTest(INVISIBLE, "", 4) ;
 		myWorld.addTest(INVISIBLE, "Abc", 0) ;
 
-		langTemplate(Game.PYTHON, "frontTimes", 
+		templatePython("frontTimes", 
 				"def frontTimes(str, n):\n",
 				"  frontLen = 3\n" +
 				"  if frontLen > len(str):\n" +
@@ -30,14 +29,24 @@ public class FrontTimes extends BatExercise {
 				"  for i in range(n):" +
 				"    res += front\n" +
 				"  return res\n");
+		templateScala("frontTimes",new String[]{"String","Int"}, 
+				"def frontTimes(str:String, n:Int):String = {\n",
+				"  var frontLen = 3\n" +
+				"  if (frontLen > str.length)\n" +
+				"    frontLen = str.length\n" +
+				"  var front = \"\"\n" +
+				"  if (str.length >0)\n" +
+				"    front = str.substring(0,frontLen)\n" +
+				"  return front * n\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( frontTimes((String)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String frontTimes(String str, int n) {
diff --git a/src/lessons/bat/string1/Last2.fr.html b/src/lessons/bat/string1/Last2.fr.html
index 289d1e0..95da17b 100644
--- a/src/lessons/bat/string1/Last2.fr.html
+++ b/src/lessons/bat/string1/Last2.fr.html
@@ -7,4 +7,4 @@ compte pas la dernière sous-chaîne) tandis que "aaaNaa" renvoie 2 (les
 occurences peuvent se chevaucher partiellement).</p>
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/Last2.html b/src/lessons/bat/string1/Last2.html
index de94bd8..3c81037 100644
--- a/src/lessons/bat/string1/Last2.html
+++ b/src/lessons/bat/string1/Last2.html
@@ -5,4 +5,4 @@ appear as a substring of the string. So "hixxxhi" yields 1 (we won't
 count the end substring) while "aaaNaa" yields 2 (substrings may
 overlap).</p>
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/Last2.java b/src/lessons/bat/string1/Last2.java
index 3eeebee..78751ae 100644
--- a/src/lessons/bat/string1/Last2.java
+++ b/src/lessons/bat/string1/Last2.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class Last2 extends BatExercise {
 	public Last2(Lesson lesson) {
@@ -23,7 +22,7 @@ public class Last2 extends BatExercise {
 		myWorld.addTest(INVISIBLE, "h") ;
 		myWorld.addTest(INVISIBLE, "") ;
 
-		langTemplate(Game.PYTHON, "last2", 
+		templatePython("last2", 
 				"def last2(str):\n",
 				"  l = len(str)\n" +
 				"  if l < 2:\n" +
@@ -34,14 +33,26 @@ public class Last2 extends BatExercise {
 				"    if str[i:i+2] == end:\n" +
 				"      count += 1\n" +
 				"  return count\n");
+		templateScala("last2", new String[]{"String"},
+				"def last2(str:String):Int = {\n",
+				"  val l = str.length\n" +
+				"  if (l < 2)\n" +
+				"    return 0\n" +
+				"  val end = str.substring(l-2,l)\n" +
+				"  var count = 0\n" +
+				"  for (i <- 0 to str.length-3)\n" +
+				"    if (str.substring(i,i+2) == end)\n" +
+				"      count += 1\n" +
+				"  return count\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( last2((String)t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	int last2(String str) {
diff --git a/src/lessons/bat/string1/Main.fr.html b/src/lessons/bat/string1/Main.fr.html
index 6643be1..476ba49 100644
--- a/src/lessons/bat/string1/Main.fr.html
+++ b/src/lessons/bat/string1/Main.fr.html
@@ -6,4 +6,4 @@ la longueur de la chaîne ou une sous-chaîne...</p>
    
 <p>Une très bonne introduction à ce type est disponible ici :
 http://javabat.com/doc/string.html.</p><p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/Main.html b/src/lessons/bat/string1/Main.html
index bf3341e..68f078c 100644
--- a/src/lessons/bat/string1/Main.html
+++ b/src/lessons/bat/string1/Main.html
@@ -5,4 +5,4 @@
    substring of it..</p>
    
 <p>A very good introduction to this type is available here:
-   http://javabat.com/doc/string.html.</p><p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+   http://javabat.com/doc/string.html.</p><p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/Main.java b/src/lessons/bat/string1/Main.java
index 8034848..8a4b69c 100644
--- a/src/lessons/bat/string1/Main.java
+++ b/src/lessons/bat/string1/Main.java
@@ -1,15 +1,6 @@
 package lessons.bat.string1;
 
-import jlm.core.model.lesson.Lesson;
-import lessons.bat.string1.AltPairs;
-import lessons.bat.string1.StringBits;
-import lessons.bat.string1.FrontTimes;
-import lessons.bat.string1.Last2;
-import lessons.bat.string1.StringMatch;
-import lessons.bat.string1.StringSplosion;
-import lessons.bat.string1.StringX;
-import lessons.bat.string1.StringTimes;
-import lessons.bat.string1.StringYak;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 
diff --git a/src/lessons/bat/string1/StringBits.fr.html b/src/lessons/bat/string1/StringBits.fr.html
index 52a0764..67bfa61 100644
--- a/src/lessons/bat/string1/StringBits.fr.html
+++ b/src/lessons/bat/string1/StringBits.fr.html
@@ -6,4 +6,4 @@ premier
 caractère. Ainsi, "Bonjour" donne "Bnor".
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringBits.html b/src/lessons/bat/string1/StringBits.html
index 66886f5..179055a 100644
--- a/src/lessons/bat/string1/StringBits.html
+++ b/src/lessons/bat/string1/StringBits.html
@@ -1,4 +1,4 @@
 <h1>StringBits</h1>
 Given a string, return a new string made of every other char starting with the first, so "Hello" yields "Hlo".
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringBits.java b/src/lessons/bat/string1/StringBits.java
index d891666..db28bf8 100644
--- a/src/lessons/bat/string1/StringBits.java
+++ b/src/lessons/bat/string1/StringBits.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringBits extends BatExercise {
 	public StringBits(Lesson lesson) {
@@ -16,20 +15,27 @@ public class StringBits extends BatExercise {
 		myWorld.addTest(INVISIBLE, "") ;
 		myWorld.addTest(INVISIBLE, "Greetings") ;
 
-		langTemplate(Game.PYTHON, "stringBits", 
+		templatePython("stringBits", 
 				"def stringBits(str):\n",
 				"  res = ''\n" +
 				"  for i in range(0,len(str),2):\n" +
 				"    res += str[i:i+1]\n" +
 				"  return res\n");
+		templateScala("stringBits",new String[] {"String"}, 
+				"def stringBits(str:String):String = {\n",
+				"  var res:String = \"\"\n" +
+				"  for (i <- 0 to str.length-1 by 2)\n" +
+				"    res += str.substring(i,i+1)\n" +
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringBits((String)t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String stringBits(String str) {
diff --git a/src/lessons/bat/string1/StringMatch.fr.html b/src/lessons/bat/string1/StringMatch.fr.html
index 07f6377..4a927e9 100644
--- a/src/lessons/bat/string1/StringMatch.fr.html
+++ b/src/lessons/bat/string1/StringMatch.fr.html
@@ -6,4 +6,4 @@ Ainsi, "xxcaazz" et "xxbaaz" renvoient 3, puisque les sous-chaînes "xx",
 "aa", et "az" apparaissent dans les mêmes emplacement dans les deux chaînes.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringMatch.html b/src/lessons/bat/string1/StringMatch.html
index f875c64..1e5a69e 100644
--- a/src/lessons/bat/string1/StringMatch.html
+++ b/src/lessons/bat/string1/StringMatch.html
@@ -5,4 +5,4 @@ the same length 2 substring. So "xxcaazz" and "xxbaaz" yields 3, since
 the "xx", "aa", and "az" substrings appear in the same place in both
 strings.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringMatch.java b/src/lessons/bat/string1/StringMatch.java
index 70a2418..e6ae922 100644
--- a/src/lessons/bat/string1/StringMatch.java
+++ b/src/lessons/bat/string1/StringMatch.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringMatch extends BatExercise {
 	public StringMatch(Lesson lesson) {
@@ -21,7 +20,7 @@ public class StringMatch extends BatExercise {
 		myWorld.addTest(INVISIBLE, "aaxxaaxx", "iaxxai") ;
 		myWorld.addTest(INVISIBLE, "iaxxai", "aaxxaaxx") ;
 
-		langTemplate(Game.PYTHON, "stringMatch", 
+		templatePython("stringMatch", 
 				"def stringMatch(a, b):\n",
 				"  l = min( len(a), len(b) )\n" +
 				"  count = 0\n" +
@@ -29,14 +28,23 @@ public class StringMatch extends BatExercise {
 				"    if a[i:i+2] == b[i:i+2]:\n" +
 				"      count += 1\n" +
 				"  return count\n");
+		templateScala("stringMatch", new String[]{"String","String"},
+				"def stringMatch(a:String, b:String):Int = {\n",
+				"  val l = Math.min( a.length, b.length )\n" +
+				"  var count = 0\n" +
+				"  for (i <- 0 to l-2)\n" +
+				"    if (a.substring(i,i+2) == b.substring(i,i+2))\n" +
+				"      count += 1\n" +
+				"  return count\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringMatch((String)t.getParameter(0), (String)t.getParameter(1)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	int stringMatch(String a, String b) {
diff --git a/src/lessons/bat/string1/StringSplosion.fr.html b/src/lessons/bat/string1/StringSplosion.fr.html
index 5aeb230..ca1a116 100644
--- a/src/lessons/bat/string1/StringSplosion.fr.html
+++ b/src/lessons/bat/string1/StringSplosion.fr.html
@@ -3,4 +3,4 @@ Soit une chaîne de caractères non vide comme "Code".
 Renvoyez une chaîne de caractères comme "CCoCodCode".
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringSplosion.html b/src/lessons/bat/string1/StringSplosion.html
index 1eb8c39..116957d 100644
--- a/src/lessons/bat/string1/StringSplosion.html
+++ b/src/lessons/bat/string1/StringSplosion.html
@@ -1,4 +1,4 @@
 <h1>StringSplosion</h1>
 Given a non-empty string like "Code" return a string like "CCoCodCode".
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringSplosion.java b/src/lessons/bat/string1/StringSplosion.java
index 53db65f..dc09669 100644
--- a/src/lessons/bat/string1/StringSplosion.java
+++ b/src/lessons/bat/string1/StringSplosion.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringSplosion extends BatExercise {
 	public StringSplosion(Lesson lesson) {
@@ -18,20 +17,27 @@ public class StringSplosion extends BatExercise {
 		myWorld.addTest(INVISIBLE, "Good") ;
 		myWorld.addTest(INVISIBLE, "Bad") ;
 
-		langTemplate(Game.PYTHON, "stringSplosion", 
+		templatePython("stringSplosion", 
 				"def stringSplosion(str):\n",
 				"  res = ''\n" +
 				"  for i in range(len(str)):\n" +
 				"    res += str[0:i+1]\n" +
 				"  return res\n");
+		templateScala("stringSplosion",new String[]{"String"}, 
+				"def stringSplosion(str:String):String = {\n",
+				"  var res = \"\"\n" +
+				"  for (i <- 0 to str.length-1) \n" +
+				"    res ++= str.substring(0,i+1)\n" +
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringSplosion((String)t.getParameter(0)) ); 
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String stringSplosion(String str) {
diff --git a/src/lessons/bat/string1/StringTimes.fr.html b/src/lessons/bat/string1/StringTimes.fr.html
index 7efb09f..74400d6 100644
--- a/src/lessons/bat/string1/StringTimes.fr.html
+++ b/src/lessons/bat/string1/StringTimes.fr.html
@@ -4,4 +4,4 @@ Renvoyez une chaîne plus grande qui consiste en n copies de la chaîne
 originale.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringTimes.html b/src/lessons/bat/string1/StringTimes.html
index 18d8e11..3928d85 100644
--- a/src/lessons/bat/string1/StringTimes.html
+++ b/src/lessons/bat/string1/StringTimes.html
@@ -1,4 +1,4 @@
 <h1>StringTimes</h1>
 Given a string and a non-negative int n, return a larger string that is n copies of the original string.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringTimes.java b/src/lessons/bat/string1/StringTimes.java
index 3fff633..72ec914 100644
--- a/src/lessons/bat/string1/StringTimes.java
+++ b/src/lessons/bat/string1/StringTimes.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringTimes extends BatExercise {
 	public StringTimes(Lesson lesson) {
@@ -20,20 +19,27 @@ public class StringTimes extends BatExercise {
 		myWorld.addTest(INVISIBLE, "code", 2) ;
 		myWorld.addTest(INVISIBLE, "code", 3) ;
 
-		langTemplate(Game.PYTHON, "stringTimes", 
+		templatePython("stringTimes", 
 				"def stringTimes(str, n):\n",
 				"  res = \"\"\n"+
 				"  for i in range(n):\n"+
 				"    res += str\n"+
 				"  return res\n");
+		templateScala("stringTimes", new String[]{"String","Int"}, 
+				"def stringTimes(str:String, n:Int):String = {\n",
+				"  var res = \"\"\n"+
+				"  for (i <- 1 to n)\n"+
+				"    res ++= str\n"+
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringTimes((String)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String stringTimes(String str, int n) {
diff --git a/src/lessons/bat/string1/StringX.fr.html b/src/lessons/bat/string1/StringX.fr.html
index ef9505b..b584abe 100644
--- a/src/lessons/bat/string1/StringX.fr.html
+++ b/src/lessons/bat/string1/StringX.fr.html
@@ -4,4 +4,4 @@ supprimés.
 Seuls les "x" au tout début ou en toute fin ne doivent pas être supprimés.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringX.html b/src/lessons/bat/string1/StringX.html
index e7d0cbf..9809926 100644
--- a/src/lessons/bat/string1/StringX.html
+++ b/src/lessons/bat/string1/StringX.html
@@ -3,4 +3,4 @@ Given a
 string, return a version where all the "x" have been removed. Except an
 "x" at the very start or end should not be removed.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringX.java b/src/lessons/bat/string1/StringX.java
index 2e81d25..44580c3 100644
--- a/src/lessons/bat/string1/StringX.java
+++ b/src/lessons/bat/string1/StringX.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringX extends BatExercise {
 	public StringX(Lesson lesson) {
@@ -19,21 +18,29 @@ public class StringX extends BatExercise {
 		myWorld.addTest(INVISIBLE, "x") ;
 		myWorld.addTest(INVISIBLE, "") ;
 
-		langTemplate(Game.PYTHON, "stringX", 
+		templatePython("stringX", 
 				"def stringX(str):\n",
 				"  res = ''\n" +
 				"  for i in range(len(str)):\n" +
 				"    if str[i] != 'x' or i == 0 or i == len(str)-1:" +
 				"      res += str[i:i+1]\n" +
 				"  return res\n");
+		templateScala("stringX", new String[] {"String"},
+				"def stringX(str:String):String = {\n",
+				"  var res = \"\"\n" +
+				"  for (i <- 0 to str.length-1)\n" +
+				"    if (str(i) != 'x' || i == 0 || i == str.length-1)" +
+				"      res += str.substring(i,i+1)\n" +
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringX((String)t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String stringX(String str) {
diff --git a/src/lessons/bat/string1/StringYak.fr.html b/src/lessons/bat/string1/StringYak.fr.html
index 84a8daa..475434e 100644
--- a/src/lessons/bat/string1/StringYak.fr.html
+++ b/src/lessons/bat/string1/StringYak.fr.html
@@ -4,4 +4,4 @@ une version où tous les "yak" sont supprimées (quel que soit le caractère à
 la place du 'a'). Les différentes chaînes "yak" ne se chevauchent pas.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/bat/string1/StringYak.html b/src/lessons/bat/string1/StringYak.html
index 7dc4a7e..5fb5d72 100644
--- a/src/lessons/bat/string1/StringYak.html
+++ b/src/lessons/bat/string1/StringYak.html
@@ -4,4 +4,4 @@ string "yak" is unlucky. Given a string, return a version where all the
 "yak" are removed, but the "a" can be any char. The "yak" strings will
 not overlap.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/bat/string1/StringYak.java b/src/lessons/bat/string1/StringYak.java
index 385b58a..7a7708a 100644
--- a/src/lessons/bat/string1/StringYak.java
+++ b/src/lessons/bat/string1/StringYak.java
@@ -1,9 +1,8 @@
 package lessons.bat.string1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class StringYak extends BatExercise {
 	public StringYak(Lesson lesson) {
@@ -18,7 +17,7 @@ public class StringYak extends BatExercise {
 		myWorld.addTest(INVISIBLE, "HiyakHi") ;
 		myWorld.addTest(INVISIBLE, "xxxyakyyyakzzz") ;
 
-		langTemplate(Game.PYTHON, "stringYak", 
+		templatePython("stringYak", 
 				"def stringYak(str):\n",
 				"  res = ''\n" +
 				"  i=0\n" +
@@ -29,14 +28,27 @@ public class StringYak extends BatExercise {
 				"      res += str[i]\n" +
 				"    i+=1\n"+
 				"  return res\n");
+		templateScala("stringYak",new String[]{"String"}, 
+				"def stringYak(str:String):String = { \n",
+				"  var res = \"\"\n" +
+				"  var i=0\n" +
+				"  while (i<str.length) {\n"+
+				"    if (i+2<str.length  && str(i) == 'y' && str(i+2)=='k')\n" +
+				"      i += 2\n" +
+				"    else\n" +
+				"      res += str(i)\n" +
+				"    i+=1\n"+
+				"  }\n"+
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( stringYak((String)t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	String stringYak(String str) {
diff --git a/src/lessons/bat/string1/short_desc.fr.html b/src/lessons/bat/string1/short_desc.fr.html
index 6afc97e..6c4957e 100644
--- a/src/lessons/bat/string1/short_desc.fr.html
+++ b/src/lessons/bat/string1/short_desc.fr.html
@@ -1,7 +1,7 @@
 <h3>Petits exercices sur les chaînes</h3>
 
 <p>Il s'agit d'exercices d'entraînement au sujet des chaînes de
-caractères. Mais malheureusement, leur intégration à JLM est encore en
+caractères. Mais malheureusement, leur intégration à PLM est encore en
 cours.</p>
 
 <p>Merci de votre patience.</p>
\ No newline at end of file
diff --git a/src/lessons/bat/string1/short_desc.html b/src/lessons/bat/string1/short_desc.html
index 4f45ad0..0111fa6 100644
--- a/src/lessons/bat/string1/short_desc.html
+++ b/src/lessons/bat/string1/short_desc.html
@@ -1,6 +1,6 @@
 <h3>Small exercises about strings</h3>
 
 <p>These are some training exercises around strings. But
-unfortunately, its integration within JLM is still ongoing.</p>
+unfortunately, its integration within PLM is still ongoing.</p>
 
 <p>Please be patient with us.</p>
\ No newline at end of file
diff --git a/src/lessons/chooser/LessonChooser.fr.html b/src/lessons/chooser/LessonChooser.fr.html
index 3292cc3..8e04046 100644
--- a/src/lessons/chooser/LessonChooser.fr.html
+++ b/src/lessons/chooser/LessonChooser.fr.html
@@ -1,38 +1,37 @@
 <table border="0" align="center"><tr>
 <td valign="center"><img src="img/world_buggle.png" /></td>
-<td valign="center">  <font size="+2">Bienvenue dans la Java Learning Machine</font>  </td>
+<td valign="center">  <font size="+2">Bienvenue dans PLM, l'exerciseur du programmeur</font>  </td>
 <td valign="center"><img src="img/world_buggle.png" /></td>
 </tr></table>
 
-Vous venez de lancer la Java Learning Machine.  Il s'agit d'une plate-forme
-pédagogique destinée à simplifier l'apprentissage de la programmation
-offrant
-un grand nombre d'exercises pour vous permettre de progresser à votre
-rythme. 
+Vous venez de lancer PLM, l'exerciseur du programmeur (Programmer's Learning
+Machine). Il s'agit d'une plate-forme pédagogique destinée à simplifier
+l'apprentissage de la programmation offrant un grand nombre d'exercises pour
+vous permettre de progresser à votre rythme. 
 
 <h1>Choisissez une leçon</h1>
 <ul>
-  <li><a href="jlm://lessons.welcome">Premiers pas</a> Cette leçon est destinée à
+  <li><a href="plm://lessons.welcome">Premiers pas</a> Cette leçon est destinée à
 guider les premiers pas en programmation de débutants sans aucune
 connaissance préalable.</li>
       
-  <li><a href="jlm://lessons.maze">Labyrinthes</a> Saurez vous vous échapper du
+  <li><a href="plm://lessons.maze">Labyrinthes</a> Saurez vous vous échapper du
 labyrinthe? </li>
   
-  <li><a href="jlm://lessons.bat.string1">Chaînes</a> Quelques exercices sur les
+  <li><a href="plm://lessons.bat.string1">Chaînes</a> Quelques exercices sur les
 chaînes de caractères.</li>
   
-  <li><a href="jlm://lessons.sort">Algorithmes de tri</a> Cette leçon vous propose
+  <li><a href="plm://lessons.sort">Algorithmes de tri</a> Cette leçon vous propose
 de découvrir les algorithmes classiques de tri par la pratique. </li>
   
-  <li><a href="jlm://lessons.recursion">Récursivité</a> Construisez des figures
+  <li><a href="plm://lessons.recursion">Récursivité</a> Construisez des figures
 géométriques classiques par récursivité.</li>
 
-  <li><a href="jlm://lessons.lightbot">LightBot</a> Dans ce petit jeu, vous devez
+  <li><a href="plm://lessons.lightbot">LightBot</a> Dans ce petit jeu, vous devez
 programmer graphiquement un petit robot pour lui faire éteindre des
 lumières. C'est un petit casse-tête pour programmeurs.</li>
     
-  <li><a href="jlm://lessons.smn">Sciences Manuelles du Numérique</a> Différentes
+  <li><a href="plm://lessons.smn">Sciences Manuelles du Numérique</a> Différentes
 activitées développées pour les Sciences Manuelles du Numérique</li>
 </ul>
 
diff --git a/src/lessons/chooser/LessonChooser.fr.rtfd/TXT.rtf b/src/lessons/chooser/LessonChooser.fr.rtfd/TXT.rtf
deleted file mode 100644
index d961fdf..0000000
--- a/src/lessons/chooser/LessonChooser.fr.rtfd/TXT.rtf
+++ /dev/null
@@ -1,44 +0,0 @@
-{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510
-{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\froman\fcharset0 Times-Roman;}
-{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red109\green109\blue109;\red0\green0\blue246;
-}
-{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1}}
-{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}}
-\vieww10800\viewh8400\viewkind0
-\deftab720
-
-\itap1\trowd \taflags0 \trgaph108\trleft-108 \trbrdrt\brdrnil \trbrdrl\brdrnil \trbrdrt\brdrnil \trbrdrr\brdrnil 
-\clvertalc \clshdrawnil \clwWidth400\clftsWidth3 \clmart10 \clmarl10 \clmarb10 \clmarr10 \clbrdrt\brdrnil \clbrdrl\brdrnil \clbrdrb\brdrnil \clbrdrr\brdrnil \clpadt20 \clpadl20 \clpadb20 \clpadr20 \gaph\cellx2880
-\clvertalc \clshdrawnil \clwWidth6400\clftsWidth3 \clmart10 \clmarl10 \clmarb10 \clmarr10 \clbrdrt\brdrnil \clbrdrl\brdrnil \clbrdrb\brdrnil \clbrdrr\brdrnil \clpadt20 \clpadl20 \clpadb20 \clpadr20 \gaph\cellx5760
-\clvertalc \clshdrawnil \clwWidth400\clftsWidth3 \clmart10 \clmarl10 \clmarb10 \clmarr10 \clbrdrt\brdrnil \clbrdrl\brdrnil \clbrdrb\brdrnil \clbrdrr\brdrnil \clpadt20 \clpadl20 \clpadb20 \clpadr20 \gaph\cellx8640
-\pard\intbl\itap1\pardeftab720
-
-\f0\fs24 \cf0 \pard\intbl\itap1\pardeftab720
-
-\f1 \cf0 \cell 
-\pard\intbl\itap1\pardeftab720
-\cf0 \'a0\'a0
-\fs36 Bienvenue dans la Java Learning Machine
-\fs24 \'a0\'a0\cell 
-\pard\intbl\itap1\pardeftab720
-
-\f0 \cf0 \pard\intbl\itap1\pardeftab720
-
-\f1 \cf0 \cell \lastrow\row
-\pard\pardeftab720
-\cf0 Vous venez de lancer la Java Learning Machine. Il s'agit d'une plate-forme p\'c3\'a9dagogique destin\'c3\'a9e \'c3\'a0 simplifier l'apprentissage de la programmation offrant un grand nombre d'exercises pour vous permettre de progresser \'c3\'a0 votre rythme.
-\b\fs48 \
-\pard\pardeftab720\sa320
-\cf0 Choisissez une le\'c3\'a7on\
-\pard\tx220\tx720\pardeftab720\li720\fi-720
-\ls1\ilvl0
-\b0\fs24 \cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.welcome/"}}{\fldrslt \ul Premiers pas}}\cf0  Cette le\'c3\'a7on est destin\'c3\'a9e \'c3\'a0 guider les premiers pas en programmation de d\'c3\'a9butants sans aucune connaissance pr\'c3\'a9alable.\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.maze"}}{\fldrslt \ul Labyrinthes}}\cf0  Saurez vous vous \'c3\'a9chaper du labyrinthe?\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.bat.string1"}}{\fldrslt \ul Cha\'c3\'aenes}}\cf0  Quelques exercices sur les cha\'c3\'aenes de caract\'c3\'a8res.\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.sort"}}{\fldrslt \ul Algorithmes de tri}}\cf0  Cette le\'c3\'a7on vous propose de d\'c3\'a9couvrir les algorithmes classiques de tri par la pratique.\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.recursion"}}{\fldrslt \ul Recursivit\'c3\'a9}}\cf0  Construisez des figures g\'c3\'a9om\'c3\'a9triques classiques par r\'c3\'a9cursivit\'c3\'a9.\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.lightbot"}}{\fldrslt \ul LightBot}}\cf0  Dans ce petit jeu, vous devez programmer graphiquement un petit robot pour lui faire \'c3\'a9teindre des lumi\'c3\'a8res. C'est un petit casse-t\'c3\'aate pour programmeurs.\
-\ls1\ilvl0\cf4 {\listtext	\'95	}{\field{\*\fldinst{HYPERLINK "jlm://lessons.smn"}}{\fldrslt \ul Science Manuelles du Num\'c3\'a9rique}}\cf0  Diff\'c3\'a9rentes activit\'c3\'a9s d\'c3\'a9velopp\'c3\'a9es pour les Sciences Manuelles du Num\'c3\'a9rique\
-\pard\pardeftab720\sa240
-{\field{\*\fldinst{HYPERLINK "jlm://load_jar"}}{\fldrslt \cf4 \ul \ulc4 \'e2\'86\'92 Charger un JAR de le\'c3\'a7on}}\
-}
\ No newline at end of file
diff --git a/src/lessons/chooser/LessonChooser.html b/src/lessons/chooser/LessonChooser.html
index abe0cfa..ed86410 100644
--- a/src/lessons/chooser/LessonChooser.html
+++ b/src/lessons/chooser/LessonChooser.html
@@ -1,32 +1,32 @@
 <table border="0" align="center"><tr>
 <td valign="center"><img src="img/world_buggle.png" /></td>
-<td valign="center">  <font size="+2">Welcome to the Java Learning Machine</font>  </td>
+<td valign="center">  <font size="+2">Welcome to the Programmer's Learning Machine</font>  </td>
 <td valign="center"><img src="img/world_buggle.png" /></td>
 </tr></table>
 
-The JLM is a Learning Management System (LMS) aiming at teaching the art of computer
+The PLM is a Learning Management System (LMS) aiming at teaching the art of computer
 programming through interactive exercises. It offers an extensive set of varied 
 exercises, allowing you to practice at your own pace. 
 
 <h1>Pick a classical lesson</h1>
 <ul>
-  <li><a href="jlm://lessons.welcome">Welcome lesson</a> 
+  <li><a href="plm://lessons.welcome">Welcome lesson</a> 
       This lesson is intended to lead the first steps in programming of absolute beginners.</li>
       
-  <li><a href="jlm://lessons.maze">Escape the maze</a> Will you escape the mazes? </li>
+  <li><a href="plm://lessons.maze">Escape the maze</a> Will you escape the mazes? </li>
   
-  <li><a href="jlm://lessons.bat.string1">String lesson</a> A bunch of exercises on strings.</li>
+  <li><a href="plm://lessons.bat.string1">String lesson</a> A bunch of exercises on strings.</li>
   
-  <li><a href="jlm://lessons.sort">Sorting lesson</a> This short lesson proposes to discover 
+  <li><a href="plm://lessons.sort">Sorting lesson</a> This short lesson proposes to discover 
     the classical sorting algorithms by practice. </li>
   
-  <li><a href="jlm://lessons.recursion">Recursion lesson</a> Build some classical 
+  <li><a href="plm://lessons.recursion">Recursion lesson</a> Build some classical 
    geometric figures through recursion.</li>
 
-  <li><a href="jlm://lessons.lightbot">LightBot</a> In this little game, you must program 
+  <li><a href="plm://lessons.lightbot">LightBot</a> In this little game, you must program 
     graphically a little robot to instruct it how to switch the lights off. It is a brain teaser 
     for programmer.</li>
     
-  <li><a href="jlm://lessons.smn">Digital Manual Science</a> Some activities developed for the Sciences Manuelles du Numérique (Digital Manual Science)</li>
+  <li><a href="plm://lessons.smn">Digital Manual Science</a> Some activities developed for the Sciences Manuelles du Numérique (Digital Manual Science)</li>
 </ul>
 
diff --git a/src/lessons/chooser/LessonChooser.java b/src/lessons/chooser/LessonChooser.java
index ecfbcaa..822909a 100644
--- a/src/lessons/chooser/LessonChooser.java
+++ b/src/lessons/chooser/LessonChooser.java
@@ -1,12 +1,12 @@
 package lessons.chooser;
 
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
 
 public class LessonChooser extends Lecture {
 
 	public LessonChooser(Lesson lesson) {
-		super(lesson);
+		super(lesson,null);
 	}
 
 }
diff --git a/src/lessons/chooser/Main.java b/src/lessons/chooser/Main.java
index f1a8517..39de84e 100644
--- a/src/lessons/chooser/Main.java
+++ b/src/lessons/chooser/Main.java
@@ -1,6 +1,6 @@
 package lessons.chooser;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 
diff --git a/src/lessons/lightbot/Board01TwoSteps.java b/src/lessons/lightbot/Board01TwoSteps.java
index 81c392a..b58b4f4 100644
--- a/src/lessons/lightbot/Board01TwoSteps.java
+++ b/src/lessons/lightbot/Board01TwoSteps.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board01TwoSteps extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board02Turn.java b/src/lessons/lightbot/Board02Turn.java
index da04a26..a6d0876 100644
--- a/src/lessons/lightbot/Board02Turn.java
+++ b/src/lessons/lightbot/Board02Turn.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board02Turn extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board03Jump.java b/src/lessons/lightbot/Board03Jump.java
index 10a8b79..1dc6f4c 100644
--- a/src/lessons/lightbot/Board03Jump.java
+++ b/src/lessons/lightbot/Board03Jump.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board03Jump extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board04Stairs.java b/src/lessons/lightbot/Board04Stairs.java
index 942f75f..e7b748e 100644
--- a/src/lessons/lightbot/Board04Stairs.java
+++ b/src/lessons/lightbot/Board04Stairs.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board04Stairs extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board05Higher.java b/src/lessons/lightbot/Board05Higher.java
index f0b4dd1..0213e6f 100644
--- a/src/lessons/lightbot/Board05Higher.java
+++ b/src/lessons/lightbot/Board05Higher.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board05Higher extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board06Func.java b/src/lessons/lightbot/Board06Func.java
index 4ea3c98..e8965bb 100644
--- a/src/lessons/lightbot/Board06Func.java
+++ b/src/lessons/lightbot/Board06Func.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board06Func extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board07Repeat.java b/src/lessons/lightbot/Board07Repeat.java
index a0645dd..8773149 100644
--- a/src/lessons/lightbot/Board07Repeat.java
+++ b/src/lessons/lightbot/Board07Repeat.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board07Repeat extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board08Rec.java b/src/lessons/lightbot/Board08Rec.java
index cbd535e..c111876 100644
--- a/src/lessons/lightbot/Board08Rec.java
+++ b/src/lessons/lightbot/Board08Rec.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board08Rec extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board09Castle.java b/src/lessons/lightbot/Board09Castle.java
index dfb25ee..ad58e6c 100644
--- a/src/lessons/lightbot/Board09Castle.java
+++ b/src/lessons/lightbot/Board09Castle.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board09Castle extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board10Wall.java b/src/lessons/lightbot/Board10Wall.java
index 82d6c25..515609c 100644
--- a/src/lessons/lightbot/Board10Wall.java
+++ b/src/lessons/lightbot/Board10Wall.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board10Wall extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board11Sea.java b/src/lessons/lightbot/Board11Sea.java
index a0db919..763c32b 100644
--- a/src/lessons/lightbot/Board11Sea.java
+++ b/src/lessons/lightbot/Board11Sea.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board11Sea extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Board12Escher.java b/src/lessons/lightbot/Board12Escher.java
index 13da363..a5aecd4 100644
--- a/src/lessons/lightbot/Board12Escher.java
+++ b/src/lessons/lightbot/Board12Escher.java
@@ -1,10 +1,10 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.lightbot.LightBotEntity;
-import jlm.universe.lightbot.LightBotExercise;
-import jlm.universe.lightbot.LightBotWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.lightbot.LightBotEntity;
+import plm.universe.lightbot.LightBotExercise;
+import plm.universe.lightbot.LightBotWorld;
 
 public class Board12Escher extends LightBotExercise {
 
diff --git a/src/lessons/lightbot/Main.java b/src/lessons/lightbot/Main.java
index 20b4108..15f903a 100644
--- a/src/lessons/lightbot/Main.java
+++ b/src/lessons/lightbot/Main.java
@@ -1,6 +1,6 @@
 package lessons.lightbot;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 	@Override
diff --git a/src/lessons/maze/Main.java b/src/lessons/maze/Main.java
index d1dd475..758fdce 100644
--- a/src/lessons/maze/Main.java
+++ b/src/lessons/maze/Main.java
@@ -2,8 +2,8 @@ package lessons.maze;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
 import lessons.maze.island.IslandMaze;
 import lessons.maze.pledge.PledgeMaze;
 import lessons.maze.randommouse.RandomMouseMaze;
diff --git a/src/lessons/maze/island/IslandMaze.fr.html b/src/lessons/maze/island/IslandMaze.fr.html
index 00f118d..1d6680b 100644
--- a/src/lessons/maze/island/IslandMaze.fr.html
+++ b/src/lessons/maze/island/IslandMaze.fr.html
@@ -6,19 +6,19 @@ labyrinthes ? Et bien, pas tous les labyrinthes...
 
 <p>L'algorithme de suivi de mur que nous avons utilisé jusqu'à présent
 fonctionne seulement si l'entrée et la sortie sont placées à côté de murs
-connectés à un mur externe. Mais si le buggle commence au milieu du
+connectés à un mur externe. Mais si la buggle commence au milieu du
 labyrinthe, il peut exister des pans de mur déconnectés du mur externe.
 
 <p>Dans cette situation, notre précédente stratégie ferait notre buggle tourner
 en rond pour toujours sur l'un de ces îlots. En effet, le labyrinthe dont
-vous devez vous échapper maintenant contient des îles, et le buggle ne
+vous devez vous échapper maintenant contient des îles, et la buggle ne
 commence pas sur un des murs externes. Vous pouvez essayer si vous voulez :
-Copie/collez votre code et appuyez sur le bouton 'run' pour admirez votre
-solution précédente échouer lamentablement.</p>
+Copie/collez votre code et appuyez sur le bouton 'Exécuter' pour admirez
+votre solution précédente échouer lamentablement.</p>
 
 <p>Cette méthode de suivre un mur est toujours efficace est permet d'échapper
 de manière assez efficace à certaines parties du labyrinthe, on ne va donc
-pas la supprimer entièrement. A la place, nous allons cesser de suivre le
+pas la supprimer entièrement. À la place, nous allons cesser de suivre le
 mur sous certaines conditions. Notez que le baggle repose près d'un mur
 externe du labyrinthe. Donc nous voulons atteindre un mur externe et ensuite
 le suivre. Nous avons par exemple de rechercher le mur nord avant de le
@@ -26,41 +26,46 @@ suivre jusqu'au baggle.
 
 <p>Pour trouver le mur nord, vous avez tout simplement à foncez vers le nord
 tant que c'est possible, et quand vous faites face à un obstacle, vous
-l'évitez ( en utilisant la méthode précédente ).</p>
+l'évitez (en utilisant la méthode précédente).</p>
 
 <div class="tip" id="tip-1" alt="Je suis perdu, je voudrais plus d'indications">
 	Notre nouvelle méthode run() va consister en deux états: notre buggle va
-alterner entre le mode "north runner" et le mode "left follower".
-Vous commencerz dans le mode "north runner", et vous passerez au mode "left
-follower" quand il y aura un mur au nord ( n'oubliez pas de vous assurez
-d'avoir un mur à votre gauche avant de changer de passer au mode "left
-follower").
-Vous repasserez au mode "north runner" dès que votre buggle fera face au
-nord et qu'elle n'est pas face à un mur.
-La manière la plus simple d'écrire une telle machine à état est quelque
-chose du type 
-<pre>
-	<code div="Java">int etat=0;
+alterner entre le mode «coureur au nord» et le mode «suiveur à gauche». Vous
+commencerz dans le mode «coureur au nord», et vous passerez au mode «suiveur
+à gauche» quand il y aura un mur au nord (n'oubliez pas de vous assurez
+d'avoir un mur à votre gauche avant de changer de passer au mode «suiveur à
+gauche»). Vous repasserez au mode «coureur au nord» dès que votre buggle
+fera face au nord et qu'elle n'est pas face à un mur. La manière la plus
+simple d'écrire une telle machine à état est quelque chose de ce type: 
+<pre>[!scala]var etat=0;
+etat match  {
+  case 0 => // courir au nord
+     ...
+     etat = 1;
+  case 1 => // suivre à gauche
+     ...
+     etat = 0;
+  case _ => println("Ce cas ne devrait pas arriver. Corrigez ce problème svp.")
+}[/!][!java]int etat=0;
 switch (etat) {
   case 0: // courir au nord
      ...
      etat = 1;
      break;
-  case 1: // suivre a gauche
+  case 1: // suivre à gauche
      ...
      etat = 0;
      break;
-}
-</code>
-<code div="python">courirNord = True
-if courirNord:
+}[/!][!python]coureurNord = True
+if coureurNord:
      ...
-     courirNord = False
-else: # suivre a gauche
+     coureurNord = False
+else: # suiveur à gauche
      ...
-     courirNord = True
-</code>
-</pre>
+     coureurNord = True[/!]</pre>
+     
+[!scala]<br/>N'oubliez pas le cas par défaut (qui accepte _), ou scala vous donnera un
+message d'erreur en échange de votre filtrage incomplet.
 </div>
 	
 <p>N'oubliez pas de faire ramasser le baggle par votre buggle à la fin de votre
diff --git a/src/lessons/maze/island/IslandMaze.html b/src/lessons/maze/island/IslandMaze.html
index c4dcdd3..63f2e30 100644
--- a/src/lessons/maze/island/IslandMaze.html
+++ b/src/lessons/maze/island/IslandMaze.html
@@ -1,68 +1,74 @@
-<h2>Lost between islands</h2>
-
-<p>You thought that your algorithm was enough to escape mazes? Well,
-not every mazes...
-</p>
-
-<p>The <i>wall follower algorithm</i> we used so far only works if the entry and the exit
-are placed near to walls connected to the external wall. But if the
-buggle begins in the middle of the maze, it may exist wall sections
-disconnected from the external wall.
-
-<p>That is why the previous strategy would let the buggle round around for
-ever. Indeed, the maze you should now escape from contains islands,
-and the buggle does not start along one of the external walls. Just
-give it a try if you want: copy your code over, push the run button
-and see your previous solution failing miserabily.</p>
-
-<p>The method of following a wall is still good and allow to escape
-very efficiently some sections of the maze, so we do not want to
-remove it entierely. Instead, we want to stop following the wall under
-some conditions. Notice that the baggle lays near to the external
-border of the maze. So, we want to reach the border and then follow
-that wall. We need for example to search for the north wall before
-following it to the baggle.
-
-<p>To find the north wall, you simply run to the north as long as it's
-possible, and when facing an obstacle, you avoid it (using previous
-method).</p>
-
-<div class="tip" id="tip-1" alt="I'm lost now, please give me some extra indications">
-	Our new run() method will consist in two modes: our
-buggle will alternate between the "north runner mode" and the "left
-follower mode". You begin in "north runner mode", and switch to "left
-follower" when you have a wall at the north (do not forget to make
-sure you have a wall at your left before switching to "left follower"
-mode). You switch to "north runner" as soon as your buggle is facing
-north and is not in front of a wall during its trip around its left
-wall. The easiest way to write such a state machine is something like 
-<pre>
-	<code div="Java">int state=0;
-switch (state) {
-  case 0: // North runner
-     ...
-     state = 1;
-     break;
-  case 1: // Left follower
-     ...
-     state = 0;
-     break;
-}
-</code>
-<code div="python">northRunner = True
-if northRunner:
-     ...
-     northRunner = False
-else: # left follower
-     ...
-     northRunner = True
-</code>
-</pre>
-</div>
-	
-<p>Don't forget to let the buggle pick the baggle at the end of your code.</p>
-	
-	
-<p>You're up. That should be enough for you to figure out how to escape this
-maze, but if not, you can always request for the tip. But you do not
-need any more help, do you?</p>
+<h2>Lost between islands</h2>
+
+<p>You thought that your algorithm was enough to escape mazes? Well,
+not every mazes...
+</p>
+
+<p>The <i>wall follower algorithm</i> we used so far only works if the entry and the exit
+are placed near to walls connected to the external wall. But if the
+buggle begins in the middle of the maze, it may exist wall sections
+disconnected from the external wall.
+
+<p>That is why the previous strategy would let the buggle round around for
+ever. Indeed, the maze you should now escape from contains islands,
+and the buggle does not start along one of the external walls. Just
+give it a try if you want: copy your code over, push the run button
+and see your previous solution failing miserabily.</p>
+
+<p>The method of following a wall is still good and allow to escape
+very efficiently some sections of the maze, so we do not want to
+remove it entierely. Instead, we want to stop following the wall under
+some conditions. Notice that the baggle lays near to the external
+border of the maze. So, we want to reach the border and then follow
+that wall. We need for example to search for the north wall before
+following it to the baggle.
+
+<p>To find the north wall, you simply run to the north as long as it's
+possible, and when facing an obstacle, you avoid it (using previous
+method).</p>
+
+<div class="tip" id="tip-1" alt="I'm lost now, please give me some extra indications">
+	Our new run() method will consist in two modes: our
+buggle will alternate between the "north runner mode" and the "left
+follower mode". You begin in "north runner mode", and switch to "left
+follower" when you have a wall at the north (do not forget to make
+sure you have a wall at your left before switching to "left follower"
+mode). You switch to "north runner" as soon as your buggle is facing
+north and is not in front of a wall during its trip around its left
+wall. The easiest way to write such a state machine is something like 
+<pre>[!scala]var state=0;
+state match  {
+  case 0 => // North runner
+     ...
+     state = 1;
+  case 1 => // Left follower
+     ...
+     state = 0;
+  case _ => println("This case should not happen. Please fix me")
+}[/!][!java]int state=0;
+switch (state) {
+  case 0: // North runner
+     ...
+     state = 1;
+     break;
+  case 1: // Left follower
+     ...
+     state = 0;
+     break;
+}[/!][!python]northRunner = True
+if northRunner:
+     ...
+     northRunner = False
+else: # left follower
+     ...
+     northRunner = True[/!]</pre>
+     
+[!scala]<br/>Don't forget the default case (matching _), or scala will issue an error since your matching would be incomplete.[/!]
+</div>
+	
+<p>Don't forget to let the buggle pick the baggle at the end of your code.</p>
+	
+	
+<p>You're up. That should be enough for you to figure out how to escape this
+maze, but if not, you can always request for the tip. But you do not
+need any more help, do you?</p>
diff --git a/src/lessons/maze/island/IslandMaze.java b/src/lessons/maze/island/IslandMaze.java
index c6ea1c0..5b64e24 100644
--- a/src/lessons/maze/island/IslandMaze.java
+++ b/src/lessons/maze/island/IslandMaze.java
@@ -2,11 +2,11 @@ package lessons.maze.island;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class IslandMaze extends ExerciseTemplated {
 
diff --git a/src/lessons/maze/island/IslandMazeEntity.java b/src/lessons/maze/island/IslandMazeEntity.java
index 328fb8f..4a1389c 100644
--- a/src/lessons/maze/island/IslandMazeEntity.java
+++ b/src/lessons/maze/island/IslandMazeEntity.java
@@ -1,24 +1,25 @@
 package lessons.maze.island;
 
-import jlm.universe.Direction;
+import plm.core.model.Game;
+import plm.universe.Direction;
 
-public class IslandMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class IslandMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void setX(int i)  {
 		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
-
+	
 	/* BEGIN TEMPLATE */
 	/* BEGIN SOLUTION */
 	public void run() {
@@ -31,7 +32,7 @@ public class IslandMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
 				while ( !isFacingWall() )
 					forward();
 				
-				this.turnRight(); // make sure that we have a left wall
+				this.right(); // make sure that we have a left wall
 				state = 1; // time to enter the Left Follower mode
 				break;
 			case 1: // Left Follower Mode
@@ -48,9 +49,9 @@ public class IslandMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
 		while ( ! isFacingWall() )
 		{
 			forward();
-			turnLeft();
+			left();
 		}
-		turnRight();
+		right();
 	}
 
 	Direction chosenDirection = Direction.NORTH;
diff --git a/src/lessons/maze/island/IslandMazeEntity.py b/src/lessons/maze/island/IslandMazeEntity.py
index 0b3ab02..73b5368 100644
--- a/src/lessons/maze/island/IslandMazeEntity.py
+++ b/src/lessons/maze/island/IslandMazeEntity.py
@@ -19,8 +19,8 @@ def stepHandOnWall():
     # POST: we still have the same wall on the left, are one step ahead
     while not isFacingWall():
         forward()
-        turnLeft() # change to turnRight to get a right follower
-    turnRight() # change to turnLeft to get a right follower
+        left() # change to right to get a right follower
+    right() # change to left to get a right follower
 
 northRunner = True
 chosenDir = Direction.NORTH
@@ -30,7 +30,7 @@ while not isOverBaggle():
     if northRunner:
         while not isFacingWall():
             forward()
-        turnRight()
+        right()
         northRunner = False
     else: # left follower mode
         stepHandOnWall()
diff --git a/src/lessons/maze/island/IslandMazeEntity.scala b/src/lessons/maze/island/IslandMazeEntity.scala
new file mode 100644
index 0000000..d009f31
--- /dev/null
+++ b/src/lessons/maze/island/IslandMazeEntity.scala
@@ -0,0 +1,66 @@
+package lessons.maze.island;
+
+import plm.universe.Direction;
+import plm.core.model.Game
+
+class ScalaIslandMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */
+	def run() {
+	/* BEGIN SOLUTION */
+		var state = 0 ;
+		setDirection(chosenDirection);
+		while ( !isOverBaggle() ) { 
+		  state match {
+			case 0 => // North runner mode
+				while ( !isFacingWall() )
+					forward();
+				
+				right(); // make sure that we have a left wall
+				state = 1; // time to enter the Left Follower mode
+			case 1 => // Left Follower Mode
+				stepHandOnWall(); // follow the left wall
+				if ( isChosenDirectionFree() && (getDirection() == chosenDirection)  ) 
+					state =0; // time to enter in North Runner mode
+			case _ =>
+			}
+		}
+		pickupBaggle();
+	}
+
+	def stepHandOnWall(){
+		while ( ! isFacingWall() )
+		{
+			forward();
+			left();
+		}
+		right();
+	}
+
+	var chosenDirection = Direction.NORTH;
+
+	def isChosenDirectionFree():Boolean = {
+		var memorizedD = getDirection();
+		setDirection(chosenDirection);
+		var isFree = ! isFacingWall();
+		setDirection(memorizedD);
+		return isFree;
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+
+}
+
+
diff --git a/src/lessons/maze/pledge/PledgeMaze.fr.html b/src/lessons/maze/pledge/PledgeMaze.fr.html
index 7debc36..3391411 100644
--- a/src/lessons/maze/pledge/PledgeMaze.fr.html
+++ b/src/lessons/maze/pledge/PledgeMaze.fr.html
@@ -2,25 +2,24 @@
 
 <p>Une fois de plus, vous pensiez que votre algorithme vous permettait de vous
 échapper des labyrinthes, et une fois de plus, votre buggle est prise dans
-un
-labyrinthe mettant votre algorithme en défaut. Vous essayer de copier votre
-code
-et de l'exécuter pour voir votre création échouer. Le piège a la forme d'un
-«G» majuscule : la buggle entre dans le piège, suit le bord interne. Au bout
-d'un moment, la direction nord est libre et votre buggle se met donc à
-courir dans cette direction. Pour retomber dans le piège...
+un labyrinthe mettant votre algorithme en défaut. Essayez de copier votre
+code et de l'exécuter pour voir : votre création précédente échoue
+lamentablement. Le piège a la forme d'un «G» majuscule : la buggle entre
+dans le piège, suit le bord interne. Au bout d'un moment, la direction nord
+est libre et votre buggle se met donc à courir dans cette direction. Pour
+retomber dans le piège...
 </p>
 
-<p>L'algorithme de Pledge (nommé d'après Jon Pledge d'Exeter) peut résoudre ce
+<p>L'algorithme de Pledge (nommé d'après Jon Pledge d'Exeter) peut sortir de ce
 labyrinthe.</p> 
 
 <p>Cet algorithme est une version modifiée l'algorithme précédent conçu pour
 éviter les obstacles. Il nécessite de choisir de manière arbitraire une
-direction vers laquelle le buggle se dirigera. Quand un obstacle est
+direction vers laquelle la buggle se dirigera. Quand un obstacle est
 rencontré, une patte (disons la patte de gauche) est gardée le long des
-obstacles tandis que les virages sont comptabilisés. Quand le buggle est
+obstacles tandis que les virages sont comptabilisés. Quand la buggle est
 face à nouveau à la direction originale, et que la somme des virages est
-égale à 0, le buggle quitte l'obstacle et continue de se déplacer dans sa
+égale à 0, la buggle quitte l'obstacle et continue de se déplacer dans sa
 direction d'origine. </p>
 
 <p>Notez que l'utilisation de la "somme des virages" à la place de la
@@ -64,11 +63,9 @@ restaurer l'état après coup.</p>
 ces changements devraient rester limités.</p>
 
 <p class="python">N'oubliez pas que si l'une de vos méthodes modifie une variable globale
-(telle
-que sommeAngles), vous devez vous assurer qu'elle définie cette globale
-correctement. Sinon, la méthode crée une nouvelle variable locale de même
-nom,
-et la globale n'est jamais modifiée.</p>
+(telle que sommeAngles), vous devez vous assurer qu'elle définie cette
+globale correctement. Sinon, la méthode crée une nouvelle variable locale de
+même nom, et la globale n'est jamais modifiée.</p>
 <div class="python"><pre>def myMethod():
   global sommeAngle
   ...
@@ -77,8 +74,7 @@ et la globale n'est jamais modifiée.</p>
 
 <div class="tip" id="tip-1" alt="Montrer un indice supplémentaire">
 Vous devez changer votre cap vers votre direction favorite (probablement le
-nord
--- NORTH). Il vous faut ensuite écrire la boucle principale de votre
+nord -- NORTH). Il vous faut ensuite écrire la boucle principale de votre
 algorithme. Tant que votre buggle n'a pas trouvé son biscuit, il faut
 avancer jusqu'à un obstacle dans la direction de prédilection. Quand un
 obstacle est rencontré, il faut garder la patte sur un mur (en utilisant
diff --git a/src/lessons/maze/pledge/PledgeMaze.java b/src/lessons/maze/pledge/PledgeMaze.java
index c9d42d4..ad15689 100644
--- a/src/lessons/maze/pledge/PledgeMaze.java
+++ b/src/lessons/maze/pledge/PledgeMaze.java
@@ -2,11 +2,11 @@ package lessons.maze.pledge;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class PledgeMaze extends ExerciseTemplated {
 
diff --git a/src/lessons/maze/pledge/PledgeMazeEntity.java b/src/lessons/maze/pledge/PledgeMazeEntity.java
index 7105617..c0db0ad 100644
--- a/src/lessons/maze/pledge/PledgeMazeEntity.java
+++ b/src/lessons/maze/pledge/PledgeMazeEntity.java
@@ -1,25 +1,23 @@
 package lessons.maze.pledge;
 
-import jlm.universe.Direction;
+import plm.core.model.Game;
+import plm.universe.Direction;
 
-public class PledgeMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class PledgeMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void setX(int i)  {
 		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
-		super.setX(i);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
-		super.setY(i);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
-		super.setPos(i,j);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
 
 	/* BEGIN TEMPLATE */
@@ -36,7 +34,7 @@ public class PledgeMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
 				while ( !isFacingWall() )
 					forward();
 				
-				turnRight(); // make sure that we have a left wall
+				right(); // make sure that we have a left wall
 				angleSum--;
 				state = 1; // time to enter the Left Follower mode
 				break;
@@ -57,10 +55,10 @@ public class PledgeMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
 		while ( ! isFacingWall() )
 		{
 			forward();
-			turnLeft();
+			left();
 			this.angleSum++;
 		}
-		turnRight();
+		right();
 		this.angleSum--;
 	}
 
diff --git a/src/lessons/maze/pledge/PledgeMazeEntity.py b/src/lessons/maze/pledge/PledgeMazeEntity.py
index d2fcda9..53fd0f7 100644
--- a/src/lessons/maze/pledge/PledgeMazeEntity.py
+++ b/src/lessons/maze/pledge/PledgeMazeEntity.py
@@ -11,9 +11,9 @@ def stepHandOnWall():
     global angleSum
     while not isFacingWall():
         forward()
-        turnLeft()
+        left()
         angleSum += 1
-    turnRight()
+    right()
     angleSum -= 1
 
 def isDirectionFree(dir):
@@ -32,7 +32,7 @@ while not isOverBaggle():
     if northRunner:
         while not isFacingWall():
             forward()
-        turnRight()
+        right()
         angleSum -= 1
         northRunner = False
     else :
diff --git a/src/lessons/maze/pledge/PledgeMazeEntity.scala b/src/lessons/maze/pledge/PledgeMazeEntity.scala
new file mode 100644
index 0000000..c60b752
--- /dev/null
+++ b/src/lessons/maze/pledge/PledgeMazeEntity.scala
@@ -0,0 +1,68 @@
+package lessons.maze.pledge;
+
+import plm.universe.Direction;
+import plm.core.model.Game
+
+class ScalaPledgeMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */
+	def run() {
+	/* BEGIN SOLUTION */
+		var state = 0 ;
+		this.angleSum = 0;
+		this.setDirection(this.chosenDirection);
+		while ( !isOverBaggle() ) {
+			state match {
+			case 0 => // North runner mode
+				while ( !isFacingWall() )
+					forward();
+				
+				right(); // make sure that we have a left wall
+				angleSum -=1;
+				state = 1; // time to enter the Left Follower mode
+			case 1 => // Left Follower Mode
+				stepHandOnWall(); // follow the left wall
+				if ( isChosenDirectionFree() && angleSum == 0  ) 
+					state =0; // time to enter in North Runner mode
+			case _ =>
+			}
+		}
+		pickupBaggle();
+	}
+
+	var angleSum= 0;
+
+	def stepHandOnWall(){
+		while ( ! isFacingWall() ) {
+			forward();
+			left();
+			angleSum += 1;
+		}
+		right();
+		angleSum -= 1;
+	}
+
+	val chosenDirection = Direction.NORTH;
+
+	def isChosenDirectionFree(): Boolean = {
+		val memorizedD = getDirection();
+		setDirection(chosenDirection);
+		val isFree = !isFacingWall();
+		setDirection(memorizedD);
+		return isFree;
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/maze/randommouse/RandomMouseMaze.fr.html b/src/lessons/maze/randommouse/RandomMouseMaze.fr.html
index 5123321..6a8e72d 100644
--- a/src/lessons/maze/randommouse/RandomMouseMaze.fr.html
+++ b/src/lessons/maze/randommouse/RandomMouseMaze.fr.html
@@ -1,7 +1,7 @@
 <h2>La souris folle</h2>
 
-<p>La journée de votre buggle commence mal. Il n'a pas eu de chance. Il est
-tombé dans un piège.  Aidez le à sortir de ce labyrinthe. 
+<p>La journée de votre buggle commence mal. Elle n'a pas eu de chance. Elle est
+tombée dans un piège.  Aidez-la à sortir de ce labyrinthe. 
 </p>
 
 <p>
@@ -16,20 +16,14 @@ hasard et est très inefficace.
 </p>
 
 <p>
-Tant que notre buggle n'a pas trouvé la sortie, il doit progresser de la
+Tant que notre buggle n'a pas trouvé la sortie, elle doit progresser de la
 façon suivante : choisir un entier entre 0 et 2 au hasard à l'aide de
 la méthode <code>random3()</code> fournie et prendre l'une des décisions
-suivantes selon l'entier choisi : avancer si il le peut, tourner à
+suivantes selon l'entier choisi : avancer si elle le peut, tourner à
 droite ou bien tourner à gauche. 
 </p>
 
-<h3>Objectif de cet exercice</h3><a name="Objectifs">
-
-<p>
-L'objectif de cet exercice est d'écrire un algorithme permettant à votre
-buggle de sortir du labyrinthe. 
-</p>
-
-<p>
-N'oubliez pas de ramasser le baggle quand vous l'avez trouvé.
+<p>Vous ne croyez pas qu'une méthode aussi stupide puisse fonctionner ? Et
+bien, essayez, vous verrez bien.
+N'oubliez pas de ramasser le biscuit quand vous l'avez trouvé.
 </p>
diff --git a/src/lessons/maze/randommouse/RandomMouseMaze.html b/src/lessons/maze/randommouse/RandomMouseMaze.html
index 2926429..28a6987 100644
--- a/src/lessons/maze/randommouse/RandomMouseMaze.html
+++ b/src/lessons/maze/randommouse/RandomMouseMaze.html
@@ -1,33 +1,27 @@
-<h2>The crazy mouse</h2>
-
-<p>The day of your buggle starts badly. Out of luck, it got trapped into a
-maze. Help it finding its path out of there. 
-</p>
-
-<p>
-The exit is represented by a baggle and you need to 
-pick this baggle in order to exit the maze.
-</p>
-
-<p>
-Since the maze is so small, we can write the dumbest possible algorithm to
-do so. It relies on randomness and proves quite inefficient.
-</p>
-
-<p>
-While the buggle didn't find the path to the escape, it must proceed the
-following way: pick a random integer between 0 and 2 by using the
-provided <code>random3()</code> method 
-and make one of the following actions: moving forward if possible, turn left or turn right. 
-</p>
-
-<h3>Exercise goal</h3><a name="Objectives">
-
-<p>
-This exercise's objective is to write an algorithm
-allowing the buggle to find its path out of the maze. 
-</p>
-
-<p>
-Don't forget to pick up the baggle once you've reached it.
-</p>
+<h2>The crazy mouse</h2>
+
+<p>The day of your buggle starts badly. Out of luck, it got trapped into a
+maze. Help it finding its path out of there. 
+</p>
+
+<p>
+The exit is represented by a baggle and you need to 
+pick this baggle in order to exit the maze.
+</p>
+
+<p>
+Since the maze is so small, we can write the dumbest possible algorithm to
+do so. It relies on randomness and proves quite inefficient.
+</p>
+
+<p>
+While the buggle didn't find the path to the escape, it must proceed the
+following way: pick a random integer between 0 and 2 by using the
+provided <code>random3()</code> method 
+and make one of the following actions: moving forward if possible, turn left or turn right. 
+</p>
+
+<p>You don't believe that it could work? 
+Well, give it a try, you will see...
+Don't forget to pick up the baggle once you've reached it.
+</p>
diff --git a/src/lessons/maze/randommouse/RandomMouseMaze.java b/src/lessons/maze/randommouse/RandomMouseMaze.java
index 4dcfa92..bdee26a 100644
--- a/src/lessons/maze/randommouse/RandomMouseMaze.java
+++ b/src/lessons/maze/randommouse/RandomMouseMaze.java
@@ -2,11 +2,11 @@ package lessons.maze.randommouse;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class RandomMouseMaze extends ExerciseTemplated {
 
diff --git a/src/lessons/maze/randommouse/RandomMouseMazeEntity.java b/src/lessons/maze/randommouse/RandomMouseMazeEntity.java
index 102a67b..fbc6df6 100644
--- a/src/lessons/maze/randommouse/RandomMouseMazeEntity.java
+++ b/src/lessons/maze/randommouse/RandomMouseMazeEntity.java
@@ -1,20 +1,22 @@
 package lessons.maze.randommouse;
 
-public class RandomMouseMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
+import plm.core.model.Game;
+
+public class RandomMouseMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void setX(int i)  {
 		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
 
 	/* BEGIN TEMPLATE */ 
@@ -32,10 +34,10 @@ public class RandomMouseMazeEntity extends jlm.universe.bugglequest.SimpleBuggle
 				}
 				break;
 			case 1:
-				turnLeft();
+				left();
 				break;
 			case 2:
-				turnRight();
+				right();
 				break;
 			}
 		}
diff --git a/src/lessons/maze/randommouse/RandomMouseMazeEntity.py b/src/lessons/maze/randommouse/RandomMouseMazeEntity.py
index 3c4b98a..290574b 100644
--- a/src/lessons/maze/randommouse/RandomMouseMazeEntity.py
+++ b/src/lessons/maze/randommouse/RandomMouseMazeEntity.py
@@ -23,8 +23,8 @@ while not isOverBaggle():
         if not isFacingWall():
             forward()
     elif n == 1:
-        turnLeft()
+        left()
     else:
-        turnRight()
+        right()
 pickupBaggle()
 # END SOLUTION
diff --git a/src/lessons/maze/randommouse/RandomMouseMazeEntity.scala b/src/lessons/maze/randommouse/RandomMouseMazeEntity.scala
new file mode 100644
index 0000000..ec757d8
--- /dev/null
+++ b/src/lessons/maze/randommouse/RandomMouseMazeEntity.scala
@@ -0,0 +1,43 @@
+package lessons.maze.randommouse;
+
+import plm.core.model.Game;
+
+class ScalaRandomMouseMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */ 
+	def run() {
+		// Your code here 
+		/* BEGIN SOLUTION */ 
+		while (!isOverBaggle()) {
+			random3() match { 
+			     case 0 if (!isFacingWall()) => forward();
+			     case 1                      => left();
+			     case 2                      => right();
+			     case _ =>
+			}
+		}
+		pickupBaggle();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	def random3():Int = {
+		Math.random() match {
+		  case n if (n<0.33) => return 0;
+		  case n if (n<0.66) => return 1;
+		  case _             => return 2;
+		}
+	}
+}
diff --git a/src/lessons/maze/shortestpath/ShortestPathMaze.fr.html b/src/lessons/maze/shortestpath/ShortestPathMaze.fr.html
index 4e2afb2..2eb0783 100644
--- a/src/lessons/maze/shortestpath/ShortestPathMaze.fr.html
+++ b/src/lessons/maze/shortestpath/ShortestPathMaze.fr.html
@@ -1,37 +1,33 @@
 <h2>Algorithme basique de recherche du plus court chemin</h2>
 
 <p>Pour conclure avec cette leçon d'introduction aux algorithmes de sortie de
-labyrinthe, nous allons étudier un autre moyen de trouver la sortie. Le
+labyrinthe, nous allons étudier un autre moyen de trouver la sortie. La
 buggle de cette leçon est spécial : c'est un jedi. Il peut ressentir la
-Force. Cela signifie qu'il peut ressentir son environnement.</p>
+Force. Cela signifie qu'elle peut ressentir son environnement.</p>
 
-<p>Sans même changer de place, il peut retrouver des informations sur le monde
-qui l'entoure, avec les instructions suivantes :</p>
+<p>Sans même changer de place, elle peut retrouver des informations sur le
+monde qui l'entoure, avec les instructions suivantes :</p>
 <ul>
-  <li><code>getWorldWidth()</code> pour connaitre la largeur du monde</li>
-  <li><code>getWorldHeight()</code> pour connaitre la hauteur du monde.</li>
-  <li><code>hasTopWall(x,y)</code> indique si la cellule (x,y) de ce monde est
-fermée
-par un mur en haut.</li>
-  <li><code>hasLeftWall(x,y)</code> indique si la cellule (x,y) de ce monde est
-fermée
-par un mur à gauche.</li>
-  <li><code>hasBaggle(x,y)</code> indique si un baggle se trouve dans la cellule
+  <li><code>getMondeLargueur()</code> pour connaitre la largeur du monde</li>
+  <li><code>getMondeHauteur()</code> pour connaitre la hauteur du monde.</li>
+  <li><code>aMurNord(x,y)</code> indique si la cellule (x,y) de ce monde est
+fermée par un mur en haut.</li>
+  <li><code>aMurOuest(x,y)</code> indique si la cellule (x,y) de ce monde est
+fermée par un mur à gauche.</li>
+  <li><code>aBiscuit(x,y)</code> indique si un baggle se trouve dans la cellule
 (x,y) de ce monde.</li>
   <li><code>setIndication(x,y,i)</code> ajoute une indication entière
-<code>i</code>
-sur le sol de la cellule (x,y).</li>  
+<code>i</code> sur le sol de la cellule (x,y).</li>  
   <li><code>getIndication(x,y,i)</code> retourne l'indication entière qui se
-trouve
-dans la cellule (x,y) (ou bien la valeur 9999 s'il n'y a pas d'indication à
-l'endroit indiqué).</li>  
+trouve dans la cellule (x,y) (ou bien la valeur 9999 s'il n'y a pas
+d'indication à l'endroit indiqué).</li>  
 </ul>
 
 <p>Il est bon de noter qu'il n'est pas possible de construire un mur sur la
-côté inférieur ou droit d'une case.Néanmoins, quand de tels murs existents,
+côté inférieur ou droit d'une case. Néanmoins, quand de tels murs existent,
 cela signifie qu'il a été construit sur une case voisine -- comme mur
-supérieur ( respectivement gauche ) sur la case qui est située en dessous (
-respectivement sur la droite ) de la case courante.</p>
+supérieur (respectivement gauche) sur la case qui est située en dessous
+(respectivement sur à droite) de la case courante.</p>
 
 <h3>Objectif de cet exercice</h3>
 
@@ -44,17 +40,14 @@ atteindre une case marquée 1, puis faites de même pour toutes les cases
 jusqu'à numéroter la case où se trouve votre buggle.</p>
 
 <p>Une fois que toutes les cases sont marquées, faites en sorte que votre
-buggle
-jedi trouve le plus court chemin en suivant les indications écrites au
-sol. Pour
-celà, il lui suffit à chaque pas d'aller sur la case de plus petite distance
-parmis celles accessibles. Vous pouvez utiliser la méthode <code>void
-setDirection(Direction d)</code> pour faire regarder votre buggle dans une
-direction spécifique comme <code>Direction.NORTH</code>,
+buggle jedi trouve le plus court chemin en suivant les indications écrites
+au sol. Pour celà, il lui suffit à chaque pas d'aller sur la case de plus
+petite distance parmis celles accessibles. Vous pouvez utiliser la méthode
+<code>void setDirection(Direction d)</code> pour faire regarder votre buggle
+dans une direction spécifique comme <code>Direction.NORTH</code>,
 <code>Direction.SOUTH</code>, <code>Direction.EAST</code> ou
 <code>Direction.WEST</code>, qui correspondent respectivement au nord, sud,
-est
-et ouest.</p>
+est et ouest.</p>
 
 <div class="tip" id="tip-1" alt="Je suis perdu, je voudrais plus d'indications">
 Utilises la Force Luke !
diff --git a/src/lessons/maze/shortestpath/ShortestPathMaze.java b/src/lessons/maze/shortestpath/ShortestPathMaze.java
index 75ded12..f616b84 100644
--- a/src/lessons/maze/shortestpath/ShortestPathMaze.java
+++ b/src/lessons/maze/shortestpath/ShortestPathMaze.java
@@ -2,11 +2,11 @@ package lessons.maze.shortestpath;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class ShortestPathMaze extends ExerciseTemplated {
 
diff --git a/src/lessons/maze/shortestpath/ShortestPathMazeEntity.java b/src/lessons/maze/shortestpath/ShortestPathMazeEntity.java
index 68bd489..281835e 100644
--- a/src/lessons/maze/shortestpath/ShortestPathMazeEntity.java
+++ b/src/lessons/maze/shortestpath/ShortestPathMazeEntity.java
@@ -1,27 +1,25 @@
 package lessons.maze.shortestpath;
 
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.BuggleWorldCell;
+import plm.core.model.Game;
+import plm.universe.Direction;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.BuggleWorldCell;
 
-public class ShortestPathMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class ShortestPathMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void setX(int i)  {
 		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
-		super.setX(i);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
-		super.setY(i);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
-		super.setPos(i,j);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
 
 	void setIndication(int x, int y, int i) {
@@ -45,7 +43,12 @@ public class ShortestPathMazeEntity extends jlm.universe.bugglequest.SimpleBuggl
 	}
 
 	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
+	public void run() {
+		/* BEGIN SOLUTION */
+		evaluatePaths(); // write on each case the distance to the maze exit
+		followShortestPath(); // make the buggle follow the shortest path
+		pickupBaggle(); // enjoy the baggle!           
+	}
 	// tools functions
 	public boolean hasRightWall(int x, int y) {
 		return hasLeftWall((x + 1) % getWorldWidth(), y); 
@@ -132,13 +135,12 @@ public class ShortestPathMazeEntity extends jlm.universe.bugglequest.SimpleBuggl
 
 			forward();
 		}    
-	}
-	/* END SOLUTION */
-
-	public void run() {
-		evaluatePaths(); // write on each case the distance to the maze exit
-		followShortestPath(); // make the buggle follow the shortest path
-		pickupBaggle(); // enjoy the baggle!           
+		/* END SOLUTION */
 	}
 	/* END TEMPLATE */
+	
+	/* BINDINGS TRANSLATION to French: Don't translate getIndication */
+	boolean aBiscuit(int x, int y) { return hasBaggle(x,y); }
+	boolean aMurNord(int x, int y) { return hasTopWall(x,y); }
+	boolean aMurOuest(int x, int y){ return hasLeftWall(x, y); }
 }
diff --git a/src/lessons/maze/shortestpath/ShortestPathMazeEntity.scala b/src/lessons/maze/shortestpath/ShortestPathMazeEntity.scala
new file mode 100644
index 0000000..636b9e1
--- /dev/null
+++ b/src/lessons/maze/shortestpath/ShortestPathMazeEntity.scala
@@ -0,0 +1,123 @@
+package lessons.maze.shortestpath;
+
+import plm.universe.Direction
+import plm.universe.bugglequest.BuggleWorld
+import plm.universe.bugglequest.BuggleWorldCell;
+import plm.core.model.Game
+
+class ScalaShortestPathMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	def setIndication(x:Int, y:Int, i:Int) {
+		val c = world.asInstanceOf[BuggleWorld].getCell(x,y);
+		c.setContent(""+i);
+	}
+	def getIndication(x:Int, y:Int): Int =  {
+		val c = world.asInstanceOf[BuggleWorld].getCell(x,y);
+		if (c.hasContent())
+			return c.getContent().toInt;
+		return 9999;
+	}
+	def hasBaggle(x:Int, y:Int):   Boolean = world.asInstanceOf[BuggleWorld].getCell(x,y).hasBaggle();
+	def hasTopWall(x:Int, y:Int):  Boolean = world.asInstanceOf[BuggleWorld].getCell(x,y).hasTopWall();
+	def hasLeftWall(x:Int, y:Int): Boolean = world.asInstanceOf[BuggleWorld].getCell(x,y).hasLeftWall();
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		evaluatePaths(); // write on each case the distance to the maze exit
+		followShortestPath(); // make the buggle follow the shortest path
+		pickupBaggle(); // enjoy the biscuit           
+	}
+	// tools functions
+	def hasRightWall(x:Int, y:Int):  Boolean = hasLeftWall((x + 1) % getWorldWidth(), y); 
+	def hasBottomWall(x:Int, y:Int): Boolean = hasTopWall(x, (y + 1) % getWorldHeight());
+
+	def setValueIfLess(x:Int, y:Int, i:Int): Boolean = {
+		var existing = getIndication(x, y);
+		if (i < existing) {
+			setIndication(x, y, i);
+			return true;
+		}
+		return false;
+	}
+
+	def evaluatePaths() {
+		// looking for labyrinth exit	
+		for (x <- 0 to getWorldWidth() -1; y <- 0 to getWorldHeight()-1)        
+			if (hasBaggle(x,y))
+				setIndication(x, y, 0);
+
+		while (true) {   
+			for (x <- 0 to getWorldWidth() -1; y <- 0 to getWorldHeight()-1) {
+				var indication = getIndication(x, y);
+				var changed = false;
+				if (indication != 9999) {
+					if (! hasBottomWall(x,y))
+						changed |= setValueIfLess(x, (y + 1) % getWorldHeight(), indication + 1);
+
+					if (! hasRightWall(x,y))
+						changed |= setValueIfLess((x + 1) % getWorldWidth(), y, indication + 1);
+
+					if (! hasTopWall(x,y))
+						changed |= setValueIfLess(x, (y+getWorldHeight() - 1) % getWorldHeight(), indication + 1);
+
+					if (! hasLeftWall(x,y))
+						changed |= setValueIfLess((x +getWorldWidth() - 1) % getWorldWidth(), y, indication + 1);
+
+					if (changed && x == getX() && y == getY())
+						return ; // reached the buggle, that's enough
+				}    
+			}
+		}
+	}
+
+	def followShortestPath() {
+		while (! isOverBaggle()) {
+
+			var x = getX();
+			var y = getY();
+
+			var topValue = 9999;
+			var bottomValue = 9999;
+			var leftValue = 9999;
+			var rightValue = 9999;
+
+			if (! hasTopWall(x, y))
+				topValue = getIndication(x, (y + getWorldHeight() - 1) % getWorldHeight());
+
+			if (! hasBottomWall(x, y))
+				bottomValue = getIndication(x, (y+1) % getWorldHeight());
+
+			if (! hasLeftWall(x, y))
+				leftValue = getIndication((x +getWorldWidth() - 1) % getWorldWidth(), y);
+
+			if (! hasRightWall(x, y))
+				rightValue = getIndication((x + 1) % getWorldWidth(), y);
+			
+			if (topValue <= bottomValue && topValue <= leftValue && topValue <= rightValue)
+				setDirection(Direction.NORTH);
+			else if (rightValue <= topValue && rightValue <= bottomValue && rightValue <= leftValue)
+				setDirection(Direction.EAST);
+			else if (leftValue <= rightValue && leftValue <= bottomValue && leftValue <= topValue)
+				setDirection(Direction.WEST);
+			else if (bottomValue <= topValue && bottomValue <= rightValue && bottomValue <= leftValue)
+				setDirection(Direction.SOUTH);
+
+			forward();
+		}    
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/maze/wallfindfollow/WallFindFollowMaze.fr.html b/src/lessons/maze/wallfindfollow/WallFindFollowMaze.fr.html
index 4beb70d..2c73487 100644
--- a/src/lessons/maze/wallfindfollow/WallFindFollowMaze.fr.html
+++ b/src/lessons/maze/wallfindfollow/WallFindFollowMaze.fr.html
@@ -1,19 +1,19 @@
 <h2>Trouver les murs à longer</h2>
 
-<p>C'est exactement le même labyrinthe que précédemment, mais le buggle ne
-commence plus au même emplacement. En particulier, il n'a plus de mur à sa
+<p>C'est exactement le même labyrinthe que précédemment, mais la buggle ne
+commence plus au même emplacement. En particulier, elle n'a plus de mur à sa
 gauche dès le départ.</p>
 
-<p>Ceci engendre que la méthode que vous avez écrite à l'exercice précédent ne
-fonctionne plus ici. Si vous l'utilisez ici sans modification, votre buggle
-va probablement commencer à tourner sur les quatres cases à côté de sa
-position de départ (si ça n'est pas le cas, et bien, vous n'avez pas
-réellement suivi la mission de l'exercice précédent. Sentez vous chanceux et
-passez à l'exercice suivant une fois que vous aurez lu ce texte).</p>
+<p>Ceci fait que la méthode écrite à l'exercice précédent ne fonctionne
+plus. Si vous l'utilisez ici sans modification, votre buggle va probablement
+commencer à tourner sur les quatres cases à côté de sa position de départ
+(si ça n'est pas le cas, et bien, vous n'avez pas réellement suivi la
+mission de l'exercice précédent. Sentez vous chanceux et passez à l'exercice
+suivant une fois que vous aurez lu ce texte).</p>
 
 <p>C'est parce que votre méthode <code>keepHandOnSideWall()</code> a une
 <b>pré-condition</b> implicite : la méthode marche bien si et seulement si
-le buggle a un mur sur sa gauche quand vous appelez cette méthode. De telles
+la buggle a un mur sur sa gauche quand vous appelez cette méthode. De telles
 pré-conditions sont très utilisées en programmation. Les spécifier
 explicitement aide à comprendre le code écrit par d'autres personnes, et
 peuvent même parfois prouver que le code marche correctement.</p>
@@ -23,7 +23,7 @@ peuvent même parfois prouver que le code marche correctement.</p>
 <p>
 Réparer le problème devrait être très facile. Assurez-vous simplement que la
 pré-condition de <code>keepHandOnSideWall()</code> est vérifiée avant de
-l'appeler Pour ce faire, mettez à jour votre code pour tout d'abord
+l'appeler. Pour ce faire, mettez à jour votre code pour tout d'abord
 rechercher à avoir un mur à sa gauche avant de rentrer dans la grande boucle
 <code>while</code>.
 </p>
diff --git a/src/lessons/maze/wallfindfollow/WallFindFollowMaze.java b/src/lessons/maze/wallfindfollow/WallFindFollowMaze.java
index d5fa105..7816292 100644
--- a/src/lessons/maze/wallfindfollow/WallFindFollowMaze.java
+++ b/src/lessons/maze/wallfindfollow/WallFindFollowMaze.java
@@ -2,18 +2,17 @@ package lessons.maze.wallfindfollow;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class WallFindFollowMaze extends ExerciseTemplated {
 
 	public WallFindFollowMaze(Lesson lesson) throws IOException, BrokenWorldFileException {
 		super(lesson);
 		tabName = "Escaper";
-		nameOfCorrectionEntity = "lessons.maze.wallfollower.WallFollowerMazeEntity"; // Use the same entity than in previous exercise
 		
 		setup(new World[] {
 				BuggleWorld.newFromFile("lessons/maze/wallfindfollow/WallFindFollowMaze"),
diff --git a/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java
new file mode 100644
index 0000000..d66feae
--- /dev/null
+++ b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.java
@@ -0,0 +1,53 @@
+package lessons.maze.wallfindfollow;
+
+import plm.core.model.Game;
+import plm.universe.Direction;
+
+ at SuppressWarnings("unused")
+public class WallFindFollowMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	private Direction uselessVariableExistingJustToMakeSureThatEclipseWontRemoveTheImport; /* If removed, user code can't use directions easily */
+	@Override
+	public void setX(int i)  {
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	@Override
+	public void setY(int i)  { 
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	@Override
+	public void setPos(int i,int j)  { 
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+	 
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	public void stepHandOnWall() {
+		// PRE: we have a wall on the left
+		// POST: we still have the same wall on the left, are one step ahead
+
+		while (!isFacingWall()) {
+			forward();
+			left(); // change to right to get a right follower
+		}
+		right(); // change to left to get a right follower
+	}
+
+	public void run() {
+		// Make sure we have a wall to the left
+		left();
+		while (!isFacingWall())
+			forward();
+		right();
+
+		while (!isOverBaggle())
+			stepHandOnWall();
+
+		pickupBaggle();
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
+
diff --git a/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.py b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.py
index f9c3ed1..d8c8069 100644
--- a/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.py
+++ b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.py
@@ -11,14 +11,14 @@ def stepHandOnWall():
     # POST: we still have the same wall on the left, are one step ahead
     while not isFacingWall():
         forward()
-        turnLeft() # change to turnRight to get a right follower
-    turnRight() # change to turnLeft to get a right follower
+        left() # change to right to get a right follower
+    right() # change to left to get a right follower
 
 # make sure that we have a wall to the left
-turnLeft()
+left()
 while not isFacingWall():
     forward()
-turnRight()
+right()
 
 while not isOverBaggle():
     stepHandOnWall()
diff --git a/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.scala b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.scala
new file mode 100644
index 0000000..0e14b3a
--- /dev/null
+++ b/src/lessons/maze/wallfindfollow/WallFindFollowMazeEntity.scala
@@ -0,0 +1,49 @@
+package lessons.maze.wallfollower;
+
+import plm.core.model.Game;
+import plm.universe.Direction;
+
+class ScalaWallFindFollowMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	val uselessVariableExistingJustToMakeSureThatEclipseWontRemoveTheImport:Direction=null; /* If removed, user code can't use directions easily */
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+	 
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def stepHandOnWall() {
+		// PRE: we have a wall on the left
+		// POST: we still have the same wall on the left, are one step ahead
+
+		while (!isFacingWall()) {
+			forward();
+			left(); // change to right to get a right follower
+		}
+		right(); // change to left to get a right follower
+	}
+
+	def run() {
+		// Make sure we have a wall to the left
+		left();
+		while (!isFacingWall())
+			forward();
+		right();
+
+		while (!isOverBaggle())
+			stepHandOnWall();
+
+		pickupBaggle();
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
+
diff --git a/src/lessons/maze/wallfollower/WallFollowerMaze.fr.html b/src/lessons/maze/wallfollower/WallFollowerMaze.fr.html
index a5ccc6f..5fb0626 100644
--- a/src/lessons/maze/wallfollower/WallFollowerMaze.fr.html
+++ b/src/lessons/maze/wallfollower/WallFollowerMaze.fr.html
@@ -7,8 +7,8 @@ pas suffisant, il va falloir être intelligent !</p>
 sont connectés les uns aux autres. Pour sortir de ce genre de labyrinthe, il
 suffit à votre buggle de longer un mur (celui à sa droite, ou celui à sa
 gauche: c'est sans importance). Tout en gardant sa patte posée sur ce mur,
-votre buggle doit avancer jusqu'à ce qu'il trouve la sortie du labyrinthe et
-ce biscuit qu'il apprécie tant.</p>
+votre buggle doit avancer jusqu'à ce qu'elle trouve la sortie du labyrinthe
+et ce biscuit qu'il apprécie tant.</p>
 
 <p>Cet algorithme fonctionne ici car il n'y a pas d'île de murs isolés, ce qui
 fait que la buggle ne peut pas boucler autour des murs sans rencontrer le
@@ -21,28 +21,27 @@ permettant à votre buggle de sortir du labyrinthe.
 démo suit le mur gauche, et il serait donc avisé d'en faire de même pour
 simplifier la comparaison de votre solution et de la démo.</p> 
 
-<p>Écrivez une méthode <code>keepHandOnSideWall()</code> qui fait avancer
-votre buggle d'une case tout en gardant la patte sur le mur du côté
-choisi. Vous devez vous assurer que votre buggle garde toujours la patte
-sur le mur et également qu'il ne risque pas de percuter un mur. Vous pouvez
-regarder l'indice (hint) si vous êtes coincés, mais vous devriez d'abord
-essayer de le faire par vous-même.</p> 
+<p>Écrivez une méthode <code>keepHandOnSideWall()</code> qui fait avancer votre
+buggle d'une case tout en gardant la patte sur le mur du côté choisi. Vous
+devez vous assurer que votre buggle garde toujours la patte sur le mur et
+également qu'elle ne risque pas de percuter un mur. Vous pouvez regarder
+l'indice (hint) si vous êtes coincé, mais vous devriez d'abord essayer de le
+faire par vous-même.</p> 
 
 <p>Enfin, écrivez l'algorithme complet qui parcourt le labyrinthe pas à pas
-jusqu'à
-trouver le biscuit et la sortie. N'oubliez pas de prendre le baggle.</p>
+jusqu'à trouver le biscuit et la sortie. N'oubliez pas de prendre le baggle.</p>
 
 <div class="tip" id="tip-1" alt="Je suis perdu, je voudrais plus d'indications">
 <p>Quand votre buggle a un mur à sa gauche, il faut considérer trois situations
-possible, qui dépendent des murs alentours. Le tableau suivant représente
+possibles, qui dépendent des murs alentours. Le tableau suivant représente
 graphiquement chaque situation initiale, et où vous devez placer votre
 buggle à la fin de l'étape.</p>
 <table border=1>
 <tr>
  <td></td>
- <td>Case 1</td>
- <td>Case 2</td>
- <td>Case 3</td>
+ <td>Cas 1</td>
+ <td>Cas 2</td>
+ <td>Cas 3</td>
 </tr><tr>
  <td>Situation initiale</td>
  <td><img src="lessons/maze/wallfollower/1A.png"/></td>
@@ -55,8 +54,9 @@ buggle à la fin de l'étape.</p>
  <td><img src="lessons/maze/wallfollower/3B.png"/></td>
 </tr>
 </table>
-<p>Si vous faites un <code>turnRight()</code> dans tous les cas à la fin de
-votre fonction, il est possible de l'écrire en trois lignes avec une boucle
+<p>Si vous faites un <code>right()</code> dans tous les cas à la fin de votre
+fonction, il est possible de l'écrire en trois lignes avec une boucle
 <code>while</code>.</p>
 </div>
 
+    
\ No newline at end of file
diff --git a/src/lessons/maze/wallfollower/WallFollowerMaze.html b/src/lessons/maze/wallfollower/WallFollowerMaze.html
index 735b9f8..1bb6a78 100644
--- a/src/lessons/maze/wallfollower/WallFollowerMaze.html
+++ b/src/lessons/maze/wallfollower/WallFollowerMaze.html
@@ -1,64 +1,65 @@
-<h2>Following the walls</h2>
-
-<p>This time, the maze is a bit more complicated. Random won't be enough, we
-ough to be smart!</p>
-
-<p>The good news is that this maze is simpler that it seems at the first glance:
-every wall are connected to each other. To get out of this kind of
-maze, the buggle only have to follow a wall (the one on its left or
-the one on its right, it doesn't matter).  While keeping a paw on the
-wall, the buggle must move forward until it finds the maze exit
-and this biscuit it loves so much.</p>
-
-<p>This works here because there is no island of isolated
-walls, so our buggle cannot loop around for ever without encountering
-its baggle.</p>
-
-<h3>Exercise goal</h3>The goal of this exercise is to write an algorithm allowing the buggle to
-get out of this maze.
-
-<p>As said earlier, it does not matter whether you decide
-to follow the left wall or the right one. Simply, the demo follows the
-left one, so you should do the same in your solution to ease the
-comparison of your solution and the demo.</p> 
-
-<p>Write a method <code>keepHandOnSideWall()</code> which lets the buggle
-move one step forward while keeping the paw on the wall of the selected
-side. You must ensure that the buggle always keep the paw on the
-wall, but also that it won't crash into a wall. You can check the tip
-for more info on this, but only do so if you're stuck. Try to do it
-without the tip first.</p> 
-
-<p>Then, write the whole algorithm to traverse the maze step
-by step (using  <code>keepHandOnSideWall()</code>) until it finds
-the biscuit and the exit. Don't forget to pick the baggle up once
-you've found it.</p>
-
-<div class="tip" id="tip-1" alt="I'm lost, please give me some extra indications">
-<p>When your buggle has a wall on the left, there is three situations to
-consider, depending on the surrounding walls. The following table
-depicts each initial situation, and where you should let your buggle
-end after one step.</p>
-<table border=1>
-<tr>
- <td></td>
- <td>Case 1</td>
- <td>Case 2</td>
- <td>Case 3</td>
-</tr><tr>
- <td>Initial situation</td>
- <td><img src="lessons/maze/wallfollower/1A.png"/></td>
- <td><img src="lessons/maze/wallfollower/2A.png"/></td>
- <td><img src="lessons/maze/wallfollower/3A.png"/></td>
-</tr><tr>
- <td>Where is the next step</td>
- <td><img src="lessons/maze/wallfollower/1B.png"/></td>
- <td><img src="lessons/maze/wallfollower/2B.png"/></td>
- <td><img src="lessons/maze/wallfollower/3B.png"/></td>
-</tr>
-</table>
-<p>If you do a <code>turnRight()</code> in any case at the end of your
-function, it's possible to write it in 3 lines with a
-<code>while</code> loop.</p>
-</div>
-
+<h2>Following the walls</h2>
+
+<p>This time, the maze is a bit more complicated. Random won't be enough, we
+ough to be smart!</p>
+
+<p>The good news is that this maze is simpler that it seems at the first glance:
+every wall are connected to each other. To get out of this kind of
+maze, the buggle only have to follow a wall (the one on its left or
+the one on its right, it doesn't matter).  While keeping a paw on the
+wall, the buggle must move forward until it finds the maze exit
+and this biscuit it loves so much.</p>
+
+<p>This works here because there is no island of isolated
+walls, so our buggle cannot loop around for ever without encountering
+its baggle.</p>
+
+<h3>Exercise goal</h3>The goal of this exercise is to write an algorithm allowing the buggle to
+get out of this maze.
+
+<p>As said earlier, it does not matter whether you decide
+to follow the left wall or the right one. Simply, the demo follows the
+left one, so you should do the same in your solution to ease the
+comparison of your solution and the demo.</p> 
+
+<p>Write a method <code>keepHandOnSideWall()</code> which lets the buggle
+move one step forward while keeping the paw on the wall of the selected
+side. You must ensure that the buggle always keep the paw on the
+wall, but also that it won't crash into a wall. You can check the tip
+for more info on this, but only do so if you're stuck. Try to do it
+without the tip first.</p> 
+
+<p>Then, write the whole algorithm to traverse the maze step
+by step (using  <code>keepHandOnSideWall()</code>) until it finds
+the biscuit and the exit. Don't forget to pick the baggle up once
+you've found it.</p>
+
+<div class="tip" id="tip-1" alt="I'm lost, please give me some extra indications">
+<p>When your buggle has a wall on the left, there is three situations to
+consider, depending on the surrounding walls. The following table
+depicts each initial situation, and where you should let your buggle
+end after one step.</p>
+<table border=1>
+<tr>
+ <td></td>
+ <td>Case 1</td>
+ <td>Case 2</td>
+ <td>Case 3</td>
+</tr><tr>
+ <td>Initial situation</td>
+ <td><img src="lessons/maze/wallfollower/1A.png"/></td>
+ <td><img src="lessons/maze/wallfollower/2A.png"/></td>
+ <td><img src="lessons/maze/wallfollower/3A.png"/></td>
+</tr><tr>
+ <td>Where is the next step</td>
+ <td><img src="lessons/maze/wallfollower/1B.png"/></td>
+ <td><img src="lessons/maze/wallfollower/2B.png"/></td>
+ <td><img src="lessons/maze/wallfollower/3B.png"/></td>
+</tr>
+</table>
+<p>If you do a <code>right()</code> in any case at the end of your
+function, it's possible to write it in 3 lines with a
+<code>while</code> loop.</p>
+</div>
+
+    
\ No newline at end of file
diff --git a/src/lessons/maze/wallfollower/WallFollowerMaze.java b/src/lessons/maze/wallfollower/WallFollowerMaze.java
index 02f2e5a..ab60532 100644
--- a/src/lessons/maze/wallfollower/WallFollowerMaze.java
+++ b/src/lessons/maze/wallfollower/WallFollowerMaze.java
@@ -2,11 +2,11 @@ package lessons.maze.wallfollower;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class WallFollowerMaze extends ExerciseTemplated {
 
diff --git a/src/lessons/maze/wallfollower/WallFollowerMazeEntity.java b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.java
index f87206b..8b1eff4 100644
--- a/src/lessons/maze/wallfollower/WallFollowerMazeEntity.java
+++ b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.java
@@ -1,35 +1,27 @@
 package lessons.maze.wallfollower;
 
-import jlm.universe.Direction;
+import plm.core.model.Game;
+import plm.universe.Direction;
 
 @SuppressWarnings("unused")
-public class WallFollowerMazeEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class WallFollowerMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
 	private Direction uselessVariableExistingJustToMakeSureThatEclipseWontRemoveTheImport; /* If removed, user code can't use directions easily */
-
 	@Override
 	public void setX(int i)  {
-		if (isInited()) 
-			throw new RuntimeException("setX(int) forbidden in this exercise");
-		super.setX(i);
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
-		super.setY(i);
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
-		super.setPos(i, j);
-	}
-	/*	// Stop moving if stepping over a baggle; commented because overriding forward is beyond the object know how of the students at this point 
-	public void forward() {
-	    if (!isOverBaggle()) 
-	      super.forward();
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
-	 */
+	 
 	/* BEGIN TEMPLATE */
 	/* BEGIN SOLUTION */
 	public void stepHandOnWall() {
@@ -38,17 +30,17 @@ public class WallFollowerMazeEntity extends jlm.universe.bugglequest.SimpleBuggl
 
 		while (!isFacingWall()) {
 			forward();
-			turnLeft(); // change to turnRight to get a right follower
+			left(); // change to right to get a right follower
 		}
-		turnRight(); // change to turnLeft to get a right follower
+		right(); // change to left to get a right follower
 	}
 
 	public void run() {
 		// Make sure we have a wall to the left
-		turnLeft();
+		left();
 		while (!isFacingWall())
 			forward();
-		turnRight();
+		right();
 
 		while (!isOverBaggle())
 			stepHandOnWall();
diff --git a/src/lessons/maze/wallfollower/WallFollowerMazeEntity.py b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.py
index f9c3ed1..d8c8069 100644
--- a/src/lessons/maze/wallfollower/WallFollowerMazeEntity.py
+++ b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.py
@@ -11,14 +11,14 @@ def stepHandOnWall():
     # POST: we still have the same wall on the left, are one step ahead
     while not isFacingWall():
         forward()
-        turnLeft() # change to turnRight to get a right follower
-    turnRight() # change to turnLeft to get a right follower
+        left() # change to right to get a right follower
+    right() # change to left to get a right follower
 
 # make sure that we have a wall to the left
-turnLeft()
+left()
 while not isFacingWall():
     forward()
-turnRight()
+right()
 
 while not isOverBaggle():
     stepHandOnWall()
diff --git a/src/lessons/maze/wallfollower/WallFollowerMazeEntity.scala b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.scala
new file mode 100644
index 0000000..56cab97
--- /dev/null
+++ b/src/lessons/maze/wallfollower/WallFollowerMazeEntity.scala
@@ -0,0 +1,49 @@
+package lessons.maze.wallfollower;
+
+import plm.core.model.Game;
+import plm.universe.Direction;
+
+class ScalaWallFollowerMazeEntity extends plm.universe.bugglequest.SimpleBuggle {
+	val uselessVariableExistingJustToMakeSureThatEclipseWontRemoveTheImport:Direction=null; /* If removed, user code can't use directions easily */
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+	 
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def stepHandOnWall() {
+		// PRE: we have a wall on the left
+		// POST: we still have the same wall on the left, are one step ahead
+
+		while (!isFacingWall()) {
+			forward();
+			left(); // change to right to get a right follower
+		}
+		right(); // change to left to get a right follower
+	}
+
+	def run() {
+		// Make sure we have a wall to the left
+		left();
+		while (!isFacingWall())
+			forward();
+		right();
+
+		while (!isOverBaggle())
+			stepHandOnWall();
+
+		pickupBaggle();
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
+
diff --git a/src/lessons/recursion/Main.java b/src/lessons/recursion/Main.java
index 9e3fde2..04e2eed 100644
--- a/src/lessons/recursion/Main.java
+++ b/src/lessons/recursion/Main.java
@@ -1,6 +1,6 @@
 package lessons.recursion;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 import lessons.recursion.circle.Circle;
 import lessons.recursion.dragoncurve.DragonCurve1;
 import lessons.recursion.dragoncurve.DragonCurve2;
@@ -9,14 +9,14 @@ import lessons.recursion.polygonfractal.PolygonFractal;
 import lessons.recursion.sierpinski.Sierpinski;
 import lessons.recursion.spiral.Spiral;
 import lessons.recursion.spiral.SpiralUse;
-import lessons.recursion.square.Square;
+import lessons.recursion.square.FourSquare;
 import lessons.recursion.star.Star;
 import lessons.recursion.tree.Tree;
 
 public class Main extends Lesson {
 	@Override
 	protected void loadExercises() {
-		addExercise(new Square(this));
+		addExercise(new FourSquare(this));
 		addExercise(new Circle(this));
 		addExercise(new Star(this));
 		addExercise(new Spiral(this));
diff --git a/src/lessons/recursion/circle/Circle.fr.html b/src/lessons/recursion/circle/Circle.fr.html
index ffb6ce8..566a09f 100644
--- a/src/lessons/recursion/circle/Circle.fr.html
+++ b/src/lessons/recursion/circle/Circle.fr.html
@@ -9,15 +9,16 @@ concaténation de petits segments.
 
 <p>Les amateurs de calcul différentiel diraient même sans doute qu'un cercle
 est la limite asymptotique d'une telle construction quand la taille des
-segments tend vers zéro alors que leur nombre tend vers l'infini (mais on
-peut tout de même réussir l'exercice sans maîtriser le calcul différentiel).</p>
+segments tend vers zéro alors que leur nombre tend vers l'infini, mais il
+est tout à fait possible de réussir cet exercice sans maîtriser le calcul
+différentiel :)</p>
 
 <h3>Objectif de l'exercice</h3> 
 
 Écrivez une fonction dessinant un cercle, avec la taille de chacun des 360
-pas passée en paramètre. Utilisez la ensuite dans votre méthode
-<code>run()</code> pour réaliser la figure dans son ensemble. Le premier
-cercle s'obtient avec des pas de 0.5, le second avec des pas de 1 et le
-troisième avec des pas de 1.5. Encore une fois, il s'agit d'un exercice de
-prise en main, et aucune récursion n'est nécessaire.
+pas passée en paramètre. Utilisez la ensuite dans votre code pour réaliser
+la figure dans son ensemble. Le premier cercle s'obtient avec des pas de
+0.5, le second avec des pas de 1 et le troisième avec des pas de 1.5. Encore
+une fois, il s'agit d'un exercice de prise en main, et aucune récursion
+n'est nécessaire.
 
diff --git a/src/lessons/recursion/circle/Circle.html b/src/lessons/recursion/circle/Circle.html
index f065d6e..370432a 100644
--- a/src/lessons/recursion/circle/Circle.html
+++ b/src/lessons/recursion/circle/Circle.html
@@ -1,21 +1,21 @@
-<h2>Three little circles</h2>
-
-As we saw (and as you can check in the documentation of this world under
-"About this world"), turtles can only draw straight lines. Despite of this,
-the goal of this world is to draw circles... This can be achived simply by
-realizing that a circle can be seen as a concatenation of very little
-segments.
-
-<p>Differential calculus would even argue that a circle is the asymptotical
-limit of such construct when the size of each segment becomes infinitely
-small while their amount becomes infinitely large (but it is still possible
-to solve this exercise without understanding differential calculus).</p>
-
-<h3>Goal of this exercise</h3> 
-
-Write a function drawing a circle, taking the size of each of the 360
-segments as parameter. Then use it in your <code>run()</code> method to draw
-the whole picture. The first circle is obtained with segments of size 0.5,
-the second with segments of size 1 and the last one with 1.5-long
-segments. Once again, this is a hand-on exercise, no recursion is needed.
-
+<h2>Three little circles</h2>
+
+As we saw (and as you can check in the documentation of this world under
+"About this world"), turtles can only draw straight lines. Despite of this,
+the goal of this world is to draw circles... This can be achived simply by
+realizing that a circle can be seen as a concatenation of very little
+segments.
+
+<p>Differential calculus would even argue that a circle is the asymptotical
+limit of such construct when the size of each segment becomes infinitely
+small while their amount becomes infinitely large, but you can definitely 
+solve this exercise without understanding differential calculus :)</p>
+
+<h3>Goal of this exercise</h3> 
+
+Write a function drawing a circle, taking the size of each of the 360
+segments as parameter. Then use it in your code to draw the whole picture. 
+The first circle is obtained with segments of size 0.5, the second with 
+segments of size 1 and the last one with 1.5-long segments. 
+Once again, this is a warming exercise, no recursion is needed.
+
diff --git a/src/lessons/recursion/circle/Circle.java b/src/lessons/recursion/circle/Circle.java
index 9251f84..a210028 100644
--- a/src/lessons/recursion/circle/Circle.java
+++ b/src/lessons/recursion/circle/Circle.java
@@ -1,10 +1,10 @@
 package lessons.recursion.circle;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Circle extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/circle/CircleEntity.java b/src/lessons/recursion/circle/CircleEntity.java
index 11c6c4f..dffe6e1 100644
--- a/src/lessons/recursion/circle/CircleEntity.java
+++ b/src/lessons/recursion/circle/CircleEntity.java
@@ -1,22 +1,22 @@
 package lessons.recursion.circle;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class CircleEntity extends Turtle {
 
 	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	public void circle(double step) {
-		for (int i=0;i<360;i++) {
-			forward(step);
-			turnRight(1);
-		}		
-	}
 	public void run() {
+		/* BEGIN SOLUTION */
 		circle(0.5);
 		circle(1);
 		circle(1.5);
 	}
-	/* END SOLUTION */
+	public void circle(double step) {
+		for (int i=0;i<360;i++) {
+			forward(step);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
 	/* END TEMPLATE */
 }
diff --git a/src/lessons/recursion/circle/CircleEntity.py b/src/lessons/recursion/circle/CircleEntity.py
index ba6dd7d..7f69230 100644
--- a/src/lessons/recursion/circle/CircleEntity.py
+++ b/src/lessons/recursion/circle/CircleEntity.py
@@ -2,7 +2,7 @@
 def circle(step):
   for i in range(360):
     forward(step)
-    turnRight(1)
+    right(1)
 
 circle(0.5)
 circle(1)
diff --git a/src/lessons/recursion/circle/CircleEntity.scala b/src/lessons/recursion/circle/CircleEntity.scala
new file mode 100644
index 0000000..d3c772a
--- /dev/null
+++ b/src/lessons/recursion/circle/CircleEntity.scala
@@ -0,0 +1,22 @@
+package lessons.recursion.circle;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaCircleEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		circle(0.5);
+		circle(1);
+		circle(1.5);
+	}
+	override def circle(step:Double) {
+		for (i <- 1 to 360) {
+			forward(step);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve1.fr.html b/src/lessons/recursion/dragoncurve/DragonCurve1.fr.html
index ebb68db..1b3bada 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve1.fr.html
+++ b/src/lessons/recursion/dragoncurve/DragonCurve1.fr.html
@@ -9,20 +9,18 @@ la courbe du Dragon d'ordre n est la courbe du Dragon d'ordre n-1 entre P et
 R suivie de la même courbe d'ordre n-1 entre R et Q (à l'envers), où PRQ est
 le triangle isocèle rectangle en R, et R est à droite du vecteur PQ.  Donc,
 si P et Q sont les points de coordonnées (x, y) et (z,t), les coordonnées
-(u, v) de R sont
+(u, v) de R sont</p>
 <pre>
 u = (x + z)/2 + (t - y)/2
 v = (y + t)/2 - (z - x)/2
 </pre>
-</p>
 
-<p>
-Le prototype de la méthode traçant la courbe est le suivant :
-<pre>void dragon(int ordre, double x, double y, double z, double t)</pre>
-</p>
+<p>Le prototype de la méthode traçant la courbe est le suivant :</p>
+<pre>[!java]void [/!]dragon([!java]int [/!]ordre[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
+
 
 <p>Vous utiliserez la méthode <code>setPos(x,y)</code> pour déplacer votre
-tortue aux coordonnées (x,y) et la méthode <code>moveTo(z,t)</code> pour
+tortue aux coordonnées (x,y) et la méthode <code>allerVers(z,t)</code> pour
 tracer un trait depuis le point où la tortue est positionnée vers le point
 de coordonnées (z,t)</p>
 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve1.html b/src/lessons/recursion/dragoncurve/DragonCurve1.html
index 9d2b288..70957f8 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve1.html
+++ b/src/lessons/recursion/dragoncurve/DragonCurve1.html
@@ -1,28 +1,26 @@
-<h2>Dragon curve (1)</h2>
-
-<p>The dragon curve is a classical example of recursive method.</p>
-
-<p>The definition of this curve is the following:<br/> 
-the dragon curve of order 1 is a vector between to arbitrary points P and Q,<br/>
-the dragon curve of order n is the dragon curve of order n-1 between P and
-R, followed by the same curve of order n-1 between R and Q (reverse side),
-where PRQ is an isoscele triangle with angle R being a right angle, and R
-being at the right of the PQ vector. Thus, if P and Q coordinates are (x, y)
-and (z, t), the coordinate (u, v) of R are given by:
-<pre>
-u = (x + z)/2 + (t - y)/2
-v = (y + t)/2 - (z - x)/2
-</pre>
-</p>
-
-<p>
-The prototype of the method drawing the curve is the following:
-<pre>void dragon(int ordre, double x, double y, double z, double t)</pre>
-</p>
-
-<p>You should use the method <code>setPos(x,y)</code> to put your turtle at
-coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line
-between the turtle position and the point (z,t).</p>
-
-<p>Have a look at each world's objective view to understand how to write the
-function.</p> 
+<h2>Dragon curve (1)</h2>
+
+<p>The dragon curve is a classical example of recursive method.</p>
+
+<p>The definition of this curve is the following:<br/> 
+the dragon curve of order 1 is a vector between to arbitrary points P and Q,<br/>
+the dragon curve of order n is the dragon curve of order n-1 between P and
+R, followed by the same curve of order n-1 between R and Q (reverse side),
+where PRQ is an isoscele triangle with angle R being a right angle, and R
+being at the right of the PQ vector. Thus, if P and Q coordinates are (x, y)
+and (z, t), the coordinate (u, v) of R are given by:</p>
+<pre>
+u = (x + z)/2 + (t - y)/2
+v = (y + t)/2 - (z - x)/2
+</pre>
+
+<p>The prototype of the method drawing the curve is the following:</p>
+<pre>[!java]void [/!]dragon([!java]int [/!]order[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
+
+
+<p>You should use the method <code>setPos(x,y)</code> to put your turtle at
+coordinates (x,y) and the method <code>moveTo(z,t)</code> to draw a line
+between the turtle position and the point(z,t).</p>
+
+<p>Have a look at each world's objective view to understand how to write the
+function.</p> 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve1.java b/src/lessons/recursion/dragoncurve/DragonCurve1.java
index 4784bdb..8aab161 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve1.java
+++ b/src/lessons/recursion/dragoncurve/DragonCurve1.java
@@ -2,11 +2,11 @@ package lessons.recursion.dragoncurve;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class DragonCurve1 extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve1Entity.java b/src/lessons/recursion/dragoncurve/DragonCurve1Entity.java
index a739f25..dd70e91 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve1Entity.java
+++ b/src/lessons/recursion/dragoncurve/DragonCurve1Entity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.dragoncurve;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class DragonCurve1Entity extends Turtle {
 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve1Entity.scala b/src/lessons/recursion/dragoncurve/DragonCurve1Entity.scala
new file mode 100644
index 0000000..d19e7f6
--- /dev/null
+++ b/src/lessons/recursion/dragoncurve/DragonCurve1Entity.scala
@@ -0,0 +1,28 @@
+package lessons.recursion.dragoncurve;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaDragonCurve1Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	def dragon(ordre:Int, x:Double, y:Double, z:Double, t:Double) {
+		/* BEGIN SOLUTION */
+		if (ordre == 1) {
+			setPos(x, y);
+			moveTo(z, t);
+		} else {
+			val u = (x + z + t - y) / 2;
+			val v = (y + t - z + x) / 2;
+			dragon(ordre - 1, x, y, u, v);
+			dragon(ordre - 1, z, t, u, v);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		dragon(getParam(0).asInstanceOf[Int], getParam(1).asInstanceOf[Double], getParam(2).asInstanceOf[Double], 
+		    getParam(3).asInstanceOf[Double], getParam(4).asInstanceOf[Double]);
+	}
+
+}
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve2.fr.html b/src/lessons/recursion/dragoncurve/DragonCurve2.fr.html
index 3aa2415..b6c3db3 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve2.fr.html
+++ b/src/lessons/recursion/dragoncurve/DragonCurve2.fr.html
@@ -20,29 +20,25 @@ exemple de <i>récursivité croisée</i>.
 
 <p>
 Le prototype de la méthode <code>dragon()</code> reste le même que
-précédemment :
-<pre>void dragon(int ordre, double x, double y, double z, double t)</pre>
+précédemment :</p>
+<pre>[!java]void [/!]dragon([!java]int [/!]ordre[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
 
-Les coordonnées (u, v) du nouveau point introduit par la méthode
-<code>dragon()</code> seront :
+<p>Les coordonnées (u, v) du nouveau point introduit par la méthode
+<code>dragon()</code> seront :</p>
 <pre>
 u = (x + z)/2 + (t - y)/2
 v = (y + t)/2 - (z - x)/2
 </pre>
-</p>
 
-<p>
-Le prototype de la méthode <code>dragonInverse()</code> est identique : :
-<pre>void dragonInverse(int ordre, double x, double y, double z, double t)</pre>
+<p>Le prototype de la méthode <code>dragonInverse()</code> est identique : :</p>
+<pre>[!java]void [/!]dragonReverse([!java]int [/!]ordre[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
 
-Les coordonnées (u, v) du nouveau point introduit par la méthode
-<code>dragonInverse()</code> seront :
+<p>Les coordonnées (u, v) du nouveau point introduit par la méthode
+<code>dragonInverse()</code> seront :</p>
 <pre>
 u = (x + z)/2 - (t - y)/2
 v = (y + t)/2 + (z - x)/2
 </pre>
-</p>
-
 
 <p>Afin de rendre, plus visible le travail de chacune des deux méthodes
 récursives, le trait tracé par la méthode <code>dragon()</code> devra être
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve2.html b/src/lessons/recursion/dragoncurve/DragonCurve2.html
index a272d39..8402d2a 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve2.html
+++ b/src/lessons/recursion/dragoncurve/DragonCurve2.html
@@ -1,51 +1,45 @@
-<h2>The dragon curve (2)</h2>
-
-<p>Previous solution induce that the turtle teleports to other location, or at
-the very least, that it moves its pen up during the drawing. Indeed, the end
-of the drawing of the first recursive call does not match the begining of
-the second recursive call. That is why we had to use the method
-<code>setPos()</code></p>	
-
-<p>In this lesson, you will write a recursive method allowing to draw the
-dragon curve without taking the pen up. For that, we need another recursive
-method drawing the mirror side of the curve.</p>
-
-<p>The method <code>dragon()</code> is then recursively defined using itself
-and <code>dragonReverse()</code>. Likewise, the method
-<code>dragonReverse()</code> is defined recursively using itself and
-<code>dragon()</code>. This is thus an example of <i>mutual recursion</i>.
-</p>
-
-<p>
-The prototype of the <code>dragon()</code> method remains unchanged from
-previous exercise:
-<pre>void dragon(int ordre, double x, double y, double z, double t)</pre>
-
-The new point's coordinate (u, v) introduced by the <code>dragon()</code>
-are:
-<pre>
-u = (x + z)/2 + (t - y)/2
-v = (y + t)/2 - (z - x)/2
-</pre>
-</p>
-
-<p>
-The prototype of the method <code>dragonReverse</code> is similar:
-<pre>void dragonReverse(int ordre, double x, double y, double z, double t)</pre>
-
-The new point's coordinate (u, v) introduced by the
-<code>dragonReverse()</code> are:
-<pre>
-u = (x + z)/2 - (t - y)/2
-v = (y + t)/2 + (z - x)/2
-</pre>
-</p>
-
-
-<p>To make the work of each method recursiv more visible, the line painted by
-the <code>dragon()</code> must be red (<code>Color.red</code>) while the
-line painted by the <code>dragonReverse()</code> must be blue
-(<code>Color.blue</code>).</p>
-
-<p>Have a look at each world's objective view to understand how to write the
-function.</p> 
+<h2>The dragon curve (2)</h2>
+
+<p>Previous solution induce that the turtle teleports to other location, or at
+the very least, that it moves its pen up during the drawing. Indeed, the end
+of the drawing of the first recursive call does not match the begining of
+the second recursive call. That is why we had to use the method
+<code>setPos()</code></p>	
+
+<p>In this lesson, you will write a recursive method allowing to draw the
+dragon curve without taking the pen up. For that, we need another recursive
+method drawing the mirror side of the curve.</p>
+
+<p>The method <code>dragon()</code> is then recursively defined using itself
+and <code>dragonReverse()</code>. Likewise, the method
+<code>dragonReverse()</code> is defined recursively using itself and
+<code>dragon()</code>. This is thus an example of <i>mutual recursion</i>.
+</p>
+
+<p>
+The prototype of the <code>dragon()</code> method remains unchanged from
+previous exercise:</p>
+<pre>[!java]void [/!]dragon([!java]int [/!]order[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
+
+<p>The new point's coordinate (u, v) introduced by the <code>dragon()</code> are:</p>
+<pre>
+u = (x + z)/2 + (t - y)/2
+v = (y + t)/2 - (z - x)/2
+</pre>
+
+<p>The prototype of the method <code>dragonReverse</code> is similar:</p>
+<pre>[!java]void [/!]dragonReverse([!java]int [/!]order[!scala]:Int[/!], [!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!], [!java]double [/!]z[!scala]:Double[/!], [!java]double [/!]t[!scala]:Double[/!])</pre>
+
+<p>The new point's coordinate (u, v) introduced by the <code>dragonReverse()</code> are:</p>
+<pre>
+u = (x + z)/2 - (t - y)/2
+v = (y + t)/2 + (z - x)/2
+</pre>
+
+<p>To make the work of each method recursiv more visible, the line painted by
+the <code>dragon()</code> must be red (<code>Color.red</code>) while the
+line painted by the <code>dragonReverse()</code> must be blue
+(<code>Color.blue</code>).</p>
+
+<p>Have a look at each world's objective view to understand how to write the
+function.</p> 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve2.java b/src/lessons/recursion/dragoncurve/DragonCurve2.java
index b08ab4b..d68454f 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve2.java
+++ b/src/lessons/recursion/dragoncurve/DragonCurve2.java
@@ -2,11 +2,11 @@ package lessons.recursion.dragoncurve;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class DragonCurve2 extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve2Entity.java b/src/lessons/recursion/dragoncurve/DragonCurve2Entity.java
index cff32c3..ab46056 100644
--- a/src/lessons/recursion/dragoncurve/DragonCurve2Entity.java
+++ b/src/lessons/recursion/dragoncurve/DragonCurve2Entity.java
@@ -2,7 +2,7 @@ package lessons.recursion.dragoncurve;
 
 import java.awt.Color;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class DragonCurve2Entity extends Turtle {
 
diff --git a/src/lessons/recursion/dragoncurve/DragonCurve2Entity.scala b/src/lessons/recursion/dragoncurve/DragonCurve2Entity.scala
new file mode 100644
index 0000000..2ca350b
--- /dev/null
+++ b/src/lessons/recursion/dragoncurve/DragonCurve2Entity.scala
@@ -0,0 +1,46 @@
+package lessons.recursion.dragoncurve;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaDragonCurve2Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	def dragon(order:Int, x:Double, y:Double, z:Double, t:Double) {
+		/* BEGIN HIDDEN */
+
+		if (order == 1) {
+			setColor(Color.red);
+			moveTo(z, t);
+		} else {
+			val u = (x + z + t - y) / 2;
+			val v = (y + t - z + x) / 2;
+			dragon(order - 1, x, y, u, v);
+			dragonInverse(order - 1, u, v, z, t);
+		}
+		/* END HIDDEN */
+	}
+
+	def dragonInverse(order:Int, x:Double, y:Double, z:Double, t:Double) {
+		/* BEGIN HIDDEN */
+
+		if (order == 1) {
+			setColor(Color.blue);
+			moveTo(z, t);
+		} else {
+			val u = (x + z - t + y) / 2;
+			val v = (y + t + z - x) / 2;
+			dragon(order - 1, x, y, u, v);
+			dragonInverse(order - 1, u, v, z, t);
+		}
+		/* END HIDDEN */
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		dragon(getParam(0).asInstanceOf[Int], getParam(1).asInstanceOf[Double], getParam(2).asInstanceOf[Double], 
+		     getParam(3).asInstanceOf[Double], getParam(4).asInstanceOf[Double]);
+	}
+
+}
diff --git a/src/lessons/recursion/hanoi/HanoiBoard.fr.html b/src/lessons/recursion/hanoi/HanoiBoard.fr.html
index e83db05..459c0d7 100644
--- a/src/lessons/recursion/hanoi/HanoiBoard.fr.html
+++ b/src/lessons/recursion/hanoi/HanoiBoard.fr.html
@@ -19,8 +19,9 @@ déjà être présents sur cette tour.</li>
 
 <h3>Objectif de l'exercice</h3> 
 
-Ecrivez le coeur de la méthode <code>public void solve(int src, int dst, int
-height) throws HanoiInvalidMove</code>. Cette méthode résoudra de manière
+Écrivez le coeur de la méthode <code>[!java]void [/!]solve([!java]int
+[/!]src[!scala]:Int[/!], [!java]int [/!]dst[!scala]:Int[/!], [!java]int
+[/!]height[!scala]:Int[/!])</code>. Cette méthode résoudra de manière
 récursibe le problème. Le premier paramètre, nommé <code>src</code>, est
 l'index de la tour initiale, le second paramètre  <code>dst</code> est
 l'index de la tour final souhaitée, et le troisième paramètre
@@ -39,8 +40,8 @@ large, le plus en bas )</li>
 
 Pour déplacer n disques du poteau A au poteau C : 
 <ul>
-  <li>déplcacer n-1 disques de A vers B. Cela laisse le disque #n seul sur le
+  <li>déplacer n-1 disques de A vers B. Cela laisse le disque numéro n seul sur le
 poteau A</li>
-  <li>déplacer le disque #n de A vers C</li>
-  <li>deplacer n-1 disques de B vers C afin qu'ils reposent sur le disque #n</li>
+  <li>déplacer le disque numéro n de A vers C</li>
+  <li>deplacer n-1 disques de B vers C afin qu'ils reposent sur le disque numéro n</li>
 </ul>
diff --git a/src/lessons/recursion/hanoi/HanoiBoard.html b/src/lessons/recursion/hanoi/HanoiBoard.html
index 79513de..d40a448 100644
--- a/src/lessons/recursion/hanoi/HanoiBoard.html
+++ b/src/lessons/recursion/hanoi/HanoiBoard.html
@@ -1,46 +1,46 @@
-<h2>Tower of Hanoi</h2>
-
-The Tower of Hanoi or Towers of Hanoi , also called the Tower of Brahma or
-Towers of Brahma, is a mathematical game or puzzle. It consists of three rods,
-and a number of disks of different sizes which can slide onto any rod. The
-puzzle starts with the disks in a neat stack in ascending order of size on one
-rod, the smallest at the top, thus forming a pyramid.
-
-The objective of the puzzle is to move the entire stack to another rod, obeying the following rules:
-<ul>
-  <li>Only one disk may be moved at a time.</li>
-
-  <li>Each move consists of taking the upper disk from one of the rods and
-  sliding it onto another rod, on top of the other disks that may already be
-  present on that rod.</li>
-
-  <li>No disk may be placed on top of a smaller disk.</li>
-</ul>
-
-<h3>Goal of this exercise</h3> 
-
-Write the core of the method: 
-<code>public void solve(int src, int dst, int height) throws HanoiInvalidMove</code>
-
-This method will recursively solve the presented problem. First parameter
-named <code>src</code> is the index of the initial tower, second parameter
-<code>dst</code> is the index of the expected final tower, and the third
-parameter <code>height</code> is the height of the tower.
-
-A key to solving this puzzle is to recognize that it can be solved by breaking
-the problem down into a collection of smaller problems and further breaking
-those problems down into even smaller problems until a solution is reached.
-
-The following procedure demonstrates this approach:
-<ul>
-  <li>label the pegs A, B, C (these labels may move at different steps)</li>
-  <li>let n be the total number of discs (the height of the initial tower)</li>
-  <li>number the discs from 1 (smallest, topmost) to n (largest, bottommost)</li>
-</ul>
-
-To move n discs from peg A to peg C:
-<ul>
-  <li>move n−1 discs from A to B. This leaves disc #n alone on peg A</li>
-  <li>move disc #n from A to C</li>
-  <li>move n−1 discs from B to C so they sit on disc #n</li>
-</ul>
+<h2>Tower of Hanoi</h2>
+
+The Tower of Hanoi or Towers of Hanoi , also called the Tower of Brahma or
+Towers of Brahma, is a mathematical game or puzzle. It consists of three rods,
+and a number of disks of different sizes which can slide onto any rod. The
+puzzle starts with the disks in a neat stack in ascending order of size on one
+rod, the smallest at the top, thus forming a pyramid.
+
+The objective of the puzzle is to move the entire stack to another rod, obeying the following rules:
+<ul>
+  <li>Only one disk may be moved at a time.</li>
+
+  <li>Each move consists of taking the upper disk from one of the rods and
+  sliding it onto another rod, on top of the other disks that may already be
+  present on that rod.</li>
+
+  <li>No disk may be placed on top of a smaller disk.</li>
+</ul>
+
+<h3>Goal of this exercise</h3> 
+
+Write the core of the method: 
+<code>[!java]void [/!]solve([!java]int [/!]src[!scala]:Int[/!], [!java]int [/!]dst[!scala]:Int[/!], [!java]int [/!]height[!scala]:Int[/!])</code>
+
+This method will recursively solve the presented problem. First parameter
+named <code>src</code> is the index of the initial tower, second parameter
+<code>dst</code> is the index of the expected final tower, and the third
+parameter <code>height</code> is the height of the tower.
+
+A key to solving this puzzle is to recognize that it can be solved by breaking
+the problem down into a collection of smaller problems and further breaking
+those problems down into even smaller problems until a solution is reached.
+
+The following procedure demonstrates this approach:
+<ul>
+  <li>label the pegs A, B, C (these labels may move at different steps)</li>
+  <li>let n be the total number of discs (the height of the initial tower)</li>
+  <li>number the discs from 1 (smallest, topmost) to n (largest, bottommost)</li>
+</ul>
+
+To move n discs from peg A to peg C:
+<ul>
+  <li>move n−1 discs from A to B. This leaves disc number n alone on peg A</li>
+  <li>move disc number n from A to C</li>
+  <li>move n−1 discs from B to C so they sit on disc number n</li>
+</ul>
diff --git a/src/lessons/recursion/hanoi/HanoiBoard.java b/src/lessons/recursion/hanoi/HanoiBoard.java
index 026c6b2..0cde935 100644
--- a/src/lessons/recursion/hanoi/HanoiBoard.java
+++ b/src/lessons/recursion/hanoi/HanoiBoard.java
@@ -1,7 +1,7 @@
 package lessons.recursion.hanoi;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.recursion.hanoi.universe.HanoiEntity;
 import lessons.recursion.hanoi.universe.HanoiWorld;
 
diff --git a/src/lessons/recursion/hanoi/HanoiBoardEntity.scala b/src/lessons/recursion/hanoi/HanoiBoardEntity.scala
new file mode 100644
index 0000000..d41e22f
--- /dev/null
+++ b/src/lessons/recursion/hanoi/HanoiBoardEntity.scala
@@ -0,0 +1,35 @@
+package lessons.recursion.hanoi;
+
+import lessons.recursion.hanoi.universe.HanoiEntity;
+
+class ScalaHanoiBoardEntity extends HanoiEntity {
+
+	override def run() {
+		solve(getParam(0).asInstanceOf[Int], getParam(1).asInstanceOf[Int]);
+	}
+
+	/* BEGIN TEMPLATE */
+	def solve(src:Int, dst:Int) {
+		solve(src,dst, getSlotSize(src));
+	}
+
+	def solve(src:Int, dst:Int, height:Int) {
+		/* BEGIN SOLUTION */
+		if (height!=0) {
+			var other = -1;
+			if (src+dst==1) /* 0+1 */
+				other=2;
+			if (src+dst==2) /* 0+2 */
+				other=1;
+			if (src+dst==3) /* 1+2 */
+				other=0;
+
+			solve(src,other, height-1);
+			move(src,dst);
+			solve(other,dst,height-1);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/recursion/hanoi/Main.java b/src/lessons/recursion/hanoi/Main.java
index f5a2f11..26c4c68 100644
--- a/src/lessons/recursion/hanoi/Main.java
+++ b/src/lessons/recursion/hanoi/Main.java
@@ -1,6 +1,6 @@
 package lessons.recursion.hanoi;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 	@Override
diff --git a/src/lessons/recursion/hanoi/universe/HanoiEntity.java b/src/lessons/recursion/hanoi/universe/HanoiEntity.java
index 65a6ec6..d1f7119 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiEntity.java
+++ b/src/lessons/recursion/hanoi/universe/HanoiEntity.java
@@ -1,7 +1,7 @@
 package lessons.recursion.hanoi.universe;
 /* BEGIN TEMPLATE */
-import jlm.universe.Entity;
-import jlm.universe.World;
+import plm.universe.Entity;
+import plm.universe.World;
 
 public class HanoiEntity extends Entity {
 	/** Instantiation Constructor (used by exercises to setup the world) 
@@ -29,7 +29,7 @@ public class HanoiEntity extends Entity {
 	}
 
 	/** Must *NOT* call HanoiEntity(name, world) because it's called in a traversal of the world so you don't want to modify it.
-	 * Instead, call HanoiEntity(name), leaving the world field empty; the JLM will fill it with the right value afterward 
+	 * Instead, call HanoiEntity(name), leaving the world field empty; the PLM will fill it with the right value afterward 
 	 */
 	@Override
 	public Entity copy() {
@@ -60,5 +60,10 @@ public class HanoiEntity extends Entity {
 		return "HanoiEntity (" + this.getClass().getName() + ")";
 	}
 	/* END HIDDEN */
+	
+	
+	/* BINDINGS TRANSLATION: French */
+	public void deplace(int src,int dst) { move(src, dst); }
+	public int  getTaillePiquet(int rank) { return getSlotSize(rank); }
 }
 /* END TEMPLATE */
diff --git a/src/lessons/recursion/hanoi/universe/HanoiMovePanel.java b/src/lessons/recursion/hanoi/universe/HanoiMovePanel.java
index 2e29bb3..1a6a399 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiMovePanel.java
+++ b/src/lessons/recursion/hanoi/universe/HanoiMovePanel.java
@@ -9,8 +9,8 @@ import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 
-import jlm.core.model.Game;
-import jlm.universe.EntityControlPanel;
+import plm.core.model.Game;
+import plm.universe.EntityControlPanel;
 
 /**
  * The control panel for the burned pancake world. 
diff --git a/src/lessons/recursion/hanoi/universe/HanoiWorld.fr.html b/src/lessons/recursion/hanoi/universe/HanoiWorld.fr.html
index 9b3561b..438c2b8 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiWorld.fr.html
+++ b/src/lessons/recursion/hanoi/universe/HanoiWorld.fr.html
@@ -10,20 +10,17 @@ disque plus grand sur un disque plus petit.</p>
 
 <p>Seules trois fonctions sont fournies :</p>
 
-<pre class="Java">void move(int src, int dst)</pre>
-<pre class="python">move(src, dst) throws HanoiInvalidMove</pre>
+<pre>[!java]void [/!]deplace([!java]int [/!]src, [!java]int [/!]dst)</pre>
 
 Elle déplace un disque d'un piquet <code>src</code> vers le piquet
 <code>dst</code>. Si vous demandez un déplacement invalide (comme le
 placement d'un disque sur un disque plus petit), une exception
 IllegalArgumentException est levée. 
 
-<pre class="Java">int getSlotSize(int slot);</pre>
-<pre class="python">getSlotSize(slot)</pre>
+<pre>[!java]int [/!]getTaillePiquet([!java]int [/!]slot)[!scala]:Int[/!]</pre>
 Retourne le nombre de disques placés sur un piquet donné. Cette fonction est
 surtout utile pour initialiser la récursion et déterminer le nombre d'appels
 récursifs à réaliser.
 
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
+<pre>[!java]boolean [/!]estChoisie()[!scala]:Boolean[/!]</pre>
 Renvoi si le monde actuel est sélectionné dans l'interface graphique.
diff --git a/src/lessons/recursion/hanoi/universe/HanoiWorld.html b/src/lessons/recursion/hanoi/universe/HanoiWorld.html
index 0130c96..c796b07 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiWorld.html
+++ b/src/lessons/recursion/hanoi/universe/HanoiWorld.html
@@ -1,27 +1,24 @@
-<h1>HanoiWorld</h1>
-
-<p>
-This world implements the ultra-classical Hanoi problem. You are asked
-to move the disk pile from the stick where they are to the target
-stick (given as second parameter in the world's name -- number 1 for
-the default world). There is some extra constraint: you can only move
-one disk at a time, and you cannot move a big disk over a smaller
-one.</p>
-
-<p>Only 3 functions are provided:</p>
-
-<pre class="Java">void move(int src, int dst)</pre>
-<pre class="python">move(src, dst) throws HanoiInvalidMove</pre>
-
-Moves one disk from the stick <code>src</code> onto the stick
-<code>dst</code>. If you try to do an invalid move (like laying a disk
-over a smaller one), an IllegalArgumentException is thrown. 
-
-<pre class="Java">int getSlotSize(int slot);</pre>
-<pre class="python">getSlotSize(slot)</pre>
-Returns the amount of disks placed on the specified slot. This is mainly 
-used to initialize the recursion and set the amount of recursive call to execute.
-
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
-Returns whether the current world is selected in the graphical interface.
+<h1>HanoiWorld</h1>
+
+<p>
+This world implements the ultra-classical Hanoi problem. You are asked
+to move the disk pile from the stick where they are to the target
+stick (given as second parameter in the world's name -- number 1 for
+the default world). There is some extra constraint: you can only move
+one disk at a time, and you cannot move a big disk over a smaller
+one.</p>
+
+<p>Only 3 functions are provided:</p>
+
+<pre>[!java]void [/!]move([!java]int [/!]src, [!java]int [/!]dst)</pre>
+
+Moves one disk from the stick <code>src</code> onto the stick
+<code>dst</code>. If you try to do an invalid move (like laying a disk
+over a smaller one), an IllegalArgumentException is thrown. 
+
+<pre>[!java]int [/!]getSlotSize([!java]int [/!]slot)[!scala]:Int[/!]</pre>
+Returns the amount of disks placed on the specified slot. This is mainly 
+used to initialize the recursion and set the amount of recursive call to execute.
+
+<pre>[!java]boolean [/!]isSelected()[!scala]:Boolean[/!]</pre>
+Returns whether the current world is selected in the graphical interface.
diff --git a/src/lessons/recursion/hanoi/universe/HanoiWorld.java b/src/lessons/recursion/hanoi/universe/HanoiWorld.java
index 85cf289..6bfa137 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiWorld.java
+++ b/src/lessons/recursion/hanoi/universe/HanoiWorld.java
@@ -6,12 +6,12 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 import javax.swing.ImageIcon;
 
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
 
 /* BEGIN TEMPLATE */
 public class HanoiWorld extends World {	
@@ -49,7 +49,7 @@ public class HanoiWorld extends World {
 	
 	/** Reset the state of the current world to the one passed in argument
 	 * 
-	 * This is mandatory for the JLM good working. Even if the prototype says that the passed object can be 
+	 * This is mandatory for the PLM good working. Even if the prototype says that the passed object can be 
 	 * any kind of world, you can be sure that it's of the same type than the current world. So, there is 
 	 * no need to check before casting your argument.
 	 * 
@@ -154,6 +154,11 @@ public class HanoiWorld extends World {
 			e.eval( "def move(src,dst):\n"+
 					"  entity.move(src,dst)\n"+
 					"def getSlotSize(slot):\n"+
+					"  return entity.getSlotSize(slot)\n"+
+					/* BINDINGS TRANSLATION: French */
+					"def deplace(src,dst):\n"+
+					"  entity.move(src,dst)\n"+
+					"def getTaillePiquet(slot):\n"+
 					"  return entity.getSlotSize(slot)\n");
 		} else {
 			throw new RuntimeException("No binding of HanoiWorld for "+lang);
diff --git a/src/lessons/recursion/hanoi/universe/HanoiWorldView.java b/src/lessons/recursion/hanoi/universe/HanoiWorldView.java
index e66f0aa..00ae3cb 100644
--- a/src/lessons/recursion/hanoi/universe/HanoiWorldView.java
+++ b/src/lessons/recursion/hanoi/universe/HanoiWorldView.java
@@ -6,8 +6,8 @@ import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.geom.Rectangle2D;
 
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
+import plm.core.ui.WorldView;
+import plm.universe.World;
 
 public class HanoiWorldView extends WorldView {
 	private static final long serialVersionUID = 1L;
diff --git a/src/lessons/recursion/koch/Koch.fr.html b/src/lessons/recursion/koch/Koch.fr.html
index 8eb69ec..9415271 100644
--- a/src/lessons/recursion/koch/Koch.fr.html
+++ b/src/lessons/recursion/koch/Koch.fr.html
@@ -7,14 +7,14 @@ reproduit à n'importe quelle échelle.
 <p>La forme générale est un triangle dont chaque coté est donné par une série
 d'appels récursifs.  La forme générale est obtenue en enchainant trois cotés
 de la façon suivante.
-<pre>void snowFlake (int levels, double length) {
-   snowSide(levels, length);
-   turnRight(120);
-   snowSide(levels, length);
-   turnRight(120);
-   snowSide(levels, length);
-   turnRight(120);
-}</pre>
+<pre>[!java]void [/!]snowFlake ([!java]int [/!]niveaux[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!])[!python]:[/!][!java|scala] {[/!]
+   snowSide(niveaux, longueur);
+   right(120);
+   snowSide(niveaux, longueur);
+   right(120);
+   snowSide(niveaux, longueur);
+   right(120);
+[!java|scala]}[/!]</pre>
 
 <p>Observez le dessin dans chaque monde objectif pour comprendre la logique de
 ce motif afin de la reproduire.  Vous devez écrire la fonction snowSide, qui
diff --git a/src/lessons/recursion/koch/Koch.html b/src/lessons/recursion/koch/Koch.html
index 1553477..8b2cf7c 100644
--- a/src/lessons/recursion/koch/Koch.html
+++ b/src/lessons/recursion/koch/Koch.html
@@ -1,19 +1,19 @@
-<h2>Snow flake</h2>
-
-We will now draw snow flakes using the Koch fractal. A fractal is a
-geometrical pattern repeated at every scale.
-
-<p>The general form is a triangle, with each side given by a serie of recursive
-calls. The general form is given by something like this:
-<pre>void snowFlake (int levels, double length) {
-   snowSide(levels, length);
-   turnRight(120);
-   snowSide(levels, length);
-   turnRight(120);
-   snowSide(levels, length);
-   turnRight(120);
-}</pre>
-
-<p>Observe the drawing in each world's objective to understand the pattern's
-logic, and then reproduce it. You must write the <code>snowSide()</code>
-method, which is recursive.
+<h2>Snow flake</h2>
+
+We will now draw snow flakes using the Koch fractal. A fractal is a
+geometrical pattern repeated at every scale.
+
+<p>The general form is a triangle, with each side given by a serie of recursive
+calls. The general form is given by something like this:
+<pre>[!java]void [/!]snowFlake ([!java]int [/!]levels[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!])[!python]:[/!][!java|scala] {[/!]
+   snowSide(levels, length);
+   right(120);
+   snowSide(levels, length);
+   right(120);
+   snowSide(levels, length);
+   right(120);
+[!java|scala]}[/!]</pre>
+
+<p>Observe the drawing in each world's objective to understand the pattern's
+logic, and then reproduce it. You must write the <code>snowSide()</code>
+method, which is recursive.
diff --git a/src/lessons/recursion/koch/Koch.java b/src/lessons/recursion/koch/Koch.java
index a58ca80..b296d48 100644
--- a/src/lessons/recursion/koch/Koch.java
+++ b/src/lessons/recursion/koch/Koch.java
@@ -2,11 +2,11 @@ package lessons.recursion.koch;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Koch extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/koch/KochEntity.java b/src/lessons/recursion/koch/KochEntity.java
index 8763a5b..f354ed0 100644
--- a/src/lessons/recursion/koch/KochEntity.java
+++ b/src/lessons/recursion/koch/KochEntity.java
@@ -1,17 +1,17 @@
 package lessons.recursion.koch;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class KochEntity extends Turtle {
 
 	/* BEGIN TEMPLATE */
 	void snowFlake (int levels, double length) {
 		snowSide(levels, length);
-		turnRight(120);
+		right(120);
 		snowSide(levels, length);
-		turnRight(120);
+		right(120);
 		snowSide(levels, length);
-		turnRight(120);
+		right(120);
 	}
 	void snowSide(int levels, double length) {
 		/* BEGIN SOLUTION */
@@ -19,11 +19,11 @@ public class KochEntity extends Turtle {
 			forward(length);
 		} else {
 			snowSide(levels-1, length/3);
-			turnLeft(60);
+			left(60);
 			snowSide(levels-1, length/3);
-			turnRight(120);
+			right(120);
 			snowSide(levels-1, length/3);
-			turnLeft(60);
+			left(60);
 			snowSide(levels-1, length/3);
 		}
 		/* END SOLUTION */	
diff --git a/src/lessons/recursion/koch/KochEntity.py b/src/lessons/recursion/koch/KochEntity.py
index 0a283ab..844b8bd 100644
--- a/src/lessons/recursion/koch/KochEntity.py
+++ b/src/lessons/recursion/koch/KochEntity.py
@@ -6,21 +6,21 @@ def snowSide(levels, length):
 			forward(length)
 		else:
 			snowSide(levels-1, length/3)
-			turnLeft(60)
+			left(60)
 			snowSide(levels-1, length/3)
-			turnRight(120)
+			right(120)
 			snowSide(levels-1, length/3)
-			turnLeft(60)
+			left(60)
 			snowSide(levels-1, length/3)
 		# END SOLUTION	
 
 def snowFlake (levels, length):
 	snowSide(levels, length)
-	turnRight(120)
+	right(120)
 	snowSide(levels, length)
-	turnRight(120)
+	right(120)
 	snowSide(levels, length)
-	turnRight(120)
+	right(120)
 # END TEMPLATE
 
 snowFlake(getParam(0), getParam(1))
diff --git a/src/lessons/recursion/koch/KochEntity.scala b/src/lessons/recursion/koch/KochEntity.scala
new file mode 100644
index 0000000..2ffb3f3
--- /dev/null
+++ b/src/lessons/recursion/koch/KochEntity.scala
@@ -0,0 +1,36 @@
+package lessons.recursion.koch;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaKochEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	def snowFlake (levels:Int, length:Double) {
+		snowSide(levels, length);
+		right(120);
+		snowSide(levels, length);
+		right(120);
+		snowSide(levels, length);
+		right(120);
+	}
+	def snowSide(levels:Int, length:Double) {
+		/* BEGIN SOLUTION */
+		if (levels == 0) {
+			forward(length);
+		} else {
+			snowSide(levels-1, length/3);
+			left(60);
+			snowSide(levels-1, length/3);
+			right(120);
+			snowSide(levels-1, length/3);
+			left(60);
+			snowSide(levels-1, length/3);
+		}
+		/* END SOLUTION */	
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		snowFlake(getParam(0).asInstanceOf[Int],getParam(1).asInstanceOf[Double]);
+	}
+}
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractal.fr.html b/src/lessons/recursion/polygonfractal/PolygonFractal.fr.html
index 62899ce..6d833f2 100644
--- a/src/lessons/recursion/polygonfractal/PolygonFractal.fr.html
+++ b/src/lessons/recursion/polygonfractal/PolygonFractal.fr.html
@@ -3,7 +3,7 @@
 La fractale que nous allons dessiner maintenant est formée d'un polygone
 auquel sont ajoutés des petits polygones sur chaque angle. Le prototype de
 la fonction le traçant est le suivant:
-<pre>void polygonFractal (int levels, int sides, double length, double shrink)</pre>
+<pre>[!java]void [/!]polygonFractal ([!java]int [/!]niveaux[!scala]:Int[/!], [!java]int [/!]cotés[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!], [!java]double [/!]multiplicateur[!scala]:Double[/!])</pre>
 
 <p>Consultez les objectifs de chaque monde pour comprendre comment écrire la
 fonction. 
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractal.html b/src/lessons/recursion/polygonfractal/PolygonFractal.html
index 1c9fe09..3928835 100644
--- a/src/lessons/recursion/polygonfractal/PolygonFractal.html
+++ b/src/lessons/recursion/polygonfractal/PolygonFractal.html
@@ -1,8 +1,8 @@
-<h2>Fractal of polygons</h2>
-
-The fractal we will now draw is formed of a polygon, with little polygons on
-each corner. The prototype of the method drawing it is the following:
-<pre>void polygonFractal (int levels, int sides, double length, double shrink)</pre>
-
-<p>Have a look at each world's objective view to understand how to write the
-function. 
+<h2>Fractal of polygons</h2>
+
+The fractal we will now draw is formed of a polygon, with little polygons on
+each corner. The prototype of the method drawing it is the following:
+<pre>[!java]void [/!]polygonFractal ([!java]int [/!]levels[!scala]:Int[/!], [!java]int [/!]sides[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!], [!java]double [/!]shrink[!scala]:Double[/!])</pre>
+
+<p>Have a look at each world's objective view to understand how to write the
+function. 
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractal.java b/src/lessons/recursion/polygonfractal/PolygonFractal.java
index 21b07ea..cab3c00 100644
--- a/src/lessons/recursion/polygonfractal/PolygonFractal.java
+++ b/src/lessons/recursion/polygonfractal/PolygonFractal.java
@@ -2,11 +2,11 @@ package lessons.recursion.polygonfractal;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class PolygonFractal extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractalEntity.java b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.java
index 22ee73c..ea9f9fe 100644
--- a/src/lessons/recursion/polygonfractal/PolygonFractalEntity.java
+++ b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.polygonfractal;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class PolygonFractalEntity extends Turtle {
 
@@ -13,10 +13,10 @@ public class PolygonFractalEntity extends Turtle {
 			for (int i=0;i<sides;i++) {
 				forward(length);
 
-				turnLeft((sides-2)*360/(sides*2));
+				left((sides-2)*360/(sides*2));
 				polygonFractal(levels-1, sides, length*shrink,shrink);
-				turnRight((sides-2)*360/(sides*2));
-				turnRight(360/sides);
+				right((sides-2)*360/(sides*2));
+				right(360/sides);
 
 			}
 		}
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractalEntity.py b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.py
index 81b5700..24e4e43 100644
--- a/src/lessons/recursion/polygonfractal/PolygonFractalEntity.py
+++ b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.py
@@ -7,10 +7,10 @@ def polygonFractal (levels, sides, length, shrink):
       for i in range(sides):
         forward(length)
         
-        turnLeft((sides-2)*360/(sides*2))
+        left((sides-2)*360/(sides*2))
         polygonFractal(levels-1, sides, length*shrink,shrink)
-        turnRight((sides-2)*360/(sides*2))
-        turnRight(360/sides)
+        right((sides-2)*360/(sides*2))
+        right(360/sides)
     # END SOLUTION
 # END TEMPLATE 
 
diff --git a/src/lessons/recursion/polygonfractal/PolygonFractalEntity.scala b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.scala
new file mode 100644
index 0000000..22a2c31
--- /dev/null
+++ b/src/lessons/recursion/polygonfractal/PolygonFractalEntity.scala
@@ -0,0 +1,31 @@
+package lessons.recursion.polygonfractal;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaPolygonFractalEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	def polygonFractal (levels:Int, sides:Int, length:Double, shrink:Double) {
+		/* BEGIN SOLUTION */
+		if (levels == 0) {
+			/* do nothing */
+		} else {
+			for (i <- 1 to sides) {
+				forward(length);
+
+				left((sides-2)*360/(sides*2));
+				polygonFractal(levels-1, sides, length*shrink,shrink);
+				right((sides-2)*360/(sides*2));
+				right(360/sides);
+
+			}
+		}
+		/* END SOLUTION */	
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		polygonFractal(getParam(0).asInstanceOf[Int],getParam(1).asInstanceOf[Int],
+		    getParam(2).asInstanceOf[Double],getParam(3).asInstanceOf[Double]);
+	}
+}
diff --git a/src/lessons/recursion/sierpinski/Sierpinski.fr.html b/src/lessons/recursion/sierpinski/Sierpinski.fr.html
index 0399cae..dfac920 100644
--- a/src/lessons/recursion/sierpinski/Sierpinski.fr.html
+++ b/src/lessons/recursion/sierpinski/Sierpinski.fr.html
@@ -1,9 +1,9 @@
 <h2>Triangle de Sierpinski</h2>
 
-La fractale que nous allons dessiner maintenant est formée d'un triangle
+<p>La fractale que nous allons dessiner maintenant est formée d'un triangle
 dans lequel sont imbriqués des triangles plus petits.  Le prototype de la
-fonction le traçant est le suivant :
-<pre>void sierpinski(int level, double length)</pre>
+fonction le traçant est le suivant :</p>
+<pre>[!java]void [/!]sierpinski([!java]int [/!]niveau[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!])</pre>
 
 <p>Consultez les objectifs de chaque monde pour comprendre comment écrire la
-fonction. 
+fonction.</p> 
diff --git a/src/lessons/recursion/sierpinski/Sierpinski.html b/src/lessons/recursion/sierpinski/Sierpinski.html
index b4fd0ae..4ef21b3 100644
--- a/src/lessons/recursion/sierpinski/Sierpinski.html
+++ b/src/lessons/recursion/sierpinski/Sierpinski.html
@@ -1,9 +1,9 @@
-<h2>Sierpinski's Triangle</h2>
-
-The fractal we will now draw is formed of a big triangle inside which
-several smaller triangles are embeeded. The prototype of the fuction to draw
-it is the following:
-<pre>void sierpinski(int level, double length)</pre>
-
-<p>Have a look at each world's objective view to understand how to write the
-function. 
+<h2>Sierpinski's Triangle</h2>
+
+<p>The fractal we will now draw is formed of a big triangle inside which
+several smaller triangles are embeeded. The prototype of the fuction to draw
+it is the following:</p>
+<pre>[!java]void [/!]sierpinski([!java]int [/!]level[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!])</pre>
+
+<p>Have a look at each world's objective view to understand how to write the
+function.</p> 
diff --git a/src/lessons/recursion/sierpinski/Sierpinski.java b/src/lessons/recursion/sierpinski/Sierpinski.java
index 58836c0..a26d68c 100644
--- a/src/lessons/recursion/sierpinski/Sierpinski.java
+++ b/src/lessons/recursion/sierpinski/Sierpinski.java
@@ -2,11 +2,11 @@ package lessons.recursion.sierpinski;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Sierpinski extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/sierpinski/SierpinskiEntity.java b/src/lessons/recursion/sierpinski/SierpinskiEntity.java
index a919ded..0d53127 100644
--- a/src/lessons/recursion/sierpinski/SierpinskiEntity.java
+++ b/src/lessons/recursion/sierpinski/SierpinskiEntity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.sierpinski;
 
-public class SierpinskiEntity extends jlm.universe.turtles.Turtle {
+public class SierpinskiEntity extends plm.universe.turtles.Turtle {
 
 	/* BEGIN TEMPLATE */
 	public void sierpinski(int level, double length) {
@@ -8,11 +8,11 @@ public class SierpinskiEntity extends jlm.universe.turtles.Turtle {
 		if (level >= 0) {
 			for (int i = 0; i < 3; i++) {
 				forward(length / 2.);
-				turnRight(360. / 3.);
+				right(360. / 3.);
 				sierpinski(level-1, length / 2.);
-				turnLeft(360. / 3.);
+				left(360. / 3.);
 				forward(length / 2.);
-				turnRight(360. / 3.);
+				right(360. / 3.);
 			}
 		}
 		/* END SOLUTION */
diff --git a/src/lessons/recursion/sierpinski/SierpinskiEntity.py b/src/lessons/recursion/sierpinski/SierpinskiEntity.py
index 655af4a..1ad9d5f 100644
--- a/src/lessons/recursion/sierpinski/SierpinskiEntity.py
+++ b/src/lessons/recursion/sierpinski/SierpinskiEntity.py
@@ -4,11 +4,11 @@ def sierpinski(level, length):
     if (level >= 0):
       for i in range(3):
         forward(length / 2.)
-        turnRight(360. / 3.)
+        right(360. / 3.)
         sierpinski(level-1, length / 2.)
-        turnLeft(360. / 3.)
+        left(360. / 3.)
         forward(length / 2.)
-        turnRight(360. / 3.)
+        right(360. / 3.)
     # END SOLUTION
 # END TEMPLATE
 sierpinski(getParam(0), getParam(1))
diff --git a/src/lessons/recursion/sierpinski/SierpinskiEntity.scala b/src/lessons/recursion/sierpinski/SierpinskiEntity.scala
new file mode 100644
index 0000000..f67c442
--- /dev/null
+++ b/src/lessons/recursion/sierpinski/SierpinskiEntity.scala
@@ -0,0 +1,26 @@
+package lessons.recursion.sierpinski;
+
+class ScalaSierpinskiEntity extends plm.universe.turtles.Turtle {
+
+	/* BEGIN TEMPLATE */
+	def sierpinski(level:Int, length:Double) {
+		/* BEGIN SOLUTION */
+		if (level >= 0) {
+			for (i <- 1 to 3) {
+				forward(length / 2.);
+				right(360. / 3.);
+				sierpinski(level-1, length / 2.);
+				left(360. / 3.);
+				forward(length / 2.);
+				right(360. / 3.);
+			}
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		sierpinski(getParam(0).asInstanceOf[Int], getParam(1).asInstanceOf[Double]);
+	}
+
+}
diff --git a/src/lessons/recursion/spiral/Spiral.fr.html b/src/lessons/recursion/spiral/Spiral.fr.html
index f851276..bc30c0a 100644
--- a/src/lessons/recursion/spiral/Spiral.fr.html
+++ b/src/lessons/recursion/spiral/Spiral.fr.html
@@ -3,26 +3,26 @@
 Nous allons maintenant écrire notre première fonction récursive avec les
 tortues. L'objectif est de dessiner des spirales de différentes formes avec
 la même fonction, dont le prototype est le suivant: 
-<pre>void spiral(int steps, int angle, int length, int increment)</pre>
+<pre>[!java]void [/!]spiral([!java]int [/!]nbPas[!scala]:Int[/!], [!java]int [/!]angle[!scala]:Int[/!], [!java]int [/!]longueur[!scala]:Int[/!], [!java]int [/!]increment[!scala]:Int[/!])</pre>
 
 Pour vous aider à comprendre comment l'écrire, voici un exemple de la suite
 des différentes valeurs prises par les paramètres dans un cas:
 <pre>
 spiral(5, 90, 0, 3);
-  forward(0);
-  turnLeft(90);
+  avance(0);
+  gauche(90);
   spiral(4,90,3,3);
-    forward(3);
-    turnLeft(90);
+    avance(3);
+    gauche(90);
     spiral(3,90,6,3);
-      forward(6);
-      turnLeft(90);
+      avance(6);
+      gauche(90);
       spiral(2,90,9,3);
-        forward(9);
-        turnLeft(90);
+        avance(9);
+        gauche(90);
         spiral(1,90,12,3);
-          forward(12);
-          turnLeft(90);
+          avance(12);
+          gauche(90);
           spiral(0,90,12,3);
 </pre>
 
diff --git a/src/lessons/recursion/spiral/Spiral.html b/src/lessons/recursion/spiral/Spiral.html
index bdfa69c..2a16a68 100644
--- a/src/lessons/recursion/spiral/Spiral.html
+++ b/src/lessons/recursion/spiral/Spiral.html
@@ -1,29 +1,29 @@
-<h2>Spirals</h2>
-
-We will now draw our first recursive function with the turtle. The goal is
-to draw different kind of spirals with the same function, which prototype is
-the following: 
-<pre>void spiral(int steps, int angle, int length, int increment)</pre>
-
-To help you understanding how to write it, here is an example of how the
-parameters change during one specific call:
-<pre>
-spiral(5, 90, 0, 3);
-  forward(0);
-  turnLeft(90);
-  spiral(4,90,3,3);
-    forward(3);
-    turnLeft(90);
-    spiral(3,90,6,3);
-      forward(6);
-      turnLeft(90);
-      spiral(2,90,9,3);
-        forward(9);
-        turnLeft(90);
-        spiral(1,90,12,3);
-          forward(12);
-          turnLeft(90);
-          spiral(0,90,12,3);
-</pre>
-
-
+<h2>Spirals</h2>
+
+We will now draw our first recursive function with the turtle. The goal is
+to draw different kind of spirals with the same function, which prototype is
+the following: 
+<pre>[!java]void [/!]spiral([!java]int [/!]steps[!scala]:Int[/!], [!java]int [/!]angle[!scala]:Int[/!], [!java]int [/!]length[!scala]:Int[/!], [!java]int [/!]increment[!scala]:Int[/!])</pre>
+
+To help you understanding how to write it, here is an example of how the
+parameters change during one specific call:
+<pre>
+spiral(5, 90, 0, 3);
+  forward(0);
+  left(90);
+  spiral(4,90,3,3);
+    forward(3);
+    left(90);
+    spiral(3,90,6,3);
+      forward(6);
+      left(90);
+      spiral(2,90,9,3);
+        forward(9);
+        left(90);
+        spiral(1,90,12,3);
+          forward(12);
+          left(90);
+          spiral(0,90,12,3);
+</pre>
+
+
diff --git a/src/lessons/recursion/spiral/Spiral.java b/src/lessons/recursion/spiral/Spiral.java
index d7ec06b..71272a1 100644
--- a/src/lessons/recursion/spiral/Spiral.java
+++ b/src/lessons/recursion/spiral/Spiral.java
@@ -1,10 +1,10 @@
 package lessons.recursion.spiral;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Spiral extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/spiral/SpiralEntity.java b/src/lessons/recursion/spiral/SpiralEntity.java
index b42d2b3..dd5780c 100644
--- a/src/lessons/recursion/spiral/SpiralEntity.java
+++ b/src/lessons/recursion/spiral/SpiralEntity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.spiral;
 
-public class SpiralEntity extends jlm.universe.turtles.Turtle {
+public class SpiralEntity extends plm.universe.turtles.Turtle {
 
 	/* BEGIN TEMPLATE */
 	public void spiral(int steps, int angle, int length, int increment)	{
@@ -9,7 +9,7 @@ public class SpiralEntity extends jlm.universe.turtles.Turtle {
 			// do nothing
 		} else {
 			forward(length);
-			turnLeft(angle);
+			left(angle);
 			spiral(steps-1, angle, length+increment, increment);
 		}
 		/* END SOLUTION */	
diff --git a/src/lessons/recursion/spiral/SpiralEntity.py b/src/lessons/recursion/spiral/SpiralEntity.py
index 0641043..59e9a5d 100644
--- a/src/lessons/recursion/spiral/SpiralEntity.py
+++ b/src/lessons/recursion/spiral/SpiralEntity.py
@@ -5,7 +5,7 @@ def spiral(steps, angle, length, increment):
     pass# do nothing
   else:
     forward(length)
-    turnLeft(angle)
+    left(angle)
     spiral(steps-1, angle, length+increment, increment)
   # END SOLUTION
 # END TEMPLATE
diff --git a/src/lessons/recursion/spiral/SpiralEntity.scala b/src/lessons/recursion/spiral/SpiralEntity.scala
new file mode 100644
index 0000000..c9c3863
--- /dev/null
+++ b/src/lessons/recursion/spiral/SpiralEntity.scala
@@ -0,0 +1,23 @@
+package lessons.recursion.spiral;
+
+class ScalaSpiralEntity extends plm.universe.turtles.Turtle {
+
+	/* BEGIN TEMPLATE */
+	def spiral(steps:Int, angle:Int, length:Int, increment:Int)	{
+		/* BEGIN SOLUTION */
+		if (steps <= 0) {
+			// do nothing
+		} else {
+			forward(length);
+			left(angle);
+			spiral(steps-1, angle, length+increment, increment);
+		}
+		/* END SOLUTION */	
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		spiral(getParam(0).asInstanceOf[Int],getParam(1).asInstanceOf[Int],
+		    getParam(2).asInstanceOf[Int],getParam(3).asInstanceOf[Int]);
+	}
+}
diff --git a/src/lessons/recursion/spiral/SpiralUse.fr.html b/src/lessons/recursion/spiral/SpiralUse.fr.html
index fe7e282..03538ab 100644
--- a/src/lessons/recursion/spiral/SpiralUse.fr.html
+++ b/src/lessons/recursion/spiral/SpiralUse.fr.html
@@ -3,32 +3,31 @@
 Saurez-vous faire les différents motifs de cet exercice en utilisant la
 méthode <code>spiral()</code>?
 
-<p>Vous devez écrire une méthode <code>doit(int)</code> qui prend en paramètre
+<p>Vous devez écrire une méthode <code>doit(page)</code> qui prend en paramètre
 le numéro de la page à dessiner. Son code est de la forme suivante. A0, B0,
 etc sont des nombres entiers. L'objectif de l'exercice est de retrouver les
 valeurs convenables pour chaque page.</p>
 
 <pre>
-void doit(int page) {
-  switch (page) {
-    case 0: /* Dessin de la première page, marquée "One" */
+[!java]void [/!]doit([!java]int [/!]page[!scala]:Int[/!])[!python]:[/!][!java|scala] {[/!]
+  [!java]switch (page) {[/!][!scala]page match {[/!][!python]  # Choix en fonction de la valeur de page[/!]
+    [!java]case 0:[/!][!scala]case 0 =>[/!][!python]if page==0:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Dessin sur la première page, nommée "One"</span>
       spiral(A0,B0,C0,D0);
-      break;
-    case 1: /* Dessin de la seconde page, marquée "Two" */
+[!java]      break;[/!]
+    [!java]case 1:[/!][!scala]case 1 =>[/!][!python]if page==1:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Dessin sur la seconde page, nommée "Two"</span>
       spiral(A1,B1,C1,D1);
-      break;
-    case 2: /* Dessin de la page marquée "Three" */
+[!java]      break;[/!]
+    [!java]case 2:[/!][!scala]case 2 =>[/!][!python]if page==2:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Dessin sur la troisième page, nommée "Three"</span> 
       spiral(A2,B2,C2,D2);
-      break;
-    case 3: /* Dessin de la page marquée "Four" */
+[!java]      break;[/!]
+    [!java]case 3:[/!][!scala]case 3 =>[/!][!python]if page==3:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Dessin sur la quatrième page, nommée "Four"</span> 
       spiral(A3,B3,C3,D3);
-      break;
-    case 4: /* Dessin de la page marquée "Five" */
-      spiral(A4,B4,C4,D4);
-      break;
+[!java]      break;[/!]
+    [!java]case 4:[/!][!scala]case 4 =>[/!][!python]if page==4:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Dessin sur la cinquième page, nommée "Five"</span>
+      spiral(A4,B4,C4,D4);[!java|scala]
+[!java]      break;[/!]
   }
-}
-</pre>
+}[/!]</pre>
 
 
 <p>Pas besoin de recopier le code de <code>spiral()</code>, la tortue de cet
diff --git a/src/lessons/recursion/spiral/SpiralUse.html b/src/lessons/recursion/spiral/SpiralUse.html
index d9e05c0..c57caf1 100644
--- a/src/lessons/recursion/spiral/SpiralUse.html
+++ b/src/lessons/recursion/spiral/SpiralUse.html
@@ -1,35 +1,34 @@
-<h2>Drawing spirals</h2>
-
-Can you reproduce the provided patterns of this exercise using the
-<code>spiral()</code> method?
-
-<p>You must provide a method called <code>doit(int)</code> taking the number of
-the page to draw as parameter. Its code is as following, with A0, B0, etc
-being integers. The goal of this exercise is to find the good values for
-each page.</p>
-
-<pre>
-void doit(int page) {
-  switch (page) {
-    case 0: /* Drawing of the first page, dubbed "One" */
-      spiral(A0,B0,C0,D0);
-      break;
-    case 1: /* Drawing of the second page, dubbed "Two" */
-      spiral(A1,B1,C1,D1);
-      break;
-    case 2: /* Drawing of the page dubbed "Three" */
-      spiral(A2,B2,C2,D2);
-      break;
-    case 3: /* Drawing of the page dubbed "Four" */
-      spiral(A3,B3,C3,D3);
-      break;
-    case 4: /* Drawing of the page dubbed "Five" */
-      spiral(A4,B4,C4,D4);
-      break;
-  }
-}
-</pre>
-
-
-<p>No need to copy over the method of <code>spiral()</code>, the turtle of this
-exercise already knows it.</p>
+<h2>Drawing spirals</h2>
+
+Can you reproduce the provided patterns of this exercise using the
+<code>spiral()</code> method?
+
+<p>You must provide a method called <code>doit(page)</code> taking the page number 
+to draw as parameter. Its code is as following, with A0, B0, etc being integers. 
+The goal of this exercise is to find the good values for each page, which requires to
+correctly understand how the spiral method works.</p>
+
+<pre>
+[!java]void [/!]doit([!java]int [/!]page[!scala]:Int[/!])[!python]:[/!][!java|scala] {[/!]
+  [!java]switch (page) {[/!][!scala]page match {[/!][!python]  # select on the value of page[/!]
+    [!java]case 0:[/!][!scala]case 0 =>[/!][!python]if page==0:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Drawing of the first page, dubbed "One"</span>
+      spiral(A0,B0,C0,D0);
+[!java]      break;[/!]
+    [!java]case 1:[/!][!scala]case 1 =>[/!][!python]if page==1:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Drawing of the second page, dubbed "Two"</span>
+      spiral(A1,B1,C1,D1);
+[!java]      break;[/!]
+    [!java]case 2:[/!][!scala]case 2 =>[/!][!python]if page==2:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed "Three"</span> 
+      spiral(A2,B2,C2,D2);
+[!java]      break;[/!]
+    [!java]case 3:[/!][!scala]case 3 =>[/!][!python]if page==3:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed "Four"</span> 
+      spiral(A3,B3,C3,D3);
+[!java]      break;[/!]
+    [!java]case 4:[/!][!scala]case 4 =>[/!][!python]if page==4:[/!] <span class="Comment">[!java|scala]//[/!][!python]#[/!] Drawing of the page dubbed "Five"</span>
+      spiral(A4,B4,C4,D4);[!java|scala]
+[!java]      break;[/!]
+  }
+}[/!]</pre>
+
+
+<p>No need to copy over the method of <code>spiral()</code>, the turtle of this
+exercise already knows it.</p>
diff --git a/src/lessons/recursion/spiral/SpiralUse.java b/src/lessons/recursion/spiral/SpiralUse.java
index 7e36695..8d7d4a9 100644
--- a/src/lessons/recursion/spiral/SpiralUse.java
+++ b/src/lessons/recursion/spiral/SpiralUse.java
@@ -1,10 +1,10 @@
 package lessons.recursion.spiral;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class SpiralUse extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/spiral/SpiralUseEntity.java b/src/lessons/recursion/spiral/SpiralUseEntity.java
index 1125ce6..9bf5fc0 100644
--- a/src/lessons/recursion/spiral/SpiralUseEntity.java
+++ b/src/lessons/recursion/spiral/SpiralUseEntity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.spiral;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class SpiralUseEntity extends Turtle {
 
@@ -9,7 +9,7 @@ public class SpiralUseEntity extends Turtle {
 			return;
 		} else {
 			forward(length);
-			turnLeft(angle);
+			left(angle);
 			spiral(steps-1, angle, length+increment, increment);
 		}
 	}
diff --git a/src/lessons/recursion/spiral/SpiralUseEntity.py b/src/lessons/recursion/spiral/SpiralUseEntity.py
index 723557c..c9f60c8 100644
--- a/src/lessons/recursion/spiral/SpiralUseEntity.py
+++ b/src/lessons/recursion/spiral/SpiralUseEntity.py
@@ -3,7 +3,7 @@ def spiral(steps, angle, length, increment):
     pass
   else:
     forward(length)
-    turnLeft(angle)
+    left(angle)
     spiral(steps-1, angle, length+increment, increment)
   
 # BEGIN TEMPLATE
diff --git a/src/lessons/recursion/spiral/SpiralUseEntity.scala b/src/lessons/recursion/spiral/SpiralUseEntity.scala
new file mode 100644
index 0000000..9f9d5a3
--- /dev/null
+++ b/src/lessons/recursion/spiral/SpiralUseEntity.scala
@@ -0,0 +1,35 @@
+package lessons.recursion.spiral;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaSpiralUseEntity extends Turtle {
+
+	def spiral(steps:Int, angle:Int, length:Int, increment:Int)	{
+		if (steps <= 0) {
+			return;
+		} else {
+			forward(length);
+			left(angle);
+			spiral(steps-1, angle, length+increment, increment);
+		}
+	}
+
+	/* BEGIN TEMPLATE */
+	def doit(page:Int) {
+		/* BEGIN SOLUTION */
+		page match {
+		case 0 =>	spiral(100,90+1,1,2);
+		case 1 =>	spiral(100,120+1,1,2);
+		case 2 => spiral(5,360/5,100,0); 
+		case 3 => spiral(5,2*360/5,150,0);
+		case 4 => spiral(360,1,1,0);   	
+		case _ => 
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		doit(getParam(0).asInstanceOf[Int]);
+	}
+}
diff --git a/src/lessons/recursion/square/FourSquare.fr.html b/src/lessons/recursion/square/FourSquare.fr.html
new file mode 100644
index 0000000..43bcab4
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquare.fr.html
@@ -0,0 +1,58 @@
+<h2>Les petites cousines des Buggles</h2>
+<p>
+Aujourd'hui, nous allons faire la connaissance des petites cousines des
+buggles : les tortues. En fait, les tortues sont bien plus vieilles que les
+buggles. Elles ont été inventées dans les années 70 par un scientifique du
+MIT nommé Seymour Papert pour aider à l'enseignement la programmation, et
+les buggles sont une variation sur le thème inventée par Lyn Turbak du
+Wellesley College plus tard.
+</p>
+<p>Les tortues sont donc un peu comme les buggles, en plus petit.  Comme les
+buggles, vous pouvez leur demander d'avancer, de tourner, de reculer,
+etc. Comme les buggles, elles laissent une trace sur leur passage quand
+elles avancent (simplement, le trait est bien plus fin).</p>
+
+<p>La principale différence est que là où les buggles ne peuvent tourner que de
+quarts de tour, les tortues peuvent tourner d'un angle quelconque précisé
+par un nombre réel (double). Cela leur donne bien plus de liberté dans leur
+mouvement. Les buggles savent faire plusieurs trucs qui échappent aux
+tortues, comme lire et écrire des messages sur le sol ou ramasser des
+objets, et il y a parfois des murs dans leur univers, mais tout cela dépasse
+complètement les tortues.</p>
+
+<p>D'un point de vue pratique, la plupart des méthodes que vous connaissez à
+propos des buggles fonctionnent également avec les tortues, à quelques
+variantes près. En particulier, la méthode <code>avance</code> prend en
+argument le nombre de pas donné comme un [!python]nombre à
+virgule[/!][!scala|java]double[/!] (voir «Aide / À propos de ce monde» dans
+le menu pour plus de détails).</p>
+
+[!java|scala]
+<h3>Des doubles ? Mais qu'est ce que c'est ?</h3>
+C'est simplement un nombre à virgule. Exemple:
+<pre>
+double x = 3.72;
+x + 1.234 // Valeur = 4.954
+x + 2. // Valeur = 5.72 (2. signifie 2.0)
+x + 2 // [!java]Valeur = 5.72 (2 converti en 2.0 automatiquement)[/!][!scala]Erreur de typage (l'opérateur + operator ne mélange pas les Double avec les Int). Il faut convertir explicitement[/!]
+x * 2. // Valeur = 7.44
+x / 2. // Valeur = 1.86 (2 converti en 2.0 automatiquement)
+[!java](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Valeur = 1 (“transtypage en int”, converti en entier en tronquant)
+Math.round(x) // Valeur = 2 (1.86 arrondi à l'entier le plus proche)
+Math.floor(x) // Valeur = 1 (1.86 arrondi en direction de moins l'infini)
+Math.floor(-5.12) // Vale = -6 (Arrondi en direction de moins l'infini)
+Math.ceiling(x) // Value = 2 (1.86 arrondi en direction de plus l'infini)
+Math.ceiling(-5.12) // Value = -5 (Arrondi en direction de plus l'infini)
+[!java](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“transtypage en double”, converti en double)
+</pre>
+[/!]
+
+<h3>Objectif de l'exercice</h3>
+<p>Bien que ce soit le premier exercice de la leçon sur la récursivité, le code
+que vous devez écrire n'est pas récursif. L'objectif est de se familiariser
+avec le monde des tortues avant d'attaquer les choses sérieuses.</p>
+
+<p>Vous devez reproduire une forme géométrique simple faite de quatre carrés de
+longueur 100 de coté (voir le monde objectif pour plus de détails). C'est
+sans doute une bonne idée d'écrire une méthode pour faire un carré, et de la
+réutiliser lors de l'écriture de votre code.</p>
diff --git a/src/lessons/recursion/square/FourSquare.html b/src/lessons/recursion/square/FourSquare.html
new file mode 100644
index 0000000..b6e7357
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquare.html
@@ -0,0 +1,55 @@
+<h2>The small cousines of Buggles</h2>
+<p>
+Today, we will meet the small cousines of the buggles: the turtles. In fact,
+turtles are much olders than the buggles. They were invented in the 70's by
+a scientific from MIT called Seymour Papert to help teaching programming,
+and the buggles are a variation on the idea invented by Lyn Turbak from
+Wellesley College later.
+</p>
+<p>Turtles are thus a bit like buggles, but smaller. Just like buggles, you can
+order them to move forward, to turn, to move backward, etc. Just like
+buggles, they leave a line on their path when they move (but the line is
+much smaller).</p>
+
+<p>The main difference is that where buggles can only move of right angles,
+turtles can move of any arbitrary angles specified by a real number (a
+double). This gives them much more liberty in their movings. The buggles can
+do several other tricks, like reading and writting messages, picking or
+dropping objects, and there is sometimes walls in their worlds (but all this
+is completely above the capacities of turtles).</p>
+
+<p>From a practical point of view, most of the methods you knew about buggles
+still work with turtles, with some minor adaptations. In particular, the
+<code>forward()</code> method takes the amount of steps to do not as an integer, 
+but as a [!python]point number[/!][!java|scala]double[/!]
+(see "About this world" for more details).</p>
+
+[!java|scala]
+<h3>Doubles? But what is it?</h3>
+It's simply a point number. Example:
+<pre>
+double x = 3.72;
+x + 1.234 // Value = 4.954
+x + 2. // Value = 5.72 (2. means 2.0)
+x + 2 // [!java]Value = 5.72 (2 automatically converted to 2.0)[/!][!scala]Type error (+ operator don't mix Double and Int); manual conversion mandatory[/!]
+x * 2. // Value = 7.44 
+x / 2. // Value = 1.86 
+[!java](int) x[/!][!scala]x.asInstanceOf[Int][/!] // Value = 1 (“casting to int”, converted to integer by truncating)
+Math.round(x) // Value = 2 (1.86 rounded to nearest integer)
+Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)
+Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)
+Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)
+Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)
+[!java](double) 17[/!][!scala]17.asInstanceOf[Double][/!] // Value = 17.0 (“casted to double”, converted to double)
+</pre>
+[/!]
+
+<h3>Goal of this exercise</h3>
+<p>Even if this is the first exercise on the recursivity lesson, the code you
+have to write is not recursive. The goal is to get familiar with the turtle
+world before getting on serious matter.</p>
+
+<p>You must reproduce a simple geometrical painting constituted of four 100
+steps long squares (see the objective world for more details). It is
+obviously a good idea to write a method to draw a square, and then use it in
+your code.</p>
diff --git a/src/lessons/recursion/square/FourSquare.java b/src/lessons/recursion/square/FourSquare.java
new file mode 100644
index 0000000..5aa637e
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquare.java
@@ -0,0 +1,20 @@
+package lessons.recursion.square;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
+
+public class FourSquare extends ExerciseTemplated {
+
+	public FourSquare(Lesson lesson) {
+		super(lesson);
+
+		/* Create initial situation */
+		World myWorld = new TurtleWorld("WhiteBoard", 400, 400);
+
+		new Turtle(myWorld, "Hawksbill", 200, 200);
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/recursion/square/FourSquareEntity.java b/src/lessons/recursion/square/FourSquareEntity.java
new file mode 100644
index 0000000..6c0780e
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquareEntity.java
@@ -0,0 +1,25 @@
+package lessons.recursion.square;
+
+import plm.universe.turtles.Turtle;
+
+public class FourSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(90,100, 90,200);
+
+		for (int i = 0; i < 4; i++) {
+			square();
+			right(90);
+		}
+	}
+	public void square() {
+		for (int i = 0; i < 4; i++) {
+			forward(100);
+			right(90);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/recursion/square/FourSquareEntity.py b/src/lessons/recursion/square/FourSquareEntity.py
new file mode 100644
index 0000000..b7a84b2
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquareEntity.py
@@ -0,0 +1,13 @@
+# BEGIN TEMPLATE 
+# BEGIN SOLUTION
+def square():
+  for i in range(4):
+    forward(100)
+    right(90)
+
+for i in range(4):
+  square()
+  right(90)
+# END SOLUTION
+# END TEMPLATE
+
diff --git a/src/lessons/recursion/square/FourSquareEntity.scala b/src/lessons/recursion/square/FourSquareEntity.scala
new file mode 100644
index 0000000..b949128
--- /dev/null
+++ b/src/lessons/recursion/square/FourSquareEntity.scala
@@ -0,0 +1,23 @@
+package lessons.recursion.square;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaFourSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 4) {
+			square();
+			right(90);
+		}
+	}
+	def square() {
+		for (i <- 1 to 4) {
+			forward(100);
+			right(90);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/recursion/square/Square.fr.html b/src/lessons/recursion/square/Square.fr.html
deleted file mode 100644
index 3f70f50..0000000
--- a/src/lessons/recursion/square/Square.fr.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<h2>Les petites cousines des Buggles</h2>
-<p>
-Aujourd'hui, nous allons faire la connaissance des petites cousines des
-buggles : les tortues. En fait, les tortues sont bien plus vieilles que les
-buggles. Elles ont été inventées dans les années 70 par un scientifique du
-MIT nommé Seymour Papert pour aider à l'enseignement la programmation, et
-les buggles sont une variation sur le thème inventée par Lyn Turbak du
-Wellesley College plus tard.
-</p>
-<p>Les tortues sont donc un peu comme les buggles, en plus petit.  Comme les
-buggles, vous pouvez leur demander d'avancer, de tourner, de reculer,
-etc. Comme les buggles, elles laissent une trace sur leur passage quand
-elles avancent (simplement, le trait est bien plus fin).
-
-<p>La principale différence est que là où les buggles ne peuvent tourner que de
-quarts de tour, les tortues peuvent tourner d'un angle quelconque précisé
-par un nombre réel (double). Cela leur donne bien plus de liberté dans leur
-mouvement. Les buggles savent faire plusieurs trucs qui échappent aux
-tortues, comme lire et écrire des messages sur le sol ou ramasser des
-objets, et il y a parfois des murs dans leur univers, mais tout cela dépasse
-complètement les tortues.
-
-<p>D'un point de vue pratique, la plupart des méthodes que vous connaissez à
-propos des buggles fonctionnent également avec les tortues, à quelques
-variantes près. En particulier, la méthode <code>forward</code> prend en
-argument le nombre de pas donné comme un nombre double (voir «Aide / À
-propos de ce monde» dans le menu pour plus de détails).
-
-<h3>Des doubles ? Mais qu'est ce que c'est ?</h3>
-C'est simplement un nombre à virgule. Exemple:
-<pre>
-double x = 3.72;
-x + 1.234 // Valeur = 4.954
-x + 2 // Valeur = 5.72 (2 converti en 2.0 automatiquement)
-x * 2 // Valeur = 7.44 (2 converti en 2.0 automatiquement)
-x / 2 // Valeur = 1.86 (2 converti en 2.0 automatiquement)
-(int) x // Valeur = 1 (“transtypage en int”, converti en entier en tronquant)
-Math.round(x) // Valeur = 2 (1.86 arrondi à l'entier le plus proche)
-Math.floor(x) // Valeur = 1 (1.86 arrondi en direction de moins l'infini)
-Math.floor(-5.12) // Vale = -6 (Arrondi en direction de moins l'infini)
-Math.ceiling(x) // Value = 2 (1.86 arrondi en direction de plus l'infini)
-Math.ceiling(-5.12) // Value = -5 (Arrondi en direction de plus l'infini)
-(double) 17 // Value = 17.0 (“transtypage en double”, converti en double)
-</pre>
-
-<h3>Objectif de l'exercice</h3>
-Bien que ce soit le premier exercice de la leçon sur la récursivité, le code
-que vous devez écrire n'est pas récursif. L'objectif est de se familiariser
-avec le monde des tortues avant d'attaquer les choses sérieuses.
-
-<p>Vous devez reproduire une forme géométrique simple faite de quatre carrés de
-longueur 100 de coté (voir le monde objectif pour plus de détails). C'est
-sans doute une bonne idée d'écrire une méthode pour faire un carré, et de la
-réutiliser lors de l'écriture de la méthode <code>run()</code> qui fait le
-travail. Il est indispensable d'écrire au moins la méthode run, dont le
-prototype est le suivant:
-<pre>
-public void run() {
-  // ecrivez ici ce que doit faire votre tortue
-}</pre>
diff --git a/src/lessons/recursion/square/Square.html b/src/lessons/recursion/square/Square.html
deleted file mode 100644
index c863ab8..0000000
--- a/src/lessons/recursion/square/Square.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<h2>The small cousines of Buggles</h2>
-<p>
-Today, we will meet the small cousines of the buggles: the turtles. In fact,
-turtles are much olders than the buggles. They were invented in the 70's by
-a scientific from MIT called Seymour Papert to help teaching programming,
-and the buggles are a variation on the idea invented by Lyn Turbak from
-Wellesley College later.
-</p>
-<p>Turtles are thus a bit like buggles, but smaller. Just like buggles, you can
-order them to move forward, to turn, to move backward, etc. Just like
-buggles, they leave a line on their path when they move (but the line is
-much smaller).
-
-<p>The main difference is that where buggles can only move of right angles,
-turtles can move of any arbitrary angles specified by a real number (a
-double). This gives them much more liberty in their movings. The buggles can
-do several other tricks, like reading and writting messages, picking or
-dropping objects, and there is sometimes walls in their worlds (but all this
-is completely above the capacities of turtles).
-
-<p>From a practical point of view, most of the methods you knew about buggles
-still work with turtles, with some minor adaptations. In particular, the
-<code>forward()</code> method takes the amount of steps to do as a double
-(see "About this world" for more details).
-
-<h3>Doubles? But what is it?</h3>
-It's simply a point number. Example:
-<pre>
-double x = 3.72;
-x + 1.234 // Value = 4.954
-x + 2 // Value = 5.72 (2 converted to 2.0 automatically)
-x * 2 // Value = 7.44 (2 converted to 2.0 automatically)
-x / 2 // Value = 1.86 (2 converted to 2.0 automatically)
-(int) x // Value = 1 (“casting to int”, converted to integer by truncating)
-Math.round(x) // Value = 2 (1.86 rounded to nearest integer)
-Math.floor(x) // Value = 1 (1.86 rounded toward minus infinity)
-Math.floor(-5.12) // Value = -6 (rounded toward minus infinity)
-Math.ceiling(x) // Value = 2 (1.86 rounded toward plus infinity)
-Math.ceiling(-5.12) // Value = -5 (rounded toward plus infinity)
-(double) 17 // Value = 17.0 (“casted to double”, converted to double)
-</pre>
-
-<h3>Goal of this exercise</h3>
-Even if this is the first exercise on the recursivity lesson, the code you
-have to write is not recursive. The goal is to get familiar with the turtle
-world before getting on serious matter.
-
-<p>You must reproduce a simple geometrical painting constituted of four 100
-steps long squares (see the objective world for more details). It is
-obviously a good idea to write a method to draw a square, and then use it in
-your <code>run()</code> in charge of doing the work. You must absolutely
-write at least the run method, which prototype is the following:
-<pre>
-public void run() {
-  // write here what your turtle is supposed to do
-}</pre>
diff --git a/src/lessons/recursion/square/Square.java b/src/lessons/recursion/square/Square.java
deleted file mode 100644
index 2eb0c70..0000000
--- a/src/lessons/recursion/square/Square.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package lessons.recursion.square;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
-
-public class Square extends ExerciseTemplated {
-
-	public Square(Lesson lesson) {
-		super(lesson);
-
-		/* Create initial situation */
-		World myWorld = new TurtleWorld("WhiteBoard", 400, 400);
-
-		new Turtle(myWorld, "Hawksbill", 200, 200);
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/recursion/square/SquareEntity.java b/src/lessons/recursion/square/SquareEntity.java
deleted file mode 100644
index 5bac24e..0000000
--- a/src/lessons/recursion/square/SquareEntity.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package lessons.recursion.square;
-
-import jlm.universe.turtles.Turtle;
-
-public class SquareEntity extends Turtle {
-
-	/* BEGIN TEMPLATE */
-	public void run() {
-		/* BEGIN SOLUTION */
-		for (int i = 0; i < 4; i++) {
-			square();
-			turnRight(90);
-		}
-	}
-	public void square() {
-		for (int i = 0; i < 4; i++) {
-			forward(100);
-			turnRight(90);
-		}
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/recursion/square/SquareEntity.py b/src/lessons/recursion/square/SquareEntity.py
deleted file mode 100644
index d711d06..0000000
--- a/src/lessons/recursion/square/SquareEntity.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# BEGIN TEMPLATE 
-# BEGIN SOLUTION
-def square():
-  for i in range(4):
-    forward(100)
-    turnRight(90)
-
-for i in range(4):
-  square()
-  turnRight(90)
-# END SOLUTION
-# END TEMPLATE
-
diff --git a/src/lessons/recursion/star/Star.java b/src/lessons/recursion/star/Star.java
index 26175aa..3962b54 100644
--- a/src/lessons/recursion/star/Star.java
+++ b/src/lessons/recursion/star/Star.java
@@ -1,10 +1,10 @@
 package lessons.recursion.star;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Star extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/star/StarEntity.java b/src/lessons/recursion/star/StarEntity.java
index 0202709..38e8a68 100644
--- a/src/lessons/recursion/star/StarEntity.java
+++ b/src/lessons/recursion/star/StarEntity.java
@@ -2,37 +2,35 @@ package lessons.recursion.star;
 
 import java.awt.Color;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class StarEntity extends Turtle {
 
 	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
+	public void run() {
+		/* BEGIN SOLUTION */
+		star(100, Color.black);
+		right(45);
+		star(80, Color.blue);
+		right(45);
+		star(60, Color.red);
+	}
 	public void branch(int size) {
 		forward(size);
-		turnRight(360 / BRANCH_COUNT);
+		right(360 / BRANCH_COUNT);
 		forward(size);
 
 		for (int i = 0; i < 2; i++)
-			turnLeft(360 / BRANCH_COUNT);
+			left(360 / BRANCH_COUNT);
 	}
 
+	public static final int BRANCH_COUNT = 5;
 	public void star(int size, Color c) {
 		setColor(c);
 		for (int i = 0; i < BRANCH_COUNT; i++) {
 			branch(size);
 		}
+		/* END SOLUTION */
 	}
-
-	public static final int BRANCH_COUNT = 5;
-
-	public void run() {
-		star(100, Color.black);
-		turnRight(45);
-		star(80, Color.blue);
-		turnRight(45);
-		star(60, Color.red);
-	}
-	/* END SOLUTION */
 	/* END TEMPLATE */
 }
diff --git a/src/lessons/recursion/star/StarEntity.py b/src/lessons/recursion/star/StarEntity.py
index 46e651e..ffe84a5 100644
--- a/src/lessons/recursion/star/StarEntity.py
+++ b/src/lessons/recursion/star/StarEntity.py
@@ -4,11 +4,11 @@ BRANCH_COUNT = 5
 
 def branch(size):
 	forward(size);
-	turnRight(360 / BRANCH_COUNT)
+	right(360 / BRANCH_COUNT)
 	forward(size)
 
 	for i in range(2):
-		turnLeft(360 / BRANCH_COUNT)
+		left(360 / BRANCH_COUNT)
 
 
 def star(size, c):
@@ -17,8 +17,8 @@ def star(size, c):
 		branch(size)
 
 star(100, Color.black)
-turnRight(45)
+right(45)
 star(80, Color.blue)
-turnRight(45)
+right(45)
 star(60, Color.red)
 # END SOLUTION
diff --git a/src/lessons/recursion/star/StarEntity.scala b/src/lessons/recursion/star/StarEntity.scala
new file mode 100644
index 0000000..e6def3b
--- /dev/null
+++ b/src/lessons/recursion/star/StarEntity.scala
@@ -0,0 +1,36 @@
+package lessons.recursion.star;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaStarEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		star(100, Color.black);
+		right(45);
+		star(80, Color.blue);
+		right(45);
+		star(60, Color.red);
+	}
+	def branch(size:Int) {
+		forward(size);
+		right(360 / BRANCH_COUNT);
+		forward(size);
+
+		for (i <- 1 to 2)
+			left(360 / BRANCH_COUNT);
+	}
+
+	val BRANCH_COUNT = 5;
+	def star(size:Int, c:Color) {
+		setColor(c);
+		for (i <- 1 to BRANCH_COUNT) {
+			branch(size);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/recursion/tree/Tree.fr.html b/src/lessons/recursion/tree/Tree.fr.html
index 325eeec..9371fff 100644
--- a/src/lessons/recursion/tree/Tree.fr.html
+++ b/src/lessons/recursion/tree/Tree.fr.html
@@ -2,7 +2,7 @@
 
 Nous allons maintenant dessiner des arbres. Pour cela, nous allons écrire
 une fonction doublement récursive de prototype 
-<pre>void tree(int steps, double length, double angle, double shrink)</pre>
+<pre>[!java]void [/!]tree([!java]int [/!]nbPas[!scala]:Int[/!], [!java]double [/!]longueur[!scala]:Double[/!], [!java]double [/!]angle[!scala]:Double[/!], [!java]double [/!]multiplicateur[!scala]:Double[/!])</pre>
 
 <p>Pour dessiner un arbre à quatre étages, il faut dessiner un tronc de la
 taille indiquée, tourner à droite de l'angle indiqué, faire un arbre à 3
diff --git a/src/lessons/recursion/tree/Tree.html b/src/lessons/recursion/tree/Tree.html
index b770229..6ea950d 100644
--- a/src/lessons/recursion/tree/Tree.html
+++ b/src/lessons/recursion/tree/Tree.html
@@ -1,15 +1,15 @@
-<h2>Trees</h2>
-
-We will now draw trees. For that, we will write a method using double
-recursion following this prototype 
-<pre>void tree(int steps, double length, double angle, double shrink)</pre>
-
-<p>To draw a tree of four levels, you have to draw a trunk of the given length,
-turn right of the given angle, draw a tree of level 3, turn left twice of
-the given angle, draw another tree of level 3, and come back to your initial
-location. 
-
-<p>If a tree's trunk is of length 'len', the trunk of the next level tree will
-be of length 'len*shrink'.
- 
-
+<h2>Trees</h2>
+
+We will now draw trees. For that, we will write a method using double
+recursion following this prototype 
+<pre>[!java]void [/!]tree([!java]int [/!]steps[!scala]:Int[/!], [!java]double [/!]length[!scala]:Double[/!], [!java]double [/!]angle[!scala]:Double[/!], [!java]double [/!]shrink[!scala]:Double[/!])</pre>
+
+<p>To draw a tree of four levels, you have to draw a trunk of the given length,
+turn right of the given angle, draw a tree of level 3, turn left twice of
+the given angle, draw another tree of level 3, and come back to your initial
+location. 
+
+<p>If a tree's trunk is of length 'len', the trunk of the next level tree will
+be of length 'len*shrink'.
+ 
+
diff --git a/src/lessons/recursion/tree/Tree.java b/src/lessons/recursion/tree/Tree.java
index d1adf84..3739ea1 100644
--- a/src/lessons/recursion/tree/Tree.java
+++ b/src/lessons/recursion/tree/Tree.java
@@ -2,11 +2,11 @@ package lessons.recursion.tree;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.World;
-import jlm.universe.turtles.Turtle;
-import jlm.universe.turtles.TurtleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
 
 public class Tree extends ExerciseTemplated {
 
diff --git a/src/lessons/recursion/tree/TreeEntity.java b/src/lessons/recursion/tree/TreeEntity.java
index 880e30c..33042f1 100644
--- a/src/lessons/recursion/tree/TreeEntity.java
+++ b/src/lessons/recursion/tree/TreeEntity.java
@@ -1,6 +1,6 @@
 package lessons.recursion.tree;
 
-import jlm.universe.turtles.Turtle;
+import plm.universe.turtles.Turtle;
 
 public class TreeEntity extends Turtle {
 
@@ -11,11 +11,11 @@ public class TreeEntity extends Turtle {
 			/* do nothing */
 		} else {
 			forward(length);
-			turnRight(angle);	         
+			right(angle);	         
 			tree(steps-1, length*shrink, angle, shrink);
-			turnLeft(2*angle);	         
+			left(2*angle);	         
 			tree(steps-1, length*shrink, angle, shrink);
-			turnRight(angle);	         
+			right(angle);	         
 			backward(length);
 		}
 		/* END SOLUTION */	
diff --git a/src/lessons/recursion/tree/TreeEntity.py b/src/lessons/recursion/tree/TreeEntity.py
index 78964ff..bcec3a0 100644
--- a/src/lessons/recursion/tree/TreeEntity.py
+++ b/src/lessons/recursion/tree/TreeEntity.py
@@ -5,11 +5,11 @@ def tree(steps, length, angle, shrink):
     pass# do nothing 
   else:
     forward(length)
-    turnRight(angle)
+    right(angle)
     tree(steps-1, length*shrink, angle, shrink)
-    turnLeft(2*angle)
+    left(2*angle)
     tree(steps-1, length*shrink, angle, shrink)
-    turnRight(angle)
+    right(angle)
     backward(length)
   # END SOLUTION
 # END TEMPLATE
diff --git a/src/lessons/recursion/tree/TreeEntity.scala b/src/lessons/recursion/tree/TreeEntity.scala
new file mode 100644
index 0000000..5a37cc0
--- /dev/null
+++ b/src/lessons/recursion/tree/TreeEntity.scala
@@ -0,0 +1,29 @@
+package lessons.recursion.tree;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaTreeEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	def tree(steps:Int, length:Double, angle:Double, shrink:Double)	{
+		/* BEGIN SOLUTION */
+		if (steps <= 0) {
+			/* do nothing */
+		} else {
+			forward(length);
+			right(angle);	         
+			tree(steps-1, length*shrink, angle, shrink);
+			left(2*angle);	         
+			tree(steps-1, length*shrink, angle, shrink);
+			right(angle);	         
+			backward(length);
+		}
+		/* END SOLUTION */	
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		tree(getParam(0).asInstanceOf[Int],getParam(1).asInstanceOf[Double],
+		    getParam(2).asInstanceOf[Double],getParam(3).asInstanceOf[Double]);
+	}
+}
diff --git a/src/lessons/sort/Main.java b/src/lessons/sort/Main.java
index 305d3a0..d2e5739 100644
--- a/src/lessons/sort/Main.java
+++ b/src/lessons/sort/Main.java
@@ -1,6 +1,6 @@
 package lessons.sort;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.bubble.AlgBubbleSort1;
 import lessons.sort.bubble.AlgBubbleSort2;
 import lessons.sort.bubble.AlgBubbleSort3;
@@ -24,17 +24,19 @@ public class Main extends Lesson {
 		addExercise(new AlgBubbleSort2(this));
 		addExercise(new AlgBubbleSort3(this));
 		
-		addExercise(new AlgInsertionSort(this));
-		addExercise(new AlgShellSort(this));
-		
-		addExercise(new AlgSelectionSort(this));
-
 		addExercise(new AlgCocktailSort1(this));
 		addExercise(new AlgCocktailSort2(this));
 		addExercise(new AlgCocktailSort3(this));
-		
+
 		addExercise(new AlgCombSort(this));
 		addExercise(new AlgCombSort11(this));
+
 		addExercise(new AlgGnomeSort(this));
+		
+		addExercise(new AlgInsertionSort(this));
+		addExercise(new AlgShellSort(this));
+		
+		addExercise(new AlgSelectionSort(this));
+		
 	}
 }
diff --git a/src/lessons/sort/baseball/BubbleBaseball.fr.html b/src/lessons/sort/baseball/BubbleBaseball.fr.html
index 44a339c..736a4e3 100644
--- a/src/lessons/sort/baseball/BubbleBaseball.fr.html
+++ b/src/lessons/sort/baseball/BubbleBaseball.fr.html
@@ -25,7 +25,7 @@ descend, en sortant peu à peu le tableau. Les grandes lignes de l'algorithme
 sont très simples : «tant que ce n'est pas trier, déplacer le trou vers le
 bas puis vers le haut. À chaque pas, c'est le plus petit des deux joueurs de
 la base qui descend, et le plus grand des deux qui monte (en fonction du
-sens de déplacement).». Après un moment, <code>isSorted()</code> devient
+sens de déplacement).». Après un moment, <code>estTrie()</code> devient
 vrai, et votre algorithme s'arrête.</p>
 
 <p>C'est tellement simple que nous pouvons nous payer le luxe d'une autre
diff --git a/src/lessons/sort/baseball/BubbleBaseball.java b/src/lessons/sort/baseball/BubbleBaseball.java
index fe039aa..f66ed29 100644
--- a/src/lessons/sort/baseball/BubbleBaseball.java
+++ b/src/lessons/sort/baseball/BubbleBaseball.java
@@ -1,7 +1,7 @@
 package lessons.sort.baseball;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.baseball.universe.BaseballWorld;
 
 public class BubbleBaseball extends ExerciseTemplated {
diff --git a/src/lessons/sort/baseball/BubbleBaseballEntity.scala b/src/lessons/sort/baseball/BubbleBaseballEntity.scala
new file mode 100644
index 0000000..753af1b
--- /dev/null
+++ b/src/lessons/sort/baseball/BubbleBaseballEntity.scala
@@ -0,0 +1,37 @@
+package lessons.sort.baseball;
+
+import lessons.sort.baseball.universe.BaseballEntity;
+import lessons.sort.baseball.universe.BaseballWorld;
+
+class ScalaBubbleBaseballEntity extends BaseballEntity {
+	
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		while (!isSorted()) {
+			while (getHoleBase()>0) {
+				var maxPos = 0;
+				var maxColor = getPlayerColor(getHoleBase()-1, 0);
+				for (pos <- 1 to getPositionsAmount()-1) 
+					if (getPlayerColor(getHoleBase()-1, pos) > maxColor) {
+						maxColor = getPlayerColor(getHoleBase()-1, pos);
+						maxPos = pos;
+					}
+				move(getHoleBase()-1,maxPos);
+			}
+			while (getHoleBase()<getBasesAmount()-1) {
+				var minPos = 0;
+				var minColor = getPlayerColor(getHoleBase()+1, 0);
+				for (pos <- 1 to getPositionsAmount()-1) 
+					if (getPlayerColor(getHoleBase()+1, pos) < minColor) {
+						minColor = getPlayerColor(getHoleBase()+1, pos);
+						minPos = pos;
+					}
+				move(getHoleBase()+1,minPos);				
+			}
+		}
+		world.asInstanceOf[BaseballWorld].assertSorted("bubble sort");
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
\ No newline at end of file
diff --git a/src/lessons/sort/baseball/InsertBaseball.java b/src/lessons/sort/baseball/InsertBaseball.java
index e03f64d..bc99532 100644
--- a/src/lessons/sort/baseball/InsertBaseball.java
+++ b/src/lessons/sort/baseball/InsertBaseball.java
@@ -1,7 +1,7 @@
 package lessons.sort.baseball;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.baseball.universe.BaseballWorld;
 
 public class InsertBaseball extends ExerciseTemplated {
diff --git a/src/lessons/sort/baseball/InsertBaseballEntity.scala b/src/lessons/sort/baseball/InsertBaseballEntity.scala
new file mode 100644
index 0000000..c0ca7fa
--- /dev/null
+++ b/src/lessons/sort/baseball/InsertBaseballEntity.scala
@@ -0,0 +1,43 @@
+package lessons.sort.baseball;
+
+import lessons.sort.baseball.universe.BaseballEntity;
+import lessons.sort.baseball.universe.BaseballWorld;
+
+class ScalaInsertBaseballEntity extends BaseballEntity {
+	
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		/* Bring the hole in 0,1 */
+		if (getHole() == 0) // It is already on base 0, but on another position
+			move(1);
+		while (getHole() > 1)
+			move(getHole()-1);
+		
+		for (player <- 2 to getBasesAmount()*getPositionsAmount()-1) {
+			//out("Sort player "+player);
+			
+			//out("Compare "+(getHole()+1)+":"+getPlayerColor(getHole()+1)+" < "+(getHole()-1)+":"+getPlayerColor(getHole()-1));
+			while (getHole()>0 && getPlayerColor(getHole()+1) < getPlayerColor(getHole()-1)) {  
+				val center = getHole();// ...2x1... with ascending positions from left to right
+				move(center+1);        // ...21x...
+				move(center-1);        // ...x12...
+			}
+			while (getHole() != player) 
+				move(getHole()+1);
+		}
+		world.asInstanceOf[BaseballWorld].assertSorted("insertion sort");
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+	
+	def getPlayerColor(pos:Int):Int = getPlayerColor(pos / getPositionsAmount(), pos % getPositionsAmount());
+	def move(pos:Int):Unit = move(pos / getPositionsAmount(), pos % getPositionsAmount());
+	def getHole():Int = getPositionsAmount()*getHoleBase()+getHolePosition();
+	
+	def out(msg:String) {
+		if (isSelected())
+			System.out.println(msg);
+	}
+	/* END HIDDEN */
+}
\ No newline at end of file
diff --git a/src/lessons/sort/baseball/Main.fr.html b/src/lessons/sort/baseball/Main.fr.html
index 70e48b4..628b547 100644
--- a/src/lessons/sort/baseball/Main.fr.html
+++ b/src/lessons/sort/baseball/Main.fr.html
@@ -4,7 +4,7 @@
 «Computer Science Unplugged». Elle a cependant été profondément réarrangée
 depuis, d'abord pour SMN (mon recueil d'activités <i>libres</i> pour
 introduire la science informatique, disponible depuis
-http://www.loria.fr/~quinson/Mediation/SMN/), et maintenant pour JLM.</p>
+http://www.loria.fr/~quinson/Mediation/SMN/), et maintenant pour PLM.</p>
 
 <p>Dans la littérature scientifique, la forme généralisée de ce problème se
 nomme «le problème du déplacement des galets» (Pebble motion problem). Les
@@ -40,7 +40,7 @@ bouclera pas. Si vous en découvrez un, merci de nous l'indiquer. Ce serait
 encore mieux s'il était possible de vérifier le critère de tête afin que les
 animateurs puissent s'en servir pendant les activités débranchées.</p>
 
-<h3>Que puis-je faire pour améliorer cet univers de JLM?</h3>
+<h3>Que puis-je faire pour améliorer cet univers de PLM?</h3>
 
 <p>Comme souvent, plusieurs points pourraient être améliorés dans le code de
 cet univers pour l'améliorer :</p>
diff --git a/src/lessons/sort/baseball/Main.html b/src/lessons/sort/baseball/Main.html
index b2b04bf..3a9e1a5 100644
--- a/src/lessons/sort/baseball/Main.html
+++ b/src/lessons/sort/baseball/Main.html
@@ -2,7 +2,7 @@
 
 <p>This activity is inspired from the orange game, from the "Computer Science Unplugged" activities repository. 
 It was however heavily since then, first for the CSIRL (my repository of <i>free</i> unplugged activities to
-introduce computer science, available at http://www.loria.fr/~quinson/Mediation/SMN/) and now for JLM.</p>
+introduce computer science, available at http://www.loria.fr/~quinson/Mediation/SMN/) and now for PLM.</p>
 
 <p>In the literature, the generalized form of this problem is known as the pebble motion problem (the bases can 
 be connected by any kind of graph, and the affinity of pebbles with bases may be different). Another variant of 
@@ -24,7 +24,7 @@ With 6 bases, it fails on 1251 of the 58860 such boards (2.12%). With 7 bases, i
 (that's 3.2%). I am still looking for a criteria ensuring that the algorithm won't loop. If you discover one, please 
 report it. Ideally, it would be simple to enforce manually so that we can use it during our unplugged activities.</p>
 
-<h3>What can I do to improve this JLM universe?</h3>
+<h3>What can I do to improve this PLM universe?</h3>
 
 <p>As usual, there are several things that could be done in the code of this universe to improve it:</p>
 <ul>
diff --git a/src/lessons/sort/baseball/Main.java b/src/lessons/sort/baseball/Main.java
index 1919cd1..71798ff 100644
--- a/src/lessons/sort/baseball/Main.java
+++ b/src/lessons/sort/baseball/Main.java
@@ -1,6 +1,6 @@
 package lessons.sort.baseball;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 public class Main extends Lesson {
 
diff --git a/src/lessons/sort/baseball/NaiveBaseball.fr.html b/src/lessons/sort/baseball/NaiveBaseball.fr.html
index 33f9260..7e0619f 100644
--- a/src/lessons/sort/baseball/NaiveBaseball.fr.html
+++ b/src/lessons/sort/baseball/NaiveBaseball.fr.html
@@ -49,7 +49,7 @@ trou est sur la base <code>B</code>, il s'agit de la base <code>B+1</code>
 (modulo le nombre de bases). Ensuite, il faut calculer la distance que
 chacune des buggles de cette base doit encore parcourir (0 si elle est déjà
 chez elle). Une fois que vous avez sélectionné l'heureuse élue, utilisez la
-méthode <code>move</code> pour la faire bouger, avant de passer à
+méthode <code>deplace</code> pour la faire bouger, avant de passer à
 l'itération suivante.</p>   
 
 <p>La principale difficulté est peut-être d'écrire les quelques équations
diff --git a/src/lessons/sort/baseball/NaiveBaseball.java b/src/lessons/sort/baseball/NaiveBaseball.java
index c27f0e6..ccbfb70 100644
--- a/src/lessons/sort/baseball/NaiveBaseball.java
+++ b/src/lessons/sort/baseball/NaiveBaseball.java
@@ -1,7 +1,7 @@
 package lessons.sort.baseball;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.baseball.universe.BaseballWorld;
 
 public class NaiveBaseball extends ExerciseTemplated {
diff --git a/src/lessons/sort/baseball/NaiveBaseballEntity.scala b/src/lessons/sort/baseball/NaiveBaseballEntity.scala
new file mode 100644
index 0000000..505a2c7
--- /dev/null
+++ b/src/lessons/sort/baseball/NaiveBaseballEntity.scala
@@ -0,0 +1,32 @@
+package lessons.sort.baseball;
+
+import lessons.sort.baseball.universe.BaseballEntity;
+import lessons.sort.baseball.universe.BaseballWorld;
+
+class ScalaNaiveBaseballEntity extends BaseballEntity {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		while (!isSorted()) {
+			val baseNext = (getHoleBase()+1) % getBasesAmount();
+			var posNext = -1;
+			var maxDistance = -1;
+			for (pos <- 0 to getPositionsAmount() -1) {
+				val player = getPlayerColor(baseNext, pos);
+				var distance = (baseNext - player + getBasesAmount()) % getBasesAmount();
+				if (distance > maxDistance) {
+					maxDistance = distance;
+					posNext = pos;
+				}
+//				System.out.println(world.toString()+"  baseNext:"+baseNext+" player:"+player+"  distance:"+distance+" (#bases:"+getBasesAmount()+")");
+			}
+//			System.out.println("move "+baseNext+","+posNext);
+			move(baseNext,posNext);
+		}
+		world.asInstanceOf[BaseballWorld].assertSorted("naive sort");
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/sort/baseball/SelectBaseball.java b/src/lessons/sort/baseball/SelectBaseball.java
index 9862034..8930be7 100644
--- a/src/lessons/sort/baseball/SelectBaseball.java
+++ b/src/lessons/sort/baseball/SelectBaseball.java
@@ -1,7 +1,7 @@
 package lessons.sort.baseball;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.baseball.universe.BaseballWorld;
 
 public class SelectBaseball extends ExerciseTemplated {
diff --git a/src/lessons/sort/baseball/SelectBaseballEntity.scala b/src/lessons/sort/baseball/SelectBaseballEntity.scala
new file mode 100644
index 0000000..97676ab
--- /dev/null
+++ b/src/lessons/sort/baseball/SelectBaseballEntity.scala
@@ -0,0 +1,76 @@
+package lessons.sort.baseball;
+
+import lessons.sort.baseball.universe.BaseballEntity;
+import lessons.sort.baseball.universe.BaseballWorld;
+
+class ScalaSelectBaseballEntity extends BaseballEntity {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (base <- 0 to getBasesAmount() -2) 
+			bringPlayersHome(base);
+		
+		world.asInstanceOf[BaseballWorld].assertSorted("selection sort");
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+	def out(msg:String) {
+		//if (false)
+		//	System.out.println(msg);
+	}
+	
+	def bringPlayersHome(base:Int) {
+		for (positionToFill <- 0 to getPositionsAmount()-1) {
+			out("Sort base "+base+", position "+positionToFill);
+			if (getPlayerColor(base, positionToFill) != base) { // not home yet
+		
+				// search for the player on the ground
+				var playerBase = findPlayerBase(base,base);
+				val playerPos = findPlayerPos(playerBase, base);
+				out("player is in "+playerBase+","+playerPos);
+
+
+				// bring the hole to the other position of that base
+				while (getHoleBase() != playerBase) {
+					if (getHoleBase()> playerBase) {
+						move(getHoleBase()-1,(playerPos+1)%2);
+					} else {
+						move(getHoleBase()+1,(playerPos+1)%2);
+					}
+				}
+				out("The hole is now with the player in "+playerBase+": "+world.toString());
+
+				if (playerBase == base) {
+					// Already in the base. Bring it to its position
+					move(base,(positionToFill+1)%2);
+
+				} else while (playerBase != base) { // bring the player to the base next to its home
+					move (playerBase-1, positionToFill);
+					move (playerBase, findPlayerPos(playerBase, base));
+					if (playerBase-1 != base) {
+						move (playerBase-1, (positionToFill+1) %2);
+					}
+					playerBase-=1;
+					out("One step further. playerBase: "+playerBase+"; world:"+world.toString());
+				}
+			}
+		}
+	}
+	
+	def findPlayerBase(start:Int, color:Int):Int = {
+		for (playerBase <- start+1 to getBasesAmount() -1)
+			for (pos <- 0 to getPositionsAmount()-1)
+				if (getPlayerColor(playerBase, pos) == color)
+					return playerBase;
+		throw new IllegalArgumentException("cannot find any player of color "+color+" starting at base "+start);
+	}
+	
+	def findPlayerPos(base:Int, color:Int):Int = {
+		for (pos <- 0 to getPositionsAmount()-1)
+			if (getPlayerColor(base, pos) == color)
+				return pos;
+		throw new IllegalArgumentException("cannot find any player of color "+color+" within base "+base);
+	}		
+	/* END HIDDEN */
+}
diff --git a/src/lessons/sort/baseball/universe/BaseballEntity.java b/src/lessons/sort/baseball/universe/BaseballEntity.java
index 16c9c5c..79e8a57 100644
--- a/src/lessons/sort/baseball/universe/BaseballEntity.java
+++ b/src/lessons/sort/baseball/universe/BaseballEntity.java
@@ -1,7 +1,7 @@
 package lessons.sort.baseball.universe;
 
-import jlm.universe.Entity;
-import jlm.universe.World;
+import plm.universe.Entity;
+import plm.universe.World;
 
 public class BaseballEntity extends Entity {
 	public BaseballEntity() {
@@ -72,4 +72,17 @@ public class BaseballEntity extends Entity {
 	public String toString(){
 		return "BaseballEntity (" + this.getClass().getName() + ")";
 	}
+	
+	/* BINDINGS TRANSLATION: French */
+	public int getNombreBases()     { return getBasesAmount(); }
+	public int getNombrePositions() { return getPositionsAmount(); }
+	public int getCouleurJoueur(int base, int position) { return getPlayerColor(base,position); }
+	public boolean estBaseTriee(int base) { return isBaseSorted(base); }
+	public boolean estTrie()              { return isSorted(); }
+
+	public int getTrouBase()     { return getHoleBase(); }
+	public int getTrouPosition() { return getHolePosition(); }
+	public void deplace(int base, int position) { move(base, position); }
+	
+	public boolean estSelectionne() { return isSelected(); }
 }
diff --git a/src/lessons/sort/baseball/universe/BaseballMovePanel.java b/src/lessons/sort/baseball/universe/BaseballMovePanel.java
index 90c42ad..876eeed 100644
--- a/src/lessons/sort/baseball/universe/BaseballMovePanel.java
+++ b/src/lessons/sort/baseball/universe/BaseballMovePanel.java
@@ -11,8 +11,8 @@ import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 
-import jlm.core.model.Game;
-import jlm.universe.EntityControlPanel;
+import plm.core.model.Game;
+import plm.universe.EntityControlPanel;
 
 /**
  * The control panel for the baseball world. 
diff --git a/src/lessons/sort/baseball/universe/BaseballWorld.fr.html b/src/lessons/sort/baseball/universe/BaseballWorld.fr.html
index 4001a1f..273fad8 100644
--- a/src/lessons/sort/baseball/universe/BaseballWorld.fr.html
+++ b/src/lessons/sort/baseball/universe/BaseballWorld.fr.html
@@ -7,44 +7,38 @@ l'interface graphique, la base <code>0</code> est la bleue foncée tandis que
 la base <code>1</code> est celle fuscia.</p>
 
 <p>Une fois que tous les joueurs du terrain sont chez eux, le trou se trouve
-dans la dernière base, celle de rang <code>getAmountOfBases()-1</code>.</p>
+dans la dernière base, celle de rang <code>getNombreBases()-1</code>.</p>
 
 <h2>Fonctions pour découvrir les dimensions du monde</h2>
 
-<pre class="Java">int getBasesAmount()</pre>
-<pre class="python">getBasesAmount()</pre>
+<pre>[!java]int [/!]getNombreBases() [!scala]:Int[/!]</pre>
 Retourne le nombre de bases dans le terrain.
 
-<pre class="Java">int getPositionsAmount()</pre>
-<pre class="python">getPositionsAmount()</pre>
+<pre>[!java]int [/!]getNombrePositions() [!scala]:Int[/!]</pre>
 Retourne le nombre de positions disponibles par base.
 
 <h2>Fonctions pour découvrir l'état du monde</h2>
 
-<pre class="Java">int getHoleBase()</pre>
-<pre class="python">getHoleBase()</pre>
+<pre>[!java]int [/!]getTrouBase() [!scala]:Int[/!]</pre>
 Retourne l'index de la base où se trouve le trou.
 
-<pre class="Java"> int getHolePosition()</pre>
-<pre class="python">getHolePosition()</pre>
+<pre>[!java]int [/!]getTrouPosition() [!scala]:Int[/!]</pre>
 Retourne la position du trou dans sa base.
 
-<pre class="Java"> int getPlayerColor(int base, int position)</pre>
-<pre class="python">getPlayerColor(base, position)</pre>
+<pre>[!java]int [/!]getCouleurJoueur([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]</pre>
 Retourne la couleur d'un joueur donné à partir de sa position.
 
-<pre class="Java">boolean isSorted()</pre>
-<pre class="python">isSorted()</pre>  
+<pre>[!java]boolean [/!]estTrie() [!scala]:Boolean[/!]</pre>
 Retourne si tous les joueurs présents sur le terrain sont chez eux.
      
-<pre class="Java">boolean isBaseSorted(int base)</pre>
-<pre class="python">isBaseSorted(base)</pre>
+<pre>[!java]boolean [/!]estBaseTriee([!java]int [/!]base)  [!scala]:Boolean[/!]</pre>
 Retourne si tous les joueurs d'une base donnée sont chez eux.
 
+<pre>[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]</pre>
+Renvoi si le monde actuel est sélectionné dans l'interface graphique.
 <h2>Fonctions pour changer le monde</h2>
 
-<pre class="Java">void move(int base, int position)</pre>
-<pre class="python">move(base, position)</pre>
+<pre>[!java]void [/!]deplace([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])</pre>
 Déplace un joueur dans le trou. Une exception IllegalArgumentException est
 levée si le joueur indiqué n'est pas suffisamment près du trou. Il peut être
 au plus à une base du trou.
diff --git a/src/lessons/sort/baseball/universe/BaseballWorld.html b/src/lessons/sort/baseball/universe/BaseballWorld.html
index 953eda9..459c9c7 100644
--- a/src/lessons/sort/baseball/universe/BaseballWorld.html
+++ b/src/lessons/sort/baseball/universe/BaseballWorld.html
@@ -5,42 +5,37 @@ The color of each base is its rank. So base <code>1</code> is of color <code>1</
 In the graphical interface, the base <code>0</code> is the dark blue
 one while the base <code>1</code> is the fuscia one.</p>
 
-<p>Once every players on the field are in their home base, the hole should be in the last base, that is of rank <code>getAmountOfBases()-1</code>.</p>
+<p>Once every players on the field are in their home base, the hole should be in the last base, 
+that is of rank <code>getBasesAmount()-1</code>.</p>
 
 <h2>Functions to retrieve the world's dimensions</h2>
 
-<pre class="Java">int getBasesAmount()</pre>
-<pre class="python">getBasesAmount()</pre>
+<pre>[!java]int [/!]getBasesAmount() [!scala]:Int[/!]</pre>
 Returns the amount of bases on this field.
 
-<pre class="Java">int getPositionsAmount()</pre>
-<pre class="python">getPositionsAmount()</pre>
-Returns the amount of player's positions per base on this field:
+<pre>[!java]int [/!]getPositionsAmount() [!scala]:Int[/!]</pre>
+Returns the amount of player's positions per base on this field.
 
 <h2>Functions to retrieve the world's state</h2>
 
-<pre class="Java">int getHoleBase()</pre>
-<pre class="python">getHoleBase()</pre>
+<pre>[!java]int [/!]getHoleBase() [!scala]:Int[/!]</pre>
 Returns the base in which the hole is located.
 
-<pre class="Java"> int getHolePosition()</pre>
-<pre class="python">getHolePosition()</pre>
+<pre>[!java]int [/!]getHolePosition() [!scala]:Int[/!]</pre>
 Returns the hole position within its base
 
-<pre class="Java"> int getPlayerColor(int base, int position)</pre>
-<pre class="python">getPlayerColor(base, position)</pre>
+<pre>[!java]int [/!]getPlayerColor([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])  [!scala]:Int[/!]</pre>
 Returns the color of the player at a given location.
 
-<pre class="Java">boolean isSorted()</pre>
-<pre class="python">isSorted()</pre>  
+<pre>[!java]boolean [/!]isSorted()  [!scala]:Boolean[/!]</pre>
 Returns whether all players of the field are at home.
      
-<pre class="Java">boolean isBaseSorted(int base)</pre>
-<pre class="python">isBaseSorted(base)</pre>
+<pre>[!java]boolean [/!]isBaseSorted([!java]int [/!]base)  [!scala]:Boolean[/!]</pre>
 Returns whether all players of a given base are at home.
 
+<pre>[!java]boolean [/!]isSelected()  [!scala]:Boolean[/!]</pre>
+Returns whether the current world is selected in the interface.
 <h2>Functions to change the world</h2>
 
-<pre class="Java">void move(int base, int position)</pre>
-<pre class="python">move(base, position)</pre>
+<pre>[!java]void [/!]move([!java]int [/!]base[!scala]:Int[/!], [!java]int [/!]position[!scala]:Int[/!])</pre>
 Moves a given player into the hole. This throws an IllegalArgumentException if the specified player is not near the hole (at most one base away).
diff --git a/src/lessons/sort/baseball/universe/BaseballWorld.java b/src/lessons/sort/baseball/universe/BaseballWorld.java
index d89c9ef..ba08e78 100644
--- a/src/lessons/sort/baseball/universe/BaseballWorld.java
+++ b/src/lessons/sort/baseball/universe/BaseballWorld.java
@@ -6,17 +6,17 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 import javax.swing.ImageIcon;
 
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.core.utils.FileUtils;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
-
 import org.xnap.commons.i18n.I18n;
 import org.xnap.commons.i18n.I18nFactory;
 
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.core.utils.FileUtils;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
+
 public class BaseballWorld extends World {
 	public static final int MIX_SORTED = 0;
 	public static final int MIX_RANDOM = 1;
@@ -33,10 +33,10 @@ public class BaseballWorld extends World {
 	private Vector<BaseballMove> moves = new Vector<BaseballMove>(); // all moves made on the field -- used for graphical purpose only
 	private I18n i18n;
 
-	/** Copy constructor used internally by JLM */
+	/** Copy constructor used internally by PLM */
 	public BaseballWorld(BaseballWorld other) {
 		super(other);
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
 		initialField = new int[other.initialField.length];
 		for (int i=0;i<initialField.length;i++)
 			initialField[i] = other.initialField[i];
@@ -50,7 +50,7 @@ public class BaseballWorld extends World {
 
 	public BaseballWorld(String name, int baseAmount, int posAmount, int mix) {
 		super(name);
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
 
 		// create the bases
 		this.baseAmount = baseAmount;
@@ -202,6 +202,26 @@ public class BaseballWorld extends World {
 					"  return entity.getPlayerColor(base,pos)\n" +
 					"def move(base,pos):\n" +
 					"  entity.move(base,pos)\n" +
+					/* BINDINGS TRANSLATION: French */
+					"def getNombreBases():\n" +
+					"  return entitygetBasesAmount()\n" +
+					"def getNombrePositions():\n" +
+					"  return entity.getPositionsAmount()\n" +
+					"def getTrouBase():\n" +
+					"  return entity.getHoleBase()\n" +
+					"def getTrouPosition():\n" +
+					"  return entity.getHolePosition()\n" +
+					"def estTrie():\n" +
+					"  return entity.isSorted()\n" +
+					"def estBaseTriee():\n" +
+					"  return entity.isBaseSorted()\n" +
+					"def getCouleurJoueur(base,pos):\n" +
+					"  return entity.getPlayerColor(base,pos)\n" +
+					"def deplace(base,pos):\n" +
+					"  (base,pos)\n" +
+					"def estSelectionne():\n"+
+					"  return isSelected()\n"+
+
 					""
 					);
 		} else {
diff --git a/src/lessons/sort/baseball/universe/BaseballWorldView.java b/src/lessons/sort/baseball/universe/BaseballWorldView.java
index 0ec2702..39e325b 100644
--- a/src/lessons/sort/baseball/universe/BaseballWorldView.java
+++ b/src/lessons/sort/baseball/universe/BaseballWorldView.java
@@ -24,14 +24,14 @@ import java.util.Vector;
 import javax.swing.JMenuItem;
 import javax.swing.JPopupMenu;
 
-import jlm.core.HumanLangChangesListener;
-import jlm.core.model.Game;
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
-
 import org.xnap.commons.i18n.I18n;
 import org.xnap.commons.i18n.I18nFactory;
 
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+import plm.core.ui.WorldView;
+import plm.universe.World;
+
 public class BaseballWorldView extends WorldView {
 	
 	private static final long serialVersionUID = 1L;
@@ -650,7 +650,7 @@ class BaseballViewActionListener implements ActionListener, HumanLangChangesList
 
 	@Override
 	public void currentHumanLanguageHasChanged(Locale newLang) {
-		i18n = I18nFactory.getI18n(getClass(),"org.jlm.i18n.Messages", newLang, I18nFactory.FALLBACK);
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages", newLang, I18nFactory.FALLBACK);
 		if (view.isUseStateView()) {
 			item.setText(i18n.tr("Switch to time view"));
 		} else {
diff --git a/src/lessons/sort/bubble/AlgBubbleSort1.fr.html b/src/lessons/sort/bubble/AlgBubbleSort1.fr.html
index fd48b51..36fd695 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort1.fr.html
+++ b/src/lessons/sort/bubble/AlgBubbleSort1.fr.html
@@ -1,21 +1,21 @@
 <h1>Tri à bulle</h1>
 
-<p>Bienvenu au monde des tris. Il permet d'expérimenter avec les algorithmes de
-tri existants. La liste des primitives que vous pouvez utiliser dans vos
-programmes est disponible dans la documentation de référence du monde (Aide
-/ À propos de ce monde).</p>
+<p>Bienvenu dans l'univers des tris. Il permet d'expérimenter avec les
+algorithmes de tri existants. La liste des primitives que vous pouvez
+utiliser dans vos programmes est disponible dans la documentation de
+référence du monde (Aide / À propos de cet univers).</p>
 
 <p>Il ne suffit pas de trier le tableau pour passer les exercices. Votre
 solution doit suivre scrupuleusement le comportement attendu de chaque
 exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et
-d'écriture sur le tableau effectuées lors de ce tri. En cas de problème, il
-est souvent assez difficile de comprendre la différence entre le
-comportement attendu et le comportement effectif.</p>
+d'écriture sur le tableau effectuées lors de ce tri. </p>
 
-<p>Pour cela, il est possible d'explorer graphiquement l'historique de
-n'importe quel monde de tri. Passez par exemple au monde Objectif et
-utilisez son menu contextuel (clic droit) pour choisir entre la vue de
-l'état courant du monde et la vue de son histoire.</p>
+<p>Quand votre algorithme diverge de l'attendu, il peut être difficile de
+comprendre la différence de comportement. Pour cela, il est possible
+d'explorer graphiquement l'historique de n'importe quel monde de tri. Passez
+par exemple au monde Objectif et utilisez son menu contextuel (clic droit)
+pour choisir entre la vue de l'état courant du monde et la vue de son
+histoire.</p>
 
 <p>La vue de l'historique n'est pas aussi complexe qu'elle en a l'air à
 première vue. Le temps s'écoule de gauche à droite, et les cases du tableau
@@ -24,8 +24,8 @@ serpentent représentent les différentes valeurs contenues dans le
 tableau. Quand deux lignes se croises, cela signifie que les valeurs du
 tableau ont été échangées à ce moment de l'historique; un embranchement
 signifie que la valeur a été copiée; une valeur en violet suivie d'un point
-d'interrogation a été lue avec getValue() et une valeur en rouge suivie d'un
-point d'exclamation a été écrite avec setValue().</p> 
+d'interrogation a été lue avec getValeur() et une valeur en rouge suivie
+d'un point d'exclamation a été écrite avec setValeur().</p> 
 
 <h2>Première tentative pour le tri à bulle</h2>
 
@@ -48,4 +48,4 @@ jamais utilisé en pratique.</p>
           Si les cases i et i+1 doivent être inverser, le faire
      tant qu'on a inverser des choses lors du dernier parcours
 </pre>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/lessons/sort/bubble/AlgBubbleSort1.html b/src/lessons/sort/bubble/AlgBubbleSort1.html
index 6fe7830..75d6706 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort1.html
+++ b/src/lessons/sort/bubble/AlgBubbleSort1.html
@@ -1,20 +1,19 @@
 <h1>BubbleSort</h1>
 
-<p>Welcome to the sorting world. It allows you to experiment with the existing
+<p>Welcome to the sorting universe. It allows you to experiment with the existing
 sorting algorithms. The list of buildins that you can use in your algorithms 
 is available in the world reference documentation ("Help"->"About this world").</p>
 
 <p>It is not enough to sort the array to pass the exercises. Your solution 
 must strictly follow the expected behavior of each exercise. This is
 enforced by checking that your algorithm needs the same amount of read
-and write operations to sort the array. When they don't match,
-understanding the difference between your code and the expected
-solution can reveal very difficult.</p>
+and write operations to sort the array. </p>
 
-<p>To help in this process, it is posible to graphically explore the
-history of your sorting algorithm. Switch to the Objective view and
-use the contextual menu (right click) to switch from the the view of
-the current state to the view of its history.</p>
+<p>When your algorithm diverges from the expectation, understanding the difference 
+between your code and the expected solution can reveal very difficult. To help in 
+this process, it is posible to graphically explore the history of your sorting 
+algorithm. Switch to the Objective view and use the contextual menu (right click) 
+to switch from the the view of the current state to the view of its history.</p>
 
 <p>The history view is a bit hairly at the first glance, but actually rather
 simple: The time flows from left to right on this graph, and each row
@@ -44,4 +43,4 @@ practice because of its bad performance (O(n^2) on average).</p>
           If cells i and i+1 must be swapped, do it
 while we swapped something during last traversal
 </pre>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/lessons/sort/bubble/AlgBubbleSort1.java b/src/lessons/sort/bubble/AlgBubbleSort1.java
index 421321b..78bbb26 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort1.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort1.java
@@ -1,9 +1,9 @@
 package lessons.sort.bubble;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgBubbleSort1 extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort1Entity.java b/src/lessons/sort/bubble/AlgBubbleSort1Entity.java
index e188087..2ef3deb 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort1Entity.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort1Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.bubble;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgBubbleSort1Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort1Entity.scala b/src/lessons/sort/bubble/AlgBubbleSort1Entity.scala
new file mode 100644
index 0000000..f1de43a
--- /dev/null
+++ b/src/lessons/sort/bubble/AlgBubbleSort1Entity.scala
@@ -0,0 +1,27 @@
+package lessons.sort.bubble;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgBubbleSort1Entity extends SortingEntity {
+
+	override def run() {
+		bubbleSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def bubbleSort()  {
+		/* BEGIN SOLUTION */
+		var swapped= false
+		do {
+			swapped = false;
+			for (i <- 0 to getValueCount()-2)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}
+		} while (swapped);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/sort/bubble/AlgBubbleSort2.java b/src/lessons/sort/bubble/AlgBubbleSort2.java
index 48fdd14..bcb0bb4 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort2.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort2.java
@@ -1,9 +1,9 @@
 package lessons.sort.bubble;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgBubbleSort2 extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort2Entity.java b/src/lessons/sort/bubble/AlgBubbleSort2Entity.java
index da1c5e5..009e0ca 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort2Entity.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort2Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.bubble;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgBubbleSort2Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort2Entity.scala b/src/lessons/sort/bubble/AlgBubbleSort2Entity.scala
new file mode 100644
index 0000000..ccaca8c
--- /dev/null
+++ b/src/lessons/sort/bubble/AlgBubbleSort2Entity.scala
@@ -0,0 +1,21 @@
+package lessons.sort.bubble;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgBubbleSort2Entity extends SortingEntity {
+
+	override def run() {
+		bubbleSort2();
+	}
+
+	/* BEGIN TEMPLATE */
+	def bubbleSort2() {
+		/* BEGIN SOLUTION */
+		for (i <- getValueCount()-1 to 0 by -1; j <- 0 to i-1) 
+			if (!isSmaller(j,j+1)) 
+				swap(j,j+1);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
+
diff --git a/src/lessons/sort/bubble/AlgBubbleSort3.java b/src/lessons/sort/bubble/AlgBubbleSort3.java
index b7c26e1..b544ca0 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort3.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort3.java
@@ -1,9 +1,9 @@
 package lessons.sort.bubble;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgBubbleSort3 extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort3Entity.java b/src/lessons/sort/bubble/AlgBubbleSort3Entity.java
index 169ec58..f867403 100644
--- a/src/lessons/sort/bubble/AlgBubbleSort3Entity.java
+++ b/src/lessons/sort/bubble/AlgBubbleSort3Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.bubble;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgBubbleSort3Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/bubble/AlgBubbleSort3Entity.scala b/src/lessons/sort/bubble/AlgBubbleSort3Entity.scala
new file mode 100644
index 0000000..cb26cb0
--- /dev/null
+++ b/src/lessons/sort/bubble/AlgBubbleSort3Entity.scala
@@ -0,0 +1,31 @@
+package lessons.sort.bubble;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgBubbleSort3Entity extends SortingEntity {
+
+	override def run() {
+		bubbleSort3();
+	}
+
+	/* BEGIN TEMPLATE */
+	def bubbleSort3() {
+		/* BEGIN SOLUTION */
+		for (i <- getValueCount()-1 to 0 by -1) {
+			var swapped = false;
+			for (j <- 0 to i-1) {
+				if (!isSmaller(j,j+1)) {
+					swap(j,j+1);
+					swapped=true;
+				}
+			}
+			if (!swapped) {
+				return;	
+			}
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort1.java b/src/lessons/sort/cocktail/AlgCocktailSort1.java
index 0c58caf..c996e59 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort1.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort1.java
@@ -1,9 +1,9 @@
 package lessons.sort.cocktail;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgCocktailSort1 extends ExerciseTemplated {
 	
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort1Entity.java b/src/lessons/sort/cocktail/AlgCocktailSort1Entity.java
index 05e044e..f8f985e 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort1Entity.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort1Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.cocktail;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgCocktailSort1Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort1Entity.scala b/src/lessons/sort/cocktail/AlgCocktailSort1Entity.scala
new file mode 100644
index 0000000..b204953
--- /dev/null
+++ b/src/lessons/sort/cocktail/AlgCocktailSort1Entity.scala
@@ -0,0 +1,33 @@
+package lessons.sort.cocktail;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgCocktailSort1Entity extends SortingEntity {
+
+	override def run() {
+		cocktailSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def cocktailSort() {
+		/* BEGIN SOLUTION */
+		var swapped = false;
+		do {
+			swapped = false;
+			for (i <- 0 to getValueCount()-2)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}	
+			for (i <- getValueCount()-2 to 0 by -1)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}	
+		} while (swapped);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort2.java b/src/lessons/sort/cocktail/AlgCocktailSort2.java
index 5f76a3a..d53658a 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort2.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort2.java
@@ -1,9 +1,9 @@
 package lessons.sort.cocktail;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgCocktailSort2 extends ExerciseTemplated {
 	
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort2Entity.java b/src/lessons/sort/cocktail/AlgCocktailSort2Entity.java
index 7affe3c..42e2110 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort2Entity.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort2Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.cocktail;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgCocktailSort2Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort2Entity.scala b/src/lessons/sort/cocktail/AlgCocktailSort2Entity.scala
new file mode 100644
index 0000000..bb1e019
--- /dev/null
+++ b/src/lessons/sort/cocktail/AlgCocktailSort2Entity.scala
@@ -0,0 +1,37 @@
+package lessons.sort.cocktail;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgCocktailSort2Entity extends SortingEntity {
+
+	override def run() {
+		cocktailSort2();
+	}
+
+	/* BEGIN TEMPLATE */
+	def cocktailSort2() {
+		/* BEGIN SOLUTION */
+		var swapped=false;
+		var begin=0;
+		var end=getValueCount()-2;
+		do {
+			swapped = false;
+			for (i <- begin to end)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}
+			end-=1;
+			for (i <- end to begin by -1)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}
+			begin+=1;
+		} while (swapped && end-begin>1);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort3.java b/src/lessons/sort/cocktail/AlgCocktailSort3.java
index 60f754b..7fd4097 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort3.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort3.java
@@ -1,9 +1,9 @@
 package lessons.sort.cocktail;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgCocktailSort3 extends ExerciseTemplated {
 	
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort3Entity.java b/src/lessons/sort/cocktail/AlgCocktailSort3Entity.java
index a9893c0..fe4e591 100644
--- a/src/lessons/sort/cocktail/AlgCocktailSort3Entity.java
+++ b/src/lessons/sort/cocktail/AlgCocktailSort3Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.cocktail;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgCocktailSort3Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/cocktail/AlgCocktailSort3Entity.scala b/src/lessons/sort/cocktail/AlgCocktailSort3Entity.scala
new file mode 100644
index 0000000..92abbff
--- /dev/null
+++ b/src/lessons/sort/cocktail/AlgCocktailSort3Entity.scala
@@ -0,0 +1,40 @@
+package lessons.sort.cocktail;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgCocktailSort3Entity extends SortingEntity {
+
+	override def run() {
+		cocktailSort3();
+	}
+
+	/* BEGIN TEMPLATE */
+	def cocktailSort3() {
+		/* BEGIN SOLUTION */
+		var swapped=false;
+		var begin=0;
+		var end=getValueCount()-2;
+		do {
+			swapped = false;
+			for (i <- begin to end)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}
+			if (!swapped) 
+				return;
+			
+			swapped=false;
+			end-=1;
+			for (i <- end to begin by -1)
+				if (!isSmaller(i,i+1)) {
+					swap(i,i+1);
+					swapped =true;
+				}
+			begin+=1;
+		} while (swapped && end-begin>1);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
+
diff --git a/src/lessons/sort/comb/AlgCombSort.fr.html b/src/lessons/sort/comb/AlgCombSort.fr.html
index c396b36..7ed9476 100644
--- a/src/lessons/sort/comb/AlgCombSort.fr.html
+++ b/src/lessons/sort/comb/AlgCombSort.fr.html
@@ -24,6 +24,22 @@ fois amène de bons résultats. Voici le pseudo-code correspondant :</p>
  tant que l'écart est plus grand que 1 ou que le dernier parcours a inversé au moins un élément
 </pre>
 
+[!scala]<p>L'un des problèmes à résoudre est que la variable <code>ecart</code> est
+entière, et que nous voulons la diviser par 1.3, qui est un double. Le
+système de types de scala ne vous laissera pas faire une chose pareil sans
+broncher. C'est que ce genre de disparité est souvent le signe de problèmes
+que le programmeur n'a pas vu. Comme ce n'est pas une erreur dans notre cas,
+nous allons devoir convertir <code>ecart</code> en double pour le temps de
+l'opération, puis convertir le résultat de retour en entier pour le stocker
+dans <code>ecart</code>. Cela s'écrit de la manière suivante:</p>
+<pre>ecart = (ecart.asInstanceOf[Double] / 1.3).asInstanceOf[Int]</pre>
+<p>C'est un peu bavard, mais finalement, cette écriture n'est pas très
+complexe. Et n'oubliez pas que le système de types est votre ami. Il est un
+peu tatillon et parfois un peu pénible (comme aujourd'hui), mais au fond, il
+trouve souvent des bugs bizarres qui auraient été très pénibles à débugger
+s'il ne les avait pas attrapé à la source.</p>
+[/!]
+
 <p>Cet algorithme a été inventé par Wlodek Dobosiewicz en 1980 et redécouvert
 et popularisé par Stephen Lacey et Richard Box, qui l'ont décrit dans le
-magazine Byte d'avril 1991.</p>
\ No newline at end of file
+magazine Byte d'avril 1991.</p>
diff --git a/src/lessons/sort/comb/AlgCombSort.html b/src/lessons/sort/comb/AlgCombSort.html
index 420791b..3f91ea7 100644
--- a/src/lessons/sort/comb/AlgCombSort.html
+++ b/src/lessons/sort/comb/AlgCombSort.html
@@ -23,6 +23,16 @@ do
 while the gap is bigger than 1 or the last traversal swapped at least one pair
 </pre>
 
+[!scala]<p>One tricky part is that we want to divide gap, that is an integer, by 1.3, that is a double.
+The type system of scala won't let us do this, because such discrepency usually denotes a programmer error.
+As this is not an error this time, we have to convert gap to Double for the time of the operation, 
+and then convert the result back to Int to store it into gap. This should be written this way:</p>
+<pre>gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int]</pre>
+<p>This is rather verbose, but actually, this notation is not very complex. And remember that the type checker
+is your friend. It's picky and sometimes annoying (as on this one), but it often catches weird bugs that
+would have been a pain to debug if not catched by the type checker.</p>
+[/!]
+
 <p>This algorithm was invented by Wlodek Dobosiewicz in 1980, and later
 rediscovered and popularized by Stephen Lacey and Richard Box, who described
-it in Byte Magazine in April 1991.</p>
\ No newline at end of file
+it in Byte Magazine in April 1991.</p>
diff --git a/src/lessons/sort/comb/AlgCombSort.java b/src/lessons/sort/comb/AlgCombSort.java
index e7c0b69..98ce91c 100644
--- a/src/lessons/sort/comb/AlgCombSort.java
+++ b/src/lessons/sort/comb/AlgCombSort.java
@@ -1,9 +1,9 @@
 package lessons.sort.comb;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgCombSort extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/comb/AlgCombSort11.java b/src/lessons/sort/comb/AlgCombSort11.java
index d6353fc..ee9d6d3 100644
--- a/src/lessons/sort/comb/AlgCombSort11.java
+++ b/src/lessons/sort/comb/AlgCombSort11.java
@@ -1,9 +1,9 @@
 package lessons.sort.comb;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgCombSort11 extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/comb/AlgCombSort11Entity.java b/src/lessons/sort/comb/AlgCombSort11Entity.java
index 14375c8..fd7a25c 100644
--- a/src/lessons/sort/comb/AlgCombSort11Entity.java
+++ b/src/lessons/sort/comb/AlgCombSort11Entity.java
@@ -1,6 +1,6 @@
 package lessons.sort.comb;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgCombSort11Entity extends SortingEntity {
 
diff --git a/src/lessons/sort/comb/AlgCombSort11Entity.scala b/src/lessons/sort/comb/AlgCombSort11Entity.scala
new file mode 100644
index 0000000..1630f8e
--- /dev/null
+++ b/src/lessons/sort/comb/AlgCombSort11Entity.scala
@@ -0,0 +1,34 @@
+package lessons.sort.comb;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgCombSort11Entity extends SortingEntity {
+
+	override def run() {
+		combSort11();
+	}
+
+	/* BEGIN TEMPLATE */
+	def combSort11() {
+		/* BEGIN SOLUTION */
+		var gap = getValueCount();
+		var swapped=false;
+		do {
+			if (gap>1) {
+				gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int];
+				if (gap == 10 || gap == 9)
+					gap = 11;
+			}
+			swapped = false;
+			for (i <- 0 to getValueCount()-gap-1)
+				if (!isSmaller(i,i+gap)) {
+					swap(i,i+gap);
+					swapped =true;
+				}	
+		} while (gap>1 || swapped);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/comb/AlgCombSortEntity.java b/src/lessons/sort/comb/AlgCombSortEntity.java
index 04a3e96..1b75713 100644
--- a/src/lessons/sort/comb/AlgCombSortEntity.java
+++ b/src/lessons/sort/comb/AlgCombSortEntity.java
@@ -1,6 +1,6 @@
 package lessons.sort.comb;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgCombSortEntity extends SortingEntity {
 
diff --git a/src/lessons/sort/comb/AlgCombSortEntity.scala b/src/lessons/sort/comb/AlgCombSortEntity.scala
new file mode 100644
index 0000000..c07410c
--- /dev/null
+++ b/src/lessons/sort/comb/AlgCombSortEntity.scala
@@ -0,0 +1,31 @@
+package lessons.sort.comb;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgCombSortEntity extends SortingEntity {
+
+	override def run() {
+		combSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def combSort() {
+		/* BEGIN SOLUTION */
+		var gap = getValueCount();
+		var swapped=false;
+		do {
+			if (gap>1) 
+				gap = (gap.asInstanceOf[Double] / 1.3).asInstanceOf[Int];
+			swapped = false;
+			for (i <- 0 to getValueCount()-gap-1)
+				if (!isSmaller(i,i+gap)) {
+					swap(i,i+gap);
+					swapped =true;
+				}	
+		} while (gap>1 || swapped);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/gnome/AlgGnomeSort.java b/src/lessons/sort/gnome/AlgGnomeSort.java
index 365930a..ce2341e 100644
--- a/src/lessons/sort/gnome/AlgGnomeSort.java
+++ b/src/lessons/sort/gnome/AlgGnomeSort.java
@@ -1,9 +1,9 @@
 package lessons.sort.gnome;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgGnomeSort extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/gnome/AlgGnomeSortEntity.java b/src/lessons/sort/gnome/AlgGnomeSortEntity.java
index 90075a0..8497d5b 100644
--- a/src/lessons/sort/gnome/AlgGnomeSortEntity.java
+++ b/src/lessons/sort/gnome/AlgGnomeSortEntity.java
@@ -1,6 +1,6 @@
 package lessons.sort.gnome;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgGnomeSortEntity extends SortingEntity {
 
diff --git a/src/lessons/sort/gnome/AlgGnomeSortEntity.scala b/src/lessons/sort/gnome/AlgGnomeSortEntity.scala
new file mode 100644
index 0000000..2e3c6b5
--- /dev/null
+++ b/src/lessons/sort/gnome/AlgGnomeSortEntity.scala
@@ -0,0 +1,30 @@
+package lessons.sort.gnome;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgGnomeSortEntity extends SortingEntity {
+
+	override def run() {
+		gnomeSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def gnomeSort() {
+		/* BEGIN SOLUTION */
+		var i=0;
+		while (i<getValueCount()-1) {
+			if (isSmaller(i,i+1))
+				i+=1;
+			else {
+				swap(i,i+1);
+				i-=1;
+			}
+			if (i == -1)
+				i=0;
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/insertion/AlgInsertionSort.java b/src/lessons/sort/insertion/AlgInsertionSort.java
index 2a80a48..84deeb0 100644
--- a/src/lessons/sort/insertion/AlgInsertionSort.java
+++ b/src/lessons/sort/insertion/AlgInsertionSort.java
@@ -1,9 +1,9 @@
 package lessons.sort.insertion;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgInsertionSort extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/insertion/AlgInsertionSortEntity.java b/src/lessons/sort/insertion/AlgInsertionSortEntity.java
index 2aff55c..878a578 100644
--- a/src/lessons/sort/insertion/AlgInsertionSortEntity.java
+++ b/src/lessons/sort/insertion/AlgInsertionSortEntity.java
@@ -1,6 +1,6 @@
 package lessons.sort.insertion;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgInsertionSortEntity extends SortingEntity {
 
diff --git a/src/lessons/sort/insertion/AlgInsertionSortEntity.scala b/src/lessons/sort/insertion/AlgInsertionSortEntity.scala
new file mode 100644
index 0000000..d5409e2
--- /dev/null
+++ b/src/lessons/sort/insertion/AlgInsertionSortEntity.scala
@@ -0,0 +1,28 @@
+package lessons.sort.insertion;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgInsertionSortEntity extends SortingEntity {
+
+	override def run() {
+		insertionSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def insertionSort() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to getValueCount()-1) {
+			var value = getValue(i);
+			var j = i;
+			while ((j > 0) && (!isSmallerThan(j-1,value))) {
+				copy(j-1,j);
+				j-=1;
+			}
+			setValue(j,value);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/sort/pancake/BasicPancake.java b/src/lessons/sort/pancake/BasicPancake.java
index 8e74441..f477f5b 100644
--- a/src/lessons/sort/pancake/BasicPancake.java
+++ b/src/lessons/sort/pancake/BasicPancake.java
@@ -1,7 +1,7 @@
 package lessons.sort.pancake;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.pancake.universe.PancakeEntity;
 import lessons.sort.pancake.universe.PancakeWorld;
 
diff --git a/src/lessons/sort/pancake/BasicPancakeEntity.scala b/src/lessons/sort/pancake/BasicPancakeEntity.scala
new file mode 100644
index 0000000..fe5a11f
--- /dev/null
+++ b/src/lessons/sort/pancake/BasicPancakeEntity.scala
@@ -0,0 +1,35 @@
+package lessons.sort.pancake;
+
+import lessons.sort.pancake.universe.PancakeEntity;
+
+class ScalaBasicPancakeEntity extends PancakeEntity {
+
+	override def run() {
+		solve();
+	}
+
+	/* BEGIN TEMPLATE */
+	def solve() {
+		/* BEGIN SOLUTION */		
+		for (rank <- getStackSize()-1 to 0 by -1) {
+			if (isSorted()) 
+				return;
+			if ( getPancakeRadius(rank) != rank+1 ) { // Current pancake is still to be sorted
+				var indexBigPancake = -1
+				for (currentPancake <- 0 to rank)
+					if ( getPancakeRadius(currentPancake) == rank+1) 
+						indexBigPancake = currentPancake;	// gotcha !
+
+				if ( indexBigPancake != 0 )
+					flip(indexBigPancake+1);	// putting the pancake at the top
+
+				if ( rank != 0 )
+					flip(getPancakeRadius(0));	// hit the bottom now !
+			}	
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+
+}
diff --git a/src/lessons/sort/pancake/BurnedPancake.java b/src/lessons/sort/pancake/BurnedPancake.java
index 3abeb8e..23434bb 100644
--- a/src/lessons/sort/pancake/BurnedPancake.java
+++ b/src/lessons/sort/pancake/BurnedPancake.java
@@ -1,7 +1,7 @@
 package lessons.sort.pancake;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.pancake.universe.PancakeEntity;
 import lessons.sort.pancake.universe.PancakeWorld;
 
diff --git a/src/lessons/sort/pancake/BurnedPancakeEntity.scala b/src/lessons/sort/pancake/BurnedPancakeEntity.scala
new file mode 100644
index 0000000..fc1976b
--- /dev/null
+++ b/src/lessons/sort/pancake/BurnedPancakeEntity.scala
@@ -0,0 +1,42 @@
+package lessons.sort.pancake;
+
+import lessons.sort.pancake.universe.PancakeEntity;
+
+class ScalaBurnedPancakeEntity extends PancakeEntity {
+
+
+	override def run() {
+		solve();
+	}
+
+	/* BEGIN TEMPLATE */
+	def solve() {
+		/* BEGIN SOLUTION */
+		val stackSize = getStackSize();
+		for ( rank <- stackSize-1 to 0 by -1) {
+			
+			if ( getPancakeRadius(rank)!=rank+1 || isPancakeUpsideDown(rank)) { // current pancake not sorted yet
+				var indexBigPancake = -1;
+				for (currentPancake <- 0 to rank)
+					if ( getPancakeRadius(currentPancake) == rank+1) 
+						indexBigPancake = currentPancake;	// gotcha !
+				
+				if ( indexBigPancake != 0 )
+					flip(indexBigPancake+1);	// move that pancake to the top
+					
+				if ( ! ( rank == 0) ) {
+					if (!isPancakeUpsideDown(0)) 
+						flip(1);	// show your dark side to the world
+					flip(getPancakeRadius(0));	// hit the bottom !
+				} else {
+					if (isPancakeUpsideDown(0)) 
+						flip(1);	// show your dark side to the world
+					
+				}
+			}	
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/sort/pancake/GatesPancake.java b/src/lessons/sort/pancake/GatesPancake.java
index bf21579..6bc73b1 100644
--- a/src/lessons/sort/pancake/GatesPancake.java
+++ b/src/lessons/sort/pancake/GatesPancake.java
@@ -1,7 +1,7 @@
 package lessons.sort.pancake;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.sort.pancake.universe.PancakeEntity;
 import lessons.sort.pancake.universe.PancakeWorld;
 
diff --git a/src/lessons/sort/pancake/GatesPancakeEntity.scala b/src/lessons/sort/pancake/GatesPancakeEntity.scala
new file mode 100644
index 0000000..c3c86ef
--- /dev/null
+++ b/src/lessons/sort/pancake/GatesPancakeEntity.scala
@@ -0,0 +1,287 @@
+package lessons.sort.pancake;
+
+import lessons.sort.pancake.universe.PancakeEntity;
+import lessons.sort.pancake.universe.PancakeWorld;
+
+
+
+/* This is not exactly the gates algorithm. Here is the original text:
+ * <ul><li><b>Case f</b>: <code>t</code> is in a block of length k+1 (the last element is <code>t+ko</code>), <code>t-o</code>
+ * is the last element of another block and <code>t+(k+1)o</code> is free (there is two differing situation, depending on the relative order of 
+ * <code>t-o</code> and <code>t+(k+1)o</code>. They are merged in 4 flip with the corresponding sequence below.<br/>
+ * <div align="center"><img src="lessons/sort/pancake/gates-f1.png"/></div><br/>
+ * Other possibility when <code>t-o > t+(k+1)o</code>:<br/>
+ * <div align="center"><img src="lessons/sort/pancake/gates-f2.png"/></div></li></ul>
+
+ */
+
+
+class ScalaGatesPancakeEntity extends PancakeEntity {
+
+	override def run() {
+		solve();
+	}
+
+	/* BEGIN HIDDEN */
+	def getRankOf(size:Int ): Int = {
+		for (rank <- 0 to getStackSize()-1)
+			if (getPancakeRadius(rank) == size)
+				return rank;
+		return -99; // Well, be robust to border cases 
+	}
+	def isFree(pos:Int):Boolean = {
+		if (pos == -99)
+			return false;
+		val radius = getPancakeRadius(pos);
+		if (pos>0) {
+			val nextRadius = getPancakeRadius(pos-1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return false;
+		}
+		if (pos<getStackSize()-1) {
+			val nextRadius = getPancakeRadius(pos+1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return false;
+		}
+		return true;
+	}
+	def isFirst(pos:Int):Boolean = {
+		if (pos == -99)
+			return false;
+		val radius = getPancakeRadius(pos);
+		if (pos>0) {
+			val nextRadius = getPancakeRadius(pos-1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return false;
+		}
+		if (pos<getStackSize()-1) {
+			val nextRadius = getPancakeRadius(pos+1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return true;
+		}
+		return false;
+	}
+	def isLast(pos:Int):Boolean = {
+		if (pos == -99)
+			return false;
+		val radius = getPancakeRadius(pos);
+		if (pos<getStackSize()-1) {
+			val nextRadius = getPancakeRadius(pos+1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return false;
+		}
+		if (pos>0) {
+			val nextRadius = getPancakeRadius(pos-1);
+			if (nextRadius == radius-1 || nextRadius == radius+1)
+				return true;
+		}
+		return false;
+	}
+	def blockLength():Int = {
+		var pos = 0;
+		var radius = getPancakeRadius(pos);
+		val o = getPancakeRadius(pos+1) - radius;
+		
+		if (o != -1 && o != 1) {
+			System.out.println("Asked to compute the block length, but the step o is "+o+" instead of +1 or -1. " +
+					"The length is then 1, but you are violating a precondition somehow");
+			return 1;
+		}
+		
+		while (pos < getStackSize()-1 && getPancakeRadius(pos+1) == radius + o) {
+			pos+=1;
+			radius += o;
+		}
+		return pos+1;
+	}
+	val debug=0; // 0: silence; 1: which cases; 2: all details
+	/* END HIDDEN */
+	
+	/* BEGIN TEMPLATE */
+	def solve() {
+		/* BEGIN SOLUTION */
+		/* cruft to search for an instance exercising all transformations */
+		var doneA=false;
+		var doneB=false;
+		var doneC=false;
+		var doneD=false;
+		var doneE=false;
+		var doneF=false;
+		var doneG=false;
+		var doneH=false;
+		val origSizes = new Array[Integer] (getStackSize());
+		for (i <- 0 to getStackSize()-1)
+			origSizes(i) = getPancakeRadius(i);
+		/* end of this cruft */
+		
+		val stackSize = getStackSize();
+		
+		if (debug>0) {
+			System.out.print("{");
+			for (rank <- 0 to stackSize -1) 
+				System.out.print(""+getPancakeRadius(rank)+", ");
+			System.out.println("}");
+		}
+		
+		while (true) {
+			val tRadius = getPancakeRadius(0);
+			val posTPlus  = getRankOf(tRadius+1); // returns -99 if non-existent, that is then ignored
+			val posTMinus = getRankOf(tRadius-1); 
+			val posT = 0;
+			
+			if (debug>1) {
+				println("t Radius: "+tRadius);
+				for (rank <- 0 to stackSize -1) {
+					print("["+rank+"]="+getPancakeRadius(rank)+"; ");
+
+					if (isFree(rank))
+						System.out.print("free;");
+					else 
+						System.out.print("NON-free;");
+
+					if (isFirst(rank))
+						System.out.print("first; ");
+					else 
+						System.out.print("NON-first; ");
+
+					if (isLast(rank))
+						System.out.print("last; ");
+					else 
+						System.out.print("NON-last; ");
+
+
+					if (rank == posTPlus)
+						System.out.print("t+1; ");
+					if (rank == posTMinus)
+						System.out.print("t-1; ");
+					if (rank == posT)
+						System.out.print("t;" );
+
+					System.out.println();
+				}
+			}
+						
+			if (isFree(posT)) {			
+				if (isFree(posTPlus)) { /* CASE A: t and t+o free */
+					if (debug>0)
+						System.out.println("Case A+");
+					flip(posTPlus);
+					doneA = true;
+				} else if (isFree(posTMinus)) { /* CASE A: t and t-o free */
+					if (debug>0)
+						System.out.println("Case A-");
+					flip(posTMinus);
+					doneA = true;
+					
+				} else if (isFirst(posTPlus)) { /* CASE B: t free, t+o first element */
+					if (debug>0)
+						System.out.println("Case B+");
+					flip(posTPlus);
+					doneB = true;
+				} else if (isFirst(posTMinus)) { /* CASE B: t free, t-o first element */
+					if (debug>0)
+						System.out.println("Case B-");
+					flip(posTMinus);
+					doneB = true;
+
+				} else if (Math.min(posTPlus,posTMinus) != -99) { /* CASE C: t free, but both t+o and t-o are last elements */
+					if (debug>0)
+						System.out.println("Case C");
+					flip(Math.min(posTPlus,posTMinus) );
+					flip(Math.min(posTPlus,posTMinus) - 1);
+					flip(Math.max(posTPlus,posTMinus) + 1);
+					flip(Math.min(posTPlus,posTMinus) - 1);
+					doneC = true;
+					
+				} else {
+					if (debug>0)
+						System.out.println("Case Cbis");
+					flip(Math.max(posTPlus,posTMinus) + 1);
+					flip(Math.max(posTPlus,posTMinus) );
+					doneC = true;
+				}
+				
+			} else { // t is in a block
+				if (blockLength() == stackSize) { // Done!
+					if (tRadius != 1) // all reverse 
+						flip(stackSize);
+					if (doneA && doneB && doneC && doneD && doneE && doneF && doneG && doneH && world.asInstanceOf[PancakeWorld].wasRandom) {
+						System.out.println("BINGO! This instance is VERY interesting as it experiences every cases of the algorithm.\nPLEASE REPORT IT. PLEASE DONT LOSE IT.");
+						System.out.print("{");
+						for (rank <- 0 to stackSize) 
+							System.out.print(""+origSizes(rank)+", ");
+						System.out.println("}");
+					}
+					return;
+				}
+				
+				if (isFree(posTPlus)) {          /* CASE D: t in a block, t+1 free */
+					if (debug>0)
+						System.out.println("Case D+");
+					flip(posTPlus);
+					doneD = true;
+
+				} else if (isFree(posTMinus)) {  /* CASE D: t in a block, t-1 free */
+					if (debug>0)
+						System.out.println("Case D-");
+					flip(posTMinus);
+					doneD = true;
+
+				} else if (isFirst(posTPlus)) {  /* CASE E: t in a block, t+1 first element */
+					if (debug>0)
+						System.out.println("Case E+");
+					flip(posTPlus);
+					doneE = true;
+
+				} else if (isFirst(posTMinus)) { /* CASE E: t in a block, t-1 first element */
+					if (debug>0)
+						System.out.println("Case E-");
+					flip(posTMinus);
+					doneE = true;
+
+				} else if (isLast(posTPlus) && posTPlus != 1) { /* CASE F+: t in a block, t+1 last element */
+					doneF = true;
+					if (debug>0)
+						System.out.println("Case F+");
+					flip(blockLength());
+					flip(posTPlus + 1);
+					val newPos = getRankOf(tRadius);
+					if (newPos>0)
+						flip(newPos);
+					
+				} else if (isLast(posTMinus) && posTMinus != 1) { /* CASE F-: t in a block, t-1 last element */
+					doneF = true;
+					if (debug>0)
+						System.out.println("Case F-");
+					flip(blockLength());
+					flip(posTMinus + 1);
+					val newPos = getRankOf(tRadius);
+					if (newPos>0)
+						flip(newPos);
+				} else {
+					val k = blockLength()-1;
+					val o = getPancakeRadius(1) - tRadius;
+					val pos = getRankOf(tRadius+(k+1)*o);
+					if (isFree(pos) || isFirst(pos)) {
+						doneG = true;
+						if (debug>0)
+							System.out.println("Case G");
+						flip(k+1);
+						flip(pos);
+					} else {
+						doneH = true;
+						if (debug>0)
+							System.out.println("Case H");
+						flip(pos+1);
+						flip(getRankOf(tRadius+k*o));
+					}
+				}
+			}
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+
+}
+ 
\ No newline at end of file
diff --git a/src/lessons/sort/pancake/Main.fr.html b/src/lessons/sort/pancake/Main.fr.html
index f1ab110..b463c89 100644
--- a/src/lessons/sort/pancake/Main.fr.html
+++ b/src/lessons/sort/pancake/Main.fr.html
@@ -33,10 +33,10 @@ faite: http://eljjdx.canalblog.com/archives/2013/02/03/26309722.html</p>
 débranchées <i>libres</i> pour introduire la science informatique,
 disponible à l'adresse http://www.loria.fr/~quinson/Mediation/SMN/), et il
 peut être intéressant de faire les activités débranchées avant d'implémenter
-ces algorithmes dans JLM.</p>
+ces algorithmes dans PLM.</p>
 
 
-<h3>Que puis-je faire pour améliorer cet univers de JLM?</h3>
+<h3>Que puis-je faire pour améliorer cet univers de PLM?</h3>
 
 <p>Comme souvent, plusieurs points pourraient être améliorés dans le code de
 cet univers pour l'améliorer :</p>
diff --git a/src/lessons/sort/pancake/Main.html b/src/lessons/sort/pancake/Main.html
index 50d7e80..17e0e5d 100644
--- a/src/lessons/sort/pancake/Main.html
+++ b/src/lessons/sort/pancake/Main.html
@@ -23,10 +23,10 @@ That's determining the minimal amount of steps that is NP.</p>
 unplugged activities to introduce computer science, available at
 http://www.loria.fr/~quinson/Mediation/SMN/), and it may be
 interesting to run the unplugged activities before implementing these
-algorithms in JLM.</p>
+algorithms in PLM.</p>
 
 
-<h3>What can I do to improve this JLM universe?</h3>
+<h3>What can I do to improve this PLM universe?</h3>
 
 <p>As usual, there are several things that could be done in the code of this universe to improve it:</p>
 <ul>
diff --git a/src/lessons/sort/pancake/Main.java b/src/lessons/sort/pancake/Main.java
index 77727a4..9d8a412 100644
--- a/src/lessons/sort/pancake/Main.java
+++ b/src/lessons/sort/pancake/Main.java
@@ -1,6 +1,6 @@
 package lessons.sort.pancake;
 
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Lesson;
 
 // see http://www.cs.ubc.ca/~harrison/Java/sorting-demo.html
 
diff --git a/src/lessons/sort/pancake/img/gates-a.svg b/src/lessons/sort/pancake/img/gates-a.svg
index 7df05aa..045a8b2 100644
--- a/src/lessons/sort/pancake/img/gates-a.svg
+++ b/src/lessons/sort/pancake/img/gates-a.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-a.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-a.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-a.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-b.svg b/src/lessons/sort/pancake/img/gates-b.svg
index 6943fd0..44e8300 100644
--- a/src/lessons/sort/pancake/img/gates-b.svg
+++ b/src/lessons/sort/pancake/img/gates-b.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-b.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-b.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-b.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-c.svg b/src/lessons/sort/pancake/img/gates-c.svg
index f00c6dc..dbdccfb 100644
--- a/src/lessons/sort/pancake/img/gates-c.svg
+++ b/src/lessons/sort/pancake/img/gates-c.svg
@@ -16,7 +16,7 @@
    height="226"
    xml:space="preserve"
    sodipodi:docname="gates-c.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-c.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-c.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90"><metadata
      id="metadata8"><rdf:RDF><cc:Work
@@ -539,7 +539,7 @@
        x="60"
        y="-19.999987"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90" /><text
        xml:space="preserve"
@@ -549,7 +549,7 @@
        id="text4100-1-9-7-4-0-3-1-8-7"
        sodipodi:linespacing="125%"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90"><tspan
          sodipodi:role="line"
@@ -572,7 +572,7 @@
        x="-59.999992"
        y="-19.999989"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90" /><text
        xml:space="preserve"
@@ -582,7 +582,7 @@
        id="text4100-1-8-7-5-7-1"
        sodipodi:linespacing="125%"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90"><tspan
          sodipodi:role="line"
@@ -605,7 +605,7 @@
        x="-39.999992"
        y="-19.999989"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90" /><rect
        style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.80000001;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
@@ -615,7 +615,7 @@
        x="20.000008"
        y="-19.999987"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90" /><rect
        style="fill:#dcdcdc;fill-opacity:1;stroke:#000000;stroke-width:0.80000001;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
@@ -625,7 +625,7 @@
        x="-160.00002"
        y="-19.999987"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90" /><text
        xml:space="preserve"
@@ -635,7 +635,7 @@
        id="text4100-1-8-4-5-8-6-0"
        sodipodi:linespacing="125%"
        transform="scale(1,-1)"
-       inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
+       inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-6-5-7-4-8.png"
        inkscape:export-xdpi="90"
        inkscape:export-ydpi="90"><tspan
          sodipodi:role="line"
diff --git a/src/lessons/sort/pancake/img/gates-d.svg b/src/lessons/sort/pancake/img/gates-d.svg
index 51d8473..63d55f4 100644
--- a/src/lessons/sort/pancake/img/gates-d.svg
+++ b/src/lessons/sort/pancake/img/gates-d.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-d.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-d.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-d.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-e.svg b/src/lessons/sort/pancake/img/gates-e.svg
index 9dff5b4..a6623ae 100644
--- a/src/lessons/sort/pancake/img/gates-e.svg
+++ b/src/lessons/sort/pancake/img/gates-e.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-e.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-e.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-e.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-f.svg b/src/lessons/sort/pancake/img/gates-f.svg
index e941b6e..929b63c 100644
--- a/src/lessons/sort/pancake/img/gates-f.svg
+++ b/src/lessons/sort/pancake/img/gates-f.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-f.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-f.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-f.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-f1.svg b/src/lessons/sort/pancake/img/gates-f1.svg
index 06f75b2..453c476 100644
--- a/src/lessons/sort/pancake/img/gates-f1.svg
+++ b/src/lessons/sort/pancake/img/gates-f1.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-f1.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-f1.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-f1.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
@@ -532,7 +532,7 @@
      y="6146.2603"
      id="text4100-3-1-0-7"
      sodipodi:linespacing="125%"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90"><tspan
        sodipodi:role="line"
@@ -554,7 +554,7 @@
      height="334.52393"
      x="4370.8813"
      y="5877.4238"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90" />
   <rect
@@ -564,7 +564,7 @@
      height="334.52383"
      x="5708.9766"
      y="5877.4238"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90" />
   <text
@@ -574,7 +574,7 @@
      y="6138.8984"
      id="text4100-9-2-6-0-4"
      sodipodi:linespacing="125%"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90"><tspan
        sodipodi:role="line"
@@ -596,7 +596,7 @@
      height="334.52393"
      x="3032.7859"
      y="5877.4238"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90" />
   <rect
@@ -613,7 +613,7 @@
      height="334.52383"
      x="1694.6904"
      y="5877.4238"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90" />
   <text
@@ -623,7 +623,7 @@
      y="6151.5972"
      id="text4100-1-9-7-4-3"
      sodipodi:linespacing="125%"
-     inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
+     inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/rect4158-5-9-9-3-5-8-5-6.png"
      inkscape:export-xdpi="90"
      inkscape:export-ydpi="90"><tspan
        sodipodi:role="line"
diff --git a/src/lessons/sort/pancake/img/gates-f2.svg b/src/lessons/sort/pancake/img/gates-f2.svg
index 3f09fda..7ae8058 100644
--- a/src/lessons/sort/pancake/img/gates-f2.svg
+++ b/src/lessons/sort/pancake/img/gates-f2.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-f2.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-f2.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-f2.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-g.svg b/src/lessons/sort/pancake/img/gates-g.svg
index 96b557e..f862109 100644
--- a/src/lessons/sort/pancake/img/gates-g.svg
+++ b/src/lessons/sort/pancake/img/gates-g.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-g1.fig.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-g1.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-g1.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/img/gates-h.svg b/src/lessons/sort/pancake/img/gates-h.svg
index 8cc8b33..0ef9bee 100644
--- a/src/lessons/sort/pancake/img/gates-h.svg
+++ b/src/lessons/sort/pancake/img/gates-h.svg
@@ -20,7 +20,7 @@
    version="1.1"
    inkscape:version="0.48.3.1 r9886"
    sodipodi:docname="gates-h.svg"
-   inkscape:export-filename="/home/mquinson/Code/JLM/src/lessons/sort/pancake/gates-h.png"
+   inkscape:export-filename="/home/mquinson/Code/PLM/src/lessons/sort/pancake/gates-h.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90">
   <metadata
diff --git a/src/lessons/sort/pancake/universe/PancakeEntity.java b/src/lessons/sort/pancake/universe/PancakeEntity.java
index d56be06..21aa165 100644
--- a/src/lessons/sort/pancake/universe/PancakeEntity.java
+++ b/src/lessons/sort/pancake/universe/PancakeEntity.java
@@ -1,7 +1,7 @@
 package lessons.sort.pancake.universe;
 
-import jlm.universe.Entity;
-import jlm.universe.World;
+import plm.universe.Entity;
+import plm.universe.World;
 
 public class PancakeEntity extends Entity {
 
@@ -26,7 +26,7 @@ public class PancakeEntity extends Entity {
 	}
 	
 	/** 
-	 * A copy method needed by the JLM
+	 * A copy method needed by the PLM
 	 * @return a new PancakeEntity with the same name as the caller
 	 */
 	@Override
@@ -82,4 +82,12 @@ public class PancakeEntity extends Entity {
 	public String toString(){
 		return "PancakeEntity (" + this.getClass().getName() + ")";
 	}
+	
+	/* BINDINGS TRANSLATION: French */
+	public void retourne(int numberOfPancakes) { flip(numberOfPancakes); }
+	public int getRayonCrepe(int rank) { return getPancakeRadius(rank); }
+	public int getTaillePile() { return getStackSize(); }
+	public boolean estCrepeRetournee(int rank) { return isPancakeUpsideDown(rank); }
+	public boolean estTriee() { return isSorted(); }
+	public boolean estChoisi() { return isSelected(); }
 }
diff --git a/src/lessons/sort/pancake/universe/PancakeFlipButtonPanel.java b/src/lessons/sort/pancake/universe/PancakeFlipButtonPanel.java
index 07121d8..c344dc1 100644
--- a/src/lessons/sort/pancake/universe/PancakeFlipButtonPanel.java
+++ b/src/lessons/sort/pancake/universe/PancakeFlipButtonPanel.java
@@ -10,8 +10,8 @@ import javax.swing.JComboBox;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 
-import jlm.core.model.Game;
-import jlm.universe.EntityControlPanel;
+import plm.core.model.Game;
+import plm.universe.EntityControlPanel;
 
 /**
  * The control panel for the burned pancake world. 
diff --git a/src/lessons/sort/pancake/universe/PancakeWorld.fr.html b/src/lessons/sort/pancake/universe/PancakeWorld.fr.html
index cdf5974..ebe103c 100644
--- a/src/lessons/sort/pancake/universe/PancakeWorld.fr.html
+++ b/src/lessons/sort/pancake/universe/PancakeWorld.fr.html
@@ -2,30 +2,24 @@
 
 <p>Cet univers est très simple, avec seulement cinq fonctions fournies.</p>
 
-<pre class="Java">int getStackSize()</pre>
-<pre class="python">getStackSize()</pre>
+<pre>[!java]int [/!]getTaillePile()  [!scala]:Int[/!]</pre>
 Renvoie la taille du tas de crêpes, c'est à dire le nombre de crêpes qui le
 compose.
 
-<pre class="Java">int getPancakeRadius(int rang)</pre>
-<pre class="python">getPancakeRadius(rang)</pre>
+<pre>[!java]int [/!]getRayonCrepe([!java]int [/!]rang[!scala]:Int[/!])  [!scala]:Int[/!]</pre>
 Renvoie le rayon de la crêpe passée en argument, sachant que le rang de la
 crêpe du haut est 0.
 
-<pre class="Java">boolean isPancakeUpsideDown(int rang)</pre>
-<pre class="python">isPancakeUpsideDown(rang)</pre>
+<pre>[!java]boolean [/!]estCrepeRetournee([!java]int [/!]rang[!scala]:Int[/!])   [!scala]:Boolean[/!]</pre>
 Renvoie ssi la crêpe passée en paramètre (la crêpe du haut étant de rang 0)
 est à l'envers, c'est-à-dire si sa face brulée est en haut.
 
-<pre class="Java">void flip(int quantité)</pre>
-<pre class="python">flip(quantité)</pre>
+<pre>[!java]void [/!]retourne([!java]int [/!]quantité[!scala]:Int[/!])</pre>
 Retourne les <code>quantité</code> premières crêpes de la pile, en partant
 du sommet de celle-ci.
 
-<pre class="Java">boolean isSorted()</pre>
-<pre class="python">isSorted()</pre>
+<pre>[!java]boolean [/!]estTrie()   [!scala]:Boolean[/!]</pre>
 Renvoie si la pile de crêpes est correctement triée.
 
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
-Renvoi si le monde actuel est sélectionné dans l'interface graphique.  
\ No newline at end of file
+<pre>[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]</pre>
+Renvoi si le monde actuel est sélectionné dans l'interface graphique.  
diff --git a/src/lessons/sort/pancake/universe/PancakeWorld.html b/src/lessons/sort/pancake/universe/PancakeWorld.html
index 101f190..3b807ad 100644
--- a/src/lessons/sort/pancake/universe/PancakeWorld.html
+++ b/src/lessons/sort/pancake/universe/PancakeWorld.html
@@ -2,26 +2,20 @@
 
 <p>This universe is very simple, with only five functions provided.</p>
 
-<pre class="Java">int getStackSize()</pre>
-<pre class="python">getStackSize()</pre>
+<pre>[!java]int [/!]getStackSize()  [!scala]:Int[/!]</pre>
 Returns the size of the stack, that is the amount of pancakes it contains.
 
-<pre class="Java">int getPancakeRadius(int rank)</pre>
-<pre class="python">getPancakeRadius(rank)</pre>
+<pre>[!java]int [/!]getPancakeRadius([!java]int [/!]rank[!scala]:Int[/!])  [!scala]:Int[/!]</pre>
 Returns the radius of the pancake passed as argument, with the rank of the top-most pancake being 0.
 
-<pre class="Java">boolean isPancakeUpsideDown(int rank)</pre>
-<pre class="python">isPancakeUpsideDown(rank)</pre>
+<pre>[!java]boolean [/!]isPancakeUpsideDown([!java]int [/!]rank[!scala]:Int[/!])   [!scala]:Boolean[/!]</pre>
 Returns whether the pancake passed as argument upside-down, that is, if its burned side is on top. As usual, the top-most pancake is of rank 0.
 
-<pre class="Java">void flip(int amount)</pre>
-<pre class="python">flip(amount)</pre>
+<pre>[!java]void [/!]flip([!java]int [/!]amount[!scala]:Int[/!])</pre>
 Flips the <code>amount</code> first pancakes composing the stack, from the top of it.
 
-<pre class="Java">boolean isSorted()</pre>
-<pre class="python">isSorted()</pre>
+<pre>[!java]boolean [/!]isSorted()   [!scala]:Boolean[/!]</pre>
 Returns whether the pancake stack is correctly sorted.
 
-<pre class="Java">boolean isSelected()</pre>
-<pre class="python">isSelected()</pre>
-Returns whether the current world is selected in the graphical interface.  
\ No newline at end of file
+<pre>[!java]boolean [/!]isSelected()   [!scala]:Boolean[/!]</pre>
+Returns whether the current world is selected in the graphical interface.  
diff --git a/src/lessons/sort/pancake/universe/PancakeWorld.java b/src/lessons/sort/pancake/universe/PancakeWorld.java
index be507c8..2724999 100644
--- a/src/lessons/sort/pancake/universe/PancakeWorld.java
+++ b/src/lessons/sort/pancake/universe/PancakeWorld.java
@@ -4,12 +4,12 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 import javax.swing.ImageIcon;
 
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.core.ui.WorldView;
-import jlm.universe.EntityControlPanel;
-import jlm.universe.World;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
 
 public class PancakeWorld extends World {
 
@@ -169,7 +169,16 @@ public class PancakeWorld extends World {
 				"def isPancakeUpsideDown(pancakeNumber):\n"+
 				"  return entity.isPancakeUpsideDown(pancakeNumber)\n" +
 				"def flip(numberOfPancakes):\n" +
-				"  entity.flip(numberOfPancakes)\n"	
+				"  entity.flip(numberOfPancakes)\n"	+
+				/* BINDINGS TRANSLATION: French */
+				"def getTaillePile():\n"+
+				"  return getStackSize()\n"+
+				"def getRayonCrepe(rank):\n"+
+				"  return getPancakeRadius(rank)\n"+
+				"def estCrepeRetournee(rank):\n"+
+				"  return isPancakeUpsideDown(rank)\n"+
+				"def retourne(nb):\n"+
+				"  return flip(nb)\n"
 				);
 		} else {
 			throw new RuntimeException("No binding of PancakeWorld for "+lang);
diff --git a/src/lessons/sort/pancake/universe/PancakeWorldView.java b/src/lessons/sort/pancake/universe/PancakeWorldView.java
index da004ac..74c1ec6 100644
--- a/src/lessons/sort/pancake/universe/PancakeWorldView.java
+++ b/src/lessons/sort/pancake/universe/PancakeWorldView.java
@@ -13,8 +13,8 @@ import java.awt.event.MouseListener;
 import java.awt.geom.Ellipse2D;
 import java.awt.geom.Rectangle2D;
 
-import jlm.core.ui.WorldView;
-import jlm.universe.World;
+import plm.core.ui.WorldView;
+import plm.universe.World;
 
 public class PancakeWorldView extends WorldView {
 
diff --git a/src/lessons/sort/selection/AlgSelectionSort.java b/src/lessons/sort/selection/AlgSelectionSort.java
index 599d9df..2fc74ad 100644
--- a/src/lessons/sort/selection/AlgSelectionSort.java
+++ b/src/lessons/sort/selection/AlgSelectionSort.java
@@ -1,9 +1,9 @@
 package lessons.sort.selection;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgSelectionSort extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/selection/AlgSelectionSortEntity.java b/src/lessons/sort/selection/AlgSelectionSortEntity.java
index 5098d3f..62e7152 100644
--- a/src/lessons/sort/selection/AlgSelectionSortEntity.java
+++ b/src/lessons/sort/selection/AlgSelectionSortEntity.java
@@ -1,6 +1,6 @@
 package lessons.sort.selection;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
 public class AlgSelectionSortEntity extends SortingEntity {
 
diff --git a/src/lessons/sort/selection/AlgSelectionSortEntity.scala b/src/lessons/sort/selection/AlgSelectionSortEntity.scala
new file mode 100644
index 0000000..0d27d6c
--- /dev/null
+++ b/src/lessons/sort/selection/AlgSelectionSortEntity.scala
@@ -0,0 +1,29 @@
+package lessons.sort.selection;
+
+import plm.universe.sort.SortingEntity;
+
+class ScalaAlgSelectionSortEntity extends SortingEntity {
+
+	override def run() {
+		selectionSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def selectionSort() {
+		/* BEGIN SOLUTION */
+		for (i <- 0 to getValueCount()-1) {
+			var min = i;	
+
+			/*  Find the smallest element in the unsorted list */
+			for (j <- i + 1 to getValueCount()-1) {
+				if (isSmaller(j,min))
+					min = j;				
+			}
+
+			/* Swap the smallest unsorted element into the end of the sorted list. */
+			swap(min,i);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/sort/shell/AlgShellSort.fr.html b/src/lessons/sort/shell/AlgShellSort.fr.html
index 9b7743f..3f30401 100644
--- a/src/lessons/sort/shell/AlgShellSort.fr.html
+++ b/src/lessons/sort/shell/AlgShellSort.fr.html
@@ -40,9 +40,9 @@ grande valeur de la suite utilisée, puis prendre les valeurs successives en
 descendant ensuite.</p>
 
 <p>De façon intéressante, déterminer la meilleure séquence de gap pour le shell
-sort s'avère être un problème de recherche actuel en informatique. Par
-exemple, un article publié en 2001 propose la suite suivante, qui semble
-optimale en pratique pour des tailles de tableau allant jusqu'à 10^5: {1, 4,
-10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best Increments for the
-Average Case of Shellsort, 13th International Symposium on Fundamentals of
-Computation Theory, LNCS 2001; Vol. 2138).</p> 
\ No newline at end of file
+sort s'avère être un problème de recherche de notre siècle en
+informatique. Par exemple, un article publié en 2001 propose la suite
+suivante, qui semble optimale en pratique pour des tailles de tableau allant
+jusqu'à 10^5: {1, 4, 10, 23, 57, 132, 301, 701, 1750} (Marcin Ciura, Best
+Increments for the Average Case of Shellsort, 13th International Symposium
+on Fundamentals of Computation Theory, LNCS 2001; Vol. 2138).</p> 
diff --git a/src/lessons/sort/shell/AlgShellSort.html b/src/lessons/sort/shell/AlgShellSort.html
index 423f5a1..974d054 100644
--- a/src/lessons/sort/shell/AlgShellSort.html
+++ b/src/lessons/sort/shell/AlgShellSort.html
@@ -34,10 +34,10 @@ optimizations. If you ever need to do so, take as initial gap the biggest
 value of the targeted serie still smaller than the array size, and then use
 decreasing values of the serie.</p>
 
-<p>Interesingly enough, determining the best gap sequence for shell sort turns
-into a contemporary research issue in computer science. For example, an
+<p>Interestingly enough, determining the best gap sequence for shell sort turns
+into a research issue of our century in computer science. For example, an
 article of 2001 introduces the following sequence, which seems to be optimal
 in practice for arrays of size up to 10^5: {1, 4, 10, 23, 57, 132, 301, 701,
 1750} (Marcin Ciura, Best Increments for the Average Case of Shellsort, 13th
 International Symposium on Fundamentals of Computation Theory, LNCS 2001;
-Vol. 2138).</p> 
\ No newline at end of file
+Vol. 2138).</p> 
diff --git a/src/lessons/sort/shell/AlgShellSort.java b/src/lessons/sort/shell/AlgShellSort.java
index 1c215eb..da6f732 100644
--- a/src/lessons/sort/shell/AlgShellSort.java
+++ b/src/lessons/sort/shell/AlgShellSort.java
@@ -1,9 +1,9 @@
 package lessons.sort.shell;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.sort.SortingEntity;
-import jlm.universe.sort.SortingWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingWorld;
 
 public class AlgShellSort extends ExerciseTemplated {
 
diff --git a/src/lessons/sort/shell/AlgShellSortEntity.java b/src/lessons/sort/shell/AlgShellSortEntity.java
index 006479f..efbb8e4 100644
--- a/src/lessons/sort/shell/AlgShellSortEntity.java
+++ b/src/lessons/sort/shell/AlgShellSortEntity.java
@@ -1,8 +1,8 @@
 package lessons.sort.shell;
 
-import jlm.universe.sort.SortingEntity;
+import plm.universe.sort.SortingEntity;
 
-/* Variante with precalculated gap:
+/* Variant with precomputed gap:
  *
  *	int [] gap = {1, 4, 10, 23, 57, 132, 301, 701, 1750};
  *	int h = 0;
@@ -16,7 +16,7 @@ import jlm.universe.sort.SortingEntity;
 public class AlgShellSortEntity extends SortingEntity {
 
 	public void run() {
-		this.shellSort();
+		shellSort();
 	}
 
 	/* BEGIN TEMPLATE */
diff --git a/src/lessons/sort/shell/AlgShellSortEntity.scala b/src/lessons/sort/shell/AlgShellSortEntity.scala
new file mode 100644
index 0000000..aa253d8
--- /dev/null
+++ b/src/lessons/sort/shell/AlgShellSortEntity.scala
@@ -0,0 +1,53 @@
+package lessons.sort.shell;
+
+import plm.universe.sort.SortingEntity;
+
+/* Variant with precomputed gap:
+ *
+ *	int [] gap = {1, 4, 10, 23, 57, 132, 301, 701, 1750};
+ *	int h = 0;
+ *  // find the largest possible gap 
+ *	while (gap[h+1] < getValueCount() && h<gap.length) {
+ *	  h++;
+ *  }
+ *  Then, use gap[h] instead of gap, and decrease by h--
+ */
+
+class ScalaAlgShellSortEntity extends SortingEntity {
+
+	override def run() {
+		shellSort();
+	}
+
+	/* BEGIN TEMPLATE */
+	def shellSort()  {
+		/* BEGIN SOLUTION */
+		var gap = getValueCount()/2;
+
+		/* while h remains larger than 0 */
+		while( gap > 0 ) {
+			/* for each set of elements (there are h sets) */
+			for (i <- gap - 1 to getValueCount()-1) {
+				/* pick the last element in the set */
+				var value = getValue(i);
+				var j = i;
+				/* compare the element at B to the one before it in the set
+				 * if they are out of order continue this loop, moving
+				 * elements "back" to make room for B to be inserted.
+				 */
+				while(j >= gap && (getValue(j-gap) > value)) {
+					copy(j-gap,j);
+					j -= gap;
+				}
+				/*  insert B into the correct place */
+				setValue(j, value);
+			}
+			/* all sets gap-sorted, now decrease set size */
+			gap = gap / 2;
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+}
+
diff --git a/src/lessons/turmites/Main.fr.html b/src/lessons/turmites/Main.fr.html
index d4ece55..a75e859 100644
--- a/src/lessons/turmites/Main.fr.html
+++ b/src/lessons/turmites/Main.fr.html
@@ -7,9 +7,10 @@ porte sur un univers fascinant.</p>
 
 <p>Ce mécanisme a été inventé en 1986 par Chris Langton, et généralisé après de
 plusieures façons (comme nous le verrons dans les prochains exercices). Il a
-été prouvé en 2000 que la trajectoire de la fourmi peut être utilisée pour
-calculer n'importe quel circuit booléen, et que la fourmi est capable de
-calcul universel ( ie, n'importe quel calcul possible peut être réalisé en
+été prouvé que les turmites et les machines de Turing sont aussi puissantes
+les unes que les autres : une trajectoire de  fourmi peut être utilisée pour
+calculer n'importe quel circuit booléen, et la fourmi est donc capable de
+calcul universel (càd, n'importe quel calcul possible peut être réalisé en
 utilisant la fourmi comme instrument de calcul). Encore un autre sujet de
 fascination...</p>
 
@@ -21,7 +22,7 @@ prouvé formellement.</p>
 <p>Consultez la page correspondante sur Wikipedia, à partir de laquelle cet
 exercice est inspiré, pour d'avantages de détails.</p>
 
-<h3>Que puis-je faire pour améliorer cet univers de JLM?</h3>
+<h3>Que puis-je faire pour améliorer cet univers de PLM?</h3>
 
 <p>Comme souvent, plusieurs points pourraient être améliorés dans le code de
 cet univers pour l'améliorer :</p>
diff --git a/src/lessons/turmites/Main.html b/src/lessons/turmites/Main.html
index 9a8e7a5..9d8ccfe 100644
--- a/src/lessons/turmites/Main.html
+++ b/src/lessons/turmites/Main.html
@@ -5,10 +5,10 @@ machines. They constitute very simple application problems, achievable
 by beginners, and open the door to an amazing world.</p>
 
 <p>This mechanism were invented in 1986 by Chris Langton, and later generalized 
-in several ways (as we shall see in the next exercises). It was proven in 2000 that 
-the ant's trajectory can be used to compute any boolean circuit, and thus that the 
-ant is capable of universal computation (ie, any possible computation can be achieved 
-using the ant as a computing device). Yet another subject of fascination...</p>
+in several ways (as we shall see in the next exercises). It was proven that Turmites and Turing machines are of equal power: 
+An ant's trajectory can be used to compute any boolean circuit, and thus that an
+ant is capable of universal computation. Put simply, any possible computation can be achieved 
+using a turmite as a computing device. Yet another subject of fascination...</p>
 
 <p>Multicolor Langton's ants were discovered in 1995 by Propp 
 et Al. Another funny fact is that the ants which name is a list of consecutive pair of 
@@ -18,7 +18,7 @@ proved.</p>
 <p>Check the corresponding wikipedia web page, of which this exercise is inspired, 
 for further details.</p>
 
-<h3>What can I do to improve this JLM universe?</h3>
+<h3>What can I do to improve this PLM universe?</h3>
 
 <p>As usual, there are several things that could be done in the code of this universe to improve it:</p>
 <ul>
diff --git a/src/lessons/turmites/Main.java b/src/lessons/turmites/Main.java
index a966a65..04ca025 100644
--- a/src/lessons/turmites/Main.java
+++ b/src/lessons/turmites/Main.java
@@ -2,8 +2,8 @@ package lessons.turmites;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
 import lessons.turmites.helloturmite.HelloTurmite;
 import lessons.turmites.langton.Langton;
 import lessons.turmites.langtoncolors.LangtonColors;
diff --git a/src/lessons/turmites/helloturmite/HelloTurmite.fr.html b/src/lessons/turmites/helloturmite/HelloTurmite.fr.html
index a593dc1..de864f0 100644
--- a/src/lessons/turmites/helloturmite/HelloTurmite.fr.html
+++ b/src/lessons/turmites/helloturmite/HelloTurmite.fr.html
@@ -16,11 +16,12 @@ tout d'abord trouver le rang de la couleur actuelle du sol dans la liste des
 couleurs. Mais cette fois, <code>rule</code> dépend à la fois de la couleur
 courante et de l'état courant. <code>rule</code> contient en fait trois
 informations dans chaque situation : la couleur à mettre, le mouvement à
-effectuer, et la valeur du prochain état. Par exemple, rule[1][0] contient
+effectuer, et la valeur du prochain état.
+Par exemple, [!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contient
 l'information à utiliser quand <code>state==1</code> et
 <code>color==0</code>. En d'autres mots, vous pouvez récupérer l'information
 relative à votre situation actuelle en utilisant
-<code>rule[etatCourant][couleurActuelle]</code></p> 
+<code>[!java|python]rule[etatCourant][couleurActuelle][/!][!scala]rule(etatCourant)(couleurActuelle)[/!]</code></p> 
 
 <p>Chaque ensemble d'informations contient trois valeurs.
 La première est le rang de la couleur à mettre sur le sol.
@@ -31,43 +32,36 @@ si l'instruction est stop, vous ne devez même pas avancer sur cette étape
 pas peuvent faire quelque chose d'autre). Finalement, le troisième entier
 est la valeur du prochain <code>state</code> à avoir après cette itération.</p> 
 
-<p class="Java">Puisque ces notations arbitraires sont parfois difficiles à se souvenir, le
-code fourni définit un ensemble de constantes que vous pouvez utiliser à la
-place des valeurs numériques. Leurs noms sont LEFT, RIGHT, etc.
-Le modifieur <code>final static</code> avant leur type est la façon
-d'indiquer les variables comme constantes en Java (désolés si la notation
-semble complexe).
-Utiliser de telles constantes rend le code beaucoup plus simple à
-lire :</p> 
-<p class="python">Puisque ces notations arbitraires sont parfois difficiles à se souvenir, le
-code fourni définit un ensemble de constantes que vous pouvez utiliser à la
-place des valeurs numériques. Leurs noms sont NOTURN, LEFT, RIGHT,
-etc. (pour TOUTDROIT, GAUCHE, DROITE). Par convention, de telles constantes
-sont écrites en majuscules en python. Techniquement, vous pouvez modifier la
-valeur de ces variables, but ce serait une très mauvause idée.
-Utiliser de telles constantes rend le code beaucoup plus simple à
-lire :</p> 
-<pre class="Java">
-  if (rule[state][currentColor][NEXT_MOVE] == LEFT) {
-    turnLeft();
-  }
-</pre>
-<pre class="python">
-  if rule[state][currentColor][NEXT_MOVE] == LEFT:
-    turnLeft()
-</pre>
-<p>C'est beaucoup plus simple à lire que ceci :</p>
-<pre class="Java">
-  if (rule[x][y][1] == 2) {
-    turnLeft();
-  }
-</pre>
-<pre class="python">
-  if rule[x][y][1] == 2:
-    turnLeft()
-</pre>
+<p>Puisque ces notations arbitraires sont parfois difficiles à se souvenir,
+vous devriez définir un ensemble de constantes que vous pouvez utiliser à la
+place des valeurs numériques. Leurs noms pourraient être GAUCHE, DROITE,
+etc.
+[!scala]Déclarez simplement ces valeurs avec le mot-clé <code>val</code> au
+lieu de <code>var</code>. De toute façon, on devrait toujours utiliser
+<code>val</code> au lieu de <code>var</code> quand on peut.[/!]
+[!java]Les modificateurs <code>final static</code> devant le nom du type est
+la façon Java de marquer des constant en Java.
+  Vous devriez écrire par exemple <code>static final int TOUTDROIT=1;</code>
+  Désolé de la complexité de cette notation. [/!]
+[!python]Par convention, de telles «variables constantes» sont écrites tout
+en majuscule en Python.
+  Rien ne vous empêche d'un point de vue technique de les modifier, mais ca
+serait une très mauvaise idée.[/!]
+Vous devriez les écrire en dehors de toute méthode pour les rendre visible
+de partout.</p>
+
+<p>Utilisez de telles constantes aident beaucoup à rendre le code plus lisible.
+Comparez les deux morceaux de code suivant:</p> 
+
+<pre>[!java]if (rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE) {[/!][!python]if rule[etat][couleurActuelle][MVT_SUIVANT] == GAUCHE:[/!][!scala]if (rule(etat)(couleurActuelle)(MVT_SUIVANT) == GAUCHE) {[/!]
+    gauche()[!java];[/!]
+[!java|scala]}[/!]</pre>
+<p>C'est un peu plus long, mais bien plus agréable à lire que ceci :</p>
+<pre>[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]
+    gauche()[!java];[/!]
+[!java|scala]}[/!]</pre>
  
-<p class="python">Enfin, vous devriez également écrire une branche <code>elif</code> pour la
+[!python]<p>Enfin, vous devriez également écrire une branche <code>elif</code> pour la
 condition <code>STOP</code>. Avoir une branche <code>else</code> qui affiche
 un message d'erreur tel que "situation inattendue" est une bonne
 pratique. Celà permet d'expliciter les présuposés du code, et assure un
@@ -76,8 +70,11 @@ problème suivant est que nous n'avons rien à faire faire dans la branche du
 cas <code>STOP</code>, mais que python n'autorise pas de branche
 <code>else</code> vide. Il faut alors utiliser l'instruction
 <code>pass</code> là où il n'y a rien à faire. Cela indique à Python qu'il y
-a bien une branche à cet emplacement, mais qu'elle ne fait rien.</p>
- 
+a bien une branche à cet emplacement, mais qu'elle ne fait rien.</p>[/!] [!java|scala]<p>Vous devriez probablement utiliser un [!java]switch[/!][!scala]filtrage[/!]
+pour que votre code reste lisible.
+Si vous avez oublié ce que c'est, retournez à <a
+href=\"plm://lessons.welcome/bdr.BDR2\">cet exercice</a>.</p>[/!]
+
 <p>Vous devriez maintenant avoir assez d'informations pour réussir.</p>
 
 <h2>Notes bibliographiques</h2>
diff --git a/src/lessons/turmites/helloturmite/HelloTurmite.html b/src/lessons/turmites/helloturmite/HelloTurmite.html
index 3693d18..b7602be 100644
--- a/src/lessons/turmites/helloturmite/HelloTurmite.html
+++ b/src/lessons/turmites/helloturmite/HelloTurmite.html
@@ -1,77 +1,73 @@
-<h2>Turmites</h2>
-
-<p>This exercise explores a new way to extend the concept of Langton's ant. Now, 
-the behavior of the ant not only depends on the color on the ground, but also on 
-its internal state (represented by an integer value). The idea of changing the 
-ant into such an automata naturally comes from the Turing machine concept. This 
-explains the name of these new animals, which is a portemanteau of <i>Turing</i> 
-and <i>Termite</i> (if you don't know what a Turing machine is, you should run 
-to wikipedia, because it is simply impossible to be a real computer scientist 
-before that).</p>     
-
-<p>Once again, you just have to write the <code>step()</code> method, in charge 
-of doing one turmite's step. Once again, you should first find the rank of the 
-current's cell ground color in the color sequence. But this time, the 
-<code>rule</code> data depends both on the current color and the current state. 
-<code>rule</code> actually contains 3 information in each situation: 
-the color to write, the move to do, and the next state value. For 
-example, rule[1][0] contains the informations to use when <code>state==1</code> and 
-<code>color==0</code>. In other worlds, you can retrieve the information relative 
-to your current situation by using <code>rule[state][currentColor]</code>.</p> 
-
-<p>Each such information set contains 3 values. The first one is the rank of the 
-color to write on the ground. The second is the move to do, with the following 
-notation: 0=stop, 1=noturn, 2=right, 4=u-turn, 8=left. Note that if the command is stop, 
-you shouldn't even move forward on that step (but you shouldn't stop your program 
-either: the next steps can do something else in a future state). Finally, the third integer is the 
-next <code>state</code> value to go into after this iteration.</p> 
-
-<p class="Java">Since these arbitrary notations are somehow difficult to remember, the template 
-code defines a set of constants that you should use instead of the direct numerical 
-values. Their names are NOTURN, LEFT, RIGHT and so on. The modifiers <code>final 
-static</code> before their type is the way to mark variables as constant in Java 
-(sorry if the notation seems complex). Using such constants greatly help making the 
-code easier to read. This allows to write things this way:</p> 
-<p class="python">Since these arbitrary notations are somehow difficult to remember, the template 
-code defines a set of constants that you should use instead of the direct numerical 
-values. Their names are NOTURN, LEFT, RIGHT and so on. By convention, such constant variables 
-are written in upper case in python. Technically, you can still modify them, but that would be 
-a very bad idea. Using such constants greatly help making the 
-code easier to read, as it allows to write things this way:</p> 
-<pre class="Java">
-  if (rule[state][currentColor][NEXT_MOVE] == LEFT) {
-    turnLeft();
-  }
-</pre>
-<pre class="python">
-  if rule[state][currentColor][NEXT_MOVE] == LEFT:
-    turnLeft()
-</pre>
-<p>This is much more easier to read than the following way:</p>
-<pre class="Java">
-  if (rule[x][y][1] == 2) {
-    turnLeft();
-  }
-</pre>
-<pre class="python">
-  if rule[x][y][1] == 2:
-    turnLeft()
-</pre>
- 
-<p class="python">Finally, you probably want to write a <code>elif</code> branch for the 
-<code>STOP</code> condition too. Having a <code>else</code> branch displaying an error 
-message such as "unknown case" is a good practice: it makes your assumptions about your 
-code more explicit, and you will get an error message if they fall short. When doing so, 
-the next problem is that you have nothing to do in the <code>STOP</code> case, but python 
-do not allows you to write empty <code>elif</code> branches. You should use the <code>pass</code> 
-instruction as a placeholder: it says python that you have a branch here, and that it 
-does not contain anything.</p>
- 
-<p>You now should have enough information to succeed.</p>
-
-<h2>Bibliographical notes</h2>
-<p>According to wikipedia, turmites were invented independently by the end of 
-the eighties. It has been shown that turmites in general are exactly equivalent 
-in power to one-dimensional Turing machines with an infinite tape, as either can 
-simulate the other. This means that absolutely any program that you can think of 
-could theoretically be computed on this device...</p>
+<h2>Turmites</h2>
+
+<p>This exercise explores a new way to extend the concept of Langton's ant. Now, 
+the behavior of the ant not only depends on the color on the ground, but also on 
+its internal state (represented by an integer value). The idea of changing the 
+ant into such an automata naturally comes from the Turing machine concept. This 
+explains the name of these new animals, which is a portemanteau of <i>Turing</i> 
+and <i>Termite</i> (if you don't know what a Turing machine is, you should run 
+to wikipedia, because it is simply impossible to be a real computer scientist 
+before that).</p>     
+
+<p>Once again, you just have to write the <code>step()</code> method, in charge 
+of doing one turmite's step. Once again, you should first find the rank of the 
+current's cell ground color in the color sequence. But this time, the 
+<code>rule</code> data depends both on the current color and the current state. 
+<code>rule</code> actually contains 3 information in each situation: 
+the color to write, the move to do, and the next state value. For 
+example, [!java|python]rule[1][0][/!][!scala]rule(1)(0)[/!] contains the informations 
+to use when <code>state==1</code> and <code>color==0</code>. 
+In other worlds, you can retrieve the information relative 
+to your current situation by using 
+<code>[!java|python]rule[state][currentColor][/!][!scala]rule(state)(currentColor)[/!]</code>.</p> 
+
+<p>Each such information set contains 3 values. The first one is the rank of the 
+color to write on the ground. The second is the move to do, with the following 
+notation: 0=stop, 1=noturn, 2=right, 4=u-turn, 8=left. Note that if the command is stop, 
+you shouldn't even move forward on that step (but you shouldn't stop your program 
+either: the next steps can do something else in a future state). Finally, the third integer is the 
+next <code>state</code> value to go into after this iteration.</p> 
+
+<p>Since these arbitrary notations are somehow difficult to remember, you should define a set of 
+constants that you should use instead of the direct numerical values. 
+Their names could be NOTURN, LEFT, RIGHT and so on. 
+[!scala]Just declare them using the keyword <code>val</code> instead of <code>var</code>.
+  You should always use <code>val</code> instead of <code>var</code> when possible anyway.[/!]
+[!java]The modifiers <code>final static</code> before their type is the way to mark variables as constant in Java. 
+  You should write for example <code>static final int NOTURN=1;</code>
+  Sorry for the complexity of this notation. [/!]
+[!python]By convention, such constant variables are written in upper case in python. 
+  Technically, you can still modify them, but that would be a very bad idea.[/!]
+You should write them out of any method so that they are globally visible.</p>
+
+<p>Using such constants greatly help making the code easier to read. Compare the next two code chunks:</p> 
+
+<pre>[!java]if (rule[state][currentColor][NEXT_MOVE] == LEFT) {[/!][!python]if rule[state][currentColor][NEXT_MOVE] == LEFT:[/!][!scala]if (rule(state)(currentColor)(NEXT_MOVE) == LEFT) {[/!]
+    left()[!java];[/!]
+[!java|scala]}[/!]</pre>
+<p>This is much more easier to read (although longer) than the following:</p>
+<pre>[!java]if (rule[i][j][1] == 2) {[/!][!python]if rule[i][j][1] == 2:[/!][!scala]if (rule(i)(j)(1) == 2) {[/!]
+    left()[!java];[/!]
+[!java|scala]}[/!]</pre>
+ 
+[!python]<p>Finally, you probably want to write a <code>elif</code> branch for the 
+<code>STOP</code> condition too. Having a <code>else</code> branch displaying an error 
+message such as "unknown case" is a good practice: it makes your assumptions about your 
+code more explicit, and you will get an error message if they fall short. When doing so, 
+the next problem is that you have nothing to do in the <code>STOP</code> case, but python 
+do not allows you to write empty <code>elif</code> branches. You should use the <code>pass</code> 
+instruction as a placeholder: it says python that you have a branch here, and that it 
+does not contain anything.</p>[/!]
+ 
+[!java|scala]<p>You should probably use a [!java]switch case[/!][!scala]pattern matching[/!] construct 
+to keep your code readable.
+If you can't remember what it is, check <a href="plm://lessons.welcome/bdr.BDR2">this exercise</a>.</p>[/!]
+
+<p>You now should have enough information to succeed.</p>
+
+<h2>Bibliographical notes</h2>
+<p>According to wikipedia, turmites were invented independently by the end of 
+the eighties. It has been shown that turmites in general are exactly equivalent 
+in power to one-dimensional Turing machines with an infinite tape, as either can 
+simulate the other. This means that absolutely any program that you can think of 
+could theoretically be computed on this device...</p>
diff --git a/src/lessons/turmites/helloturmite/HelloTurmite.java b/src/lessons/turmites/helloturmite/HelloTurmite.java
index 2d75c29..dd2d5be 100644
--- a/src/lessons/turmites/helloturmite/HelloTurmite.java
+++ b/src/lessons/turmites/helloturmite/HelloTurmite.java
@@ -1,8 +1,8 @@
 package lessons.turmites.helloturmite;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bugglequest.BuggleWorld;
 import lessons.turmites.universe.TurmiteWorld;
 
 public class HelloTurmite extends ExerciseTemplated {
diff --git a/src/lessons/turmites/helloturmite/HelloTurmiteEntity.java b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.java
index 21ae3cd..223bbb3 100644
--- a/src/lessons/turmites/helloturmite/HelloTurmiteEntity.java
+++ b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.java
@@ -2,15 +2,15 @@ package lessons.turmites.helloturmite;
 
 import java.awt.Color;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class HelloTurmiteEntity extends SimpleBuggle {
 	Color[] allColors = {Color.white, Color.black, Color.blue, Color.cyan, Color.green, Color.orange, Color.red, 
 			Color.gray, Color.magenta, Color.darkGray, Color.pink, Color.lightGray};
 
 	/* BEGIN TEMPLATE */
-	/* Do not change these definitions */
-	final static int STOP   = 0;
+	final static int STOP   = 0; /* for example */ 
+	/* BEGIN HIDDEN */
 	final static int NOTURN = 1;
 	final static int LEFT   = 2;
 	final static int BACK   = 4;
@@ -19,7 +19,7 @@ public class HelloTurmiteEntity extends SimpleBuggle {
 	final static int NEXT_COLOR = 0;
 	final static int NEXT_MOVE  = 1;
 	final static int NEXT_STATE = 2;
-
+	/* END HIDDEN */
 
 	int state = 0;
 
@@ -39,9 +39,9 @@ public class HelloTurmiteEntity extends SimpleBuggle {
 		switch (rule[state][currentColor][NEXT_MOVE]) {
 		case STOP:   /* nothing */;            break;
 		case NOTURN: /* no turn */; forward(); break;
-		case LEFT:   turnLeft();   	forward(); break;
-		case RIGHT:  turnRight();   forward(); break;
-		case BACK:   turnBack();    forward(); break;
+		case LEFT:   left();   	forward(); break;
+		case RIGHT:  right();   forward(); break;
+		case BACK:   back();    forward(); break;
 		default:
 			System.out.println("Unknown turn command associated to i="+currentColor+": "+rule[state][currentColor][NEXT_MOVE]);
 		}
diff --git a/src/lessons/turmites/helloturmite/HelloTurmiteEntity.py b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.py
index a04b480..65400db 100644
--- a/src/lessons/turmites/helloturmite/HelloTurmiteEntity.py
+++ b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.py
@@ -31,13 +31,13 @@ def step(rule, colors):
 	elif (rule[state][currentColor][NEXT_MOVE] == NOTURN):
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == LEFT):
-		turnLeft()
+		left()
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == RIGHT):
-		turnRight()
+		right()
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == BACK):
-		turnBack()
+		back()
 		forward()
 	else:
 		log("Unknown turn command associated to i=%d: %d" % (currentColor, rule[state][currentColor][NEXT_MOVE]))
diff --git a/src/lessons/turmites/helloturmite/HelloTurmiteEntity.scala b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.scala
new file mode 100644
index 0000000..58da80e
--- /dev/null
+++ b/src/lessons/turmites/helloturmite/HelloTurmiteEntity.scala
@@ -0,0 +1,68 @@
+package lessons.turmites.helloturmite;
+
+import java.awt.Color
+import plm.universe.bugglequest.SimpleBuggle;
+import lessons.turmites.universe.TurmiteWorld
+
+class ScalaHelloTurmiteEntity extends SimpleBuggle {
+		val allColors = Array(Color.white, Color.black, Color.blue, Color.cyan, Color.green, Color.orange, Color.red, 
+			Color.gray, Color.magenta, Color.darkGray, Color.pink, Color.lightGray);
+
+	val STOP   = 0;
+	val NOTURN = 1;
+	val LEFT   = 2;
+	val BACK   = 4;
+	val RIGHT  = 8;
+
+	val NEXT_COLOR = 0;
+	val NEXT_MOVE  = 1;
+	val NEXT_STATE = 2;
+
+
+	/* BEGIN TEMPLATE */
+	var state = 0;
+
+	def step(colors:Array[Color], rule:Array[Array[Array[Int]]] ) {
+		/* Your code comes here */
+		/* BEGIN SOLUTION */
+		var currentColor=0;
+		
+		val current = getGroundColor(); 
+		for (i <- 0 to colors.length-1) 
+			if (current == colors(i)) 
+				currentColor = i;
+
+		setBrushColor(colors( rule(state)(currentColor)(NEXT_COLOR) ));
+		brushDown();
+		brushUp();
+
+		rule(state)(currentColor)(NEXT_MOVE) match {
+		  case STOP   => /* nothing */
+		  case NOTURN => /* no turn */ forward(); 
+		  case LEFT   => left();   	   forward(); 
+		  case RIGHT  => right();      forward(); 
+		  case BACK   => back();       forward(); 
+		  case _      => System.out.println("Unknown turn command associated to i="+currentColor+": "+rule(state)(currentColor)(NEXT_MOVE));
+		}
+
+		state = rule(state)(currentColor)(NEXT_STATE);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() { 
+		val nbSteps = getParam(0).asInstanceOf[Int];
+
+		val rule = getParam(1).asInstanceOf[ Array[Array[Array[Int]]] ];
+
+		var colors = new Array[Color] (rule.length);
+		for (i <- 0 to rule.length-1)
+			colors(i) = allColors(i);
+
+
+		for (i <- 1 to nbSteps) {
+			world.asInstanceOf[TurmiteWorld].stepDone();
+			step(colors,rule);
+		}
+	}
+}
diff --git a/src/lessons/turmites/langton/Langton.fr.html b/src/lessons/turmites/langton/Langton.fr.html
index cd4dac3..84411ba 100644
--- a/src/lessons/turmites/langton/Langton.fr.html
+++ b/src/lessons/turmites/langton/Langton.fr.html
@@ -8,23 +8,23 @@ chaotique, un schéma général <i>apparaît</i></p>
 
 <p>Les règles sont absolument triviales: pour calculer quel sera le prochain
 pas, vous devez regarder la couleur actuelle du sol ( en utilisant
-<code>getGroundColor()</code>). Si c'est blanc, changez la en noir, tournez
-à droite et avancez d'une case. Si la couleur du sol est le noir, changez la
+<code>getCouleurSol()</code>). Si c'est blanc, changez la en noir, tournez à
+droite et avancez d'une case. Si la couleur du sol est le noir, changez la
 en blanc, tournez à gauche et avancez d'une case.</p> 
 
 <p>Il est difficile de trouver des règles plus simples, n'est-ce pas ? Et bien,
 allons-y et codons-les maintenant. Vous avez à compléter la méthode
 <code>step()</code>, qui définit le comportement de la fourmi à chaque
-pas. Vous utiliserez probablement la méthode <code>getGroundColor()</code>
+pas. Vous utiliserez probablement la méthode <code>getCouleurSol()</code>
 pour récupérer la valeur de la case sur laquelle la fourmi se trouve. Les
 couleurs intéressantes sont tout simplement <code>Color.black</code> pour le
 noir ou <code>Color.white</code> pour le blanc.</p>
 
-<p class="Java">Pour comparer les couleurs, il n'est pas possible d'utiliser le signe égal
-(=) parce ces choses ne sont pas des valeurs scalaires normales mais des
-objets. À la place, vous devez écrire quelque chose comme cela :
-</p> 
-<pre class="Java">
+[!java]
+<p>Pour comparer les couleurs, il n'est pas possible d'utiliser le double signe
+égal (==) parce ces choses ne sont pas des valeurs scalaires normales mais
+des objets. À la place, vous devez écrire quelque chose comme cela :</p> 
+<pre>
 Color c /* = une initialisation*/;
 if (c.equals(Color.black)) {
   /* c'était égal */
@@ -32,14 +32,15 @@ if (c.equals(Color.black)) {
   /* ce n'était pas égal */
 }
 </pre>
+[/!]
 
 <p>Changer la couleur du sol n'est pas difficile, seulement un peu long : vous
 avez à changer la couleur de la brosse de votre buggle, l'abaisser (pour
-marquer la case courante -- avec <code>brushDown()</code>), et relever la
-brosse (avec <code>brushUp()</code>) pour éviter des problèmes lorsque la
+marquer la case courante -- avec <code>baisseBrosse()</code>), et relever la
+brosse (avec <code>leveBrosse()</code>) pour éviter des problèmes lorsque la
 buggle va se déplacer. Vous être naturellement libre d'organiser votre code
 comme vous le souhaitez, mais vous pouvez vouloir écrire une méthode
-<code>setGroundColor(couleur)</code> pour factoriser le tout.</p>
+<code>setCouleurSol(couleur)</code> pour factoriser le tout.</p>
 
 <p>Comme vous pouvez le constater avec l'exécution de cet exercice, l'intérêt
 dans cet algorithme est qu'après environ 10 000 pas de comportement
diff --git a/src/lessons/turmites/langton/Langton.html b/src/lessons/turmites/langton/Langton.html
index c32038e..12a9fa3 100644
--- a/src/lessons/turmites/langton/Langton.html
+++ b/src/lessons/turmites/langton/Langton.html
@@ -1,43 +1,44 @@
-<h2>Langton's ant</h2>
-
-<p>In this exercise, you will turn your buggle into a <i>Langton's ant</i>. These 
-artificial little animals are very interesting because they are given simple 
-rules that depend only on their local environment, and after a period of 
-apparent chaotic behavior, a general pattern <i>emerges</i>.</p>
-
-<p>The rules are absolutely trivial: to compute what the next step should be, 
-you should check the current color of the ground (using 
-<code>getGroundColor()</code>). If it's white, change it to black, turn right 
-and move forward by one cell. If the ground is currently black, change it to 
-white, turn left and move forward by one cell.</p> 
-
-<p>It's hard to come up with simpler rules isn't it? Well, let's go and code it 
-now. You have to complete the <code>step()</code> method, which encodes the 
-behavior of the ant at each step. You will probably use the <code>getGroundColor()</code> 
-method to retrieve the color of the cell on which the ant is currently. 
-Colors of interest are simply named <code>Color.black</code> and <code>Color.white</code>.</p>
-
-<p class="Java">To compare colors, you cannot use the equal sign (=), because these things are not 
-scalar values but objects. Instead, you need to write something like the following:
-</p> 
-<pre class="Java">
-Color c /* = some initialization */;
-if (c.equals(Color.black)) {
-  /* that's equal */
-} else {
-  /* that was not equal */
-}
-</pre>
-
-<p>Changing the ground color is not difficult, but a bit long: you have to 
-change the brush color of your buggle, set the brush down (to mark the current 
-cell -- with <code>brushDown()</code>), and set the brush back up (with 
-<code>brushUp()</code>) to avoid further issues when the buggle will 
-move. You are naturally free of organizing your code the way you want, but you may
-want to write a <code>setGroundColor(color)</code> method to factorize things a bit.</p>
-
-<p>As you can see from the execution of this exercise, the interest in this algorithm 
-is that after about 10000 steps of relative chaotic behavior, the ant start building 
-a regular pattern. This emergence of a regular pattern from the chaos is rather 
-fascinating, isn't it? Move on to the next exercise to see more of them.</p>   
-
+<h2>Langton's ant</h2>
+
+<p>In this exercise, you will turn your buggle into a <i>Langton's ant</i>. These 
+artificial little animals are very interesting because they are given simple 
+rules that depend only on their local environment, and after a period of 
+apparent chaotic behavior, a general pattern <i>emerges</i>.</p>
+
+<p>The rules are absolutely trivial: to compute what the next step should be, 
+you should check the current color of the ground (using 
+<code>getGroundColor()</code>). If it's white, change it to black, turn right 
+and move forward by one cell. If the ground is currently black, change it to 
+white, turn left and move forward by one cell.</p> 
+
+<p>It's hard to come up with simpler rules isn't it? Well, let's go and code it 
+now. You have to complete the <code>step()</code> method, which encodes the 
+behavior of the ant at each step. You will probably use the <code>getGroundColor()</code> 
+method to retrieve the color of the cell on which the ant is currently. 
+Colors of interest are simply named <code>Color.black</code> and <code>Color.white</code>.</p>
+
+[!java]
+<p>To compare colors, you cannot use the equal signs (==), because these things are not 
+scalar values but objects. Instead, you need to write something like the following:</p> 
+<pre>
+Color c /* = some initialization */;
+if (c.equals(Color.black)) {
+  /* that's equal */
+} else {
+  /* that was not equal */
+}
+</pre>
+[/!]
+
+<p>Changing the ground color is not difficult, but a bit long: you have to 
+change the brush color of your buggle, set the brush down (to mark the current 
+cell -- with <code>brushDown()</code>), and set the brush back up (with 
+<code>brushUp()</code>) to avoid further issues when the buggle will 
+move. You are naturally free of organizing your code the way you want, but you may
+want to write a <code>setGroundColor(color)</code> method to factorize things a bit.</p>
+
+<p>As you can see from the execution of this exercise, the interest in this algorithm 
+is that after about 10000 steps of relative chaotic behavior, the ant start building 
+a regular pattern. This emergence of a regular pattern from the chaos is rather 
+fascinating, isn't it? Move on to the next exercise to see more of them.</p>   
+
diff --git a/src/lessons/turmites/langton/Langton.java b/src/lessons/turmites/langton/Langton.java
index 9a9b248..7d1396c 100644
--- a/src/lessons/turmites/langton/Langton.java
+++ b/src/lessons/turmites/langton/Langton.java
@@ -1,7 +1,7 @@
 package lessons.turmites.langton;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.turmites.universe.TurmiteWorld;
 
 public class Langton extends ExerciseTemplated {
diff --git a/src/lessons/turmites/langton/LangtonEntity.java b/src/lessons/turmites/langton/LangtonEntity.java
index 1d7cc40..ecf8ac6 100644
--- a/src/lessons/turmites/langton/LangtonEntity.java
+++ b/src/lessons/turmites/langton/LangtonEntity.java
@@ -2,14 +2,14 @@ package lessons.turmites.langton;
 
 import java.awt.Color;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class LangtonEntity extends SimpleBuggle {
 	/* BEGIN TEMPLATE */
 	public void step() {
 		/* BEGIN SOLUTION */
 		if (getGroundColor().equals(Color.white)) {
-			turnRight();
+			right();
 
 			setBrushColor(Color.black);
 			brushDown();
@@ -17,7 +17,7 @@ public class LangtonEntity extends SimpleBuggle {
 
 			forward();
 		} else {
-			turnLeft();
+			left();
 
 			setBrushColor(Color.white);
 			brushDown();
diff --git a/src/lessons/turmites/langton/LangtonEntity.py b/src/lessons/turmites/langton/LangtonEntity.py
index 7d4bf11..d495a3a 100644
--- a/src/lessons/turmites/langton/LangtonEntity.py
+++ b/src/lessons/turmites/langton/LangtonEntity.py
@@ -4,13 +4,13 @@
 def step():
 	# BEGIN SOLUTION
 	if getGroundColor() == Color.white:
-		turnRight()
+		right()
 		setBrushColor(Color.black)
 		brushDown()
 		brushUp()
 		forward()
 	else:
-		turnLeft()
+		left()
 		setBrushColor(Color.white)
 		brushDown()
 		brushUp()
diff --git a/src/lessons/turmites/langton/LangtonEntity.scala b/src/lessons/turmites/langton/LangtonEntity.scala
new file mode 100644
index 0000000..c7c88ae
--- /dev/null
+++ b/src/lessons/turmites/langton/LangtonEntity.scala
@@ -0,0 +1,39 @@
+package lessons.turmites.langton;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaLangtonEntity extends SimpleBuggle {
+	/* BEGIN TEMPLATE */
+	def step() {
+		/* BEGIN SOLUTION */
+		if (getGroundColor() == Color.white) {
+			right();
+
+			setBrushColor(Color.black);
+			brushDown();
+			brushUp();
+
+			forward();
+		} else {
+			left();
+
+			setBrushColor(Color.white);
+			brushDown();
+			brushUp();
+
+			forward();				
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() { 
+		val nbSteps = getParam(0).asInstanceOf[Int]; 
+		for (i <- 1 to nbSteps) {
+			step();
+			world.asInstanceOf[lessons.turmites.universe.TurmiteWorld].stepDone();
+		}
+	}
+}
diff --git a/src/lessons/turmites/langtoncolors/LangtonColors.fr.html b/src/lessons/turmites/langtoncolors/LangtonColors.fr.html
index a3f040b..881a25a 100644
--- a/src/lessons/turmites/langtoncolors/LangtonColors.fr.html
+++ b/src/lessons/turmites/langtoncolors/LangtonColors.fr.html
@@ -17,21 +17,19 @@ une balle. LRRRRRLLR dessine un carré, LLRRRLRLRLLR dessine un schéma
 régulier tordu après une période ressemblant à un comportement chaotique, et
 RRLLLRLLLRRR semble remplir un sablier...</p>  
 
-<p class="Java">Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très
+<p>Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très
 compliqué, même si ce n'est pas complètement trivial. Comme précédemment,
 vous avez à écrire une fonction <code>step</code>. Mais cette fois, elle
 reçoit deux tableaux comme paramètres. Le premier définit les règles à
 suivre selon la couleur du sol tandis que le deuxième done la séquence de
-couleur à utiliser. Par exemple, la fourmi de base aurait <code>{'R',
-'L'}</code> et <code>{Color.white, Color.black}</code> comme arguments.</p>
-
-<p class="python">Métamorphoser votre buggle en une fourmi de Langton générique n'est pas très
-compliqué, même si ce n'est pas complètement trivial. Comme précédemment,
-vous avez à écrire une fonction <code>step</code>. Mais cette fois, elle
-reçoit deux tableaux comme paramètres. Le premier définit les règles à
-suivre selon la couleur du sol tandis que le deuxième done la séquence de
-couleur à utiliser. Par exemple, la fourmi de base aurait <code>['R',
-'L']</code> et <code>[Color.white, Color.black]</code> comme arguments.</p>
+couleur à utiliser. Par exemple, la fourmi de base aurait
+[!java]<code>{'R', 'L'}</code> et <code>{Color.white,
+Color.black}</code>[/!]
+[!python]<code>['R', 'L']</code> et <code>[Color.white,
+Color.black]</code>[/!]
+[!scala]<code>Array('R', 'L')</code> et <code>Array(Color.white,
+Color.black)</code>[/!]
+comme arguments.</p>
 
 <p>A chaque pas, vous avez toujours à appliquer le pseudo-code suivant :</p>
 <ul>
diff --git a/src/lessons/turmites/langtoncolors/LangtonColors.html b/src/lessons/turmites/langtoncolors/LangtonColors.html
index 07f3de5..1da7137 100644
--- a/src/lessons/turmites/langtoncolors/LangtonColors.html
+++ b/src/lessons/turmites/langtoncolors/LangtonColors.html
@@ -1,39 +1,36 @@
-<h2>Multicolor Langton's ant</h2>
-
-<p>There is several ways to extend the concept of Langton's ant. In this exercise, 
-we explore first one, using more than two colors. It remains very similar to the 
-base case: the behavior at each step still depends on the ground color, but you 
-have more than 2 possibilities. It allows to have more than one kind of ant, 
-depending on what you decide to do for each color. For example, the ant LRL takes
-3 colors. It turns left on the first color, right on the second one and left 
-on the third color. According to this definition, the basic ant is a RL (since it 
-turns right on white cells and left on black ones).</p>
-
-<p>Some of these ants draw fascinating patterns (switch the world to see them): 
-LLRR build a symmetric figure resembling loosely to a ball, LRRRRRLLR draws a 
-square, LLRRRLRLRLLR draws a convoluted regular pattern after a period of 
-seemingly chaotic behavior, and RRLLLRLLLRRR seems to fill a hour glass...</p>  
-
-<p class="Java">Changing your buggle into a generic Langton's ant is not very complicated, 
-although it is not completely trivial. As previously, you have to write a 
-<code>step</code> function. But this time, it receives two arrays as parameters. 
-The first one defines the rules to follow depending on the ground color while the 
-second one gives the sequence of colors to use. For example, the basic ant would 
-have <code>{'R', 'L'}</code> and <code>{Color.white, Color.black}</code> as arguments.</p>
-
-<p class="python">Changing your buggle into a generic Langton's ant is not very complicated, 
-although it is not completely trivial. As previously, you have to write a 
-<code>step</code> function. But this time, it receives two arrays as parameters. 
-The first one defines the rules to follow depending on the ground color while the 
-second one gives the sequence of colors to use. For example, the basic ant would 
-have <code>['R', 'L']</code> and <code>[Color.white, Color.black]</code> as arguments.</p>
-
-<p>At each step, you thus have to apply the following pseudo-code:</p>
-<ul>
- <li>Find the position of the ground color in the color sequence;</li>
- <li>Turn left or right depending on the content of the rule array at that position;</li>
- <li>Mark the current ground with the next color in the sequence (the last color being followed by the first one);</li>
- <li>Move forward by one step.</li>
-</ul> 
-
-<p>You now should have enough information to succeed.</p>
+<h2>Multicolor Langton's ant</h2>
+
+<p>There is several ways to extend the concept of Langton's ant. In this exercise, 
+we explore first one, using more than two colors. It remains very similar to the 
+base case: the behavior at each step still depends on the ground color, but you 
+have more than 2 possibilities. It allows to have more than one kind of ant, 
+depending on what you decide to do for each color. For example, the ant LRL takes
+3 colors. It turns left on the first color, right on the second one and left 
+on the third color. According to this definition, the basic ant is a RL (since it 
+turns right on white cells and left on black ones).</p>
+
+<p>Some of these ants draw fascinating patterns (switch the world to see them): 
+LLRR build a symmetric figure resembling loosely to a ball, LRRRRRLLR draws a 
+square, LLRRRLRLRLLR draws a convoluted regular pattern after a period of 
+seemingly chaotic behavior, and RRLLLRLLLRRR seems to fill a hour glass...</p>  
+
+<p>Changing your buggle into a generic Langton's ant is not very complicated, 
+although it is not completely trivial. As previously, you have to write a 
+<code>step</code> function. But this time, it receives two arrays as parameters. 
+The first one defines the rules to follow depending on the ground color while the 
+second one gives the sequence of colors to use. For example, the basic ant would 
+have 
+[!java]<code>{'R', 'L'}</code> and <code>{Color.white, Color.black}</code>[/!]
+[!python]<code>['R', 'L']</code> and <code>[Color.white, Color.black]</code>[/!]
+[!scala]<code>Array('R', 'L')</code> and <code>Array(Color.white, Color.black)</code>[/!]
+as arguments.</p>
+
+<p>At each step, you thus have to apply the following pseudo-code:</p>
+<ul>
+ <li>Find the position of the ground color in the color sequence;</li>
+ <li>Turn left or right depending on the content of the rule array at that position;</li>
+ <li>Mark the current ground with the next color in the sequence (the last color being followed by the first one);</li>
+ <li>Move forward by one step.</li>
+</ul> 
+
+<p>You now should have enough information to succeed.</p>
diff --git a/src/lessons/turmites/langtoncolors/LangtonColors.java b/src/lessons/turmites/langtoncolors/LangtonColors.java
index edcfed7..9b517ce 100644
--- a/src/lessons/turmites/langtoncolors/LangtonColors.java
+++ b/src/lessons/turmites/langtoncolors/LangtonColors.java
@@ -1,8 +1,8 @@
 package lessons.turmites.langtoncolors;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bugglequest.BuggleWorld;
 import lessons.turmites.universe.TurmiteWorld;
 
 public class LangtonColors extends ExerciseTemplated {
diff --git a/src/lessons/turmites/langtoncolors/LangtonColorsEntity.java b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.java
index 2a2a8c1..98dba03 100644
--- a/src/lessons/turmites/langtoncolors/LangtonColorsEntity.java
+++ b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.java
@@ -2,7 +2,7 @@ package lessons.turmites.langtoncolors;
 
 import java.awt.Color;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class LangtonColorsEntity extends SimpleBuggle {
 	Color[] allColors = {Color.white, Color.black, Color.blue, Color.cyan, Color.green, Color.orange, Color.red, 
@@ -15,8 +15,8 @@ public class LangtonColorsEntity extends SimpleBuggle {
 		for (int i=0;i<colors.length;i++) {
 			if (current.equals(colors[i])) {
 				switch (rule[i]) {
-				case 'L': turnLeft(); break;
-				case 'R': turnRight(); break;
+				case 'L': left(); break;
+				case 'R': right(); break;
 				default:
 					System.out.println("Unknown command associated to i="+i+": "+rule[i]);
 				}
diff --git a/src/lessons/turmites/langtoncolors/LangtonColorsEntity.py b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.py
index b5147ca..1d8f21c 100644
--- a/src/lessons/turmites/langtoncolors/LangtonColorsEntity.py
+++ b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.py
@@ -4,9 +4,9 @@ def step(rule, colors):
 	for i in range( len(colors) ):
 		if getGroundColor() == colors[i]:
 			if rule[i] == 'L':
-				turnLeft()
+				left()
 			elif rule[i] == 'R':
-				turnRight()
+				right()
 			else:
 				log("Unknown command associated to i=%d: %s" %(i,rule[i]))
 			newrank = (i+1) % (len(colors))
diff --git a/src/lessons/turmites/langtoncolors/LangtonColorsEntity.scala b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.scala
new file mode 100644
index 0000000..181d604
--- /dev/null
+++ b/src/lessons/turmites/langtoncolors/LangtonColorsEntity.scala
@@ -0,0 +1,49 @@
+package lessons.turmites.langtoncolors;
+
+import java.awt.Color
+import plm.universe.bugglequest.SimpleBuggle;
+import lessons.turmites.universe.TurmiteWorld
+
+class ScalaLangtonColorsEntity extends SimpleBuggle {
+	val allColors = Array(Color.white, Color.black, Color.blue, Color.cyan, Color.green, Color.orange, Color.red, 
+			Color.gray, Color.magenta, Color.darkGray, Color.pink, Color.lightGray);
+
+	/* BEGIN TEMPLATE */
+	def step(rule:Array[Char], colors:Array[Color]) {
+		/* BEGIN SOLUTION */
+		var current = getGroundColor(); 
+		for (i <- 0 to colors.length-1) {
+			if (current == colors(i)) {
+			  rule(i) match {
+			    case 'L' => left()
+			    case 'R' => right()
+			    case _   => System.out.println("Unknown command associated to i="+i+": "+rule(i));
+			  }
+
+			  setBrushColor(colors( (i+1) % colors.length ));
+			  brushDown();
+			  brushUp();
+
+			  forward();
+
+			  return;
+			}
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() { 
+		val nbSteps = getParam(0).asInstanceOf[Int];
+		val rule = getParam(1).asInstanceOf[Array[Char]];
+
+		var colors = new Array[Color] (rule.length);
+		for (i <- 0 to rule.length-1)
+			colors(i) = allColors(i);
+
+		for (i <- 1 to nbSteps) {
+			world.asInstanceOf[TurmiteWorld].stepDone();
+			step(rule,colors);
+		}
+	}
+}
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreator.fr.html b/src/lessons/turmites/turmitecreator/TurmiteCreator.fr.html
index 3377fea..5de87bc 100644
--- a/src/lessons/turmites/turmitecreator/TurmiteCreator.fr.html
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreator.fr.html
@@ -3,7 +3,7 @@
 <p>Cet exercice vous permet de construire vos propres turmites. Pour réussir
 cet exercice, vous devez simplement écrire une méthode <code>init()</code>
 qui initialise <code>rule</code> pour utiliser les tables de transitions
-suivantes (de Wikipedia), met la position initiale du buggle à (8;33), et
+suivantes (de Wikipedia), met la position initiale de la buggle à (8;33), et
 demande de faire 8342 pas.</p> 
 
 <table border="1" style="text-align:center">
@@ -65,12 +65,10 @@ les ajouter à cette liste.  </p>
 turmites: seuls des noirs et blancs sont décrits. Vous pouvez considérer
 l'idée de soumettre vos créations directement à l'encyclopédie libre.</p>
 
-<p class="python">Voici quelques turmites bicolores, issues de
-http://demonstrations.wolfram.com/Turmites/ Elles n'ont pas été écrites avec
-la syntaxe Python, mais les convertir ne devrait pas poser beaucoup de
-problèmes.</p> 
-<p class="Java">Voici quelques turmites bicolores, issues de
-http://demonstrations.wolfram.com/Turmites/</p> 
+<p>Voici quelques turmites bicolores, issues de
+http://demonstrations.wolfram.com/Turmites/
+[!scala|python]Elles n'ont pas été écrites avec la syntaxe [!thelang], mais
+les convertir ne devrait pas poser beaucoup de problèmes.[/!]</p> 
 
 <pre>
 {{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: La fourmi de Langton
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreator.html b/src/lessons/turmites/turmitecreator/TurmiteCreator.html
index bead72a..8edc8d4 100644
--- a/src/lessons/turmites/turmitecreator/TurmiteCreator.html
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreator.html
@@ -1,148 +1,147 @@
-<h2>Creating Turmites</h2>
-
-<p>This exercise allows you to build your own turmites. To pass the 
-exercise, you should simply write a <code>init()</code> method which initializes the <code>rule</code> to 
-use the following transitions table (from wikipedia), set the buggle initial position at (8;33), and ask for 8342 steps.</p> 
-
-<table border="1" style="text-align:center">
-<tr>
-<th rowspan="3" colspan="2"></th>
-<th colspan="6">Current color</th>
-</tr>
-<tr>
-<th colspan="3">0</th>
-<th colspan="3">1</th>
-
-</tr>
-<tr style="font-size:9pt">
-<th>Write color</th>
-<th>Turn</th>
-<th>Next state</th>
-<th>Write color</th>
-<th>Turn</th>
-<th>Next state</th>
-</tr>
-<tr>
-<th rowspan="2">Current state</th>
-
-<th>0</th>
-<td>1</td>
-<td>R</td>
-<td>0</td>
-<td>1</td>
-<td>R</td>
-<td>1</td>
-</tr>
-<tr>
-<th>1</th>
-
-<td>0</td>
-<td>N</td>
-<td>0</td>
-<td>0</td>
-<td>N</td>
-<td>1</td>
-</tr>
-</table>
-
-<p>where the direction to turn is one of <b>L</b> (90° left), <b>R</b> (90° right), <b>N</b> (no turn) and <b>U</b> (180° U-turn).</p>
-
-<h2>Going further</h2>
-<p>This exercise is naturally an excuse to let you experiment with your own turmites. 
-Feel free to change the transition table and the amount of steps to experiment by 
-yourself. To that extend, you may find the Ed Pegg Jr's library useful. If you find 
-new interesting patterns, send them per email so that we can integrate
-them to this list!  </p>
-
-<p>In addition, wikipedia is desperately missing some good looking
-colorful turmites: only black and white ones are depicted.  You should
-consider submitting your creations directly to the free
-encyclopedia.</p>
-
-<p class="python">Here are some 2-color turmites, extracted from http://demonstrations.wolfram.com/Turmites/
-They are not written using the python syntax, but converting them should be easy.</p> 
-<p class="Java">Here are some 2-color turmites, extracted from http://demonstrations.wolfram.com/Turmites/</p> 
-
-<pre>
-{{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant
-{{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: binary counter
-{{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: (filled triangle)
-{{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: spiral in a box
-{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: stripe-filled spiral
-{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: stepped pyramid
-{{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: contoured island
-{{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: woven placemat
-{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: snowflake-ish
-{{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: slow city builder
-{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: framed computer art
-{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: balloon bursting (makes a spreading highway)
-{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: makes a horizontal highway
-{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: makes a 45 degree highway
-{{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: makes a 45 degree highway
-{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: spiral in a filled box
-{{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: glaciers
-{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: golden rectangle!
-{{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: fizzy spill
-{{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: nested cabinets
-{{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: (cross)
-{{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: saw-tipped growth
-{{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: curves in blocks growth
-{{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: textured growth
-{{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: (diamond growth)
-{{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: coiled rope
-{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: (growth)
-{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: (square spiral)
-{{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: loopy growth with holes
-{{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: Lanton's Ant drawn with squares
-{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: growth with curves and blocks
-{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: distracted spiral builder
-{{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: cauliflower stalk (45 deg highway)
-{{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: worm trails (eventually turns cyclic!)
-{{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: eventually makes a two-way highway!
-{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: almost symmetric mould bloom
-{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: makes a 1 in 2 gradient highway
-{{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: immediately makes a 1 in 3 highway
-{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {1, LEFT  , 0}}} # 39: squares and diagonals growth
-{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient
-{{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient
-{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, LEFT  , 1}, {1, NOTURN, 1}}} # 42: maze-like growth
-{{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 43: growth by cornices 
-{{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway
-{{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway
-</pre> 
-
-<p>Langton's ants may not share the expressiveness power of the turmites, but they remain 
-fascinating too. You can experiment with them using the initLangton() method, provided
-in your template, that allows to build a Turmite transition table from a Langton's ant
-name. Tiny changes in the ant may result huge changes. For example, "RRL" does not 
-seem to lead to any constructed pattern, even after a million steps, but "RLL" starts 
-building a very simple highway pattern after less than 100 steps!</p>  
-
-<p>Quite a lot of Langton's ants build highways: RL, of course, but also RLRLRLLRLR (about 2500 steps). 
-The chaotic behavior of ants before the highway can be very short (as with RLL that only need 100 steps 
-to converge) or very long, as with LLLLLLRRLRRR which seems chaotic for more than 500,000 steps before 
-build the highway or even RRLLLRRRLRRR which needs 1170000 to start converging. Some are narrow, and 
-others are very large, such as RRLRLLRLRR (200,000 steps). This ant is also notable since it is somehow 
-squarish even before the highway start where most others do not show anything notable before their 
-highway.<p>
-
-<p>Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), RRLLLRLLLRRR (30,000 steps), 
-RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR (20,000 steps). Some even fill the whole space (RRLRR 
-after 3000 steps). Some of my personal favorite ones are the ones where the ant seem to be bouncing 
-within a box that gets bigger on each bump, such as LRRRRRLLR (30,000 steps). LRRRRLLLRRR is even 
-more impressing since the bounces within the box are regular and since it converges more rapidly to 
-its stable behavior (15,000 steps are enough).</p>
-
-<p>Finally, some ants are just build artistic patterns. You should check this video for some beautiful 
-ones: http://www.youtube.com/watch?v=1X-gtr4pEBU. If you want to convert them into your code, you have to 
-shift them by one: For example, the one depicted at 3:42 is not RRLRLRLLRL, but RLRLRLLRLR (the first visible 
-move should be read as last one).</p>
-
-<p>As you can see by exploring the above set of turmites, they are usually not as colorful as the ants, but 
-this may be because very few colors suffice to exhibit complex behaviors. For example, there is a specific 
-class of turmites called <i>busy beavers</i> which are turmites that write a lot of things before stopping 
-(busy beavers are usually classical turing machines, but the idea fits perfectly to turmites too). There is 
-a sort of international competition where people strive to find the turmite that covers the biggest area 
-before stopping. The web page is here: 
-http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines 
-
+<h2>Creating Turmites</h2>
+
+<p>This exercise allows you to build your own turmites. To pass the 
+exercise, you should simply write a <code>init()</code> method which initializes the <code>rule</code> to 
+use the following transitions table (from wikipedia), set the buggle initial position at (8;33), and ask for 8342 steps.</p> 
+
+<table border="1" style="text-align:center">
+<tr>
+<th rowspan="3" colspan="2"></th>
+<th colspan="6">Current color</th>
+</tr>
+<tr>
+<th colspan="3">0</th>
+<th colspan="3">1</th>
+
+</tr>
+<tr style="font-size:9pt">
+<th>Write color</th>
+<th>Turn</th>
+<th>Next state</th>
+<th>Write color</th>
+<th>Turn</th>
+<th>Next state</th>
+</tr>
+<tr>
+<th rowspan="2">Current state</th>
+
+<th>0</th>
+<td>1</td>
+<td>R</td>
+<td>0</td>
+<td>1</td>
+<td>R</td>
+<td>1</td>
+</tr>
+<tr>
+<th>1</th>
+
+<td>0</td>
+<td>N</td>
+<td>0</td>
+<td>0</td>
+<td>N</td>
+<td>1</td>
+</tr>
+</table>
+
+<p>where the direction to turn is one of <b>L</b> (90° left), <b>R</b> (90° right), <b>N</b> (no turn) and <b>U</b> (180° U-turn).</p>
+
+<h2>Going further</h2>
+<p>This exercise is naturally an excuse to let you experiment with your own turmites. 
+Feel free to change the transition table and the amount of steps to experiment by 
+yourself. To that extend, you may find the Ed Pegg Jr's library useful. If you find 
+new interesting patterns, send them per email so that we can integrate
+them to this list!  </p>
+
+<p>In addition, wikipedia is desperately missing some good looking
+colorful turmites: only black and white ones are depicted.  You should
+consider submitting your creations directly to the free
+encyclopedia.</p>
+
+<p>Here are some 2-color turmites, extracted from http://demonstrations.wolfram.com/Turmites/
+[!python|scala]They are not written using the [!thelang] syntax, but converting them should be easy.[/!]</p> 
+
+<pre>
+{{{1, RIGHT , 0}, {0, LEFT  , 0}}}  # 1: Langton's ant
+{{{1, RIGHT , 0}, {0, NOTURN, 0}}}  # 2: binary counter
+{{{0, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 3: (filled triangle)
+{{{0, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {0, NOTURN, 1}}} # 4: spiral in a box
+{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 5: stripe-filled spiral
+{{{0, RIGHT , 1}, {0, LEFT  , 0}}, {{1, LEFT  , 1}, {1, NOTURN, 0}}} # 6: stepped pyramid
+{{{0, RIGHT , 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {1, LEFT  , 0}}} # 7: contoured island
+{{{0, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {0, RIGHT , 1}}} # 8: woven placemat
+{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {1, LEFT  , 0}}} # 9: snowflake-ish
+{{{1, LEFT  , 0}, {0, NOTURN, 1}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 10: slow city builder
+{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 0}, {0, LEFT  , 1}}} # 11: framed computer art
+{{{1, LEFT  , 0}, {1, RIGHT , 1}}, {{0, RIGHT , 1}, {1, LEFT  , 0}}} # 12: balloon bursting (makes a spreading highway)
+{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 13: makes a horizontal highway
+{{{1, LEFT  , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 1}, {1, RIGHT , 0}}} # 14: makes a 45 degree highway
+{{{1, LEFT  , 1}, {0, LEFT  , 1}}, {{1, RIGHT , 1}, {0, LEFT  , 0}}} # 15: makes a 45 degree highway
+{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{1, NOTURN, 0}, {1, RIGHT , 0}}} # 16: spiral in a filled box
+{{{1, LEFT  , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 17: glaciers
+{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 18: golden rectangle!
+{{{1, LEFT  , 1}, {1, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 19: fizzy spill
+{{{1, LEFT  , 1}, {1, RIGHT , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 20: nested cabinets
+{{{1, NOTURN, 1}, {0, LEFT  , 1}}, {{1, RIGHT , 0}, {1, NOTURN, 1}}} # 21: (cross)
+{{{1, NOTURN, 1}, {0, NOTURN, 0}}, {{0, RIGHT , 0}, {1, LEFT  , 0}}} # 22: saw-tipped growth
+{{{1, NOTURN, 1}, {0, NOTURN, 1}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 23: curves in blocks growth
+{{{1, NOTURN, 1}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 0}}} # 24: textured growth
+{{{1, NOTURN, 1}, {0, RIGHT , 1}}, {{1, LEFT  , 0}, {1, RIGHT , 0}}} # 25: (diamond growth)
+{{{1, NOTURN, 1}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {0, NOTURN, 0}}} # 26: coiled rope
+{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, NOTURN, 1}}} # 27: (growth)
+{{{1, RIGHT , 0}, {0, LEFT  , 1}}, {{1, LEFT  , 0}, {0, RIGHT , 1}}} # 28: (square spiral)
+{{{1, RIGHT , 0}, {1, RIGHT , 1}}, {{0, NOTURN, 0}, {0, NOTURN, 1}}} # 29: loopy growth with holes
+{{{1, RIGHT , 1}, {0, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 0}}} # 30: Lanton's Ant drawn with squares
+{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, LEFT  , 1}, {1, LEFT  , 0}}} # 31: growth with curves and blocks
+{{{1, RIGHT , 1}, {0, RIGHT , 0}}, {{0, NOTURN, 0}, {1, RIGHT , 1}}} # 32: distracted spiral builder
+{{{1, RIGHT , 1}, {0, RIGHT , 1}}, {{1, NOTURN, 0}, {1, NOTURN, 1}}} # 33: cauliflower stalk (45 deg highway)
+{{{1, RIGHT , 1}, {1, LEFT  , 1}}, {{1, RIGHT , 1}, {0, RIGHT , 0}}} # 34: worm trails (eventually turns cyclic!)
+{{{1, RIGHT , 1}, {1, NOTURN, 0}}, {{1, NOTURN, 0}, {0, NOTURN, 1}}} # 35: eventually makes a two-way highway!
+{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, NOTURN, 0}, {0, NOTURN, 0}}} # 36: almost symmetric mould bloom
+{{{1, RIGHT , 1}, {1, RIGHT , 0}}, {{0, RIGHT , 0}, {1, NOTURN, 1}}} # 37: makes a 1 in 2 gradient highway
+{{{1, RIGHT , 1}, {1, RIGHT , 1}}, {{1, LEFT  , 1}, {0, RIGHT , 0}}} # 38: immediately makes a 1 in 3 highway
+{{{0, RIGHT , 1}, {1, RIGHT , 1}}, {{0, LEFT  , 2}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {1, LEFT  , 0}}} # 39: squares and diagonals growth
+{{{1, LEFT  , 1}, {0, NOTURN, 0}}, {{0, RIGHT , 2}, {1, LEFT  , 0}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 40: streak at approx. an 8.1 in 1 gradient
+{{{1, LEFT  , 1}, {0, NOTURN, 2}}, {{0, RIGHT , 2}, {1, NOTURN, 1}}, {{1, RIGHT , 1}, {1, NOTURN, 0}}} # 41: streak at approx. a 1.14 in 1 gradient
+{{{1, LEFT  , 1}, {1, LEFT  , 1}}, {{1, NOTURN, 0}, {0, NOTURN, 2}}, {{0, LEFT  , 1}, {1, NOTURN, 1}}} # 42: maze-like growth
+{{{1, LEFT  , 2}, {0, RIGHT , 0}}, {{1, LEFT  , 0}, {0, RIGHT , 0}}, {{0, LEFT  , 0}, {0, LEFT  , 1}}} # 43: growth by cornices 
+{{{1, RIGHT , 0}, {0, RIGHT , 2}}, {{0, LEFT  , 0}, {0, RIGHT , 0}}, {{0, NOTURN, 1}, {1, LEFT  , 0}}} # 44: makes a 1 in 7 highway
+{{{1, RIGHT , 1}, {0, LEFT  , 0}}, {{1, RIGHT , 2}, {0, NOTURN, 0}}, {{1, LEFT  , 0}, {0, LEFT  , 0}}} # 45: makes a 4 in 1 highway
+</pre> 
+
+<p>Langton's ants may not share the expressiveness power of the turmites, but they remain 
+fascinating too. You can experiment with them using the initLangton() method, provided
+in your template, that allows to build a Turmite transition table from a Langton's ant
+name. Tiny changes in the ant may result huge changes. For example, "RRL" does not 
+seem to lead to any constructed pattern, even after a million steps, but "RLL" starts 
+building a very simple highway pattern after less than 100 steps!</p>  
+
+<p>Quite a lot of Langton's ants build highways: RL, of course, but also RLRLRLLRLR (about 2500 steps). 
+The chaotic behavior of ants before the highway can be very short (as with RLL that only need 100 steps 
+to converge) or very long, as with LLLLLLRRLRRR which seems chaotic for more than 500,000 steps before 
+build the highway or even RRLLLRRRLRRR which needs 1170000 to start converging. Some are narrow, and 
+others are very large, such as RRLRLLRLRR (200,000 steps). This ant is also notable since it is somehow 
+squarish even before the highway start where most others do not show anything notable before their 
+highway.<p>
+
+<p>Some ants fill solid sectors, such as RRLLLRLLLRRR (16,000 steps), RRLLLRLLLRRR (30,000 steps), 
+RRLLLRRRRRLR (125,000 steps) or RRLRLLRRRRRR (20,000 steps). Some even fill the whole space (RRLRR 
+after 3000 steps). Some of my personal favorite ones are the ones where the ant seem to be bouncing 
+within a box that gets bigger on each bump, such as LRRRRRLLR (30,000 steps). LRRRRLLLRRR is even 
+more impressing since the bounces within the box are regular and since it converges more rapidly to 
+its stable behavior (15,000 steps are enough).</p>
+
+<p>Finally, some ants are just build artistic patterns. You should check this video for some beautiful 
+ones: http://www.youtube.com/watch?v=1X-gtr4pEBU. If you want to convert them into your code, you have to 
+shift them by one: For example, the one depicted at 3:42 is not RRLRLRLLRL, but RLRLRLLRLR (the first visible 
+move should be read as last one).</p>
+
+<p>As you can see by exploring the above set of turmites, they are usually not as colorful as the ants, but 
+this may be because very few colors suffice to exhibit complex behaviors. For example, there is a specific 
+class of turmites called <i>busy beavers</i> which are turmites that write a lot of things before stopping 
+(busy beavers are usually classical turing machines, but the idea fits perfectly to turmites too). There is 
+a sort of international competition where people strive to find the turmite that covers the biggest area 
+before stopping. The web page is here: 
+http://code.google.com/p/ruletablerepository/wiki/TwoDimensionalTuringMachines 
+
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreator.java b/src/lessons/turmites/turmitecreator/TurmiteCreator.java
index b805948..195d992 100644
--- a/src/lessons/turmites/turmitecreator/TurmiteCreator.java
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreator.java
@@ -1,7 +1,7 @@
 package lessons.turmites.turmitecreator;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
 import lessons.turmites.universe.TurmiteWorld;
 
 public class TurmiteCreator extends ExerciseTemplated {
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.java b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.java
index a56c629..0652bef 100644
--- a/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.java
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.java
@@ -2,7 +2,7 @@ package lessons.turmites.turmitecreator;
 
 import java.awt.Color;
 
-public class TurmiteCreatorEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class TurmiteCreatorEntity extends plm.universe.bugglequest.SimpleBuggle {
 	Color[] allColors = {Color.white, Color.yellow, Color.red, Color.cyan, Color.green, Color.orange, 
 			Color.blue, Color.black,
 			Color.gray, Color.magenta, Color.darkGray, Color.pink, Color.lightGray};
@@ -31,9 +31,9 @@ public class TurmiteCreatorEntity extends jlm.universe.bugglequest.SimpleBuggle
 		switch (rule[state][currentColor][NEXT_MOVE]) {
 		case STOP:   /* nothing */;            break;
 		case NOTURN: /* no turn */; forward(); break;
-		case LEFT:   turnLeft();   	forward(); break;
-		case RIGHT:  turnRight();   forward(); break;
-		case BACK:   turnBack();    forward(); break;
+		case LEFT:   left();   	forward(); break;
+		case RIGHT:  right();   forward(); break;
+		case BACK:   back();    forward(); break;
 		default:
 			System.out.println("Unknown turn command associated to i="+currentColor+": "+rule[state][currentColor][NEXT_MOVE]);
 		}
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.py b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.py
index 753171c..ec3fff7 100644
--- a/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.py
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.py
@@ -28,13 +28,13 @@ def step(rule, colors):
 	elif (rule[state][currentColor][NEXT_MOVE] == NOTURN):
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == LEFT):
-		turnLeft()
+		left()
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == RIGHT):
-		turnRight()
+		right()
 		forward()
 	elif (rule[state][currentColor][NEXT_MOVE] == BACK):
-		turnBack()
+		back()
 		forward()
 	else:
 		log("Unknown turn command associated to i=%d: %d" % (currentColor, rule[state][currentColor][NEXT_MOVE]))
diff --git a/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.scala b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.scala
new file mode 100644
index 0000000..f6bf689
--- /dev/null
+++ b/src/lessons/turmites/turmitecreator/TurmiteCreatorEntity.scala
@@ -0,0 +1,139 @@
+package lessons.turmites.turmitecreator;
+
+import java.awt.Color
+
+import plm.universe.bugglequest.SimpleBuggle
+import lessons.turmites.universe.TurmiteWorld
+
+class ScalaTurmiteCreatorEntity extends SimpleBuggle {
+	val allColors = Array(Color.white, Color.yellow, Color.red, Color.cyan, Color.green, Color.orange, 
+			Color.blue, Color.black,
+			Color.gray, Color.magenta, Color.darkGray, Color.pink, Color.lightGray);
+
+	var state = 0;
+
+	def step(colors:Array[Color]) {
+		var currentColor=0;
+
+		val current = getGroundColor();
+		for (i <- 0 to colors.length-1) 
+			if (current == colors(i)) 
+				currentColor = i;
+
+				setBrushColor(colors( rule(state)(currentColor)(NEXT_COLOR) ));
+				brushDown();
+				brushUp();
+
+				rule(state)(currentColor)(NEXT_MOVE) match {
+				case STOP   => /* nothing */
+				case NOTURN => /* no turn */ forward(); 
+				case LEFT   => left();   	   forward(); 
+				case RIGHT  => right();      forward(); 
+				case BACK   => back();       forward(); 
+				case _      => System.out.println("Unknown turn command associated to i="+currentColor+": "+rule(state)(currentColor)(NEXT_MOVE));
+				}
+
+				state = rule(state)(currentColor)(NEXT_STATE);
+	}
+
+	/* BEGIN TEMPLATE */
+	/* Do not change these definitions */
+	val STOP   = 0;
+	val NOTURN = 1;
+	val LEFT   = 2;
+	val BACK   = 4;
+	val RIGHT  = 8;
+
+	val NEXT_COLOR = 0;
+	val NEXT_MOVE  = 1;
+	val NEXT_STATE = 2;
+	
+	
+	var rule:Array[Array[Array[Int]]] = null // Change this
+	var nbSteps:Int = 0; // Change this
+
+	/** init the rule array from a string defining a Langton's ant 
+	 * 
+	 *  You can use this method inside your init() method if you want 
+	 *  to test langton's ant instead of full turmites.
+	 */
+	def initLangton(name:String) {
+		val nbColors = name.length(); /* As many colors as letters in the ant's name */
+
+		rule = new Array[Array[Array[Int]]] (1); /* one state only */
+		rule(0) = new Array[Array[Int]] (nbColors); /* As many colors as letters in the ant's name */
+		for (i <- 0 to nbColors-1) {
+			rule(0)(i) = new Array[Int] (3); /* every command set has 3 elements */ 
+
+			rule(0)(i)(NEXT_COLOR) = (i+1) % nbColors;
+
+			if (name.charAt(i) == 'L') {
+				rule(0)(i)(NEXT_MOVE) = LEFT;			
+			} else if (name.charAt(i) == 'R') {
+				rule(0)(i)(NEXT_MOVE) = RIGHT;
+			} else {
+				System.out.println("Unknown command in your ant's name: "+name.charAt(i));
+			}
+
+			rule(0)(i)(NEXT_STATE) = 0; /* only one state */
+
+			// println("{"+rule(0)(i)(NEXT_COLOR)+","+rule(0)(i)(NEXT_MOVE)+","+rule(0)(i)(NEXT_STATE)+"}");
+		}
+	}
+	def init() {
+		/* Your code comes here. */
+
+		/* Something like 
+		 *   nbSteps = 42;
+		 *   rule = Array( Array( Array(0,NOTURN,0), Array(0, NOTURN, 0) ) ); 
+		 * but with possibly more states (ie, bigger second dimension), and more color (ie bigger third -- internal -- dimension) 
+		 * and naturally, less boring than this turmite doing absolutely nothing (runs forward endlessly).
+		 */
+
+		/* It can also be something like
+		 *   nbSteps = 42;
+		 *   initLangton("RL");
+		 */
+
+		/* remember to send your best creations for inclusion in the gallery */
+		/* BEGIN SOLUTION */
+		nbSteps = 8342;
+		rule = Array( Array( Array(1, LEFT, 0), Array(1, LEFT, 1)), Array( Array(0, NOTURN, 0), Array(0, NOTURN, 1)));
+		setX(8); setY(33);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() {
+		init();
+
+		var colors = new Array[Color] (rule(0).length);
+		for (i <- 0 to rule(0).length-1) {
+			if (i<allColors.length) {
+				colors(i) = allColors(i);		    
+			} else {
+				/* allColors is too short; create the other colors randomly */
+				var newColor:Color = null
+						do {
+							newColor = new Color(
+									(Math.random()*255.).asInstanceOf[Int] ,
+									(Math.random()*255.).asInstanceOf[Int] ,
+									(Math.random()*255.).asInstanceOf[Int] );
+							for (j <- 0 to i-1) {
+								if (colors(j) == newColor) {
+									/* Damn we already picked that color; take another one please */
+									newColor = null;
+								}
+							}
+						} while (newColor == null);
+			colors(i) = newColor;
+			}
+		}
+
+
+		for (stepIt <- 1 to nbSteps) {
+			step(colors);
+			world.asInstanceOf[TurmiteWorld].stepDone();
+		}
+	}
+}
diff --git a/src/lessons/turmites/universe/TurmiteWorld.fr.html b/src/lessons/turmites/universe/TurmiteWorld.fr.html
index 9543b20..1e846fe 100644
--- a/src/lessons/turmites/universe/TurmiteWorld.fr.html
+++ b/src/lessons/turmites/universe/TurmiteWorld.fr.html
@@ -1,51 +1,18 @@
-<h1>Le monde des Buggles</h1>
-Ce monde a été inventé par Lyn Turbak, du Wellesley College. Il est peuplé
-de Buggles, petites bêtes qui comprennent des ordres simples, et offre de
-nombreuses possibilités d'interaction avec le monde: prendre ou poser des
-objets, colorier le sol, se cogner à des murs, etc.
+<h1>L'univers des turmites</h1>
 
-<h2>Méthodes comprises par les buggles</h2>
-<table border=1>
-<tr><td colspan=2 align=center><b>Bouger</b><br/> (voir aussi la note sur les exceptions, plus bas)</td></tr>
-  <tr><td><b>Tourner à gauche<br/>Tourner à droite<br/>Se retourner<br/>Avancer<br/>Reculer</b></td>
-      <td>void turnLeft()<br/>void turnRight()<br/>void turnBack()<br/>
-          void forward() ou void forward(int)<br/>void backward() ou void backward(int)<br/></td></tr>
-  <tr><td><b>Obtenir l'abcisse<br/>Obtenir l'ordonnée<br/>Changer l'abcisse<br/>Changer l'ordonnée<br/>Changer la position</b></td>
-      <td>int getX()<br/>int getY()<br/>void setX(int)<br/>void setY(int)<br/>void setPos(int,int)</td></tr>
-
-<tr><td colspan=2 align=center><b>Informations sur la buggle</b></td></tr>
-  <tr><td><b>Obtenir la couleur<br/>Changer la couleur</b></td>
-      <td>Color getColor()<br/>void setColor(Color)</td></tr>				
-  <tr><td><b>Chercher un mur devant<br/>Chercher un mur derriere</b></td>
-      <td>boolean isFacingWall()<br/>boolean isBackingWall()</td></tr>				
-  <tr><td><b>Obtenir la direction<br/>Changer la direction</b><br/>Les directions valides sont :</td>
-      <td>Direction getDirection()<br/>void setDirection(Direction)<br/>Direction.NORTH, Direction.EAST, Direction.SOUTH et Direction.WEST</td></tr>
- 
-<tr><td colspan=2 align=center><b>À propos de la brosse</b></td></tr>
-  <tr><td><b>Baisser la brosse<br/>Lever la brosse<br/>Obtenir la position de la brosse</b></td>
-      <td>void brushUp()<br/>void brushDown()<br/>boolean isBrushDown()</td></tr>
-  <tr><td><b>Modifier la couleur de la brosse<br/>Obtenir la couleur de la brosse</b></td>
-      <td>void setBrushColor(Color)<br/>Color getBrushColor()</td></tr>
+<p>Cet univers est très semblable à celui des buggles, mais vous n'utiliserez
+probablement pas toutes les méthodes des buggles. Cette page résume donc les
+quelques méthodes que vous serez amenés à utiliser.</p>
 
-<tr><td colspan=2 align=center><b>Interagir avec le monde</b></td></tr>
-  <tr><td><b>Obtenir la couleur du sol</b></td><td>Color getGroundColor()</td></tr>
+<p></p>
 
-  <tr><td><b>Chercher un baggle par terre<br/>Chercher un baggle dans ses poches<br/>Prendre un baggle<br/>Poser un baggle</b><br/>
-      (voir la note sur les exceptions)</td>
-      <td>boolean isOverBaggle()<br/>boolean isCarryingBaggle()<br/>void pickupBaggle()<br/>void dropBaggle()</td></tr>
+<table border=1>
+  <tr><td><b>Tourner à gauche<br/>Tourner à droite<br/>Se retourner<br/>Avancer<br/>Reculer</b></td>
+      <td>[!java]void [/!]gauche()<br/>[!java]void [/!]droite()<br/>[!java]void [/!]retourne()<br/>
+          [!java]void [/!]avance() ou [!java]void [/!]avance([!java]int
+[/!]steps[!scala]:Int[/!])<br/>
+          [!java]void [/!]recule() or [!java]void [/!]recule([!java]int
+[/!]steps[!scala]:Int[/!])<br/></td></tr>
 
-  <tr><td><b>Chercher un message<br/>Ajouter un message<br/>Lire le message<br/>Effacer le message</b></td>
-      <td>boolean isOverMessage()<br/>void writeMessage(String)<br/>String readMessage()<br/>void clearMessage()</td></tr>
+  <tr><td><b>Obtenir la couleur du sol</b></td><td>[!java]Color [/!]getCouleurSol()[!scala]:Color[/!]</td></tr>
 </table>
-
-<h2>Note sur les exceptions</h2>
-Les buggles normales lèvent une exception BuggleWallException si on cherche
-à leur faire traverser un mur.
-Elles lèvent une exception NoBaggleUnderBuggleException si vous cherchez à
-prendre un baggle dans une case qui n'en contient pas, ou une exception
-AlreadyHaveBaggleException si vous portez déjà un baggel.
-Tenter de déposer un baggel sur une case qui en contient déjà lève une
-exception AlreadyHaveBaggleException.
-<p>Les "SimpleBuggles" (ie, celles utilisées dans les premiers exercices)
-affiche un message d'erreur sans que vous ayez à vous soucier de ce qu'est
-une exception.</p>
diff --git a/src/lessons/turmites/universe/TurmiteWorld.html b/src/lessons/turmites/universe/TurmiteWorld.html
index 7ecf97d..cc962b9 100644
--- a/src/lessons/turmites/universe/TurmiteWorld.html
+++ b/src/lessons/turmites/universe/TurmiteWorld.html
@@ -1,49 +1,15 @@
-<h1>BuggleWorld</h1>
-This world was invented by Lyn Turbak, at Wellesley College. It is full of
-Buggles, little animals understanding simple orders, and offers numerous
-possibilities of interaction with the world: taking or dropping objects,
-paint the ground, hit walls, etc.
-
-<h2>Methods understood by buggles</h2>
-<table border=1>
-<tr><td colspan=2 align=center><b>Moving</b><br/> (See also the note on exceptions, below)</td></tr>
-  <tr><td><b>Turn left<br/>Turn right<br/>Turn back<br/>Moving forward<br/>Moving back</b></td>
-      <td>void turnLeft()<br/>void turnRight()<br/>void turnBack()<br/>
-          void forward() or void forward(int)<br/>void backward() or void backward(int)<br/></td></tr>
-  <tr><td><b>Get X coordinate<br/>Get Y coordinate<br/>Set X coordinate<br/>Set Y coordinate<br/>Set position</b></td>
-      <td>int getX()<br/>int getY()<br/>void setX(int)<br/>void setY(int)<br/>void setPos(int,int)</td></tr>
-
-<tr><td colspan=2 align=center><b>Information on the buggle</b></td></tr>
-  <tr><td><b>Get the color<br/>Set the color</b></td>
-      <td>Color getColor()<br/>void setColor(Color)</td></tr>				
-  <tr><td><b>Look for a wall forward<br/>Look for a wall backward</b></td>
-      <td>boolean isFacingWall()<br/>boolean isBackingWall()</td></tr>				
-  <tr><td><b>Get heading<br/>Set heading</b><br/>valid directions are:</td>
-      <td>Direction getDirection()<br/>void setDirection(Direction)<br/>Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST</td></tr>
- 
-<tr><td colspan=2 align=center><b>About the brush</b></td></tr>
-  <tr><td><b>Brush down<br/>Brush up<br/>Get brush position</b></td>
-      <td>void brushUp()<br/>void brushDown()<br/>boolean isBrushDown()</td></tr>
-  <tr><td><b>Change the brush color<br/>Get the color of the brush</b></td>
-      <td>void setBrushColor(Color)<br/>Color getBrushColor()</td></tr>
-
-<tr><td colspan=2 align=center><b>Interacting with the world</b></td></tr>
-  <tr><td><b>Get the color of the ground</b></td><td>Color getGroundColor()</td></tr>
-
-  <tr><td><b>Look for a baggle on the ground<br/>Look for a baggle in bag<br/>Pickup a baggle<br/>Drop a baggle</b><br/>
-      (see the note on exceptions)</td>
-      <td>boolean isOverBaggle()<br/>boolean isCarryingBaggle()<br/>void pickupBaggle()<br/>void dropBaggle()</td></tr>
-
-  <tr><td><b>Look for a message<br/>Add a message<br/>Read the message<br/>Erase the message</b></td>
-      <td>boolean isOverMessage()<br/>void writeMessage(String)<br/>String readMessage()<br/>void clearMessage()</td></tr>
-</table>
-
-<h2>Note on exceptions</h2>
-Regular buggles throw a BuggleWallException exception if you ask them to
-traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you
-ask them to pickup a baggle from an empty cell, or a
-AlreadyHaveBaggleException exception if they already carry a baggle.  Trying
-to drop a baggle on a cell already containing one throws an
-AlreadyHaveBaggleException exception.
-<p>SimpleBuggles (ie, the one used in first exercises) display an error message
-on problem so that you don't need to know what an exception is.</p>
+<h1>Turmite universe</h1>
+
+<p>This universe is very similar to the buggle one, but you will probably not use all buggles methods.
+So, this page only recap the buggle methods that you will use.</p>
+
+<p></p>
+
+<table border=1>
+  <tr><td><b>Turn left<br/>Turn right<br/>Turn back<br/>Moving forward<br/>Moving back</b></td>
+      <td>[!java]void [/!]left()<br/>[!java]void [/!]right()<br/>[!java]void [/!]back()<br/>
+          [!java]void [/!]forward() or [!java]void [/!]forward([!java]int [/!]steps[!scala]:Int[/!])<br/>
+          [!java]void [/!]backward() or [!java]void [/!]backward([!java]int [/!]steps[!scala]:Int[/!])<br/></td></tr>
+
+  <tr><td><b>Get the color of the ground</b></td><td>[!java]Color [/!]getGroundColor()[!scala]:Color[/!]</td></tr>
+</table>
diff --git a/src/lessons/turmites/universe/TurmiteWorld.java b/src/lessons/turmites/universe/TurmiteWorld.java
index 7d2f7f9..dd35a05 100644
--- a/src/lessons/turmites/universe/TurmiteWorld.java
+++ b/src/lessons/turmites/universe/TurmiteWorld.java
@@ -7,15 +7,15 @@ import javax.script.ScriptEngine;
 import javax.script.ScriptException;
 import javax.swing.ImageIcon;
 
-import jlm.core.model.Game;
-import jlm.core.model.ProgrammingLanguage;
-import jlm.core.ui.ResourcesCache;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.Direction;
-import jlm.universe.World;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.ui.BuggleWorldView;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Direction;
+import plm.universe.World;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.ui.BuggleWorldView;
 
 public class TurmiteWorld extends BuggleWorld {	
 	/** A copy constructor (mandatory for the internal compilation mechanism to work)
@@ -48,7 +48,7 @@ public class TurmiteWorld extends BuggleWorld {
 	
 	/** Reset the state of the current world to the one passed in argument
 	 * 
-	 * This is mandatory for the JLM good working. Even if the prototype says that the passed object can be 
+	 * This is mandatory for the PLM good working. Even if the prototype says that the passed object can be 
 	 * any kind of world, you can be sure that it's of the same type than the current world. So, there is 
 	 * no need to check before casting your argument.
 	 * 
@@ -114,7 +114,11 @@ public class TurmiteWorld extends BuggleWorld {
 			engine.put("daWorld", this);
 			engine.eval(
 					"def stepDone():\n"+
-					"	daWorld.stepDone()\n");
+					"	daWorld.stepDone()\n"+
+					/* BINDINGS TRANSLATION: French */
+					"def pasFait():\n"+
+					"	daWorld.stepDone()\n"
+					);
 		}
 	}
 	
diff --git a/src/lessons/turmites/universe/TurmiteWorldView.java b/src/lessons/turmites/universe/TurmiteWorldView.java
index b166b9f..4ce3868 100644
--- a/src/lessons/turmites/universe/TurmiteWorldView.java
+++ b/src/lessons/turmites/universe/TurmiteWorldView.java
@@ -3,8 +3,8 @@ package lessons.turmites.universe;
 import java.awt.Color;
 import java.awt.Graphics;
 
-import jlm.universe.World;
-import jlm.universe.bugglequest.ui.BuggleWorldView;
+import plm.universe.World;
+import plm.universe.bugglequest.ui.BuggleWorldView;
 
 
 
diff --git a/src/lessons/turtleart/CircleSquareEntity.java b/src/lessons/turtleart/CircleSquareEntity.java
new file mode 100644
index 0000000..6e89fb8
--- /dev/null
+++ b/src/lessons/turtleart/CircleSquareEntity.java
@@ -0,0 +1,23 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class CircleSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,100, 35,200);
+
+        for (int i = 0; i < 4; i++) {
+        	forward(100);
+        	right(90);
+        }
+        forward(100);
+        right(90);
+        forward(50);
+        circle(50);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleSquareEntity.py b/src/lessons/turtleart/CircleSquareEntity.py
new file mode 100644
index 0000000..daedd38
--- /dev/null
+++ b/src/lessons/turtleart/CircleSquareEntity.py
@@ -0,0 +1,12 @@
+# BEGIN SOLUTION
+addSizeHint(35,100, 35,200);
+
+for i in range(4):
+   forward(100);
+   right(90);
+
+forward(100);
+right(90);
+forward(50);
+circle(50);
+# END SOLUTION
diff --git a/src/lessons/turtleart/CircleSquareEntity.scala b/src/lessons/turtleart/CircleSquareEntity.scala
new file mode 100644
index 0000000..1266125
--- /dev/null
+++ b/src/lessons/turtleart/CircleSquareEntity.scala
@@ -0,0 +1,23 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaCircleSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,100, 35,200);
+
+        for (i <- 1 to 4) {
+        	forward(100);
+        	right(90);
+        }
+        forward(100);
+        right(90);
+        forward(50);
+        circle(50);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleTenEntity.java b/src/lessons/turtleart/CircleTenEntity.java
new file mode 100644
index 0000000..97c97f5
--- /dev/null
+++ b/src/lessons/turtleart/CircleTenEntity.java
@@ -0,0 +1,16 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class CircleTenEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    for (int i=10; i<=100;i+=10) {
+	        circle(i);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleTenEntity.py b/src/lessons/turtleart/CircleTenEntity.py
new file mode 100644
index 0000000..61f65fe
--- /dev/null
+++ b/src/lessons/turtleart/CircleTenEntity.py
@@ -0,0 +1,4 @@
+# BEGIN SOLUTION
+for i in range(10,110,10):
+	circle(i);
+# END SOLUTION
diff --git a/src/lessons/turtleart/CircleTenEntity.scala b/src/lessons/turtleart/CircleTenEntity.scala
new file mode 100644
index 0000000..b71f3a1
--- /dev/null
+++ b/src/lessons/turtleart/CircleTenEntity.scala
@@ -0,0 +1,16 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaCircleTenEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    for (i <- 10 to 100 by 10) {
+	        circle(i);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleTwoEntity.java b/src/lessons/turtleart/CircleTwoEntity.java
new file mode 100644
index 0000000..8124d10
--- /dev/null
+++ b/src/lessons/turtleart/CircleTwoEntity.java
@@ -0,0 +1,21 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class CircleTwoEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		for (int i=0; i<360;i++) {
+			forward(1.);
+			right(1);
+		}
+		for (int i=0; i<360;i++) {
+			forward(2);
+			right(1);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleTwoEntity.py b/src/lessons/turtleart/CircleTwoEntity.py
new file mode 100644
index 0000000..9b45e8a
--- /dev/null
+++ b/src/lessons/turtleart/CircleTwoEntity.py
@@ -0,0 +1,9 @@
+# BEGIN SOLUTION
+for i in range(360):
+	forward(1.);
+	right(1);
+
+for i in range(360):
+	forward(2);
+	right(1);
+# END SOLUTION
diff --git a/src/lessons/turtleart/CircleTwoEntity.scala b/src/lessons/turtleart/CircleTwoEntity.scala
new file mode 100644
index 0000000..e594b08
--- /dev/null
+++ b/src/lessons/turtleart/CircleTwoEntity.scala
@@ -0,0 +1,21 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaCircleTwoEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 360) {
+			forward(1.);
+			right(1);
+		}
+		for (i <- 1 to 360) {
+			forward(2);
+			right(1);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleYingEntity.java b/src/lessons/turtleart/CircleYingEntity.java
new file mode 100644
index 0000000..3fd2bdb
--- /dev/null
+++ b/src/lessons/turtleart/CircleYingEntity.java
@@ -0,0 +1,25 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class CircleYingEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    for (int i=0; i<360;i++) {
+	        forward(2);
+	        right(1);
+	    }
+	    for (int i=0; i<180;i++) {
+	        forward(1);
+	        right(1);
+	    }
+	    for (int i=0; i<180;i++) {
+	        forward(1);
+	        left(1);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/CircleYingEntity.py b/src/lessons/turtleart/CircleYingEntity.py
new file mode 100644
index 0000000..070fd13
--- /dev/null
+++ b/src/lessons/turtleart/CircleYingEntity.py
@@ -0,0 +1,12 @@
+# BEGIN SOLUTION
+for i in range(360):
+	forward(2);
+	right(1);
+for i in range(180):
+	forward(1)
+	right(1)
+
+for i in range(180):
+	forward(1);
+	left(1);
+# END SOLUTION
diff --git a/src/lessons/turtleart/CircleYingEntity.scala b/src/lessons/turtleart/CircleYingEntity.scala
new file mode 100644
index 0000000..a177bae
--- /dev/null
+++ b/src/lessons/turtleart/CircleYingEntity.scala
@@ -0,0 +1,25 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaCircleYingEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    for (i <- 1 to 360) {
+	        forward(2);
+	        right(1);
+	    }
+	    for (i <- 1 to 180) {
+	        forward(1);
+	        right(1);
+	    }
+	    for (i <- 1 to 180) {
+	        forward(1);
+	        left(1);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskFourEntity.java b/src/lessons/turtleart/DiskFourEntity.java
new file mode 100644
index 0000000..47df2ea
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourEntity.java
@@ -0,0 +1,29 @@
+package lessons.turtleart;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+public class DiskFourEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		quadrant();
+		setColor(Color.RED);
+		quadrant();
+		setColor(Color.ORANGE);
+		quadrant();
+		setColor(Color.MAGENTA);
+		quadrant();
+	}
+	public void quadrant() {
+		for (int i=0; i<90;i++) {
+			forward(100);
+			backward(100);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskFourEntity.py b/src/lessons/turtleart/DiskFourEntity.py
new file mode 100644
index 0000000..9af7f6c
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourEntity.py
@@ -0,0 +1,15 @@
+# BEGIN SOLUTION
+def quadrant():
+	for i in range(90):
+		forward(100);
+		backward(100);
+		right(1);
+
+quadrant();
+setColor(Color.RED);
+quadrant();
+setColor(Color.ORANGE);
+quadrant();
+setColor(Color.MAGENTA);
+quadrant();
+# END SOLUTION
diff --git a/src/lessons/turtleart/DiskFourEntity.scala b/src/lessons/turtleart/DiskFourEntity.scala
new file mode 100644
index 0000000..2acb79c
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourEntity.scala
@@ -0,0 +1,29 @@
+package lessons.turtleart;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaDiskFourEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		quadrant();
+		setColor(Color.RED);
+		quadrant();
+		setColor(Color.ORANGE);
+		quadrant();
+		setColor(Color.MAGENTA);
+		quadrant();
+	}
+	def quadrant() {
+		for (i <- 1 to 90) {
+			forward(100);
+			backward(100);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskFourthEntity.java b/src/lessons/turtleart/DiskFourthEntity.java
new file mode 100644
index 0000000..7ccd288
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourthEntity.java
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class DiskFourthEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(135, 150, 135, 50);
+	    for (int i=0; i<90;i++) {
+	        forward(100);
+	        backward(100);
+	        right(1);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskFourthEntity.py b/src/lessons/turtleart/DiskFourthEntity.py
new file mode 100644
index 0000000..6faa890
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourthEntity.py
@@ -0,0 +1,7 @@
+# BEGIN SOLUTION
+addSizeHint(135, 150, 135, 50);
+for i in range(90):
+	forward(100);
+	backward(100);
+	right(1);
+# END SOLUTION
\ No newline at end of file
diff --git a/src/lessons/turtleart/DiskFourthEntity.scala b/src/lessons/turtleart/DiskFourthEntity.scala
new file mode 100644
index 0000000..7ccc003
--- /dev/null
+++ b/src/lessons/turtleart/DiskFourthEntity.scala
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaDiskFourthEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(135, 150, 135, 50);
+	    for (i <- 1 to 90) {
+	        forward(100);
+	        backward(100);
+	        right(1);
+	    }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskTwoEntity.java b/src/lessons/turtleart/DiskTwoEntity.java
new file mode 100644
index 0000000..56cff4b
--- /dev/null
+++ b/src/lessons/turtleart/DiskTwoEntity.java
@@ -0,0 +1,28 @@
+package lessons.turtleart;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+public class DiskTwoEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		for (int i=0;i<18;i++) {
+			setColor(Color.BLACK);
+			quadrant();
+			setColor(Color.RED);
+			quadrant();
+		}
+	}
+	public void quadrant() {
+		for (int i=0; i<20;i++) {
+			forward(100);
+			backward(100);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/DiskTwoEntity.py b/src/lessons/turtleart/DiskTwoEntity.py
new file mode 100644
index 0000000..954b9d0
--- /dev/null
+++ b/src/lessons/turtleart/DiskTwoEntity.py
@@ -0,0 +1,13 @@
+# BEGIN SOLUTION
+def quadrant():
+	for i in range(20):
+		forward(100);
+		backward(100);
+		right(1);
+
+for i in range(18):
+	setColor(Color.BLACK);
+	quadrant();
+	setColor(Color.RED);
+	quadrant();
+# END SOLUTION
diff --git a/src/lessons/turtleart/DiskTwoEntity.scala b/src/lessons/turtleart/DiskTwoEntity.scala
new file mode 100644
index 0000000..b904145
--- /dev/null
+++ b/src/lessons/turtleart/DiskTwoEntity.scala
@@ -0,0 +1,28 @@
+package lessons.turtleart;
+
+import java.awt.Color;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaDiskTwoEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1  to 18) {
+			setColor(Color.BLACK);
+			quadrant();
+			setColor(Color.RED);
+			quadrant();
+		}
+	}
+	def quadrant() {
+		for (i <- 1 to 20) {
+			forward(100);
+			backward(100);
+			right(1);
+		}		
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseEntity.java b/src/lessons/turtleart/HouseEntity.java
new file mode 100644
index 0000000..e21e8d9
--- /dev/null
+++ b/src/lessons/turtleart/HouseEntity.java
@@ -0,0 +1,32 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class HouseEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(50,265, 150,265);
+	    addSizeHint(35,250, 35,150);
+	 
+	    house(100);
+	}
+	void house(int len) {
+	    forward(len);
+	    
+	    right(30);
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseEntity.py b/src/lessons/turtleart/HouseEntity.py
new file mode 100644
index 0000000..6aa9e71
--- /dev/null
+++ b/src/lessons/turtleart/HouseEntity.py
@@ -0,0 +1,19 @@
+# BEGIN SOLUTION
+def house(len):
+	forward(len);
+	    
+	right(30);
+	for i in range(3):
+		forward(len);
+		right(120);
+	    
+	right(60);    
+	for i in range(3):
+	    	forward(len);
+	    	right(90);
+	    	
+addSizeHint(50,265, 150,265);
+addSizeHint(35,250, 35,150);
+	 
+house(100);
+# END SOLUTION
diff --git a/src/lessons/turtleart/HouseEntity.scala b/src/lessons/turtleart/HouseEntity.scala
new file mode 100644
index 0000000..5840136
--- /dev/null
+++ b/src/lessons/turtleart/HouseEntity.scala
@@ -0,0 +1,32 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaHouseEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(50,265, 150,265);
+	    addSizeHint(35,250, 35,150);
+	 
+	    house(100);
+	}
+	def house(len:Int) {
+	    forward(len);
+	    
+	    right(30);
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseManyEntity.java b/src/lessons/turtleart/HouseManyEntity.java
new file mode 100644
index 0000000..295cdf4
--- /dev/null
+++ b/src/lessons/turtleart/HouseManyEntity.java
@@ -0,0 +1,62 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class HouseManyEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(35,220, 35,250);
+	    addSizeHint(80,250, 100,250);
+	    addSizeHint(20,250-75, 20, 250);
+	 
+	    line();
+	    house(30);
+	    penUp();right(90);forward(150);left(90);penDown();
+	    house(30);
+	    penUp();
+	    left(90);
+	    forward(150);
+	    right(90);
+	    forward(75);
+	    penDown();
+	    line();
+	}
+	void nextLine() {
+	     penUp();
+	     left(90);
+	     forward(200);
+	     right(90);
+	     forward(75);
+	     penDown();    
+	}
+	void line() {
+	     for (int cpt=0;cpt<4;cpt++) {
+	        house(30);
+	        leveCrayon();
+	        right(90);
+	        forward(50);
+	        left(90);
+	        penDown();
+	     }
+	     nextLine();
+	}
+	void house(int len) {
+	    forward(len);
+	    
+	    right(30);
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseManyEntity.py b/src/lessons/turtleart/HouseManyEntity.py
new file mode 100644
index 0000000..4cb0c7c
--- /dev/null
+++ b/src/lessons/turtleart/HouseManyEntity.py
@@ -0,0 +1,47 @@
+# BEGIN SOLUTION
+def nextLine():
+	penUp();
+	left(90);
+	forward(200);
+	right(90);
+	forward(75);
+	penDown();    
+	
+def line():
+	for i in range(4):
+		house(30);
+		leveCrayon();
+	        right(90);
+	        forward(50);
+	        left(90);
+	        penDown();     
+	nextLine();
+
+def house(len):
+	forward(len);
+	    
+	right(30);
+	for i in range(3):
+	    	forward(len);
+	    	right(120);
+	right(60);    
+	for i in range (3):
+	    	forward(len);
+	    	right(90);
+
+addSizeHint(35,220, 35,250);
+addSizeHint(80,250, 100,250);
+addSizeHint(20,250-75, 20, 250);
+	 
+line();
+house(30);
+penUp();right(90);forward(150);left(90);penDown();
+house(30);
+penUp();
+left(90);
+forward(150);
+right(90);
+forward(75);
+penDown();
+line();
+# END SOLUTION
diff --git a/src/lessons/turtleart/HouseManyEntity.scala b/src/lessons/turtleart/HouseManyEntity.scala
new file mode 100644
index 0000000..2c2fc6f
--- /dev/null
+++ b/src/lessons/turtleart/HouseManyEntity.scala
@@ -0,0 +1,62 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaHouseManyEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(35,220, 35,250);
+	    addSizeHint(80,250, 100,250);
+	    addSizeHint(20,250-75, 20, 250);
+	 
+	    line();
+	    house(30);
+	    penUp();right(90);forward(150);left(90);penDown();
+	    house(30);
+	    penUp();
+	    left(90);
+	    forward(150);
+	    right(90);
+	    forward(75);
+	    penDown();
+	    line();
+	}
+	def nextLine() {
+	     penUp();
+	     left(90);
+	     forward(200);
+	     right(90);
+	     forward(75);
+	     penDown();    
+	}
+	def line() {
+	     for (i <- 1 to 4) {
+	        house(30);
+	        leveCrayon();
+	        right(90);
+	        forward(50);
+	        left(90);
+	        penDown();
+	     }
+	     nextLine();
+	}
+	def house(len:Int) {
+	    forward(len);
+	    
+	    right(30);
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseThreeEntity.java b/src/lessons/turtleart/HouseThreeEntity.java
new file mode 100644
index 0000000..0351fd9
--- /dev/null
+++ b/src/lessons/turtleart/HouseThreeEntity.java
@@ -0,0 +1,39 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class HouseThreeEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(35,120, 35,150);
+	    addSizeHint(80,150, 100,150);
+	 
+	     for (int i=0;i<4;i++) {
+	        house(30);
+	        leveCrayon();
+	        right(90);
+	        forward(50);
+	        left(90);
+	        penDown();
+	     }
+	}
+	void house(int len) {
+	    forward(len);
+	    
+	    right(30);
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (int i = 0; i < 3; i++) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/HouseThreeEntity.py b/src/lessons/turtleart/HouseThreeEntity.py
new file mode 100644
index 0000000..a067338
--- /dev/null
+++ b/src/lessons/turtleart/HouseThreeEntity.py
@@ -0,0 +1,26 @@
+# BEGIN SOLUTION
+def house(len):
+	forward(len);
+	    
+	right(30);
+	for i in range(3):
+		forward(len);
+		right(120);
+	    
+	right(60);    
+	for i in range(3):
+	    	forward(len);
+	    	right(90);
+
+addSizeHint(35,120, 35,150);
+addSizeHint(80,150, 100,150);
+
+for i in range(4):
+	house(30);
+	leveCrayon();
+	right(90);
+	forward(50);
+	left(90);
+	penDown();
+# END SOLUTION
+
diff --git a/src/lessons/turtleart/HouseThreeEntity.scala b/src/lessons/turtleart/HouseThreeEntity.scala
new file mode 100644
index 0000000..d5d6406
--- /dev/null
+++ b/src/lessons/turtleart/HouseThreeEntity.scala
@@ -0,0 +1,39 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaHouseThreeEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(35,120, 35,150);
+	    addSizeHint(80,150, 100,150);
+	 
+	     for (i <- 1 to 4) {
+	        house(30);
+	        leveCrayon();
+	        right(90);
+	        forward(50);
+	        left(90);
+	        penDown();
+	     }
+	}
+	def house(len:Int) {
+	    forward(len);
+	    
+	    right(30);
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(120);
+	    }
+	    
+	    right(60);    
+	    for (i <- 1 to 3) {
+	    	forward(len);
+	    	right(90);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Main.fr.html b/src/lessons/turtleart/Main.fr.html
new file mode 100644
index 0000000..f6b923c
--- /dev/null
+++ b/src/lessons/turtleart/Main.fr.html
@@ -0,0 +1,32 @@
+<h1>L'art de la tortue</h1>
+
+<p>Dès sa conception dans les années 60, la tortue LOGO s'est révélé être un
+outil fascinant pour dessiner sur ordinateur. Cette leçon vous permet
+d'explorer certaines des figures les plus classiques, et de dessiner les
+vôtres.</p>
+
+<p>La syntaxe du langage n'est absolument pas présentée, mais si vous
+connaissez les bases (ou si quelqu'un peut répondre à vos questions), vous
+pouvez faire ces exercices même si vous êtes un débutant absolu en
+programmation.</p>
+
+<p>Envoyez nous vos plus belles contributions pour que nous les ajoutions à
+cette galerie afin d'inspirer les futurs utilisateurs.</p>
+
+<h3>Que puis-je faire pour améliorer cet univers de PLM?</h3>
+
+<p>Comme souvent, plusieurs points pourraient être améliorés dans le code de
+cet univers pour l'améliorer :</p>
+<ul>
+  <li>Lorsqu'on préfère faire son propre dessin plutôt que suivre l'exercice
+proposer, les messages «vous avez échoués» deviennent vite agaçant. Il
+faudrait un mode créatif dans PLM, où le monde ne serait plus comparé à la
+solution attendue, et où il ne serait pas remis à zéro automatiquement entre
+les exécutions.</li>
+  <li>D'autres exercices devraient être ajoutés. http://neoparaiso.com/logo/#sect4
+constitue une source d'inspiration quasi inépuisable.</li>
+  <li>Il manque des primitives cache()/montre() pour décider si la tortue doit
+être affichée.</li>
+  <li>Il manque des primitives arc() et arcVers() pour dessiner un arc de cercle,
+en restant sur place ou en bougeant jusqu'à la fin de l'arc.</li> 
+</ul>
diff --git a/src/lessons/turtleart/Main.html b/src/lessons/turtleart/Main.html
new file mode 100644
index 0000000..97e677c
--- /dev/null
+++ b/src/lessons/turtleart/Main.html
@@ -0,0 +1,21 @@
+<h1>Turtle Art</h1>
+
+<p>Since its inception in the 60's, the LOGO turtle fascinates by its ability to draw nice figures on computer. 
+This lesson allows you to explore some of the classical figures, and draw your own.</p>
+
+<p>The language's syntax is absolutely not presented, but if you know a bit of it or if someone tells you, 
+you can take these exercises even if you are an absolute beginner in programming.</p>
+
+<p>Please send us your best contributions so that they get added to this gallery to inspire the next ones.</p>
+
+<h3>What can I do to improve this PLM universe?</h3>
+
+<p>As usual, there are several things that could be done in the code of this universe to improve it:</p>
+<ul>
+  <li>When you don't want to follow the proposed exercises but draw your own stuff, the "you failed" message really gets annoying. 
+      We should have a "Creative mode" in PLM, where the world is not checked against the answer. 
+      Also, we should not clean the board automatically in this mode.</li>
+  <li>Other exercises should be added. A whole lot of exercises are available from http://neoparaiso.com/logo/#sect4.</li>
+  <li>Missing: the built-ins hide()/show(), that decide whether the turtle must be shown.</li>
+  <li>Missing: the built-ins arc() and arcTo(), that draw an arc, either w/o moving or by moving to the end of the arc.</li> 
+</ul>
diff --git a/src/lessons/turtleart/Main.java b/src/lessons/turtleart/Main.java
new file mode 100644
index 0000000..6c4e858
--- /dev/null
+++ b/src/lessons/turtleart/Main.java
@@ -0,0 +1,135 @@
+package lessons.turtleart;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+import plm.core.ui.ResourcesCache;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.turtles.Turtle;
+import plm.universe.turtles.TurtleWorld;
+import plm.universe.turtles.TurtleWorldView;
+
+public class Main extends Lesson {
+	
+	@Override
+	protected void loadExercises() throws IOException, BrokenWorldFileException {
+		addExercise(new TurtleGraphicalExercise(this,"Square",       300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"SmallSquare",  300,300, 50,150));
+		addExercise(new TurtleGraphicalExercise(this,"Stairs",       300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"TriangleFlat", 300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"Triangle",     300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"House",        300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"HouseThree",   300,300, 50,150));
+		addExercise(new TurtleGraphicalExercise(this,"HouseMany",    300,300, 50,250));
+		addExercise(new TurtleGraphicalExercise(this,"Polygon6",     300,300, 81,190));
+		addExercise(new TurtleGraphicalExercise(this,"Polygon7",     300,300, 65,190));
+		addExercise(new TurtleGraphicalExercise(this,"Polygon15",    300,300, 55,165));
+		addExercise(new TurtleGraphicalExercise(this,"Polygon360",   300,300, 35,149));
+		addExercise(new TurtleGraphicalExercise(this,"CircleTwo",    300,300, 35,149));
+		addExercise(new TurtleGraphicalExercise(this,"CircleYing",   300,300, 35,149));
+		addExercise(new TurtleGraphicalExercise(this,"CircleSquare", 300,300, 50,200));
+		addExercise(new TurtleGraphicalExercise(this,"CircleTen",    300,300, 150,150));
+		addExercise(new TurtleGraphicalExercise(this,"DiskFourth",   300,300, 150,150));
+		addExercise(new TurtleGraphicalExercise(this,"DiskFour",     300,300, 150,150));
+		addExercise(new TurtleGraphicalExercise(this,"DiskTwo",      300,300, 150,150));
+		addExercise(new TurtleGraphicalExercise(this,"Star",         300,300, 150,200));
+		
+		setCurrentExercise(currentExercise); // recompute the missions
+	}
+
+	@Override
+	public void setCurrentExercise(Lecture exo) {
+		super.setCurrentExercise(exo);
+		try {
+			Game.waitInitThreads();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		for (Lecture l : exercises())
+			l.loadHTMLMission();		
+	}
+}
+
+class TurtleGraphicalExercise extends ExerciseTemplated{
+	
+	public TurtleGraphicalExercise(Lesson lesson,String name,
+			int worldWidth,int worldHeight,int tx, int ty) {
+		
+		super(lesson, lesson.getClass().getName()+"."+name);
+		
+		setName(name);
+		tabName = "Source";
+		nameOfCorrectionEntity = lesson.getClass().getName().replace(".Main","")+"."+name+"Entity";
+		World myWorld = new TurtleWorld(name, worldWidth, worldHeight);
+		Turtle t = new Turtle(myWorld, "Hawksbill", tx, ty);
+		t.setHeading(-90);
+		setup(myWorld);
+	}
+	@Override
+	public void loadHTMLMission() {
+		StringBuffer res = new StringBuffer();
+		for (Lecture l : getLesson().exercises()) {
+			int iconSize=100;
+			Exercise exo = (Exercise) l;
+			boolean isSelected = exo.equals(getLesson().getCurrentExercise());
+			boolean isPassed = Game.getInstance().studentWork.getPassed(exo, Game.getProgrammingLanguage());
+			
+			String path = "TurtleGraphics/"+exo.getId()+(isSelected?"-selected":"")+(isPassed?"-passed":"")+".png";
+			
+			// Recompute the icon if not cached
+			ImageIcon icon = ResourcesCache.getIcon(path,true);
+			if (icon == null) {
+				BufferedImage bImg = new BufferedImage(iconSize, iconSize, BufferedImage.TYPE_INT_ARGB);
+				Graphics2D cg = bImg.createGraphics();
+				cg.setColor(new Color(1, 1, 1, 0));
+				cg.fillRect(0, 0, bImg.getHeight(), bImg.getWidth());		
+
+				TurtleWorld tw;
+				do {
+					try {
+						Game.waitInitThreads();
+					} catch (InterruptedException e) {
+						e.printStackTrace();
+					}
+					tw= (TurtleWorld) exo.getWorlds(WorldKind.ANSWER).get(0);
+				} while (! tw.isAnswerWorld());
+				
+				((TurtleWorldView) tw.getView()).doPaint(cg,iconSize,iconSize,false);
+				
+				// Add a box around it
+				cg.setTransform(new AffineTransform()); // draw in 100x100, not world's dimensions
+				cg.setColor(isSelected?Color.RED:Color.lightGray);
+				cg.drawRect(1, 1, iconSize-2,iconSize-2);
+				
+				// Marker if it's passed
+				if (isPassed) {
+					Image star = ResourcesCache.getIcon("resources/star.png").getImage(); 
+					cg.drawImage(star, 3, iconSize-star.getHeight(null)-2, null);
+				}
+				
+				// Cache it
+				ResourcesCache.setIcon(path,new ImageIcon(bImg));
+			}
+			    
+			String lessonPart = "lessons."+getLesson().getId().replace("/",".").replace(".Main","");
+			String exoPart = exo.getLocalId(); 
+			res.append("<a href=\"plm://"+lessonPart+"/"+exoPart+"\">");
+			res.append("<img src=\"");
+			res.append(path);
+			res.append("\"></a> ");
+		}
+		setMission(res.toString());
+	}
+}
\ No newline at end of file
diff --git a/src/lessons/turtleart/Polygon15Entity.java b/src/lessons/turtleart/Polygon15Entity.java
new file mode 100644
index 0000000..3a54050
--- /dev/null
+++ b/src/lessons/turtleart/Polygon15Entity.java
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class Polygon15Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(45,135, 45,165);
+	    int sides=20;
+
+	    for (int i=0; i<sides;i++) {
+	        forward(30);
+	        right(360/sides);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon15Entity.py b/src/lessons/turtleart/Polygon15Entity.py
new file mode 100644
index 0000000..93e33bb
--- /dev/null
+++ b/src/lessons/turtleart/Polygon15Entity.py
@@ -0,0 +1,8 @@
+# BEGIN SOLUTION
+addSizeHint(45,135, 45,165);
+sides=20
+
+for i in range (sides):
+	forward(30);
+	right(360/sides);
+# END SOLUTION
diff --git a/src/lessons/turtleart/Polygon15Entity.scala b/src/lessons/turtleart/Polygon15Entity.scala
new file mode 100644
index 0000000..5e057ab
--- /dev/null
+++ b/src/lessons/turtleart/Polygon15Entity.scala
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaPolygon15Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(45,135, 45,165);
+	    val sides=20;
+
+	    for (i <- 1 to sides) {
+	        forward(30);
+	        right(360/sides);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon360Entity.java b/src/lessons/turtleart/Polygon360Entity.java
new file mode 100644
index 0000000..2a9ab45
--- /dev/null
+++ b/src/lessons/turtleart/Polygon360Entity.java
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class Polygon360Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(15,149, 15,151);
+
+		for (int i=0; i<360;i++) {
+			forward(2);
+			right(1);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon360Entity.py b/src/lessons/turtleart/Polygon360Entity.py
new file mode 100644
index 0000000..9b096fc
--- /dev/null
+++ b/src/lessons/turtleart/Polygon360Entity.py
@@ -0,0 +1,7 @@
+# BEGIN SOLUTION
+addSizeHint(15,149, 15,151);
+
+for i in range(360):
+	forward(2);
+	right(1);
+# END SOLUTION
diff --git a/src/lessons/turtleart/Polygon360Entity.scala b/src/lessons/turtleart/Polygon360Entity.scala
new file mode 100644
index 0000000..eb93cc9
--- /dev/null
+++ b/src/lessons/turtleart/Polygon360Entity.scala
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaPolygon360Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(15,149, 15,151);
+
+		for (i <- 1 to 360) {
+			forward(2);
+			right(1);
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon6Entity.java b/src/lessons/turtleart/Polygon6Entity.java
new file mode 100644
index 0000000..0053eb7
--- /dev/null
+++ b/src/lessons/turtleart/Polygon6Entity.java
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class Polygon6Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(65,110, 65,190);
+
+	    for (int i=0; i<6;i++) {
+	        forward(80);
+	        right(360/6);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon6Entity.py b/src/lessons/turtleart/Polygon6Entity.py
new file mode 100644
index 0000000..698c2be
--- /dev/null
+++ b/src/lessons/turtleart/Polygon6Entity.py
@@ -0,0 +1,7 @@
+# BEGIN SOLUTION
+addSizeHint(65,110, 65,190);
+
+for i in range (6):
+	forward(80);
+	right(360/6);
+# END SOLUTION
diff --git a/src/lessons/turtleart/Polygon6Entity.scala b/src/lessons/turtleart/Polygon6Entity.scala
new file mode 100644
index 0000000..de3a346
--- /dev/null
+++ b/src/lessons/turtleart/Polygon6Entity.scala
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaPolygon6Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+	    addSizeHint(65,110, 65,190);
+
+	    for (i <- 1 to 6) {
+	        forward(80);
+	        right(360/6);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon7Entity.java b/src/lessons/turtleart/Polygon7Entity.java
new file mode 100644
index 0000000..775f793
--- /dev/null
+++ b/src/lessons/turtleart/Polygon7Entity.java
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class Polygon7Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(52,110, 52,190);
+		
+	    for (int i=0; i<7;i++) {
+	        forward(80);
+	        right(360./7.);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/Polygon7Entity.py b/src/lessons/turtleart/Polygon7Entity.py
new file mode 100644
index 0000000..3e16adc
--- /dev/null
+++ b/src/lessons/turtleart/Polygon7Entity.py
@@ -0,0 +1,7 @@
+# BEGIN SOLUTION
+addSizeHint(52,110, 52,190);
+		
+for i in range(7):
+	forward(80);
+	right(360./7.);
+# END SOLUTION
diff --git a/src/lessons/turtleart/Polygon7Entity.scala b/src/lessons/turtleart/Polygon7Entity.scala
new file mode 100644
index 0000000..9972376
--- /dev/null
+++ b/src/lessons/turtleart/Polygon7Entity.scala
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaPolygon7Entity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		addSizeHint(52,110, 52,190);
+		
+	    for (i <- 1 to 7) {
+	        forward(80);
+	        right(360./7.);
+	    }
+	    /* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/SmallSquareEntity.java b/src/lessons/turtleart/SmallSquareEntity.java
new file mode 100644
index 0000000..edbc06b
--- /dev/null
+++ b/src/lessons/turtleart/SmallSquareEntity.java
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class SmallSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,150);
+        addSizeHint(150,35, 50,35);
+
+        for (int i = 0; i < 4; i++) {
+        	forward(100);
+        	right(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/SmallSquareEntity.py b/src/lessons/turtleart/SmallSquareEntity.py
new file mode 100644
index 0000000..f9ce21a
--- /dev/null
+++ b/src/lessons/turtleart/SmallSquareEntity.py
@@ -0,0 +1,8 @@
+# BEGIN SOLUTION
+addSizeHint(35,50, 35,150);
+addSizeHint(150,35, 50,35);
+
+for i in range(4):
+	forward(100);
+	right(90);
+# END SOLUTION
diff --git a/src/lessons/turtleart/SmallSquareEntity.scala b/src/lessons/turtleart/SmallSquareEntity.scala
new file mode 100644
index 0000000..1450023
--- /dev/null
+++ b/src/lessons/turtleart/SmallSquareEntity.scala
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaSmallSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,150);
+        addSizeHint(150,35, 50,35);
+
+        for (i <- 1 to 4) {
+        	forward(100);
+        	right(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/SquareEntity.java b/src/lessons/turtleart/SquareEntity.java
new file mode 100644
index 0000000..08370a7
--- /dev/null
+++ b/src/lessons/turtleart/SquareEntity.java
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class SquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,250);
+        addSizeHint(250,35, 50,35);
+
+        for (int i = 0; i < 4; i++) {
+        	forward(200);
+        	right(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/SquareEntity.py b/src/lessons/turtleart/SquareEntity.py
new file mode 100644
index 0000000..f6fc8ff
--- /dev/null
+++ b/src/lessons/turtleart/SquareEntity.py
@@ -0,0 +1,8 @@
+# BEGIN SOLUTION
+addSizeHint(35,50, 35,250);
+addSizeHint(250,35, 50,35);
+
+for i in range(4):
+	forward(200);
+	right(90);
+# END SOLUTION
diff --git a/src/lessons/turtleart/SquareEntity.scala b/src/lessons/turtleart/SquareEntity.scala
new file mode 100644
index 0000000..968b17e
--- /dev/null
+++ b/src/lessons/turtleart/SquareEntity.scala
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaSquareEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,250);
+        addSizeHint(250,35, 50,35);
+
+        for (i <- 1 to 4) {
+        	forward(200);
+        	right(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/StairsEntity.java b/src/lessons/turtleart/StairsEntity.java
new file mode 100644
index 0000000..395a62f
--- /dev/null
+++ b/src/lessons/turtleart/StairsEntity.java
@@ -0,0 +1,21 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class StairsEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(50,170, 85,170);
+
+        for (int i = 0; i < 6; i++) {
+        	forward(35);
+        	right(90);
+            forward(35);
+            left(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/StairsEntity.py b/src/lessons/turtleart/StairsEntity.py
new file mode 100644
index 0000000..0da8523
--- /dev/null
+++ b/src/lessons/turtleart/StairsEntity.py
@@ -0,0 +1,9 @@
+# BEGIN SOLUTION
+addSizeHint(50,170, 85,170);
+
+for i in range(6):
+  forward(35);
+  right(90);
+  forward(35);
+  left(90);
+# END SOLUTION
diff --git a/src/lessons/turtleart/StairsEntity.scala b/src/lessons/turtleart/StairsEntity.scala
new file mode 100644
index 0000000..c68c36a
--- /dev/null
+++ b/src/lessons/turtleart/StairsEntity.scala
@@ -0,0 +1,21 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaStairsEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(50,170, 85,170);
+
+        for (i <- 1 to 6) {
+        	forward(35);
+        	right(90);
+            forward(35);
+            left(90);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/StarEntity.java b/src/lessons/turtleart/StarEntity.java
new file mode 100644
index 0000000..fde00bc
--- /dev/null
+++ b/src/lessons/turtleart/StarEntity.java
@@ -0,0 +1,25 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class StarEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		for (int i = 0; i < BRANCH_COUNT; i++) 
+			branch(50);
+		
+	}
+	static final int BRANCH_COUNT = 5;
+	public void branch(int size) {
+		forward(size);
+		right(360 / BRANCH_COUNT);
+		forward(size);
+
+		for (int i = 0; i < 2; i++)
+			left(360 / BRANCH_COUNT);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/StarEntity.py b/src/lessons/turtleart/StarEntity.py
new file mode 100644
index 0000000..7436207
--- /dev/null
+++ b/src/lessons/turtleart/StarEntity.py
@@ -0,0 +1,13 @@
+# BEGIN SOLUTION
+def branch(size):
+  forward(size);
+  right(360 / BRANCH_COUNT);
+  forward(size);
+  #
+  for i in range(2):
+    left(360 / BRANCH_COUNT);
+
+BRANCH_COUNT = 5;
+for i in range(BRANCH_COUNT):
+   branch(50);
+# END SOLUTION
diff --git a/src/lessons/turtleart/StarEntity.scala b/src/lessons/turtleart/StarEntity.scala
new file mode 100644
index 0000000..49be8b0
--- /dev/null
+++ b/src/lessons/turtleart/StarEntity.scala
@@ -0,0 +1,25 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaStarEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to BRANCH_COUNT) 
+			branch(50);
+		
+	}
+	val BRANCH_COUNT = 5;
+	def branch(size:Int) {
+		forward(size);
+		right(360 / BRANCH_COUNT);
+		forward(size);
+
+		for (i <- 1 to 2)
+			left(360 / BRANCH_COUNT);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/TriangleEntity.java b/src/lessons/turtleart/TriangleEntity.java
new file mode 100644
index 0000000..2248a52
--- /dev/null
+++ b/src/lessons/turtleart/TriangleEntity.java
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class TriangleEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(50,265, 250,265);
+        
+        right(30);
+        for (int i = 0; i < 3; i++) {
+        	forward(200);
+        	right(120);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/TriangleEntity.py b/src/lessons/turtleart/TriangleEntity.py
new file mode 100644
index 0000000..1d2d003
--- /dev/null
+++ b/src/lessons/turtleart/TriangleEntity.py
@@ -0,0 +1,8 @@
+# BEGIN SOLUTION
+addSizeHint(50,265, 250,265);
+        
+right(30);
+for i in range(3):
+    forward(200);
+    right(120);
+# END SOLUTION
diff --git a/src/lessons/turtleart/TriangleEntity.scala b/src/lessons/turtleart/TriangleEntity.scala
new file mode 100644
index 0000000..5c51264
--- /dev/null
+++ b/src/lessons/turtleart/TriangleEntity.scala
@@ -0,0 +1,20 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaTriangleEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(50,265, 250,265);
+        
+        right(30);
+        for (i <- 1 to 3) {
+        	forward(200);
+        	right(120);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/TriangleFlatEntity.java b/src/lessons/turtleart/TriangleFlatEntity.java
new file mode 100644
index 0000000..4295ee3
--- /dev/null
+++ b/src/lessons/turtleart/TriangleFlatEntity.java
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+public class TriangleFlatEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,250);
+
+        for (int i = 0; i < 3; i++) {
+        	forward(200);
+        	right(120);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/TriangleFlatEntity.py b/src/lessons/turtleart/TriangleFlatEntity.py
new file mode 100644
index 0000000..18a7b1d
--- /dev/null
+++ b/src/lessons/turtleart/TriangleFlatEntity.py
@@ -0,0 +1,7 @@
+# BEGIN SOLUTION
+addSizeHint(35,50, 35,250);
+
+for i in range(3):
+    forward(200);
+    right(120);
+# END SOLUTION
diff --git a/src/lessons/turtleart/TriangleFlatEntity.scala b/src/lessons/turtleart/TriangleFlatEntity.scala
new file mode 100644
index 0000000..50b4870
--- /dev/null
+++ b/src/lessons/turtleart/TriangleFlatEntity.scala
@@ -0,0 +1,19 @@
+package lessons.turtleart;
+
+import plm.universe.turtles.Turtle;
+
+class ScalaTriangleFlatEntity extends Turtle {
+
+	/* BEGIN TEMPLATE */
+	override def run() {
+		/* BEGIN SOLUTION */
+        addSizeHint(35,50, 35,250);
+
+        for (i <- 1 to 3) {
+        	forward(200);
+        	right(120);
+        }
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/turtleart/icon.png b/src/lessons/turtleart/icon.png
new file mode 100644
index 0000000..e152828
Binary files /dev/null and b/src/lessons/turtleart/icon.png differ
diff --git a/src/lessons/turtleart/short_desc.fr.html b/src/lessons/turtleart/short_desc.fr.html
new file mode 100644
index 0000000..2a6bb50
--- /dev/null
+++ b/src/lessons/turtleart/short_desc.fr.html
@@ -0,0 +1,6 @@
+<h3>L'art de la tortue</h3>
+<p>Dessinez de belles figures avec la tortue Logo, et apprenez la programmation
+en jouant.</p>
+
+<p>Vous devez connaître la syntaxe de base du langage que vous allez choisir,
+mais aucune expérience n'est nécessaire pour entreprendre cette leçon.</p>
diff --git a/src/lessons/turtleart/short_desc.html b/src/lessons/turtleart/short_desc.html
new file mode 100644
index 0000000..5426877
--- /dev/null
+++ b/src/lessons/turtleart/short_desc.html
@@ -0,0 +1,5 @@
+<h3>Turtle Art</h3>
+<p>Draw beautiful figures with the Logo turtle, and learn programming while playing.</p>
+
+<p>You should know the basic syntax of the programming language you will choose, 
+but no exhaustive programming practice is required to take this lesson.</p>
diff --git a/src/lessons/welcome/Main.fr.html b/src/lessons/welcome/Main.fr.html
index b4273c9..d6ccee8 100644
--- a/src/lessons/welcome/Main.fr.html
+++ b/src/lessons/welcome/Main.fr.html
@@ -495,3 +495,17 @@ exercice :
   <td>Le concept n'est pas indispensable à l'exercice</td>
   <td align="center"><img src="img/focus_not.png" /></td></tr>
 </table>
+
+
+
+<h2>Que vais-je apprendre?</h2>
+<p>Vous allez apprendre les bases de la programmation. Disons au moins que les
+principaux concepts vous auront été présentés, vous permettant de lire et
+comprendre la plupart des algorithmes.
+Vous ne pourrez toujours pas écrire ou même lire des programmes complets en
+[!thelang] car la notion d'objet ne fait pas partie des objectifs de cette
+leçon, mais vous maîtriserez ce qu'on appelle la «programmation tactique»,
+ce qui veut dire que votre maîtrise de la syntaxe vous permettra de vous
+concentrer sur les problèmes à résoudre sans vous battre contre le
+compilateur à propos de la syntaxe.</p>
+
diff --git a/src/lessons/welcome/Main.html b/src/lessons/welcome/Main.html
index 5b0fcdc..9930f7e 100644
--- a/src/lessons/welcome/Main.html
+++ b/src/lessons/welcome/Main.html
@@ -494,3 +494,16 @@ intended for beginners. List of seen notions per exercise:
   <td>Concept not mandated by the exercise</td>
   <td align="center"><img src="img/focus_not.png" /></td></tr>
 </table>
+
+
+
+<h2>What will I learn?</h2>
+<p>You will learn the very basics of programming. At least, you will
+be presented the most important concepts, allowing you to read most
+simple algorithms. You will not be able to write or read full programs
+because you will still not know about objects, but you will master
+what is called "Tactical programming", meaning that you will master
+the syntax enough to not have any issue with it, allowing you to focus
+on the fundamental problems of what you want to solve instead of
+struggling with syntaxic difficulties.</p>
+
diff --git a/src/lessons/welcome/Main.java b/src/lessons/welcome/Main.java
index af1f1a0..447f975 100644
--- a/src/lessons/welcome/Main.java
+++ b/src/lessons/welcome/Main.java
@@ -2,15 +2,15 @@ package lessons.welcome;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.Lecture;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
 import lessons.welcome.array.array123.Array123;
 import lessons.welcome.array.array667.Array667;
 import lessons.welcome.array.arraycount9.ArrayCount9;
 import lessons.welcome.array.arrayfront9.ArrayFront9;
 import lessons.welcome.array.averagevalue.AverageValue;
-import lessons.welcome.array.basics.Array;
+import lessons.welcome.array.basics.Array1;
 import lessons.welcome.array.basics.Array2;
 import lessons.welcome.array.has271.Has271;
 import lessons.welcome.array.indexof.maxvalue.IndexOfMaxValue;
@@ -18,72 +18,76 @@ import lessons.welcome.array.indexof.value.IndexOfValue;
 import lessons.welcome.array.maxvalue.MaxValue;
 import lessons.welcome.array.notriples.NoTriples;
 import lessons.welcome.array.occurenceofvalue.OccurrenceOfValue;
-import lessons.welcome.baggleseeker.BaggleSeeker;
-import lessons.welcome.basics.Basics;
-import lessons.welcome.basicsdrawg.BasicsDrawG;
+import lessons.welcome.bat.bool1.Close10;
+import lessons.welcome.bat.bool1.CountTeen;
+import lessons.welcome.bat.bool1.Diff21;
+import lessons.welcome.bat.bool1.HasTeen;
+import lessons.welcome.bat.bool1.IcyHot;
+import lessons.welcome.bat.bool1.In1020;
+import lessons.welcome.bat.bool1.In3050;
+import lessons.welcome.bat.bool1.LastDigit;
+import lessons.welcome.bat.bool1.LoneTeen;
+import lessons.welcome.bat.bool1.Makes10;
+import lessons.welcome.bat.bool1.Max1020;
+import lessons.welcome.bat.bool1.MonkeyTrouble;
+import lessons.welcome.bat.bool1.NearHundred;
+import lessons.welcome.bat.bool1.ParotTrouble;
+import lessons.welcome.bat.bool1.PosNeg;
+import lessons.welcome.bat.bool1.SleepIn;
+import lessons.welcome.bat.bool1.SumDouble;
+import lessons.welcome.bat.bool2.AlarmClock;
+import lessons.welcome.bat.bool2.AnswerCell;
+import lessons.welcome.bat.bool2.BlueTicket;
+import lessons.welcome.bat.bool2.CaughtSpeeding;
+import lessons.welcome.bat.bool2.CigarParty;
+import lessons.welcome.bat.bool2.DateFashion;
+import lessons.welcome.bat.bool2.GreenTicket;
+import lessons.welcome.bat.bool2.In1To10;
+import lessons.welcome.bat.bool2.InOrder;
+import lessons.welcome.bat.bool2.InOrderEqual;
+import lessons.welcome.bat.bool2.LastDigit2;
+import lessons.welcome.bat.bool2.LessBy10;
+import lessons.welcome.bat.bool2.MaxMod5;
+import lessons.welcome.bat.bool2.NearTen;
+import lessons.welcome.bat.bool2.RedTicket;
+import lessons.welcome.bat.bool2.ShareDigit;
+import lessons.welcome.bat.bool2.SortaSum;
+import lessons.welcome.bat.bool2.SquirrelPlay;
+import lessons.welcome.bat.bool2.TeaParty;
+import lessons.welcome.bat.bool2.TeenSum;
+import lessons.welcome.bat.bool2.TwoAsOne;
+import lessons.welcome.bat.bool2.WithoutDoubles;
 import lessons.welcome.bdr.BDR;
 import lessons.welcome.bdr.BDR2;
-import lessons.welcome.bool1.Close10;
-import lessons.welcome.bool1.CountTeen;
-import lessons.welcome.bool1.Diff21;
-import lessons.welcome.bool1.HasTeen;
-import lessons.welcome.bool1.IcyHot;
-import lessons.welcome.bool1.In1020;
-import lessons.welcome.bool1.In3050;
-import lessons.welcome.bool1.LastDigit;
-import lessons.welcome.bool1.LoneTeen;
-import lessons.welcome.bool1.Makes10;
-import lessons.welcome.bool1.Max1020;
-import lessons.welcome.bool1.MonkeyTrouble;
-import lessons.welcome.bool1.NearHundred;
-import lessons.welcome.bool1.ParotTrouble;
-import lessons.welcome.bool1.PosNeg;
-import lessons.welcome.bool1.SleepIn;
-import lessons.welcome.bool1.SumDouble;
-import lessons.welcome.bool2.AlarmClock;
-import lessons.welcome.bool2.AnswerCell;
-import lessons.welcome.bool2.BlueTicket;
-import lessons.welcome.bool2.CaughtSpeeding;
-import lessons.welcome.bool2.CigarParty;
-import lessons.welcome.bool2.DateFashion;
-import lessons.welcome.bool2.GreenTicket;
-import lessons.welcome.bool2.In1To10;
-import lessons.welcome.bool2.InOrder;
-import lessons.welcome.bool2.InOrderEqual;
-import lessons.welcome.bool2.LastDigit2;
-import lessons.welcome.bool2.LessBy10;
-import lessons.welcome.bool2.MaxMod5;
-import lessons.welcome.bool2.NearTen;
-import lessons.welcome.bool2.RedTicket;
-import lessons.welcome.bool2.ShareDigit;
-import lessons.welcome.bool2.SortaSum;
-import lessons.welcome.bool2.SquirrelPlay;
-import lessons.welcome.bool2.TeaParty;
-import lessons.welcome.bool2.TeenSum;
-import lessons.welcome.bool2.TwoAsOne;
-import lessons.welcome.bool2.WithoutDoubles;
 import lessons.welcome.conditions.Conditions;
 import lessons.welcome.environment.Environment;
-import lessons.welcome.loop.dowhileloop.LoopDoWhile;
-import lessons.welcome.loop.dowhileloop.Poucet;
-import lessons.welcome.loop.forloop.LoopCourse;
-import lessons.welcome.loop.forloop.LoopCourseForest;
-import lessons.welcome.loop.forloop.LoopFor;
-import lessons.welcome.loop.forloop.LoopStairs;
-import lessons.welcome.loop.whileloop.LoopWhile;
-import lessons.welcome.loop.whileloop.WhileMoria;
+import lessons.welcome.instructions.Instructions;
+import lessons.welcome.instructions.InstructionsDrawG;
+import lessons.welcome.loopdowhile.LoopDoWhile;
+import lessons.welcome.loopdowhile.Poucet;
+import lessons.welcome.loopfor.LoopCourse;
+import lessons.welcome.loopfor.LoopCourseForest;
+import lessons.welcome.loopfor.LoopFor;
+import lessons.welcome.loopfor.LoopStairs;
+import lessons.welcome.loopwhile.BaggleSeeker;
+import lessons.welcome.loopwhile.LoopWhile;
+import lessons.welcome.loopwhile.WhileMoria;
 import lessons.welcome.methods.args.MethodsArgs;
 import lessons.welcome.methods.basics.Methods;
-import lessons.welcome.methods.doghouse.MethodsDogHouse;
+import lessons.welcome.methods.basics.MethodsDogHouse;
+import lessons.welcome.methods.flowerpot.FlowerCase;
+import lessons.welcome.methods.flowerpot.FlowerPot;
 import lessons.welcome.methods.picture.MethodsPicture;
-import lessons.welcome.methods.picture2.MethodsPicture2;
-import lessons.welcome.methods.picture3.MethodsPicture3;
-import lessons.welcome.methods.picture4.MethodsPicture4;
+import lessons.welcome.methods.picture.MethodsPictureLarge;
+import lessons.welcome.methods.picture.PatternPicture;
+import lessons.welcome.methods.picture.PictureMono;
+import lessons.welcome.methods.picture.PictureMono2;
+import lessons.welcome.methods.picture.PictureMono3;
 import lessons.welcome.methods.returning.MethodsReturning;
-import lessons.welcome.slug.SlugHunting;
-import lessons.welcome.slug.SlugSnail;
-import lessons.welcome.slug.SlugTracking;
-import lessons.welcome.snake.Snake;
+import lessons.welcome.methods.slug.SlugHunting;
+import lessons.welcome.methods.slug.SlugSnail;
+import lessons.welcome.methods.slug.SlugTracking;
+import lessons.welcome.traversal.Snake;
 import lessons.welcome.traversal.column.TraversalByColumn;
 import lessons.welcome.traversal.diagonal.TraversalDiagonal;
 import lessons.welcome.traversal.line.TraversalByLine;
@@ -97,17 +101,19 @@ public class Main extends Lesson {
 	@Override
 	protected void loadExercises() throws IOException, BrokenWorldFileException {
 		addExercise(new Environment(this));
-		Lecture basics = addExercise(new Basics(this));
 		
-		addExercise(new BasicsDrawG(this), basics);
-		Lecture conditions = addExercise(new Conditions(this));
+		Lecture instructions = addExercise(new Instructions(this));
+		addExercise(new InstructionsDrawG(this), instructions);
+		
+		//Lecture conditions = 
+		addExercise(new Conditions(this));
+
 		Lecture loopWhile = addExercise(new LoopWhile(this));
 		addExercise(new BaggleSeeker(this), loopWhile);
 		addExercise(new BDR(this),loopWhile);
 		addExercise(new BDR2(this),loopWhile);
 		addExercise(new WhileMoria(this),loopWhile);
 		
-		
 		Lecture vars = addExercise(new Variables(this));
 		addExercise(new RunFour(this), vars);
 		addExercise(new RunHalf(this), vars);
@@ -121,23 +127,69 @@ public class Main extends Lesson {
 		addExercise(new Poucet(this), loopDoWhile);
 		
 		Lecture methodsVoid = addExercise(new Methods(this));
-		
 		  addExercise(new MethodsDogHouse(this),methodsVoid);
-		
-  		  Lecture picture = addExercise(new MethodsPicture(this),methodsVoid);
-		    addExercise(new MethodsPicture2(this),picture);
-		    addExercise(new MethodsPicture3(this),picture);
- 	 	    addExercise(new MethodsPicture4(this),picture);
- 	 	  
+  		  addExercise(new PictureMono(this),methodsVoid);
+		  addExercise(new PictureMono2(this),methodsVoid);
+		  addExercise(new PictureMono3(this),methodsVoid);
+		 	 	  
  	 	Lecture methodReturns = addExercise(new MethodsReturning(this));
 		  addExercise(new SlugTracking(this),methodReturns);
 		  addExercise(new SlugHunting(this),methodReturns);
 		
 		Lecture methodArg = addExercise(new MethodsArgs(this));
 		  addExercise(new SlugSnail(this), methodArg);
-				
+		  addExercise(new MethodsPicture(this), methodArg);
+		  addExercise(new MethodsPictureLarge(this), methodArg);
+ 	 	  addExercise(new PatternPicture(this), methodArg);
+ 	 	  addExercise(new FlowerPot(this), methodArg);
+ 	 	  addExercise(new FlowerCase(this), methodArg);
+	
+		  // First serie of boolean fun
+		  Lecture bat = addExercise(new SleepIn(this));
+		  addExercise(new MonkeyTrouble(this),bat);
+		  addExercise(new NearHundred(this),bat);
+		  addExercise(new SumDouble(this),bat);
+		  addExercise(new Diff21(this),bat);
+		  addExercise(new ParotTrouble(this),bat);
+		  addExercise(new Makes10(this),bat);
+		  addExercise(new PosNeg(this),bat);
+		  addExercise(new IcyHot(this),bat);
+		  addExercise(new In1020(this),bat);
+		  addExercise(new HasTeen(this),bat);
+		  addExercise(new LoneTeen(this),bat);
+		  addExercise(new CountTeen(this),bat);
+		  addExercise(new Close10(this),bat);
+		  addExercise(new In3050(this),bat);
+		  addExercise(new Max1020(this),bat);
+		  addExercise(new LastDigit(this),bat);
+
+		  // Second serie of boolean fun
+		  bat = addExercise(new AlarmClock(this));
+		  addExercise(new AnswerCell(this),bat);
+		  addExercise(new BlueTicket(this),bat);
+		  addExercise(new CaughtSpeeding(this),bat);
+		  addExercise(new CigarParty(this),bat);
+		  addExercise(new DateFashion(this),bat);
+		  addExercise(new GreenTicket(this),bat);
+		  addExercise(new In1To10(this),bat);
+		  addExercise(new InOrder(this),bat);
+		  addExercise(new InOrderEqual(this),bat);
+		  addExercise(new LastDigit2(this),bat);
+		  addExercise(new LessBy10(this),bat);
+		  addExercise(new MaxMod5(this),bat);
+		  addExercise(new NearTen(this),bat);
+		  addExercise(new RedTicket(this),bat);
+		  addExercise(new ShareDigit(this),bat);
+		  addExercise(new SortaSum(this),bat);
+		  addExercise(new SquirrelPlay(this),bat);
+		  addExercise(new TeaParty(this),bat);
+		  addExercise(new TeenSum(this),bat);
+		  addExercise(new TwoAsOne(this),bat);
+		  addExercise(new WithoutDoubles(this),bat);
+
+		  
 		// arrays exercises 
-		Lecture arrays = addExercise(new Array(this));
+		Lecture arrays = addExercise(new Array1(this));
 		addExercise(new Array2(this),arrays);
 		addExercise(new IndexOfValue(this),arrays);
 		addExercise(new OccurrenceOfValue(this),arrays);
@@ -159,48 +211,5 @@ public class Main extends Lesson {
 		addExercise(new TraversalZigZag(this),snake);
 		addExercise(new TraversalDiagonal(this),snake);
 		
-		// First serie of boolean fun
-		Lecture bat = addExercise(new SleepIn(this),conditions);
-		addExercise(new MonkeyTrouble(this),bat);
-		addExercise(new NearHundred(this),bat);
-		addExercise(new SumDouble(this),bat);
-		addExercise(new Diff21(this),bat);
-		addExercise(new ParotTrouble(this),bat);
-		addExercise(new Makes10(this),bat);
-		addExercise(new PosNeg(this),bat);
-		addExercise(new IcyHot(this),bat);
-		addExercise(new In1020(this),bat);
-		addExercise(new HasTeen(this),bat);
-		addExercise(new LoneTeen(this),bat);
-		addExercise(new CountTeen(this),bat);
-		addExercise(new Close10(this),bat);
-		addExercise(new In3050(this),bat);
-		addExercise(new Max1020(this),bat);
-		addExercise(new LastDigit(this),bat);
-
-		// Second serie of boolean fun
-		bat = addExercise(new AlarmClock(this),conditions);
-		addExercise(new AnswerCell(this),bat);
-		addExercise(new BlueTicket(this),bat);
-		addExercise(new CaughtSpeeding(this),bat);
-		addExercise(new CigarParty(this),bat);
-		addExercise(new DateFashion(this),bat);
-		addExercise(new GreenTicket(this),bat);
-		addExercise(new In1To10(this),bat);
-		addExercise(new InOrder(this),bat);
-		addExercise(new InOrderEqual(this),bat);
-		addExercise(new LastDigit2(this),bat);
-		addExercise(new LessBy10(this),bat);
-		addExercise(new MaxMod5(this),bat);
-		addExercise(new NearTen(this),bat);
-		addExercise(new RedTicket(this),bat);
-		addExercise(new ShareDigit(this),bat);
-		addExercise(new SortaSum(this),bat);
-		addExercise(new SquirrelPlay(this),bat);
-		addExercise(new TeaParty(this),bat);
-		addExercise(new TeenSum(this),bat);
-		addExercise(new TwoAsOne(this),bat);
-		addExercise(new WithoutDoubles(this),bat);
 	}
-
 }
diff --git a/src/lessons/welcome/array/array123/Array123.fr.html b/src/lessons/welcome/array/array123/Array123.fr.html
index 80af5f2..37a1db9 100644
--- a/src/lessons/welcome/array/array123/Array123.fr.html
+++ b/src/lessons/welcome/array/array123/Array123.fr.html
@@ -3,4 +3,4 @@ Soit un tableau d'entiers, renvoyez vrai si .. 1, 2, 3, .. apparaissent
 quelquepart dans le tableau.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/array123/Array123.html b/src/lessons/welcome/array/array123/Array123.html
index 04a172c..78eaed9 100644
--- a/src/lessons/welcome/array/array123/Array123.html
+++ b/src/lessons/welcome/array/array123/Array123.html
@@ -1,4 +1,4 @@
 <h1>Array123</h1>
 Given an array of integers, return true if .. 1, 2, 3, .. appears in the array somewhere.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/array123/Array123.java b/src/lessons/welcome/array/array123/Array123.java
index b4aac21..13a8c42 100644
--- a/src/lessons/welcome/array/array123/Array123.java
+++ b/src/lessons/welcome/array/array123/Array123.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.array123;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class Array123 extends BatExercise {
 	public Array123(Lesson lesson) {
@@ -21,20 +20,27 @@ public class Array123 extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {1}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {}) ;
 
-		langTemplate(Game.PYTHON, "array123", 
+		templatePython("array123", 
 				"def array123(nums):\n",
 				"  for i in range(len(nums)-2):\n" +
 				"    if nums[i]==1  and  nums[i+1]==2  and  nums[i+2]==3:\n"+
 				"      return True\n"+
 				"  return False\n");
+		templateScala("array123", new String[] {"Array[Int]"}, 
+				"def array123(nums:Array[Int]): Boolean = {\n",
+				"  for (i <- 0 to nums.length-3)\n" +
+				"    if (nums(i)==1  &&  nums(i+1)==2  &&  nums(i+2)==3)\n"+
+				"      return true\n"+
+				"  return false\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( array123((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	boolean array123(int[] nums) {
diff --git a/src/lessons/welcome/array/array667/Array667.fr.html b/src/lessons/welcome/array/array667/Array667.fr.html
index 31714de..f39757e 100644
--- a/src/lessons/welcome/array/array667/Array667.fr.html
+++ b/src/lessons/welcome/array/array667/Array667.fr.html
@@ -4,4 +4,4 @@ la suite de l'autre dans le tableau. Comptez également le nombre de fois où
 le deuxième "6" est en fait un 7.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/array667/Array667.html b/src/lessons/welcome/array/array667/Array667.html
index 97daf2a..fa9fe43 100644
--- a/src/lessons/welcome/array/array667/Array667.html
+++ b/src/lessons/welcome/array/array667/Array667.html
@@ -4,4 +4,4 @@ array of integers, return the number of times that two 6's are next to each
 other in the array. Also count instances where the second "6" is
 actually a 7.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/array667/Array667.java b/src/lessons/welcome/array/array667/Array667.java
index 450611f..d18581e 100644
--- a/src/lessons/welcome/array/array667/Array667.java
+++ b/src/lessons/welcome/array/array667/Array667.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.array667;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class Array667 extends BatExercise {
 	public Array667(Lesson lesson) {
@@ -24,21 +23,29 @@ public class Array667 extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {1, 2, 3, 5, 6}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {1, 2, 3, 6, 6}) ;
 
-		langTemplate(Game.PYTHON, "array667", 
+		templatePython("array667", 
 				"def array667(nums):\n",
 				"  count=0\n"+
 				"  for i in range( len(nums)-1):\n"+
 				"    if (nums[i] == 6) and (nums[i+1]==6 or nums[i+1]==7):\n"+
 				"      count += 1\n"+
 				"  return count\n");
+		templateScala("array667", new String[] {"Array[Int]"},
+				"def array667(nums:Array[Int]): Int = {\n",
+				"  var count=0\n"+
+				"  for (i <- 0 to nums.length-2)\n"+
+				"    if ((nums(i) == 6) && (nums(i+1)==6 || nums(i+1)==7))\n"+
+				"      count += 1\n"+
+				"  return count\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( array667((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	int array667(int[] nums) {
diff --git a/src/lessons/welcome/array/arraycount9/ArrayCount9.fr.html b/src/lessons/welcome/array/arraycount9/ArrayCount9.fr.html
index 0cebf9f..20b2ca1 100644
--- a/src/lessons/welcome/array/arraycount9/ArrayCount9.fr.html
+++ b/src/lessons/welcome/array/arraycount9/ArrayCount9.fr.html
@@ -2,4 +2,4 @@
 Soit un tableau d'entiers, renvoyez le nombre de 9 dans ce tableau.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/arraycount9/ArrayCount9.html b/src/lessons/welcome/array/arraycount9/ArrayCount9.html
index 2e69630..f974705 100644
--- a/src/lessons/welcome/array/arraycount9/ArrayCount9.html
+++ b/src/lessons/welcome/array/arraycount9/ArrayCount9.html
@@ -1,4 +1,4 @@
 <h1>ArrayCount9</h1>
 Given an array of integers, return the number of 9's in the array.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/arraycount9/ArrayCount9.java b/src/lessons/welcome/array/arraycount9/ArrayCount9.java
index 725a0a6..ce1f662 100644
--- a/src/lessons/welcome/array/arraycount9/ArrayCount9.java
+++ b/src/lessons/welcome/array/arraycount9/ArrayCount9.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.arraycount9;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class ArrayCount9 extends BatExercise {
 	public ArrayCount9(Lesson lesson) {
@@ -18,21 +17,29 @@ public class ArrayCount9 extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {4, 2, 4, 3, 1}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {9, 2, 4, 3, 1}) ;
 
-		langTemplate(Game.PYTHON, "arrayCount9", 
+		templatePython("arrayCount9", 
 				"def arrayCount9(nums):\n",
 				"  res = 0\n" +
 				"  for value in nums:\n" +
 				"    if value == 9:\n" +
 				"      res += 1\n" +
 				"  return res\n");
+		templateScala("arrayCount9", new String[]{"Array[Int]"},
+				"def arrayCount9(nums:Array[Int]): Int = {\n",
+				"  var res = 0\n" +
+				"  for (value <- nums)\n" +
+				"    if (value == 9)\n" +
+				"      res += 1\n" +
+				"  return res\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( arrayCount9((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	int arrayCount9(int[] nums) {
diff --git a/src/lessons/welcome/array/arrayfront9/ArrayFront9.fr.html b/src/lessons/welcome/array/arrayfront9/ArrayFront9.fr.html
index ccbdb1d..d4b6193 100644
--- a/src/lessons/welcome/array/arrayfront9/ArrayFront9.fr.html
+++ b/src/lessons/welcome/array/arrayfront9/ArrayFront9.fr.html
@@ -3,4 +3,4 @@ Soit un tableau d'entiers, renvoyez vrai si l'un des 4 premiers éléments
 dans ce tableau est un 9. Le tableau peut contenir moins de 4 éléments.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/arrayfront9/ArrayFront9.html b/src/lessons/welcome/array/arrayfront9/ArrayFront9.html
index 6644aa1..b4f1511 100644
--- a/src/lessons/welcome/array/arrayfront9/ArrayFront9.html
+++ b/src/lessons/welcome/array/arrayfront9/ArrayFront9.html
@@ -1,4 +1,4 @@
 <h1>ArrayFront9</h1>
 Given an array of integers, return true if one of the first 4 elements in the array is a 9. The array length may be less than 4.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/arrayfront9/ArrayFront9.java b/src/lessons/welcome/array/arrayfront9/ArrayFront9.java
index ac29381..5865283 100644
--- a/src/lessons/welcome/array/arrayfront9/ArrayFront9.java
+++ b/src/lessons/welcome/array/arrayfront9/ArrayFront9.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.arrayfront9;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class ArrayFront9 extends BatExercise {
 	public ArrayFront9(Lesson lesson) {
@@ -23,21 +22,28 @@ public class ArrayFront9 extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {3, 9, 2, 3, 3}) ;
 
-		langTemplate(Game.PYTHON, "arrayFront9", 
+		templatePython("arrayFront9", 
 				"def arrayFront9(nums):\n",
 				"  for i in range( min( len(nums), 4) ):\n" +
 				"    if nums[i] == 9:\n" +
 				"      return True\n" +
 				"  return False\n");
+		templateScala("arrayFront9", new String[]{"Array[Int]"},
+				"def arrayFront9(nums:Array[Int]): Boolean = {\n",
+				"  for (i <- 0 to Math.min(nums.length,4)-1)\n"+
+				"    if (nums(i) == 9)\n" +
+				"      return true\n" +
+				"  return false\n"+
+				"}");
 
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( arrayFront9((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	boolean arrayFront9(int[] nums) {
diff --git a/src/lessons/welcome/array/averagevalue/AverageValue.java b/src/lessons/welcome/array/averagevalue/AverageValue.java
index ad21405..9f4c422 100644
--- a/src/lessons/welcome/array/averagevalue/AverageValue.java
+++ b/src/lessons/welcome/array/averagevalue/AverageValue.java
@@ -2,11 +2,10 @@ package lessons.welcome.array.averagevalue;
 
 import java.util.Random;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class AverageValue extends BatExercise {
 
@@ -31,21 +30,28 @@ public class AverageValue extends BatExercise {
 		myWorld.addTest(INVISIBLE, new int[] {1, 2}) ;
 		myWorld.addTest(INVISIBLE, new int[] {42}) ;
 
-		langTemplate(Game.PYTHON, "averageValue", 
+		templatePython("averageValue", 
 				"def averageValue(nums):\n",
 				"  total = 0\n"+
 				"  for i in range(len(nums)):\n" +
 				"    total += nums[i]\n"+
 				"  return total / len(nums)\n");
+		templateScala("averageValue",new String[] {"Array[Int]"}, 
+				"def averageValue(nums:Array[Int]): Int = {\n",
+				"  var total = 0\n"+
+				"  for (i <- 0 to nums.length -1) \n" +
+				"    total += nums(i)\n"+
+				"  return total / nums.length\n"+
+				"}");
 		setup(myWorld);		
 	}
 	
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( averageValue((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	int averageValue(int[] nums) {
diff --git a/src/lessons/welcome/array/basics/Array.fr.html b/src/lessons/welcome/array/basics/Array.fr.html
deleted file mode 100644
index 70c4227..0000000
--- a/src/lessons/welcome/array/basics/Array.fr.html
+++ /dev/null
@@ -1,237 +0,0 @@
-<h1>Tricots et séquences</h1>
-
-L'objectif de cet exercice est de reproduire le motif de la première colonne
-en le décalant d'une case (voir l'onglet Objectives pour plus de
-détails). La grande différence entre cet exercice et les précédents sur les
-motifs, c'est qu'il faut maintenant lire (sur la première colonne) le motif
-souhaité, puis le reproduire ensuite. Il est impossible de faire autrement
-car votre programme sera exécuté par trois buggles dans trois mondes
-différents, chacune ayant un motif propre à reproduire.
-
-<p>Une possibilité est de lire la prochaine case, puis d'aller la recopier en
-position, avant de revenir lire la case suivante, etc. Mais comme vous
-n'avez pas le droit d'utiliser les méthodes permettant de téléporter la
-buggle à une case particulière (<code>setPos()</code> et autres), cette
-façon de faire va être très pénible à mettre en place. </p>
- 
-<p class="Java">Le plus simple est de stocker l'enchainement de couleurs constituant le
-motif dans un <b>tableau</b>.</p>
-<h2 class="Java">Tableaux</h2> 
-<p class="Java">Un tableau est une séquence d'emplacements dans lesquels on peut mettre des
-valeurs de même type (une par emplacement). C'est donc une séquence de cases
-de même type :</p>
-
-
-<p class="python">Le plus simple est de stocker l'enchainement de couleurs constituant le
-motif dans une <b>liste</b>.</p>
-<h2 class="python">Les listes</h2> 
-<p class="python">Une liste est une séquence d'emplacements dans lesquels on peut mettre des
-valeurs (une par emplacement). Chaque cellule est une variable à part
-entière. La liste est donc une séquence de valeurs. Il est même possible de
-stoquer des valeurs de type différentes dans une liste, avec par exemple des
-entiers dans certaines cases et des couleurs dans d'autres cases. En quelque
-sorte, une liste ressemble un peu à une étagère où chaque étage peut
-contenir une valeur donnée.</p>
-
-<br>
-<div style="text-align:center">
-	<img src="lessons/welcome/array/array.png"/>
-</div>
-
-<p class="Java">T est le nom du tableau, T[0] est le nom de la première case, T[1] de la
-deuxième case, T[2] de la troisième case, etc... Et oui, la première case
-est T[0] et la dernière case d'un tableau de dimension N est T[N - 1].</p>
-<p class="python">T est le nom de la liste, T[0] est le nom de la première case, T[1] de la
-deuxième case, T[2] de la troisième case, etc... Et oui, la première case
-est T[0] et la dernière case d'une liste de taille N est T[N - 1]. Cela peut
-sembler étrange de commencer à compter à partir de 0 et non de 1, mais c'est
-ainsi (et cela s'explique par des raisons historiques obscures).</p>
-
-<p>On peut utiliser une variable entière <i>i</i> pour accéder avec T[i] aux
-cases : lorsque <i>i</i> vaut 0 alors T[i] dénote la case T[0], lorsque
-<i>i</i> vaut 10, T[i] dénote T[10]. On dit alors que <i>i</i> est un
-<b>indice</b> dans le tableau T .
-
-<h3>Initialisation</h3>
-<p>Si <code>T</code> contient 10 éléments, on peut alors initialiser son
-contenu
-avec une simple boucle :</p>
-<pre class="Java">
-for (int i = 0; i<10; i++) {
-   T[i] = 3;
-}
-</pre>
-<pre class="python">
-for i in range(10):
-   T[i] = 3;
-</pre>
-
-<p class="python"><code>range(max)</code> renvoie la liste de tous les entiers inférieurs à
-<code>max</code>, en commençant à 0. Il y a exactement <code>max</code>
-valeurs répondant à ces critères. Par exemple, si <code>max</code> est 3,
-les valeurs renvoyées seront 0, 1 et 2.</p>
-
-<p><code>T[i]</code> s'utilise comme une variable. On peut l'affecter :</p> 
-<pre>T[i] = 78</pre>
-
-<p>On peut réutiliser et tester cette valeur : </p>
-<pre>x = T[i]</pre>
-
-<p>On peut tester cette valeur :</p>
-<pre class="Java">
-if (T[i] > 0 ) {
-    // instructions...
-}
-</pre>
-<pre class="python">
-if T[i] > 0:
-    // instructions...
-</pre>
-
-<h3>Déclaration d'un tableau</h3>
-<p class="python">Si vous connaissez à l'avance le contenu de votre liste, vous pouvez
-affecter ces valeurs directement. Placez-les simplement entre crochets et
-séparées par des virgules comme ceci :</p>
-<pre class="python">
-L = [1, 3, 5, 7, 9] 
-# L est maintenant une liste de 5 valeurs, toutes des entiers
-</pre>
-<p class="python">Dans le cas contraire, le plus simple est de créer une liste vide puis
-d'ajouter chaque valeur séparément :</p>
-<pre class="python">
-L2 = [] 
-# L2 est maintenant une liste vide
-L2.append(1)
-L2.append(3)
-L2.append(5)
-L2.append(7)
-L2.append(9) 
-# Son contenu est maintenant le même que celui de L ci-dessus
-</pre> 
- 
-<p class="Java">Un tableau se déclare de la manière suivante :</p>
-<pre class="Java">int[] T;</pre>
-
-<p class="Java"><code>int</code> indique que les éléments du tableau <code>T</code> sont de
-type entier est le nom du tableau, <code>[]</code> indique qu'il s'agit d'un
-tableau. On peut aussi écrire cette déclaration de la manière suivante. Les
-deux écritures sont syntaxiquement équivalente, mais la première est souvent
-préférée en Java.</p>
-<pre class="Java">int T[];</pre>
-
-<h3 class="Java">Allocation d'un tableau</h3>
-
-<p class="Java">Déclarer un tableau <code>T</code> nous réserve juste le nom <code>T</code>
-pour l'utiliser plus tard. Mais le tableau n'est pas initialisé : il n'a pas
-de valeur. Que voudrait dire <code>T[4]</code> si nous n'avons pas encore
-dit que <code>T</code> est un tableau d'au moins 5 éléments ?</p>
-
-<p class="Java">Avant tout, il faut donc lui affecter une valeur à <code>T</code>:</p>
-<pre class="Java">T = new int[10];</pre>
-
-<p class="Java"><code>new</code> indique qu'il faut créer quelque chose, et
-<code>int[10]</code> indique qu'il s'agit d'un tableau de 10 valeur
-entières. En réponse, un tableau d'entiers de longueur 10 est crée en
-mémoire, et la variable <code>T</code> référence ce tableau.</p>
-
-<p class="Java">La taille d'un tableau est fixée et ne peut plus être changée après la
-création du tableau. Pour connapitre la taille d'un tableau <code>T</code>,
-on peut consulter la valeur de la variable <code>T.length</code>.</p>
-
-<p class="Java">
-Il est interdit d'écrire quelque chose comme <code>int T[10]</code>.Il faut
-absolument utiliser l'instruction <code>new</code>. Par contre, on peut très
-bien donner la dimension par une variable <code>i</code>.
-<pre class="Java">T = new int[i];</pre>
-<p class="Java">Dans ce cas, la taille du tableau sera la valeur de <code>i</code> <b>au
-moment où on a fait le</b> <code>new</code>. Si <code>i</code> change après
-coup, cela ne modifie pas la taille du tableau.</p>
-
-<h4 class="Java">Déclaration et allocation</h4>
-<pre class="Java">int[] T = new int[10];</pre>
-
-<p class="Java">On déclare et alloue le tableau en une seule ligne.</p>
-
-<h4 class="Java">Déclaration et initialisation</h4>
-<pre class="Java">int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };</pre>
-
-<p class="Java">On déclare, alloue et initialise le tableau en une seule ligne. Pour
-connaître la taille du tableau à allouer, le compilateur compte les valeurs
-données.  Ce code est équivalent à :
-<pre class="Java">
-int[] T = new int[10];
-T[0] = 1;
-T[1] = 2;
-...
-T[9] = 10;
-</pre>
-
-<p class="Java">C'est aussi équivalent au code :
-<pre class="Java">
-int[] T = new int[10];
-for (int i=0; i<T.length; i++) {
-  T[i] = i+1;
-}
-</pre>
-
-
-
-
-
-<h3 class="python">Listes et paramètres de méthode</h3>
-<p class="python">Il est parfaitement autorisé de passer une liste en paramètre à une
-méthode. Cette méthode peut ensuite utiliser cette liste comme si elle avait
-été définie localement. Les méthodes peuvent même renvoyer des listes en
-guise de résultats sans complication particulière. Par exemple, voici une
-méthode qui double la valeur de toutes les valeurs de la liste qu'elle
-reçoit en paramètre :
-<pre class="python">
-L = [1, 3, 5, 7, 9]
-def doubler(param):
-  for i in range( len(param) ):
-    param[i] *= 2
-</pre>
-
-
-<h3 class="Java">Tableaux et paramètres de méthode</h3>
-<p class="Java">On peut tout à fait passer un tableau en paramètre d'une méthode. La méthode
-doit l'indiquer dans son prototype de la façon suivante:</p>
-<pre class="Java">void maMethode(int[] valeurs) {
-  // faire quelque chose
-}</pre>
-
-<p class="Java">Coté appelant, c'est aussi simple :</p>
-<pre class="Java">
-int[] tab = new int[10];
-// initialiser les valeurs
-maMethode(tab);
-</pre>
-
-<p class="Java">On peut également avoir des méthodes renvoyant des tableaux en résultat :</p>
-<pre class="Java">int[] autreMethode() {
-  int[] resultat = new int[10];
-  // faire quelque chose
-  return resultat;
-}</pre>
-
-<h2>Objectif de l'exercice</h2>
-<p class="python">Votre code devrait sauvegarder dans une liste le motif de couleurs observées
-sur la première colonne. Le plus simple est de faire une liste vide, puis
-d'ajouter les couleurs les unes après les autres avec <code>append()</code>.</p>  
-
-
-<p class="Java">La méthode <code>run()</code> que vous devez écrire doit commencer par
-déclarer un tableau de couleurs (<code>Color[]</code>) et
-l'allouer. Attention, le premier monde est de taille 6x6, mais ce n'est pas
-le cas des autres. Utilisez donc la méthode <code>getWorldHeight()</code>
-pour retrouver le nombre de lignes du monde actuel.</p>
-
-<p class="Java">Une fois le tableau alloué, il faut le remplir. Pour chaque case de la
-colonne, lisez la couleur du sol (avec <code>getGroundColor()</code>), et
-stockez le résultat de cette méthode dans la bonne case du tableau.</p>
-
-<p>Une fois le motif de la première colonne lu et sauvegardé, il faut le
-répliquer sur toutes les colonnes, par exemple en exécutant
-<code>getWorldWidth()</code> fois une méthode écrite tout exprès.</p> 
-
-<p>À vous de jouer.</p>
\ No newline at end of file
diff --git a/src/lessons/welcome/array/basics/Array.html b/src/lessons/welcome/array/basics/Array.html
deleted file mode 100644
index 51ccdb5..0000000
--- a/src/lessons/welcome/array/basics/Array.html
+++ /dev/null
@@ -1,229 +0,0 @@
-<h1>Knotting and sequences</h1>
-
-The goal of this exercise is to reproduce the pattern of the first row in
-the other rows with a shift of one cell (see the Objective tab for
-details). The biggest difference between this exercise and the other we had
-on patterns is that you have to read the pattern (on first row) before
-reproducing it. You cannot do otherwise because the same code will be
-executed on three different worlds, each of them having its specific
-pattern.
-
-<p>One solution is to read the next cell, and go copy it in position before
-coming back to read the second cell. But since it is forbidden to use the
-methods to teleport the buggle to a specific position (<code>setPos()</code>
-and similar), this approach will be a pain to implement. </p>
- 
-<p class="Java">The simplest is to store the sequence of colors that constitute 
-the whole pattern in an <b>array</b>.</p>
-<h2 class="Java">Arrays</h2> 
-<p class="Java">An array is a sequence of positions in which one can store values of the
-same kind (one value per cell). It is thus a sequence of values of the same
-kind:</p>
-
-
-<p class="python">The simplest is to store the sequence of colors that constitute 
-the whole in a <b>list</b>.</p>
-<h2 class="python">Lists</h2> 
-<p class="python">A list is an array of positions in which one can store values. Each  
-cell is a variable on its own. A list is then a sequence of values. Lists can even mix 
-values of differing types, such as integer values in some cells and colors in other cells.
-At the end, a list is very similar to a storage shelve, where each level can store a 
-separate value.</p>
-
-<br>
-<div style="text-align:center">
-	<img src="lessons/welcome/array/array.png"/>
-</div>
-
-<p class="Java">T is the array's name, T[0] is the name of the first cell, T[1] the name of
-the second cell, T[2] the third one, etc. And yes, the first cell in
-numbered T[0] and the last one of an array of size N is T[N-1].</p>
-<p class="python">T is the list's name, T[0] is the name of the first cell, T[1] the name of
-the second cell, T[2] the third one, etc. And yes, the first cell in
-numbered T[0] and the last one of a list of size N is T[N-1]. It may seem funny to 
-count starting from 0 and not from 1 as usual, but some historical reasons make it 
-unavoidable here.</p>
-
-<p>We can use an integer variable <i>i</i> to access with T[i] to the 
-cells: when the value of <i>i</i> is 0, then T[i] accesses T[0], when the
-value of <i>i</i> is 10, then T[i] accesses T[10]. <i>i</i> is said to be
-the index in T.
-
-<h3>Initialization</h3>
-<p>If <code>T</code> contains 10 elements, then each cell can be
-initialized with a simple loop:</p>
-<pre class="Java">
-for (int i = 0; i<10; i++) {
-   T[i] = 3;
-}
-</pre>
-<pre class="python">
-for i in range(10):
-   T[i] = 3;
-</pre>
-
-<p class="python">Note that <code>range(max)</code> returns the list of all 
-integers that are smaller than <code>max</code>, starting with 0. There is exactly 
-max such values. For example, if <code>max</code> is 3, the returned values are 
-0, 1 and 2.</p>
-
-<p><code>T[i]</code> can be used just like a variable. We can set a new value:</p> 
-<pre>T[i] = 78</pre>
-
-<p>We can retrieve and use its value: </p>
-<pre>x = T[i]</pre>
-
-<p>We can test this value:</p>
-<pre class="Java">
-if (T[i] > 0 ) {
-    // instructions...
-}
-</pre>
-<pre class="python">
-if T[i] > 0:
-    // instructions...
-</pre>
-
-<h3>Declaring an array</h3>
-<p class="python">If you know beforehand the content of your list, you can affect these values all together. 
-Just put them between square braces and separated by commas as follows:</p>
-<pre class="python">
-L = [1, 3, 5, 7, 9] 
-# L is now an array of 5 values, all of them being integers
-</pre>
-<p class="python">Otherwise, you probably want to create an empty list and then append each values separately:</p>
-<pre class="python">
-L2 = [] 
-# L2 is now an empty list
-L2.append(1)
-L2.append(3)
-L2.append(5)
-L2.append(7)
-L2.append(9) 
-# Its content is now the same as L previously
-</pre> 
- 
-<p class="Java">An array can be declared the following way:</p>
-<pre class="Java">int[] T;</pre>
-
-<p class="Java"><code>int</code> means that the elements of the array are of type integer;
-<code>T</code> is the name of the array and <code>[]</code> means that we
-are speaking of an array. It is also possible to declare the same array the
-following way. Both writings are equivalent, but the first one is often
-prefered in Java.</p>
-<pre class="Java">int T[];</pre>
-
-<h3 class="Java">Allocating an array</h3>
-
-<p class="Java">Declaring a variable <code>T</code> that stores an array only reserve the name <code>T</code> for
-later use. But the array is not initialized yet: it does not have any
-value. What would <code>T[4]</code> mean if we didn't say that the array is
-at least 5 cells long?</p>
-
-<p class="Java">First and foremost, we have to give a value to <code>T</code>:</p>
-<pre class="Java">T = new int[10];</pre>
-
-<p class="Java"><code>new</code> means that we want to create something, and
-<code>int[10]</code> means that it is an array of 10 integer values. In
-return, an array of 10 integer cells is created in memory, and the
-<code>T</code> variable reference this array.</p>
-
-<p class="Java">The size of an array is fixed and cannot be changed after the creation of
-the array. To know the size of a <code>T</code> array, we can consult the
-value of the variable <code>T.length</code>.</p>
-
-<p class="Java">
-It is forbidden to write something like
-<code>int T[10];</code>
-You are required to use the <code>new</code> instruction. On the other hand,
-you perfectly can specify the size with a variable <code>i</code>.
-<pre class="Java">T = new int[i];</pre>
-<p class="Java">In this case, the array's size will be set to the value of <code>i</code>
-<b>when <code>new</code> gets called</b>. If the variable changes afterward,
-it won't change the array's size.</p>
-
-<h4 class="Java">Declaration and allocation</h4>
-<pre class="Java">int[] T = new int[10];</pre>
-
-<p class="Java">We declare and allocate the array on the same line.</p>
-
-<h4 class="Java">Declaration and initialization</h4>
-<pre class="Java">int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };</pre>
-
-<p class="Java">We declare, allocate and initialize the array on the same line. To know the
-size of the array to allocate, the compiler counts the provided values. This
-code is equivalent to:
-<pre class="Java">
-int[] T = new int[10];
-T[0] = 1;
-T[1] = 2;
-...
-T[9] = 10;
-</pre>
-
-<p class="Java">It is also equivalent to:
-<pre class="Java">
-int[] T = new int[10];
-for (int i=0; i<T.length; i++) {
-  T[i] = i+1;
-}
-</pre>
-
-
-
-
-
-<h3 class="python">Lists and method parameters</h3>
-<p class="python">It is perfectly ok to pass a list to a method as a parameter. This method
-can then use this parameter as if it were defined there. Methods can also return lists as 
-result without any complication. As an example, here is a method doubling every values of 
-the list received as a parameter:
-<pre class="python">
-L = [1, 3, 5, 7, 9]
-def doubling(param):
-  for i in range( len(param) ):
-    param[i] *= 2
-</pre>
-
-
-<h3 class="Java">Arrays and method parameters</h3>
-<p class="Java">It is perfectly ok to pass an array to a method as a parameter. The method
-must have a prototype similar to:</p>
-<pre class="Java">void myMethod(int[] values) {
-  // do something
-}</pre>
-
-<p class="Java">On the caller side, that also very simple:</p>
-<pre class="Java">
-int[] tab = new int[10];
-// initalize the values
-myMethod(tab);
-</pre>
-
-<p class="Java">We can also have methods returns arrays as results:</p>
-<pre class="Java">int[] otherMethod() {
-  int[] result = new int[10];
-  // do something
-  return result;
-}</pre>
-
-<h2>Goal of this exercise</h2>
-<p class="python">Your code should save the color pattern observed on the first row into a list. 
-The easiest is to create an empty list, and then <code>append()</code> the colors one after the others.</p>  
-
-
-<p class="Java">The <code>run()</code> method that you should write must declare an array of
-colors (<code>Color[]</code>) and allocate it. Beware, the first world is
-6x6, but this is not the case of the others. Use the
-<code>getWorldHeight()</code> method to retrieve the amount of lines in the
-current world.</p>
-
-<p class="Java">Once the array allocated, we have to fill it. For each cel of the row, read
-the ground color (with <code>getGroundColor()</code>), and store it in the
-right cell of the array.</p>
-
-<p>Once you managed to read and save the pattern on the first row, you have to reapply the 
-pattern on every rows, for example by executing <code>getWorldHeight()</code> times 
-a method written specifically for this.</p> 
-
-<p>You're up.</p>
\ No newline at end of file
diff --git a/src/lessons/welcome/array/basics/Array.java b/src/lessons/welcome/array/basics/Array.java
deleted file mode 100644
index 14a29d5..0000000
--- a/src/lessons/welcome/array/basics/Array.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package lessons.welcome.array.basics;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class Array extends ExerciseTemplated {
-
-	public Array(Lesson lesson) {
-		super(lesson);
-		BuggleWorld[] myWorlds = new BuggleWorld[3];
-				
-		myWorlds[0] = new BuggleWorld("Pattern 1",6,6);
-		((BuggleWorld) myWorlds[0]).setColor(0,0,Color.red);
-		((BuggleWorld) myWorlds[0]).setColor(0,1,Color.cyan);
-		((BuggleWorld) myWorlds[0]).setColor(0,2,Color.green);
-		((BuggleWorld) myWorlds[0]).setColor(0,3,Color.magenta);
-		((BuggleWorld) myWorlds[0]).setColor(0,4,Color.orange);
-		((BuggleWorld) myWorlds[0]).setColor(0,5,Color.pink);
-
-		myWorlds[1] = new BuggleWorld("Pattern 2",7,7);
-		((BuggleWorld) myWorlds[1]).setColor(0,2,Color.red);
-		((BuggleWorld) myWorlds[1]).setColor(0,6,Color.cyan);
-		((BuggleWorld) myWorlds[1]).setColor(0,5,Color.green);
-		((BuggleWorld) myWorlds[1]).setColor(0,4,Color.magenta);
-		((BuggleWorld) myWorlds[1]).setColor(0,3,Color.orange);
-		((BuggleWorld) myWorlds[1]).setColor(0,0,Color.pink);
-		((BuggleWorld) myWorlds[1]).setColor(0,1,Color.yellow);
-
-		myWorlds[2] = new BuggleWorld("Pattern 3",8,8);
-		((BuggleWorld) myWorlds[2]).setColor(0,0,Color.red);
-		((BuggleWorld) myWorlds[2]).setColor(0,7,Color.cyan);
-		((BuggleWorld) myWorlds[2]).setColor(0,1,Color.green);
-		((BuggleWorld) myWorlds[2]).setColor(0,6,Color.magenta);
-		((BuggleWorld) myWorlds[2]).setColor(0,2,Color.orange);
-		((BuggleWorld) myWorlds[2]).setColor(0,5,Color.pink);
-		((BuggleWorld) myWorlds[2]).setColor(0,3,Color.yellow);
-		((BuggleWorld) myWorlds[2]).setColor(0,4,Color.black);
-
-		new Buggle(myWorlds[0], "Picasso", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
-		new Buggle(myWorlds[1], "Braque", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
-		new Buggle(myWorlds[2], "Ingres", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
-		
-		setup(myWorlds);
-	}
-}
diff --git a/src/lessons/welcome/array/basics/Array-answer0.map b/src/lessons/welcome/array/basics/Array1-answer0.map
similarity index 100%
rename from src/lessons/welcome/array/basics/Array-answer0.map
rename to src/lessons/welcome/array/basics/Array1-answer0.map
diff --git a/src/lessons/welcome/array/basics/Array-answer1.map b/src/lessons/welcome/array/basics/Array1-answer1.map
similarity index 100%
rename from src/lessons/welcome/array/basics/Array-answer1.map
rename to src/lessons/welcome/array/basics/Array1-answer1.map
diff --git a/src/lessons/welcome/array/basics/Array-answer2.map b/src/lessons/welcome/array/basics/Array1-answer2.map
similarity index 100%
rename from src/lessons/welcome/array/basics/Array-answer2.map
rename to src/lessons/welcome/array/basics/Array1-answer2.map
diff --git a/src/lessons/welcome/array/basics/Array1.fr.html b/src/lessons/welcome/array/basics/Array1.fr.html
new file mode 100644
index 0000000..571743b
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1.fr.html
@@ -0,0 +1,298 @@
+<h1>[!java|scala]Tableaux[/!][!python]Listes[/!] et tricot</h1>
+
+L'objectif de cet exercice est de reproduire le motif de la première colonne
+en le décalant d'une case (voir l'onglet «Objectif» pour plus de
+détails). La grande différence entre cet exercice et les précédents sur les
+motifs, c'est qu'il faut maintenant lire (sur la première colonne) le motif
+souhaité, puis le reproduire ensuite. Il est impossible de faire autrement
+car votre programme sera exécuté par trois buggles dans trois mondes
+différents, chacune ayant un motif propre à reproduire.
+
+<p>Une possibilité est de lire la prochaine case, puis d'aller la recopier en
+position, avant de revenir lire la case suivante, etc. Mais comme vous
+n'avez pas le droit d'utiliser les méthodes permettant de téléporter la
+buggle à une case particulière (<code>setPos()</code> et autres), cette
+façon de faire va être très pénible à mettre en place. </p>
+ 
+<p>Le plus simple est de stocker l'enchainement de couleurs constituant le
+motif dans
+[!java|scala]un <b>tableau</b>[/!][!python]une <b>liste</b>[/!].
+Mais avant de pouvoir faire cela, nous devons en apprendre un peu plus sur
+les [!java|scala]tableau[/!][!python]listes[/!].</p>
+
+<h2>[!java|scala]Les tableaux[/!][!python]Les listes[/!]</h2> 
+
+<p>[!java|scala]Un tableau[/!][!python]Une liste[/!] est une séquence ordonnée
+de variables qui marchent ensemble.
+C'est un peu similaire à une commode dont les différents tiroirs peuvent
+stocker des valeurs différentes.
+Chaque variable de la séquence est identifiée par sa position et peut
+stocker une valeur spécifique.
+[!java|scala]Toutes les cellules d'un tableau doivent stocker des valeurs du
+même type de données parce que les tableaux sont homogènes en [!thelang].
+Il est cependant possible de contourner cette restriction en utilisant le
+type de données <code>[!java]Object[/!][!scala]Any[/!]</code> qui peut
+contenir [!java]presque[/!] tous les autres type de données[!scala] («any»
+veut dire «n'importe» en anglais)[/!].
+[!java]Les types primitifs comme ceux que nous avons utilisé jusqu'à présent
+(int, boolean, double, char, etc) ne peuvent pas être stockés dans une
+variable Object, mais leurs variantes objectifiées (Integer, Boolean,
+Double, Char, Boolean, etc) peuvent l'être.[/!]
+Il est cependant raisonnable de rendre ses tableaux aussi spécifiques que
+possible. Si vous avez l'intention de stocker des entiers, faites en un
+tableau de [!java]integer[/!][!scala]Int[/!], pas de
+[!java]Object[/!][!scala]Any[/!].[/!]
+[!python]Les listes peuvent contenir des données de différents types, en
+mélangeant par exemple quelques valeurs entières dans certaines cellules
+avec des entiers dans d'autres cellules.[/!]
+
+<p><div style="text-align:center"><img src="lessons/welcome/array/array.png"/></div>
+
+<p>T est le nom [!python]de la liste[/!][!scala|java]du tableau[/!],
+[!java|python]T[0][/!][!scala]T(0)[/!] est le nom de la première case,
+[!java|python]T[1][/!][!scala]T(1)[/!] de la deuxième case,
+[!java|python]T[2][/!][!scala]T(2)[/!] de la troisième case, etc...
+Et oui, la première case est [!java|python]T[0][/!][!scala]T(0)[/!] et la
+dernière case
+[!python]d'une liste[/!][!scala|java]d'un tableau[/!] de taille N est
+[!java|python]T[N-1][/!][!scala]T(N-1)[/!].
+Cela peut sembler étrange de commencer à compter à partir de 0 et non de 1,
+mais c'est ainsi (et cela s'explique par des raisons historiques obscures).</p>
+
+<h3>Usage de base</h3>
+
+<p>On peut utiliser une variable entière <i>i</i> pour accéder avec
+[!java|python]T[i][/!][!scala]T(i)[/!] aux cases.
+Quand <i>i</i> vaut 0 alors [!java|python]T[i][/!][!scala]T(i)[/!] dénote la
+case [!java|python]T[0][/!][!scala]T(0)[/!];
+lorsque <i>i</i> vaut 10,  [!java|python]T[i][/!][!scala]T(i)[/!] dénote
+[!java|python]T[10][/!][!scala]T(10)[/!].
+On dit alors que <i>i</i> est un <b>indice</b> dans [!java|scala]le
+tableau[/!][!python]la liste[/!] T.
+<code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> peut être utilisé comme
+n'importe quelle variable.
+On peut lui affecter une nouvelle valeur:</p> 
+<pre>[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]</pre>
+
+<p>On peut réutiliser et tester cette valeur : </p>
+<pre>x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]</pre>
+
+<p>On peut tester cette valeur :</p>
+<pre>if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) [!scala|java]{[/!][!python]:[/!]
+    [!java|scala]//[/!][!python]#[/!] instructions...
+[!java|scala]}[/!]</pre>
+
+<p>Il est également très simple de parcourir [!java|scala]tout le
+tableau[/!][!python]toute la liste[/!], par exemple pour initialiser chaque
+cellule.</p>
+
+<pre>[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!]
+   [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>[!java|scala]La notation <code>T.length</code> permet d'accéder à la taille
+(«length» en anglais) du tableau T,[/!]
+[!python]La fonction <code>len()</code> renvoie la longueur de la liste
+T,[/!]
+ce qui permet de construire facilement la boucle.
+[!python]En fait, la fonction <code>len()</code> est bien plus générique et
+peut être utilisée pour calculer la taille de nombreux objets. Appliquée à
+une chaîne de caractères par exemple, elle retourne le nombre de caractères
+composant cette chaîne.[/!]
+[!scala]N'oubliez pas de commencer à <code>0</code> pour terminer à
+<code>T.length-1</code> au lieu de <code>1 to T.length</code>![/!]
+
+<p>Si vous souhaitez simplement parcourir les valeurs de T sans avoir besoin de
+l'index de chaque valeur, vous pouvez écrire simplement :</p>
+<pre>[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in T:[/!]
+  action()[!java];[/!]
+[!java|scala]}[/!]</pre>
+<p>[!java]Cette construction s'appelle une boucle <code>for</code> étendue en
+Java.
+La variable <i>i</i> prend successivement toutes les valeurs de l'ensemble
+placé à droite des deux-points (:).[/!]
+[!python|scala]Cette écriture est finalement très semblable à la
+précédente.
+Simplement, <code>[!python]range(n)[/!][!scala]i to j[/!]</code> retourne un
+ensemble d'entiers sur lequel la boucle <code>for</code> itère.
+En fait, [!thelang] offre d'autres moyens très élégants de traverser des
+[!python]listes[/!][!scala]tableaux[/!]
+et d'autres collections de données. Mais cela devrait être le sujet
+d'exercices spécifiques (qui restent à écrire dans PLM).[/!]</p>
+
+
+<h3>Declarer [!python]une liste[/!][!java|scala]un tableau[/!]</h3>
+
+[!python]
+<p>Si vous connaissez à l'avance le contenu de votre liste, vous pouvez
+affecter ces valeurs directement. Placez-les simplement entre crochets et
+séparées par des virgules comme ceci :</p>
+<pre>
+L = [1, 3, 5, 7, 9] 
+<span class="comment"># L est maintenant une liste de 5 valeurs, toutes des entiers</span></pre>
+<p>Dans le cas contraire, le plus simple est de créer une liste vide puis
+d'ajouter chaque valeur séparément à la liste :</p>
+<pre>
+L2 = [] 
+<span class="comment"># L2 est maintenant une liste vide</span>
+L2.append(1)
+L2.append(3)
+L2.append(5)
+L2.append(7)
+L2.append(9) 
+<span class="comment"># Son contenu est maintenant le même que celui de L ci-dessus</span></pre> 
+[/!] [!java|scala]
+<p>Pour créer une variable nommée <b>T</b> pouvant contenir un tableau
+d'entiers, on écrira :</p>
+<pre>[!java]int[] T;[/!][!scala]var T:Array[Int][/!]</pre>
+
+<p>[!java]<code>int</code> indique que les éléments du tableau sont de type
+entier;
+<code>[]</code> indique que nous parlons d'un tableau tandis que
+<code>T</code> est le nom de la variable.
+Pour des raisons historiques, cela peut également être écrit sous la forme
+<code>int T[]</code> (avec [] à droite du nom de la variable),
+mais cette forme est moins lisible et devrait probablement être évitée.[/!]
+[!scala]La notation <code>[Int]</code> spécialise le type <code>Array</code>
+(«tableau» en anglais), qui est générique. Cela spécifie que chaque case du
+tableau est un entier. Le type d'un tableau de booleens s'écrirait
+simplement <code>Array[Boolean]</code>.[/!]
+</p>
+
+<h3>Allocation d'un tableau</h3>
+
+<p>Déclarer un tableau <code>T</code> nous réserve juste le nom <code>T</code>
+pour l'utiliser plus tard, mais pas la place en mémoire pour stocker les
+cases. Le tableau n'est pas initialisé : il n'a pas de valeur. Que voudrait
+dire <code>T[4]</code> si nous n'avons pas encore dit que <code>T</code> est
+un tableau de 5 éléments ?</p>
+
+<p>Avant tout, il faut donc lui affecter une valeur à <code>T</code>:</p>
+<pre>[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]</pre>
+
+<p><code>new</code> indique qu'il faut créer quelque chose, et
+<code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> indique qu'il
+s'agit d'un tableau de 10 valeur entières. En réponse, un tableau d'entiers
+de longueur 10 est crée en mémoire, et la variable <code>T</code>
+<b>référence</b> ce tableau.</p>
+
+<p>La taille d'un tableau est fixée et ne peut plus être changée après la
+création du tableau. Pour connaître la taille d'un tableau <code>T</code>,
+on peut consulter la variable <code>T.length</code>.</p>
+
+<p>Lors de l'allocation, vous pouvez spécifier la taille à utiliser avec une
+variable:
+<code>[!java]int[] T = new int[i];[/!][!scala]var T = new
+Array[Int](i);[/!]</code>
+Dans ce cas, la taille du tableau est fixée à la valeur de <code>i</code>
+<i>quand <code>new</code> a été appelé</i>.
+La taille du tableau ne peut toujours pas être modifiée. Même si la valeur
+de <code>i</code> est modifiée ensuite, la taille reste la même.
+[!java]Enfin, il est interdit d'écrire quelque chose comme <code>int
+T[10];</code> pour déclarer la variable. Il faut absolument utiliser
+<code>new</code> pour l'allouer, comme dans <code>int[] T = new
+int[10];</code> [/!]</p>
+
+<h4>Déclaration et initialisation</h4>
+<p>Si vous connaissez le contenu de votre tableau à l'avance, vous pouvez le
+déclarer, l'allouer et l'initialiser en un coup:</p>
+<pre>[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]</pre>
+
+<p>Pour connaître la taille du tableau à allouer, le compilateur compte les
+valeurs données.  Ce code est équivalent à :</p>
+<pre>[!java]int[] T = new int[10];
+T[0] = 1;
+T[1] = 2;
+...
+T[9] = 10;[/!][!scala]var T = new Array[Int](10);
+T(0) = 1
+T(1) = 2
+...
+T(9) = 10[/!]</pre>
+
+<p>C'est aussi équivalent au code :</p>
+<pre>[!java]int[] T = new int[10];
+for (int i=0; i<T.length; i++) {
+  T[i] = i+1;
+}[/!][!scala]var T = new Array[Int](10);
+for (i <- 0 to T.length-1) {
+  T(i) = i+1
+}[/!]</pre>
+
+
+<!-- end of java|scala. python comes back -->
+[/!]
+
+<h3>Les [!python]listes[/!][!scala|java]tableaux[/!] et les paramètres de
+méthodes</h3>
+<p>On peut tout à fait passer [!java|scala]un tableau[/!][!python]une liste[/!]
+en paramètre d'une méthode. La méthode peut alors l'utiliser comme si la
+variable avait été définie localement:</p>
+<pre>[!java]boolean a42Premier(int[] tableau) {
+    return tableau[0] == 42;
+}[/!][!python]def a42Premier(liste):
+  return liste[0] == 42[/!][!scala]def a42Premier(tableau:Array[Int]):Boolean = {
+  return tableau(0) == 42
+}[/!]</pre>
+
+<p>Coté appelant, c'est aussi simple :</p>
+<pre>[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]
+[!java|scala]<span class="comment">// Initialisation des valeurs omise</span>
+[/!]if (a42Premier(tab))[!java|scala] {[/!][!python]:[/!]
+   <span class="comment">[!java|scala]//[/!][!python]#[/!] faire des choses</span>
+[!java|scala]}[/!]</pre>
+
+[!java]
+<p>Si vous voulez allouer et initialiser le tableau au vol lors du passage de
+paramètre, c'est un peu plus compliqué car il faut dire au compilateur le
+type du paramètre que vous construisez. Il faut alors utiliser la
+construction suivante, même si elle n'est pas très belle.</p>
+<pre>if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {
+   <span class="comment">// faire des choses</span>
+}</pre>
+[/!]
+
+<p>Les méthodes peuvent également retourner des
+[!java|scala]tableaux[/!][!python]listes[/!] comme résultat sans aucun
+problème.
+Voici une méthode retournant [!java|scala]un tableau[/!][!python]une
+liste[/!] de la taille demandée après avoir initialisé toutes les cases à la
+valeur 42.</p>
+
+<pre>[!java]int[] remplir42(int taille) {
+    int[] res = new int[taille];
+    for (int i=0; i<taille; i++) 
+        res[i] = 42;
+    return res;
+}[/!][!scala]def remplir42(taille:Int):Array[Int] = {
+    var res = new Array[int] (taille)
+    for (i <- 0 to taille -1) {
+        res(i) = 42;
+    }
+    return res;
+}[/!][!python]def remplir42(taille):
+    res = []
+    for i in range(taille):
+        res.append(42)
+    return res[/!]</pre>
+
+<h2>Objectif de l'exercice</h2>
+
+<p>Enfin ! Après toutes ces explications, nous pouvons revenir à l'exercice.</p>
+<p>Votre mission est plutôt simple au fond. Votre code doit sauvegarder le
+motif de couleurs observé sur la première colonne. Il faut bien entendu
+sauvegarder ces valeurs dans [!java|scala]un tableau[/!][!python]une
+liste[/!].
+[!python]Le plus simple pour cela est de créer une liste vide puis d'y
+adjoindre (avec <code>append()</code> les différentes couleurs lues sur le
+sol de la première colonne (avec <code>getCouleurSol()</code>).[/!]
+[!java|scala]Pour cela, il faut déclarer et créer un tableau de
+<code>Color</code>s. Attention, les différents mondes ne sont pas tous de la
+même taille et il faut utiliser <code>getMondeHauteur()</code> pour trouver
+la taille du monde courant. Une fois créé, remplissez le tableau en lisant
+les couleurs au sol de la première colonne (avec
+<code>getCouleurSol()</code>).[/!]</p>  
+
+<p>Une fois le motif de la première colonne lu et sauvegardé, il faut le
+répliquer sur toutes les colonnes, par exemple en exécutant
+<code>getMondeLargeur()</code> fois une méthode écrite tout exprès.</p> 
diff --git a/src/lessons/welcome/array/basics/Array1.html b/src/lessons/welcome/array/basics/Array1.html
new file mode 100644
index 0000000..9a110bc
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1.html
@@ -0,0 +1,242 @@
+<h1>[!java|scala]Arrays[/!][!python]Lists[/!] and Knotting</h1>
+
+The goal of this exercise is to reproduce the pattern of the first row in
+the other rows with a shift of one cell (see the Objective tab for
+details). The biggest difference between this exercise and the others we had
+on patterns is that you have to read the pattern (on first row) before
+reproducing it. You cannot do otherwise because the same code will be
+executed on three different worlds, each of them having a specific
+pattern.
+
+<p>One solution is to read the next cell, and go copy it in position before
+coming back to read the second cell. But since it is forbidden to use the
+methods to teleport the buggle to a specific position (<code>setPos()</code>
+and similar), this approach will be a pain to implement. </p>
+ 
+<p>The simplest is to store the sequence of colors that constitute 
+the whole pattern in an [!java|scala]<b>array</b>[/!][!python]<b>list</b>[/!].
+But before we can do so, we should learn a bit what [!java|scala]arrays[/!][!python]lists[/!] are.</p>
+
+<h2>[!java|scala]Arrays[/!][!python]List[/!]</h2> 
+
+<p>[!java|scala]An array[/!][!python]A list[/!] is an ordered sequence of variables that go together.
+It is somehow similar to a shelve where each level can store a separate value. Each 
+variable of the sequence is identified by its position, and can store
+a specific value. [!java|scala]All cells of the array must store values of the same
+type because arrays are homogeneous in [!thelang]. It is possible to trick this 
+restriction by using the datatype <code>[!java]Object[/!][!scala]Any[/!]</code> 
+that can contain [!java]almost[/!] any other datatype. [!java]Primitive types such 
+as the ones we saw so far (int, boolean, double, char, etc) cannot be stored in an 
+Object variable, but their objectified counter-part (Integer, Boolean, Double, 
+Char, Boolean, etc) can.[/!] It is however a good practice to make the type of an array 
+as specific as possible, i.e., if you plan to store some integers in your array, make it an 
+array of integers, not of [!java]Object[/!][!scala]Any[/!].[/!]
+[!python]Lists can even mix values of differing types, such as integer values in some cells and colors in other cells.[/!]
+
+<p><div style="text-align:center"><img src="lessons/welcome/array/array.png"/></div>
+
+<p>T is the [!java|scala]array[/!][!python]list[/!]'s name, 
+[!java|python]T[0][/!][!scala]T(0)[/!] is the name of the first cell, 
+[!java|python]T[1][/!][!scala]T(1)[/!] the name of the second cell, 
+[!java|python]T[2][/!][!scala]T(2)[/!] the third one, etc. And yes, the first cell is
+numbered [!java|python]T[0][/!][!scala]T(0)[/!] while the last one of [!java|scala]an array[/!][!python]a list[/!] 
+of size N is [!java|python]T[N-1][/!][!scala]T(N-1)[/!]. It may seem funny to count starting from 0 and not from 1 
+as usual, but some historical reasons make it unavoidable here.</p>
+
+<h3>Basic usage</h3>
+
+<p>We can use an integer variable <i>i</i> to access with [!java|python]T[i][/!][!scala]T(i)[/!] to the 
+cells: when the value of <i>i</i> is 0, then [!java|python]T[i][/!][!scala]T(i)[/!] accesses 
+[!java|python]T[0][/!][!scala]T(0)[/!]; 
+when the value of <i>i</i> is 10, then [!java|python]T[i][/!][!scala]T(i)[/!] accesses 
+[!java|python]T[10][/!][!scala]T(10)[/!]. 
+<i>i</i> is said to be the <b>index</b> in T. 
+<code>[!java|python]T[i][/!][!scala]T(i)[/!]</code> can be used just like any
+variable. We can set a new value:</p> 
+<pre>[!java|python]T[i][/!][!scala]T(i)[/!] = 78[!java];[/!]</pre>
+
+<p>We can retrieve and use its value: </p>
+<pre>x = [!java|python]T[i][/!][!scala]T(i)[/!][!java];[/!]</pre>
+
+<p>We can test this value:</p>
+<pre>if ([!java|python]T[i][/!][!scala]T(i)[/!] > 0) [!scala|java]{[/!][!python]:[/!]
+    [!java|scala]//[/!][!python]#[/!] instructions...
+[!java|scala]}[/!]</pre>
+
+<p>It is very easy to traverse the whole [!scala|java]array[/!][!python]list[/!], for 
+example to initialize each cells.</p>
+
+<pre>[!java]for (int i = 0; i<T.length; i++) {[/!][!python]for i in range(len(T)):[/!][!scala]for (i <- 0 to T.length-1) {[/!]
+   [!java|python]T[i][/!][!scala]T(i)[/!] = 3[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>[!java|scala]The notation <code>T.length</code> retrieves the length of the array T,[/!]
+[!python]The function <code>len()</code> retrieves the length of the list T,[/!] 
+allowing to build a classical for loop easily. 
+[!python]Actually, the <code>len()</code> function is much more generic and can be used to retrieve the length of many objects. 
+Applied  to strings for example, it returns the amount of chars in this string.[/!] 
+[!scala]Don't forget to start at <code>0</code> and stop at <code>T.length-1</code> instead of <code>1 to T.length</code>
+however.[/!]
+
+<p>If you just want to iterate over the values of T without keeping track of their index, you can simply write:</p>
+<pre>[!java]for (int i: T) {[/!][!scala]for (i <- T) {[/!][!python]for i in T:[/!]
+  action()[!java];[/!]
+[!java|scala]}[/!]</pre>
+<p>[!java]This construct is called an <i>extended loop</i> in Java. The variable <i>i</i> takes all values
+of the set located to the right of the colon (:), one after the other.[/!]
+
+[!python|scala]This is actually very similar to the previous construct. 
+Simply, <code>[!python]range(n)[/!][!scala]i to j[/!]</code> returns a set of integers over which the 
+for construct iterates.
+Actually, [!thelang] offers much more elegant ways to traverse [!python]lists[/!][!scala]arrays[/!] and 
+other data collections, but this should be the topic of a specific set of exercises (that are still to be 
+written in PLM).[/!]</p>
+
+
+<h3>Declaring [!python]a list[/!][!java|scala]an array[/!]</h3>
+
+[!python]
+<p>If you know beforehand the content of your list, you can affect these values all together. 
+Just put them between square braces and separated by commas as follows:</p>
+<pre>
+L = [1, 3, 5, 7, 9] 
+<span class="comment"># L is now an array of 5 values, all of them being integers</span></pre>
+<p>Otherwise, you probably want to create an empty list and then append each values separately to the list:</p>
+<pre>
+L2 = [] 
+<span class="comment"># L2 is now an empty list</span>
+L2.append(1)
+L2.append(3)
+L2.append(5)
+L2.append(7)
+L2.append(9) 
+<span class="comment"># Its content is now the same as L previously</span></pre> 
+[/!]
+ 
+[!java|scala]
+<p>To declare a variable named <b>T</b> that can store arrays of integers, one should write:</p>
+<pre>[!java]int[] T;[/!][!scala]var T:Array[Int][/!]</pre>
+
+<p>[!java]<code>int</code> means that the elements of the array are of type integer;
+<code>[]</code> means that we are speaking of an array and <code>T</code> is the name of the variable. 
+For historical reasons, this can also be written as  <code>int T[]</code> (with the [] after the variable name), 
+but this is less readable and should probably be avoided.[/!]
+[!scala]The <code>[Int]</code> notation specializes the Array type (that is generic), specifying that each cell 
+of this array is an integer. An array of booleans would simply by written <code>Array[Boolean]</code>.[/!]
+</p>
+
+<h3>Allocating an array</h3>
+
+<p>Declaring a variable <code>T</code> that stores an array only reserve the <b>name</b> <code>T</code> for
+later use, but not the memory area to store the cells. The array is not initialized yet: it does not have any
+value. What would <code>[!java]T[4][/!][!scala]T(4)[/!]</code> mean if we didn't say that the array is
+5 cells long?</p>
+
+<p>First and foremost, we have to give a value to <code>T</code>:</p>
+<pre>[!java]T = new int[10];[/!][!scala]var T = new Array[Int](10)[/!]</pre>
+
+<p><code>new</code> means that we want to create something, and
+<code>[!java]int[10][/!][!scala]Array[Int](10)[/!]</code> means that it is an array of 10 integer values. 
+In return, an array of 10 integer cells is created in memory, and the <code>T</code> variable 
+<b>references</b> this array.</p>
+
+<p>The size of an array is fixed and cannot be changed after the creation of
+the array. The size of a <code>T</code> array can be retrieve by consulting the
+variable <code>T.length</code>.</p>
+
+<p>While allocating, you can specify the size with a variable: <code>[!java]int[] T = new int[i];[/!][!scala]var T = new Array[Int](i);[/!]</code>
+In this case, the array's size will be set to the value of <code>i</code> <i>when <code>new</code> gets called</i>. 
+The size of the array still cannot be modified : even if the variable <code>i</code> changes afterward, 
+the size remains to the value given when it was allocated.
+[!java]Also, it is forbidden to write something like <code>int T[10];</code> when declaring the variable.
+You are required to use the <code>new</code> instruction to allocate it, as in 
+<code>int[] T = new int[10];</code> [/!]</p>
+
+<h4>Declaration and initialization</h4>
+<p>If you know beforehand the content of your array, you can declare, allocate and initialize it in one shoot:</p>
+<pre>[!java]int[] T = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };[/!][!scala]var T = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)[/!]</pre>
+
+<p>To know the size of the array to allocate, the compiler counts the provided values. 
+This code is equivalent to:</p>
+<pre>[!java]int[] T = new int[10];
+T[0] = 1;
+T[1] = 2;
+...
+T[9] = 10;[/!][!scala]var T = new Array[Int](10);
+T(0) = 1
+T(1) = 2
+...
+T(9) = 10[/!]</pre>
+
+<p>It is also equivalent to:</p>
+<pre>[!java]int[] T = new int[10];
+for (int i=0; i<T.length; i++) {
+  T[i] = i+1;
+}[/!][!scala]var T = new Array[Int](10);
+for (i <- 0 to T.length-1) {
+  T(i) = i+1
+}[/!]</pre>
+
+
+[/!]<!-- end of java|scala. python comes back -->
+
+<h3>[!python]Lists[/!][!scala|java]Arrays[/!] and method parameters</h3>
+<p>It is perfectly OK to pass [!python]a list[/!][!java|scala]an array[/!] to a method as a parameter. 
+This method can then use this parameter as if it were defined locally:</p>
+<pre>[!java]boolean has42First(int[] array) {
+    return array[0] == 42;
+}[/!][!python]def has42First(list):
+  return list[0] == 42[/!][!scala]def has42First(array:Array[Int]):Boolean = {
+  return array(0) == 42
+}[/!]</pre>
+
+<p>On the caller side, that also very simple:</p>
+<pre>[!java]int[] tab = new int[10];[/!][!scala]var tab = new Array[Int] (10)[/!][!python]tab = [1, 3, 5, 7, 9][/!]
+[!java|scala]<span class="comment">// Values initialization omitted</span>
+[/!]if (has42First(tab))[!java|scala] {[/!][!python]:[/!]
+   <span class="comment">[!java|scala]//[/!][!python]#[/!] do something</span>
+[!java|scala]}[/!]</pre>
+
+[!java]
+<p>If you want to allocate and initialize the array in one shoot, that's 
+a bit more complicated as the compiler has to know the type of the parameter you are creating. 
+For that, use the following (ugly) construct:</p>
+<pre>if (has42First(   new int[] {1, 3, 5, 7, 9}   ) {
+   <span class="comment">// do something</span>
+}</pre>
+[/!]
+
+<p>Methods can also return [!java|scala]arrays[/!][!python]lists[/!] as result without any complication. 
+Here is a method that returns [!java|scala]an array[/!][!python]a list[/!] of the requested size, filled with 42s.</p>
+
+<pre>[!java]int[] fill42(int size) {
+    int[] res = new int[size];
+    for (int i=0; i<size; i++) 
+        res[i] = 42;
+    return res;
+}[/!][!scala]def fill42(size:Int):Array[Int] = {
+    var res = new Array[int] (size)
+    for (i <- 0 to size -1) {
+        res(i) = 42;
+    }
+    return res;
+}[/!][!python]def fill42(size):
+    res = []
+    for i in range(size):
+        res.append(42)
+    return res[/!]</pre>
+
+<h2>Goal of this exercise</h2>
+
+<p>At least! After this long explanation, we can come back to the exercise.</p>
+<p>Your mission is rather simple actually. 
+Your code should save the color pattern observed on the first row into [!java|scala]an array[/!][!python]a list[/!]. 
+[!python]The easiest is to create an empty list, and then <code>append()</code> the colors one after the others as 
+you read them (with <code>getGroundColor()</code>).[/!]
+[!java|scala]For that, you should declare and allocate an array of <code>Color</code>. Beware, there is several
+worlds, of differing size; use <code>getWorldHeight()</code> to retrieve the size of the current world.
+Once the array allocated, fill it by reading the ground color in each locations (with <code>getGroundColor()</code>).[/!]</p>  
+
+<p>Once you managed to read and save the pattern on the first row, you have to reapply the 
+pattern on every rows, for example by executing <code>getWorldHeight()</code> times 
+a method written specifically for this.</p> 
diff --git a/src/lessons/welcome/array/basics/Array1.java b/src/lessons/welcome/array/basics/Array1.java
new file mode 100644
index 0000000..c0af03f
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1.java
@@ -0,0 +1,50 @@
+package lessons.welcome.array.basics;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Array1 extends ExerciseTemplated {
+
+	public Array1(Lesson lesson) {
+		super(lesson);
+		BuggleWorld[] myWorlds = new BuggleWorld[3];
+				
+		myWorlds[0] = new BuggleWorld("Pattern 1",6,6);
+		((BuggleWorld) myWorlds[0]).setColor(0,0,Color.red);
+		((BuggleWorld) myWorlds[0]).setColor(0,1,Color.cyan);
+		((BuggleWorld) myWorlds[0]).setColor(0,2,Color.green);
+		((BuggleWorld) myWorlds[0]).setColor(0,3,Color.magenta);
+		((BuggleWorld) myWorlds[0]).setColor(0,4,Color.orange);
+		((BuggleWorld) myWorlds[0]).setColor(0,5,Color.pink);
+
+		myWorlds[1] = new BuggleWorld("Pattern 2",7,7);
+		((BuggleWorld) myWorlds[1]).setColor(0,2,Color.red);
+		((BuggleWorld) myWorlds[1]).setColor(0,6,Color.cyan);
+		((BuggleWorld) myWorlds[1]).setColor(0,5,Color.green);
+		((BuggleWorld) myWorlds[1]).setColor(0,4,Color.magenta);
+		((BuggleWorld) myWorlds[1]).setColor(0,3,Color.orange);
+		((BuggleWorld) myWorlds[1]).setColor(0,0,Color.pink);
+		((BuggleWorld) myWorlds[1]).setColor(0,1,Color.yellow);
+
+		myWorlds[2] = new BuggleWorld("Pattern 3",8,8);
+		((BuggleWorld) myWorlds[2]).setColor(0,0,Color.red);
+		((BuggleWorld) myWorlds[2]).setColor(0,7,Color.cyan);
+		((BuggleWorld) myWorlds[2]).setColor(0,1,Color.green);
+		((BuggleWorld) myWorlds[2]).setColor(0,6,Color.magenta);
+		((BuggleWorld) myWorlds[2]).setColor(0,2,Color.orange);
+		((BuggleWorld) myWorlds[2]).setColor(0,5,Color.pink);
+		((BuggleWorld) myWorlds[2]).setColor(0,3,Color.yellow);
+		((BuggleWorld) myWorlds[2]).setColor(0,4,Color.black);
+
+		new Buggle(myWorlds[0], "Picasso", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
+		new Buggle(myWorlds[1], "Braque", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
+		new Buggle(myWorlds[2], "Ingres", 0, 0, Direction.SOUTH, Color.black, Color.lightGray);
+		
+		setup(myWorlds);
+	}
+}
diff --git a/src/lessons/welcome/array/basics/Array1Entity.java b/src/lessons/welcome/array/basics/Array1Entity.java
new file mode 100644
index 0000000..46bc615
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1Entity.java
@@ -0,0 +1,57 @@
+package lessons.welcome.array.basics;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+
+public class Array1Entity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void setX(int i)  {
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	@Override
+	public void setY(int i)  { 
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	@Override
+	public void setPos(int i,int j)  { 
+		if (isInited())
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		Color[] colors = new Color[getWorldHeight()];
+
+		/* read the colors */
+		for (int i=0;i<getWorldHeight();i++) {
+			colors[i]=getGroundColor();
+			forward();
+		}
+
+		/* duplicate the pattern */
+		for (int i=1; i<getWorldWidth();i++) {
+			left();
+			forward();
+			right();
+			forward();
+			makeLine(colors);
+		}
+	}
+	void makeLine(Color[] colors) {
+		for (int i=0;i<getWorldWidth();i++) {
+			mark(colors[i]);
+			forward();
+		}
+	}
+	void mark(Color c){
+		setBrushColor(c);
+		brushDown();
+		brushUp();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/array/basics/Array1Entity.py b/src/lessons/welcome/array/basics/Array1Entity.py
new file mode 100644
index 0000000..ea1e091
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1Entity.py
@@ -0,0 +1,37 @@
+def setX(i):
+	errorMsg("Sorry Dave, I cannot let you run setX(i) in this exercise")
+
+def setY(i):
+	errorMsg("Sorry Dave, I cannot let you run setY(i) in this exercise")
+def setPos(x,y):
+	errorMsg("Sorry Dave, I cannot let you run setPos(x,y) in this exercise")
+
+# BEGIN TEMPLATE
+# BEGIN SOLUTION
+def mark(color):
+	setBrushColor(color)
+	brushDown()
+	brushUp()
+
+colors = []
+
+# read the colors
+for i in range(getWorldHeight()):
+	colors.append(getGroundColor())
+	forward()
+
+def makeLine (colors):
+	for i in range(getWorldWidth()):
+		mark(colors[i])
+		forward()
+
+# duplicate the pattern
+for i in range(getWorldWidth()-1):
+	left()
+	forward()
+	right()
+	forward()
+	makeLine(colors)
+
+# END SOLUTION
+# END TEMPLATE
diff --git a/src/lessons/welcome/array/basics/Array1Entity.scala b/src/lessons/welcome/array/basics/Array1Entity.scala
new file mode 100644
index 0000000..e1ee4a8
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array1Entity.scala
@@ -0,0 +1,55 @@
+package lessons.welcome.array.basics;
+
+import java.awt.Color;
+import plm.core.model.Game
+
+class ScalaArray1Entity extends plm.universe.bugglequest.SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		val colors = new Array[Color](getWorldHeight());
+
+		/* read the colors */
+		for (i <- 0 to getWorldHeight()-1) {
+			colors(i) = getGroundColor()
+					forward();
+		}
+
+		/* duplicate the pattern */
+		for (col <- 1 to getWorldWidth()-1) {
+			left();
+			forward();
+			right();
+			forward();
+			makeLine(colors);
+		}
+	}
+
+	def makeLine(colors:Array[Color]) {
+		for (i <- 0 to getWorldWidth()-1) {
+			mark(colors(i));
+			forward();
+		}
+	}
+	
+	def mark(c:Color){
+		setBrushColor(c);
+		brushDown();
+		brushUp();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/array/basics/Array2.fr.html b/src/lessons/welcome/array/basics/Array2.fr.html
index a2aeead..f9dd5f2 100644
--- a/src/lessons/welcome/array/basics/Array2.fr.html
+++ b/src/lessons/welcome/array/basics/Array2.fr.html
@@ -1,7 +1,7 @@
-<h1>Tricots, séquences et modulos</h1>
+<h1>[!java|scala]Tableaux[/!][!python]Listes[/!], tricot et modulo</h1>
 
-Cet exercice ressemble au précédent : il faut reproduire le motif de
-couleurs de la première colonne dans les colonnes suivantes. 
+<p>Cet exercice ressemble au précédent : il faut reproduire le motif de
+couleurs de la première colonne dans les colonnes suivantes.</p>
 
 <p>La première différence est que le monde est entouré d'un mur : il faut donc
 modifier légèrement les parcours pour s'assurer que la buggle ne se cogne
@@ -11,22 +11,21 @@ seulement <code>getWorldHeight()-1</code> pas dans la boucle.</p>
 
 <p>La seconde différence est que le décalage à effectuer entre les colonnes
 n'est pas fixe, mais écrit sur la première case de chaque colonne. Pour
-obtenir l'information sous forme d'un entier, on peut utiliser:
-<pre class="Java">int offset = Integer.parseInt(readMessage())</pre>
+obtenir l'information sous forme d'un entier, on peut utiliser:</p>
 
-<code>readMessage()</code> lit l'indication au sol sous forme d'une chaine
-de caractères, tandis que <code>Integer.parseInt()</code> transforme une
-chaine de caractères en entiers en la <i>lisant</i>.
+<pre>[!java]int decalage = Integer.parseInt(readMessage())[/!][!python]decalage = int( readMessage() )[/!][!scala]val decalage = readMessage().toInt[/!]</pre>
 
-<pre class="python">offset = int( readMessage() )</pre>
-<code>readMessage()</code> lit l'indication au sol sous forme d'une chaine
-de caractères, tandis que <code>int()</code> transforme le résultat en
-entier en <i>lisant</i> la chaîne de caractères.
+<p><code>readMessage()</code> lit l'indication au sol sous forme d'une chaîne
+de caractères,
+tandis que
+<code>[!java]Integer.parseInt(ch)[/!][!scala]ch.toInt[/!][!python]int(ch)[/!]</code>
+
+transforme la chaîne <code>ch</code> en un entier en la <i>lisant</i>.</p>
 
 <p>Ensuite, pour trouver la bonne couleur à utiliser, le plus simple est
 d'utiliser l'opérateur <code>%</code> (modulo). Par exemple, <code>(i + 5) %
 taille</code> permet de trouver la <code>i</code>ieme case d'un tableau de
 taille <code>taille</code> quand on applique un décalage de <code>5</code>
-cases.
+cases.</p>
 
 <p>À vous de jouer.</p>
diff --git a/src/lessons/welcome/array/basics/Array2.html b/src/lessons/welcome/array/basics/Array2.html
index cb6f292..b35faf7 100644
--- a/src/lessons/welcome/array/basics/Array2.html
+++ b/src/lessons/welcome/array/basics/Array2.html
@@ -1,30 +1,27 @@
-<h1>Knotting, sequences and modulo</h1>
-
-This exercise is similar to the previous one: you have to reproduce the
-color pattern of the first cell into the other ones. 
-
-<p>The first difference is that the world is bordered of walls: you thus have
-to slightly modify your trajectory to ensure that the buggle does not crash
-into a wall. The simpler for that is to handle the first cell out of the
-<code>for</code> loop and do only <code>getWorldHeight()-1</code> steps in
-the loop.</p>
-
-<p>The other difference is that the offset to apply between columns is not
-fixed, but written on the first cell of each column. To get the info as an
-integer, we can use:
-<pre class="Java">int offset = Integer.parseInt(readMessage())</pre>
-
-<code>readMessage()</code> gets the message on the ground as a String, while
-<code>Integer.parseInt()</code> transforms a String into an integer by
-<i>reading</i> it.
-
-<pre class="python">offset = int( readMessage() )</pre>
-<code>readMessage()</code> gets the message on the ground as a String, while
-<code>int()</code> transforms it into an integer value by <i>reading</i> it.
-
-<p>Then, to pick the right color, the easier is to use the <code>%</code>
-(modulo) operator. For example, <code>(i + 5) % size</code> allows to
-retrieve the <code>i</code>th cell of an array of size <code>size</code>
-with an offset of <code>5</code>.
-
-<p>You're up.</p>
+<h1>[!java|scala]Arrays[/!][!python]Lists[/!], Knotting and Modulos</h1>
+
+<p>This exercise is similar to the previous one: you have to reproduce the
+color pattern of the first cell into the other ones.</p>
+
+<p>The first difference is that the world is bordered of walls: you thus have
+to slightly modify your trajectory to ensure that the buggle does not crash
+into a wall. The simpler for that is to handle the first cell out of the
+<code>for</code> loop and do only <code>getWorldHeight()-1</code> steps in
+the loop.</p>
+
+<p>The other difference is that the offset to apply between columns is not
+fixed, but written on the first cell of each column. To get the info as an
+integer, we can use:</p>
+
+<pre>[!java]int offset = Integer.parseInt(readMessage())[/!][!python]offset = int( readMessage() )[/!][!scala]val offset = readMessage().toInt[/!]</pre>
+
+<p><code>readMessage()</code> gets the message on the ground as a [!java|scala]String[/!][!python]string[/!], 
+while <code>[!java]Integer.parseInt(str)[/!][!scala]str.toInt[/!][!python]int(str)[/!]</code> 
+transforms the string <code>str</code> into an integer by <i>reading</i> it.</p>
+
+<p>Then, to pick the right color, the easier is to use the <code>%</code>
+(modulo) operator. For example, <code>(i + 5) % size</code> allows to
+retrieve the <code>i</code>th cell of an array of size <code>size</code>
+with an offset of <code>5</code>.</p>
+
+<p>You're up.</p>
diff --git a/src/lessons/welcome/array/basics/Array2.java b/src/lessons/welcome/array/basics/Array2.java
index 93d55c2..02392ec 100644
--- a/src/lessons/welcome/array/basics/Array2.java
+++ b/src/lessons/welcome/array/basics/Array2.java
@@ -2,11 +2,11 @@ package lessons.welcome.array.basics;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class Array2 extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/array/basics/Array2Entity.java b/src/lessons/welcome/array/basics/Array2Entity.java
index 911e22c..297c6f5 100644
--- a/src/lessons/welcome/array/basics/Array2Entity.java
+++ b/src/lessons/welcome/array/basics/Array2Entity.java
@@ -2,23 +2,24 @@ package lessons.welcome.array.basics;
 
 import java.awt.Color;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class Array2Entity extends SimpleBuggle {
 	@Override
 	public void setX(int i)  {
 		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
 	}
 	@Override
 	public void setY(int i)  { 
 		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
 	}
 	@Override
 	public void setPos(int i,int j)  { 
 		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
 	}
 
 	/* BEGIN TEMPLATE */
@@ -42,9 +43,9 @@ public class Array2Entity extends SimpleBuggle {
 
 		/* Duplicate the pattern */
 		for (int i=1; i<getWorldWidth();i++) {
-			turnLeft();
+			left();
 			forward();
-			turnRight();
+			right();
 			makeLine(colors);
 		}
 	}
diff --git a/src/lessons/welcome/array/basics/Array2Entity.py b/src/lessons/welcome/array/basics/Array2Entity.py
index a5c45bd..e030ccb 100644
--- a/src/lessons/welcome/array/basics/Array2Entity.py
+++ b/src/lessons/welcome/array/basics/Array2Entity.py
@@ -32,9 +32,9 @@ def makeLine (colors):
 
 # duplicate the pattern
 for i in range(getWorldWidth()-1):
-	turnLeft()
+	left()
 	forward()
-	turnRight()
+	right()
 	makeLine(colors)
 
 # END SOLUTION
diff --git a/src/lessons/welcome/array/basics/Array2Entity.scala b/src/lessons/welcome/array/basics/Array2Entity.scala
new file mode 100644
index 0000000..3f218ae
--- /dev/null
+++ b/src/lessons/welcome/array/basics/Array2Entity.scala
@@ -0,0 +1,59 @@
+package lessons.welcome.array.basics;
+
+import java.awt.Color
+import plm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game
+
+class ScalaArray2Entity extends SimpleBuggle {
+	override def setX(i: Int)  {
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setX() in this exercise."));
+	}
+	override def setY(i: Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setY() in this exercise."));
+	}
+	override def setPos(x: Int, y:Int)  { 
+		if (isInited)
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use setPos() in this exercise."));
+	}
+
+	/* BEGIN TEMPLATE */
+	def run() {
+	/* BEGIN SOLUTION */
+		val colors = new Array[Color](getWorldHeight());
+
+		/* read the colors */
+		colors(0) = getGroundColor();
+		for (i <- 1 to getWorldHeight()-1) {
+			forward();
+			colors(i) = getGroundColor();
+		}
+		backward(getWorldHeight()-1);
+
+		/* duplicate the pattern */
+		for (col <- 1 to getWorldWidth()-1) {
+			left();
+			forward();
+			right();
+			makeLine(colors);
+		}
+	}
+
+	def makeLine(colors: Array[Color]) {
+		val offset = readMessage().toInt;
+		mark(colors( (0+offset)%colors.length ) );
+		for (i <- 1 to getWorldWidth()-1) {
+			forward();
+			mark(colors(  (i+offset)%colors.length  ));
+		}
+		backward(getWorldHeight()-1);
+	}
+	def mark(c:Color){
+		setBrushColor(c);
+		brushDown();
+		brushUp();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/array/basics/ArrayEntity.java b/src/lessons/welcome/array/basics/ArrayEntity.java
deleted file mode 100644
index 4ce3ea9..0000000
--- a/src/lessons/welcome/array/basics/ArrayEntity.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package lessons.welcome.array.basics;
-
-import java.awt.Color;
-
-public class ArrayEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	@Override
-	public void setX(int i)  {
-		if (isInited())
-			throw new RuntimeException("setX(int) forbidden in this exercise");
-	}
-	@Override
-	public void setY(int i)  { 
-		if (isInited())
-			throw new RuntimeException("setY(int) forbidden in this exercise");
-	}
-	@Override
-	public void setPos(int i,int j)  { 
-		if (isInited())
-			throw new RuntimeException("setPos(int,int) forbidden in this exercise");
-	}
-
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	void mark(Color c){
-		setBrushColor(c);
-		brushDown();
-		brushUp();
-	}
-
-	public void run() {
-		Color[] colors = new Color[getWorldHeight()];
-
-		/* read the colors */
-		for (int i=0;i<getWorldHeight();i++) {
-			colors[i]=getGroundColor();
-			forward();
-		}
-
-		/* duplicate the pattern */
-		for (int i=1; i<getWorldWidth();i++) {
-			turnLeft();
-			forward();
-			turnRight();
-			forward();
-			makeLine(colors);
-		}
-	}
-
-	void makeLine(Color[] colors) {
-		for (int i=0;i<getWorldWidth();i++) {
-			mark(colors[i]);
-			forward();
-		}
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/array/basics/ArrayEntity.py b/src/lessons/welcome/array/basics/ArrayEntity.py
deleted file mode 100644
index 2ee2ef7..0000000
--- a/src/lessons/welcome/array/basics/ArrayEntity.py
+++ /dev/null
@@ -1,37 +0,0 @@
-def setX(i):
-	errorMsg("Sorry Dave, I cannot let you run setX(i) in this exercise")
-
-def setY(i):
-	errorMsg("Sorry Dave, I cannot let you run setY(i) in this exercise")
-def setPos(x,y):
-	errorMsg("Sorry Dave, I cannot let you run setPos(x,y) in this exercise")
-
-# BEGIN TEMPLATE
-# BEGIN SOLUTION
-def mark(color):
-	setBrushColor(color)
-	brushDown()
-	brushUp()
-
-colors = []
-
-# read the colors
-for i in range(getWorldHeight()):
-	colors.append(getGroundColor())
-	forward()
-
-def makeLine (colors):
-	for i in range(getWorldWidth()):
-		mark(colors[i])
-		forward()
-
-# duplicate the pattern
-for i in range(getWorldWidth()-1):
-	turnLeft()
-	forward()
-	turnRight()
-	forward()
-	makeLine(colors)
-
-# END SOLUTION
-# END TEMPLATE
diff --git a/src/lessons/welcome/array/has271/Has271.fr.html b/src/lessons/welcome/array/has271/Has271.fr.html
index ca84db8..4784cc8 100644
--- a/src/lessons/welcome/array/has271/Has271.fr.html
+++ b/src/lessons/welcome/array/has271/Has271.fr.html
@@ -5,4 +5,4 @@ une valeur, suivie de cette valeur plus 5, suivie par cette valeur moins
 correcte.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/has271/Has271.html b/src/lessons/welcome/array/has271/Has271.html
index c8bbfc8..17c5648 100644
--- a/src/lessons/welcome/array/has271/Has271.html
+++ b/src/lessons/welcome/array/has271/Has271.html
@@ -5,4 +5,4 @@ followed by the value plus 5, followed by the value minus 1.
 Additionally the 271 counts even if the "1" differs by 2 or less from
 the correct value.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/has271/Has271.java b/src/lessons/welcome/array/has271/Has271.java
index dafc824..ec7bc01 100644
--- a/src/lessons/welcome/array/has271/Has271.java
+++ b/src/lessons/welcome/array/has271/Has271.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.has271;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class Has271 extends BatExercise {
 	public Has271(Lesson lesson) {
@@ -24,22 +23,30 @@ public class Has271 extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {2, 7, 5, 10, 1}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {2, 7, -2, 4, 10, 2}) ;
 
-		langTemplate(Game.PYTHON, "has271",
+		templatePython("has271",
 				"import math\ndef has271(nums):\n",
 				"  count=0\n"+
 				"  for i in range( len(nums)-1):\n"+
 				"    if (nums[i] + 5 == nums[i+1]) and (math.fabs(nums[i+2]-nums[i]+1)<=2):\n"+
 				"      return True\n"+
 				"  return False\n");
+		templateScala("has271", new String[] {"Array[Int]"},
+				"def has271(nums:Array[Int]): Boolean = {\n",
+				"  var count=0\n"+
+				"  for (i <- 0 to nums.length-2)\n"+
+				"    if ((nums(i) + 5 == nums(i+1)) && (Math.abs(nums(i+2)-nums(i)+1)<=2))\n"+
+				"      return true\n"+
+				"  return false\n"+
+				"}");
 
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( has271((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	boolean has271(int[] nums) {
diff --git a/src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.java b/src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.java
index 4916dab..82d1e84 100644
--- a/src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.java
+++ b/src/lessons/welcome/array/indexof/maxvalue/IndexOfMaxValue.java
@@ -2,11 +2,10 @@ package lessons.welcome.array.indexof.maxvalue;
 
 import java.util.Random;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class IndexOfMaxValue extends BatExercise {
 
@@ -27,7 +26,7 @@ public class IndexOfMaxValue extends BatExercise {
 		myWorld.addTest(VISIBLE, tab) ;
 		myWorld.addTest(INVISIBLE, tab2) ;
 
-		langTemplate(Game.PYTHON, "indexOfMaxValue", 
+		templatePython("indexOfMaxValue", 
 				"def indexOfMaxValue(nums):\n",
 				"  max=nums[0]\n" +
 				"  maxIdx = 0\n" +
@@ -36,15 +35,26 @@ public class IndexOfMaxValue extends BatExercise {
 				"      max = nums[i]\n" +
 				"      maxIdx = i\n"+
 				"  return maxIdx\n");
+		templateScala("indexOfMaxValue", new String[]{"Array[Int]"},
+				"def indexOfMaxValue(nums:Array[Int]):Int = {\n",
+				"  var max=nums(0)\n" +
+				"  var maxIdx = 0\n" +
+				"  for (i <- 0 to nums.length-1)\n" +
+				"    if (nums(i)>max) {\n"+
+				"      max = nums(i)\n" +
+				"      maxIdx = i\n"+
+				"    }\n"+
+				"  return maxIdx\n"+
+				"}");
 
 		setup(myWorld);
 	}
 	
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( indexOfMaximum( (int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	// computes the index of the maximum of the values contained in tab variable
diff --git a/src/lessons/welcome/array/indexof/value/IndexOfValue.java b/src/lessons/welcome/array/indexof/value/IndexOfValue.java
index 4717d62..68709a2 100644
--- a/src/lessons/welcome/array/indexof/value/IndexOfValue.java
+++ b/src/lessons/welcome/array/indexof/value/IndexOfValue.java
@@ -2,11 +2,10 @@ package lessons.welcome.array.indexof.value;
 
 import java.util.Random;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class IndexOfValue extends BatExercise {
 
@@ -47,20 +46,27 @@ public class IndexOfValue extends BatExercise {
 		myWorld.addTest(INVISIBLE, tab4, r.nextInt(35)-15);
 		myWorld.addTest(INVISIBLE, tab4, getIndex(tab4));
 
-		langTemplate(Game.PYTHON, "indexOfValue", 
+		templatePython("indexOfMaxValue", 
 				"def indexOfMaxValue(nums,val):\n",
 				"  for i in range(len(nums)):\n" +
 				"    if nums[i]==val:\n"+
 				"      return i\n" +
 				"  return -1\n");
+		templateScala("indexOfMaxValue", new String[] {"Array[Int]","Int"}, 
+				"def indexOfMaxValue(nums:Array[Int] ,value:Int): Int = {\n",
+				"  for (i <- 0 to nums.length-1)\n" +
+				"    if (nums(i)==value) \n"+
+				"      return i\n" +
+				"  return -1\n"+
+				"}");
 		
 		setup(myWorld);
 	}
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( indexOf( (int[])t.getParameter(0), (Integer)t.getParameter(1) ) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	// computes the index of the first value equals to 'lookingFor' contained in tab variable
diff --git a/src/lessons/welcome/array/maxvalue/MaxValue.java b/src/lessons/welcome/array/maxvalue/MaxValue.java
index b239712..31bb003 100644
--- a/src/lessons/welcome/array/maxvalue/MaxValue.java
+++ b/src/lessons/welcome/array/maxvalue/MaxValue.java
@@ -2,11 +2,10 @@ package lessons.welcome.array.maxvalue;
 
 import java.util.Random;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class MaxValue extends BatExercise {
 
@@ -37,22 +36,30 @@ public class MaxValue extends BatExercise {
 		myWorld.addTest(INVISIBLE, tab3) ;
 		myWorld.addTest(INVISIBLE, tab4) ;
 
-		langTemplate(Game.PYTHON, "maxValue", 
+		templatePython("maxValue", 
 				"def maxValue(nums):\n",
 				"  max=nums[0]\n"+
 				"  for i in range(len(nums)):\n"+
 				"    if nums[i] > max:\n"+
 				"      max = nums[i]\n"+
 				"  return max\n");
+		templateScala("maxValue",new String[] {"Array[Int]"}, 
+				"def maxValue(nums:Array[Int]): Int = {\n",
+				"  var max=nums(0)\n"+
+				"  for (i <- 0 to nums.length-1)\n"+
+				"    if (nums(i) > max)\n"+
+				"      max = nums(i)\n"+
+				"  return max\n"+
+				"}");
 
 		setup(myWorld);
 	}
 	
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( maxValue( (int[])t.getParameter(0) ));
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	// computes the index of the maximum of the values contained in tab variable
diff --git a/src/lessons/welcome/array/notriples/NoTriples.fr.html b/src/lessons/welcome/array/notriples/NoTriples.fr.html
index 9f21f7a..e6c54f9 100644
--- a/src/lessons/welcome/array/notriples/NoTriples.fr.html
+++ b/src/lessons/welcome/array/notriples/NoTriples.fr.html
@@ -4,4 +4,4 @@ Soit un tableau d'entiers, on dire qu'un triplet est une valeur qui apparait
 pas de triplet.
 
 <p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/array/notriples/NoTriples.html b/src/lessons/welcome/array/notriples/NoTriples.html
index 699c0fd..00d1a13 100644
--- a/src/lessons/welcome/array/notriples/NoTriples.html
+++ b/src/lessons/welcome/array/notriples/NoTriples.html
@@ -4,4 +4,4 @@ array of integers, we'll say that a triple is a value appearing 3 times in
 a row in the array. Return true if the array does not contain any
 triples.
 
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/array/notriples/NoTriples.java b/src/lessons/welcome/array/notriples/NoTriples.java
index 553e4e1..80b4659 100644
--- a/src/lessons/welcome/array/notriples/NoTriples.java
+++ b/src/lessons/welcome/array/notriples/NoTriples.java
@@ -1,9 +1,8 @@
 package lessons.welcome.array.notriples;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class NoTriples extends BatExercise {
 	public NoTriples(Lesson lesson) {
@@ -20,21 +19,29 @@ public class NoTriples extends BatExercise {
 		myWorld.addTest(INVISIBLE, (Object)new int[] {1}) ;
 		myWorld.addTest(INVISIBLE, (Object)new int[] {}) ;
 
-		langTemplate(Game.PYTHON, "noTriples", 
+		templatePython("noTriples", 
 				"def noTriples(nums):\n",
 				"  count=0\n"+
 				"  for i in range( len(nums)-2 ):\n"+
 				"    if (nums[i] == nums[i+1]) and (nums[i+1] == nums[i+2]):\n"+
 				"      return False\n"+
 				"  return True\n");
+		templateScala("noTriples",new String[]{"Array[Int]"}, 
+				"def noTriples(nums:Array[Int]): Boolean = {\n",
+				"  var count=0\n"+
+				"  for (i <- 0 to nums.length-3)\n"+
+				"    if ( (nums(i) == nums(i+1)) && (nums(i+1) == nums(i+2)) )\n"+
+				"      return false\n"+
+				"  return true\n"+
+				"}");
 		setup(myWorld);
 	}
 
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( noTriples((int[])t.getParameter(0)) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 	/* BEGIN TEMPLATE */
 	boolean noTriples(int[] nums) {
diff --git a/src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.java b/src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.java
index ec7067e..04a1635 100644
--- a/src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.java
+++ b/src/lessons/welcome/array/occurenceofvalue/OccurrenceOfValue.java
@@ -2,11 +2,10 @@ package lessons.welcome.array.occurenceofvalue;
 
 import java.util.Random;
 
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
 
 public class OccurrenceOfValue extends BatExercise {
 
@@ -49,13 +48,21 @@ public class OccurrenceOfValue extends BatExercise {
 
 		
 		
-		langTemplate(Game.PYTHON, "occurrences", 
+		templatePython("occurrences", 
 				"def occurrences(nums,lookingFor):\n",
 				"  count = 0\n" +
 				"  for i in range(len(nums)):\n" +
 				"    if nums[i] == lookingFor:\n" +
 				"      count += 1\n" +
 				"  return count\n");
+		templateScala("occurrences", new String[]{"Array[Int]","Int"},
+				"def occurrences(nums:Array[Int],lookingFor:Int):Int = {\n",
+				"  var count = 0\n" +
+				"  for (i <- 0 to nums.length-1)\n" +
+				"    if (nums(i) == lookingFor)\n" +
+				"      count += 1\n" +
+				"  return count\n"+
+				"}");
 
 		setup(myWorld);
 	}
@@ -75,11 +82,11 @@ public class OccurrenceOfValue extends BatExercise {
 	}
 
 	/* END TEMPLATE */
-	/* BEGIN SKEL */
 	public void run(BatTest t) {
+		/* BEGIN SKEL */
 		t.setResult( occurrences( (int[])t.getParameter(0), (Integer)t.getParameter(1) ) );
+		/* END SKEL */
 	}
-	/* END SKEL */
 
 }
 
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeeker.fr.html b/src/lessons/welcome/baggleseeker/BaggleSeeker.fr.html
deleted file mode 100644
index 2230016..0000000
--- a/src/lessons/welcome/baggleseeker/BaggleSeeker.fr.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<h2>Chercheur de baggles</h2>
-<p>Le monde des buggles contient parfois des <i>baggles</i>, sorte de petits
-biscuits que les buggles peuvent déplacer d'un endroit à un autre. Pour
-cela, elles peuvent utiliser des fonctions spécifiques :
-<code>isOverBaggle(), isCarryingBaggle(), pickupBaggle()</code> et
-<code>dropBaggle()</code>. Tous les détails se trouvent dans la
-documentation accessible depuis «Aide/À propos de ce monde».
-
-<h3>Objectif de cet exercice</h3>
-
-<p>Faites en sorte que chaque buggle trouve son baggle en adaptant le code que
-vous aviez écrit pour l'exercice précédent (faites un copie/colle de ce que
-vous aviez fait pour gagner du temps).
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeeker.html b/src/lessons/welcome/baggleseeker/BaggleSeeker.html
deleted file mode 100644
index 9c5e845..0000000
--- a/src/lessons/welcome/baggleseeker/BaggleSeeker.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h2>Baggle Seeking</h2>
-<p>The buggle world can sometimes contain some <i>baggles</i>, which are little
-biscuits that buggles can carry from one point to another. For that, they
-have to use specific methods such as <code>isOverBaggle(), isCarryingBaggle(), 
-pickupBaggle()</code> or <code>dropBaggle()</code>. Check their documentation in
-"Help/About this world" for more details.
-
-<h3>Exercise goal</h3>
-
-<p>Let each buggle find its baggle by adapting the code you wrote in previous exercise
- (copy/paste what you've done before to save time).
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeeker.java b/src/lessons/welcome/baggleseeker/BaggleSeeker.java
deleted file mode 100644
index 30a639f..0000000
--- a/src/lessons/welcome/baggleseeker/BaggleSeeker.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package lessons.welcome.baggleseeker;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-public class BaggleSeeker extends ExerciseTemplated {
-
-	public BaggleSeeker(Lesson lesson) {
-		super(lesson);
-
-		BuggleWorld myWorld = new BuggleWorld("Kitchen",7,7);
-		for (int i=0;i<7;i++) {
-			new Buggle(myWorld, "Cooker "+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
-
-			try {
-				myWorld.newBaggle(i, 6-i);
-			} catch (AlreadyHaveBaggleException e) {
-				e.printStackTrace();
-			}
-		}
-		setup(myWorld);
-	}
-}
\ No newline at end of file
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeekerEntity.java b/src/lessons/welcome/baggleseeker/BaggleSeekerEntity.java
deleted file mode 100644
index 68d1a65..0000000
--- a/src/lessons/welcome/baggleseeker/BaggleSeekerEntity.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package lessons.welcome.baggleseeker;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class BaggleSeekerEntity extends SimpleBuggle {
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-
-
-	@Override
-	public void run() { 
-		/* BEGIN TEMPLATE */
-		/* BEGIN SOLUTION */
-		while (!isOverBaggle()) {
-			forward();
-		}
-		/* END SOLUTION */
-		/* END TEMPLATE */
-	}
-}
diff --git a/src/lessons/welcome/basics/Basics.fr.html b/src/lessons/welcome/basics/Basics.fr.html
deleted file mode 100644
index 50fef54..0000000
--- a/src/lessons/welcome/basics/Basics.fr.html
+++ /dev/null
@@ -1,93 +0,0 @@
-  <h2>Instructions</h2>
-
-  Félicitations ! Vous venez d'écrire votre premier programme ! Vous avez
-compris l'idée maintenant : programmer, c'est simplement donner des
-instructions à l'ordinateur, qui les applique aveuglément. La plus grande
-difficulté est d'expliquer quoi faire à quelqu'un d'aussi bête que
-l'ordinateur...  
-  
-  <p>Le programme le plus simple est formé d'une suite d'ordres simples donnés à
-la
-machine. C'est assez comparable à une recette de cuisine où l'on dit
-<i>cassez
-les oeufs puis ajoutez du sel puis mélangez le tout puis faites
-cuire</i>. Dans
-les programmes, de tels instructions  sont appellées fonctions ou
-méthodes, et vous devez les doter de parenthèses comme dans  
-		<pre>nomDeLaMethode()</pre>
-		
-   <p class="Java">
-   Java veut que les instructions soient séparées par des points-virgules (;).
-L'exemple ci-dessus de recette s'écrirait donc à peu près ainsi:</p>
-<pre class="Java">
-casserLesOeufs();
-ajouterDuSel();
-melangerLeTout();
-faireCuire();
-</pre>
-    
-   <p class="Python">Python veut que les instructions soient séparées soit par des
-points-virgules
-(;), soit par des retours à la ligne.
-L'exemple ci-dessus de recette s'écrirait donc à peu près ainsi:</p>
-<pre class="Python">
-casserLesOeufs()
-ajouterDuSel()
-melangerLeTout()
-faireCuire()
-</pre>
-   <p class="Python">
-   Il serait également possible de l'écrire sous la forme suivante, mais placer
-plusieurs instructions sur la même ligne est généralement considéré comme
-une
-très mauvaise habitude car cela complique grandement la relecture du code
-après
-coup.</p>
-<pre class="Python">
-casserLesOeufs(); ajouterDuSel(); melangerLeTout(); faireCuire();
-</pre>
-
-  <p class="Java">Bien entendu, ces méthodes n'existent pas en Java, mais il serait possible
-de
-les définir par vous même (nous verrons plus tard comment définir vos
-propres méthodes).</p>
-  <p class="Python">Bien entendu, ces méthodes n'existent pas en Python, mais il serait possible
-de
-les définir par vous même (nous verrons plus tard comment définir vos
-propres méthodes).</p>
-  <p>Pour l'instant, nous allons utiliser les instructions de la buggle. Il
-y a une méthode pour chaque bouton du contrôle interactif.  Pour faire la
-même
-chose que le bouton <b>forward</b> (faire avancer la buggle d'un pas), il
-faut
-écrire dans l'éditeur : <pre class="Java">forward();</pre> <pre class="Python">forward()</pre>
-  De même, pour faire l'équivalent des boutons <b>backward</b>, <b>turn
-left</b> et <b>turn right</b>, il faut utiliser respectivement : 
-<pre class="Java">
-backward();
-turnLeft();
-turnRight();
-</pre>
-<pre class="Python">
-backward()
-turnLeft()
-turnRight()
-</pre>
-	 Le bouton <b>mark</b> est un peu particulier, puisqu'il correspond à deux
-méthodes : la première lève le crayon, tandis que la seconde le baisse.
-<pre class="Java">
-brushUp();
-brushDown();
-</pre>
-<pre class="Python">
-brushUp()
-brushDown()
-</pre>
-  <p>La buggle offre d'autres méthodes, présentées dans le menu "Help/about this
-world". Elles seront introduites au fur et à mesure des besoins.</p>
-
-
-  <h3>Objectif de cet exercice</h3><a name="Objectives"> Notre second programme sera un peu plus compliqué,
-mais pas tellement. L'objectif de votre buggle est simplement de se dessiner
-une maison (une boîte), et de se cacher dedans. Vérifiez le monde objectif
-pour voir exactement ce que cela veut dire. 
diff --git a/src/lessons/welcome/basics/Basics.html b/src/lessons/welcome/basics/Basics.html
deleted file mode 100644
index d977de1..0000000
--- a/src/lessons/welcome/basics/Basics.html
+++ /dev/null
@@ -1,80 +0,0 @@
-  <h2>Instructions</h2>
-
-  Congratulations! You just wrote your first program! You got the idea now: 
-  programming is nothing more than giving simple instructions to the computer that 
-  blindly apply them. The main difficulty is to explain stuff to someone as stupid 
-  as a computer...  
-  
-  <p>Programs are mainly suites of method calls, which are no more than a list of
-   simple order given to the machine. It is very similar to a recipe stating
-   <i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>. 
-   In your programs, such built instructions are called functions or methods, and you 
-   should add parenthesis to invoke them, as in  
-		<pre>nameOfTheMethod()</pre>
-		
-   <p class="Java">
-   Java want to have the instructions separated by semi-columns (;). 
-    The previous example would thus be written in a similar way:</p>
-<pre class="Java">
-meltTheChocolatePieces();
-addSugar();
-coolMix();
-serve();
-</pre>
-    
-   <p class="Python">Python want to have the instructions  
-   separated by either semi-columns (;) or by new lines. The previous example would thus 
-   be written the following way.</p>
-<pre class="Python">
-meltTheChocolatePieces()
-addSugar()
-coolMix()
-serve()
-</pre>
-   <p class="Python">
-   It could also be written in the following way, but it's generally considered as a bad 
-   practice to group several instructions on the same line since it greatly hinders the 
-   readability.</p>
-<pre class="Python">
-meltTheChocolatePieces(); addSugar(); coolMix(); serve()
-</pre>
-
-  <p class="Java">Of course, these specific methods do not exist in Java, but it may be possible 
-  to define them by yourself (we'll see later how to define your how methods).</p>
-  <p class="Python">Of course, these specific methods do not exist in Python, but it may be possible 
-  to define them by yourself (we'll see later how to define your how methods).</p>
-  <p>For now, 
-  we'll simply go for the buggle instructions. There is a method for each button of the 
-  interactive control panel. To achieve the same effect than the <b>forward</b> button 
-  (making the buggle moving one step forward), you need to write the following in the
-  editor: <pre class="Java">forward();</pre> <pre class="Python">forward()</pre>
-  Likewise, to achieve the same effect than the <b>backward</b>, <b>turn
-  left</b> and <b>turn right</b> buttons, you need to use respectively: 
-<pre class="Java">
-backward();
-turnLeft();
-turnRight();
-</pre>
-<pre class="Python">
-backward()
-turnLeft()
-turnRight()
-</pre>
-	 The <b>mark</b> button is a bit particular, since it correspond to two
-methods: the first one moves the pen up while the second moves it down.
-<pre class="Java">
-brushUp();
-brushDown();
-</pre>
-<pre class="Python">
-brushUp()
-brushDown()
-</pre>
-  <p>The buggle offers other methods, that are presented from the "Help/about
-   this world" menu and will be introduced on need.</p>
-
-
-  <h3>Exercise goal</h3><a name="Objectives">
-  Our second program will be a bit more complicated, but not much. The goal for 
-  your buggle is simply to draw a house (a box), and hide inside. Check the 
-  objective world to see exactly what this means. 
diff --git a/src/lessons/welcome/basics/Basics.java b/src/lessons/welcome/basics/Basics.java
deleted file mode 100644
index 9095500..0000000
--- a/src/lessons/welcome/basics/Basics.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package lessons.welcome.basics;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class Basics extends ExerciseTemplated {
-
-	public Basics(Lesson lesson) {
-		super(lesson);
-		tabName="Program";
-
-		BuggleWorld myWorld = new BuggleWorld("Training World", 7,7);
-		new Buggle(myWorld, "Rookie", 2, 4, Direction.NORTH, Color.black, Color.lightGray);
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/basics/BasicsEntity.java b/src/lessons/welcome/basics/BasicsEntity.java
deleted file mode 100644
index e994fc0..0000000
--- a/src/lessons/welcome/basics/BasicsEntity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package lessons.welcome.basics;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class BasicsEntity extends SimpleBuggle {
-
-	@Override
-	public void run() {
-		/* BEGIN TEMPLATE */
-		/* BEGIN SOLUTION */
-		brushDown();
-		for (int i=0;i<4;i++) {
-			forward(2);
-			turnRight();
-		}
-		brushUp();
-		forward();
-		turnRight();
-		forward();
-		turnLeft();
-		/* END SOLUTION */
-		/* END TEMPLATE */
-	}
-
-}
diff --git a/src/lessons/welcome/basics/BasicsEntity.js b/src/lessons/welcome/basics/BasicsEntity.js
deleted file mode 100644
index 6ff2b2b..0000000
--- a/src/lessons/welcome/basics/BasicsEntity.js
+++ /dev/null
@@ -1,19 +0,0 @@
-# BEGIN TEMPLATE 
-function side(){
-    forward()
-    forward()
-    turnRight()
-}
-
-brushDown()
-
-for (var i=0;i<3;i++) 
-    side()
-                
-forward()
-turnRight()
-
-brushUp()
-forward()
-# END TEMPLATE
-
diff --git a/src/lessons/welcome/basics/BasicsEntity.py b/src/lessons/welcome/basics/BasicsEntity.py
deleted file mode 100644
index c1ca40f..0000000
--- a/src/lessons/welcome/basics/BasicsEntity.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# BEGIN SOLUTION
-
-brushDown()
-
-for i in range(4):
-    forward()
-    forward()
-    turnRight()
-                
-brushUp()
-forward()
-turnRight()
-forward()
-turnLeft()
-# END SOLUTION
-
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawG.fr.html b/src/lessons/welcome/basicsdrawg/BasicsDrawG.fr.html
deleted file mode 100644
index a8e66e0..0000000
--- a/src/lessons/welcome/basicsdrawg/BasicsDrawG.fr.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<h2>Écrire des programmes plus complexes</h2>
-  Maintenant que vous savez écrire des choses sur le sol, nous allons utiliser
-cette compétence pour dessiner un merveilleux G par terre. Consultez le
-panneau d'objectif pour les détails de ce qui est attendu. 
-
-  <p>Quand vous écrivez un programme un peu complexe, il est souvent pratique
-d'ajouter des <b>commentaires</b> pour simplifier la relecture du code après
-coup. Ici par exemple, il est assez facile de se perdre dans les ordres
-nécessaires au dessin. Il peut être pratique d'ajouter des commentaires
-comme
-<i>fin de la barre verticale</i> ou <i>Fini de dessiner le G. Retournons à
-la
-position initiale</i>. Documenter votre code est presque toujours nécessaire
-si
-quelqu'un (vous ou quelqu'un d'autre) veut le lire après coup. Cependant,
-commenter des
-choses triviales est une mauvaise idée car cela dilue les informations
-dans des commentaires trop verbeux. En anglais, ce travers s'appelle
-<i>overcommenting</i>.</p>
-   
-  <p class="Java">Il y a trois sortes de commentaires en Java, indiquant au compilateur qu'il
-ne
-doit pas lire le texte ajouté pour les humains.</p>
-  <p class="Python">Il y a deux sortes de commentaires en Python, indiquant au compilateur qu'il
-ne
-doit pas lire le texte ajouté pour les humains.</p>
-   
-  <ul class="Java">
-    <li class="Java"><b>Commentaires sur une seule ligne</b>. Dès que le compilateur rencontre
-les symboles //, il ignore la fin de la ligne.</li>      
-    <li class="Java"><b>Commentaires sur plusieurs lignes</b>. Le compilateur ignore tout ce qui
-se trouve entre les symboles /* et */, même s'ils sont sur des lignes
-différentes</li>
-  </ul>
-
-  <ul class="Python">
-    <li class="Python"><b>Commentaires sur une seule ligne</b>. Dès que le compilateur rencontre le
-symbole #, il ignore la fin de la ligne.</li>
-    <li class="Python"><b>Commentaires sur plusieurs lignes</b>. Le compilateur ignore tout ce qui
-se
-trouve entre une ligne commençant par ''' et la prochaine ligne terminant
-par '''.</li>      
-  </ul>
-
-<pre class="Java">
-appelMethodeLuParLeCompilateur(); <span class="comment"> // tout ceci est ignoré</span>
-autreAppel(); <span class="comment">/* ceci est</span>
-              <span class="comment"> également ignoré */</span>
-encoreUnAppel();
-</pre>  
-<pre class="Python">
-appelMethodeLuParLeCompilateur() <span class="comment"> # tout ceci est ignoré</span>
-autreAppel() 
-<span class="comment">''' ceci est</span>
-<span class="comment"> également ignoré '''</span>
-encoreUnAppel()
-</pre>  
-  
-  <p class="Java">Il existe une troisième forme de commentaires en Java, entre /** et */, qui
-sont lus par un programme nommé JavaDoc pour générer automatiquement la
-documentation expliquant comment utiliser le code. Ces commentaires doivent
-suivre un formalisme précis.</p>
-
-  <p class="Python">Les commentaires sur plusieurs lignes sont souvent utilisés pour documenter
-comment utiliser le code, tandis que les autres types de commentaires sont
-souvent utilisés pour documenter comment le code fonctionne.</p>
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawG.html b/src/lessons/welcome/basicsdrawg/BasicsDrawG.html
deleted file mode 100644
index feef6e0..0000000
--- a/src/lessons/welcome/basicsdrawg/BasicsDrawG.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<h2>Writing more complex programs</h2>
-  Now that we know how to draw things on the board, we'll enjoy this ability and 
-  draw a beautiful G on the board (check Objective panel for details on what's 
-  expected). 
-
-  <p>When you write a quite complex program, it is sometimes useful to <b>add
-   comments</b> to simplify the code reviews afterward. Here for example, it's 
-   quite easy to get lost in the drawing process, and you may want to add 
-   comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to 
-   move back to initial position</i>. Commenting your code is almost mandatory if you 
-   (or someone else) want to read it afterward, although overcommenting 
-   (describing obvious stuff) is a bad idea as the important idea get lost in the noise.</p>
-   
-  <p class="Java">There is three types of comments in Java, instructing the compiler 
-   to not read the text you add for humans:</p>
-  <p class="Python">There is two types of comments in Python, instructing the compiler 
-   to not read the text you add for humans:</p>
-   
-  <ul class="Java">
-    <li class="Java"><b>Comments on a single line</b>. When the compiler encounters the symbols //,
-      it ignores the end of the line.</li>      
-    <li class="Java"><b>Comments on several lines</b>. The compiler ignores anything placed
-      between the symbols /* and */ even if they are placed on differing lines.</li>
-  </ul>
-
-  <ul class="Python">
-    <li class="Python"><b>Comments on a single line</b>. When the compiler encounters the symbol #,
-      it ignores the end of the line.</li>
-    <li class="Python"><b>Comments on several lines</b>. The compiler ignores anything placed
-      between a line beginning with ''' and the next line ending with '''.</li>      
-  </ul>
-
-<pre class="Java">
-methodCallReadByTheCompiler(); <span class="comment">// all this is ignored</span>
-otherCall(); <span class="comment">/* This is</span>
-              <span class="comment"> also ignored */</span>
-yetAnotherCall();
-</pre>  
-<pre class="Python">
-methodCallReadByTheCompiler() <span class="comment"># all this is ignored</span>
-otherCall() 
-<span class="comment">''' This is</span>
-<span class="comment">also ignored  '''</span>
-yetAnotherCall()
-</pre>  
-  
-  <p class="Java">There is a third kind of comments in Java, between /** and */, which are read by a
-specific program called JavaDoc to generate automatically the documentation
-explaining how to use the code. These comments must follow a very precise
-formalism.</p>
-
-  <p class="Python">The comments on several lines are often used to document how to use the code, while others 
-  are more used to describe how this code works.</p>
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawG.java b/src/lessons/welcome/basicsdrawg/BasicsDrawG.java
deleted file mode 100644
index 1d2c763..0000000
--- a/src/lessons/welcome/basicsdrawg/BasicsDrawG.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package lessons.welcome.basicsdrawg;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class BasicsDrawG extends ExerciseTemplated {
-
-	public BasicsDrawG(Lesson lesson) {
-		super(lesson);
-		tabName = "SourceCode";
-
-		BuggleWorld myWorld = new BuggleWorld("Training World", 7, 7);
-		new Buggle(myWorld, "Rookie", 5, 1, Direction.NORTH, Color.black, Color.blue);
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.java b/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.java
deleted file mode 100644
index c6a5fee..0000000
--- a/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package lessons.welcome.basicsdrawg;
-
-
-public class BasicsDrawGEntity extends jlm.universe.bugglequest.SimpleBuggle {
-
-	@Override
-	public void run() {
-		/* BEGIN TEMPLATE */
-		/* BEGIN SOLUTION */
-		brushDown();
-		turnLeft();
-		forward();
-		forward();
-		forward();
-		forward();
-		turnLeft();
-		forward();
-		forward();
-		forward();
-		forward();
-		turnLeft();
-		forward();
-		forward();
-		forward();
-		forward();
-		turnLeft();
-		forward();
-		forward();
-		turnLeft();
-		forward();
-		/* back home */
-		brushUp();
-		turnRight();
-		forward(2);
-		turnRight();
-		forward();
-		turnLeft();
-		/* END SOLUTION */
-		/* END TEMPLATE */
-	}
-
-}
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.py b/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.py
deleted file mode 100644
index 859132c..0000000
--- a/src/lessons/welcome/basicsdrawg/BasicsDrawGEntity.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# BEGIN SOLUTION
-brushDown()
-turnLeft()
-forward(4)
-turnLeft()
-forward(4)
-turnLeft()
-forward(4)
-turnLeft()
-forward()
-forward()
-turnLeft()
-forward()
-# back home 
-brushUp()
-turnRight()
-forward(2)
-turnRight()
-forward()
-turnLeft()
-# END SOLUTION
-
diff --git a/src/lessons/welcome/bat/bool1/Close10.fr.html b/src/lessons/welcome/bat/bool1/Close10.fr.html
new file mode 100644
index 0000000..a9176dd
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Close10.fr.html
@@ -0,0 +1,11 @@
+<h1>Proche de 10</h1>
+<p>Étant donné deux nombres entiers, retourner la valeur la plus proche de 10,
+ou 0 en cas de match nul.
+[!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un
+nombre.[/!]
+[!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un
+nombre. Remarquez également que vous ne pouvez utiliser cette fonction que
+si vous avez importé le module math.[/!]</p>
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/Close10.html b/src/lessons/welcome/bat/bool1/Close10.html
new file mode 100644
index 0000000..f0aeee3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Close10.html
@@ -0,0 +1,7 @@
+<h1>Close to 10</h1>
+<p>Given 2 int values, return whichever value is nearest to the value 10, or return 0 in the event of a tie. 
+[!java|scala]Note that Math.abs(n) returns the absolute value of a number.[/!]
+[!python]Note that math.fabs(n) returns the absolute value of a number. 
+This function can only be used if you imported the math module.[/!]</p>
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/Close10.java b/src/lessons/welcome/bat/bool1/Close10.java
new file mode 100644
index 0000000..637258b
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Close10.java
@@ -0,0 +1,62 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class Close10 extends BatExercise {
+
+	public Close10(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("close10");
+
+		myWorld.addTest(VISIBLE,  8,13);
+		myWorld.addTest(VISIBLE,  13,8);
+		myWorld.addTest(VISIBLE,  13,7);
+
+		myWorld.addTest(INVISIBLE, 7,13);
+		myWorld.addTest(INVISIBLE, 5,21);
+		myWorld.addTest(INVISIBLE, 0,20);
+		myWorld.addTest(INVISIBLE, 10,10);
+
+		templatePython("close10", 
+				"import math\ndef close10(a, b):\n",
+				"   if math.fabs(10-a) == math.fabs(10-b):\n"+
+				"      return 0\n"+
+				"   elif math.fabs(10-a) < math.fabs(10-b):\n"+
+				"      return a\n"+
+				"   else:\n"+
+				"      return b\n");
+		templateScala("close10",new String[] {"Int","Int"},
+				"def close10(a:Int, b:Int): Int = {\n",
+				"   if (Math.abs(10-a) == Math.abs(10-b))\n"+
+				"      return 0\n"+
+				"   else if (Math.abs(10-a) < Math.abs(10-b))\n"+
+				"      return a\n"+
+				"   else\n"+
+				"      return b\n"+
+				"}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult(close10((Integer)t.getParameter(0),(Integer)t.getParameter(1)));
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int close10(int a, int b) {
+		/* BEGIN SOLUTION */
+		if (Math.abs(a-10)==Math.abs(b-10))
+			return 0;
+		if (Math.abs(a-10)<Math.abs(b-10))
+			return a;
+		return b;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/CountTeen.fr.html b/src/lessons/welcome/bat/bool1/CountTeen.fr.html
new file mode 100644
index 0000000..16da16d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/CountTeen.fr.html
@@ -0,0 +1,4 @@
+<h1>Compter les ados</h1>
+<p>On dira qu'un nombre est "ado" s'il appartient est entre 13 et 19
+(inclus). Étant donné quatre nombres entiers, retournez combien d'entre eux
+sont ados.</p>
diff --git a/src/lessons/welcome/bool1/CountTeen.html b/src/lessons/welcome/bat/bool1/CountTeen.html
similarity index 100%
rename from src/lessons/welcome/bool1/CountTeen.html
rename to src/lessons/welcome/bat/bool1/CountTeen.html
diff --git a/src/lessons/welcome/bat/bool1/CountTeen.java b/src/lessons/welcome/bat/bool1/CountTeen.java
new file mode 100644
index 0000000..ea61028
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/CountTeen.java
@@ -0,0 +1,79 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class CountTeen extends BatExercise {
+
+	public CountTeen(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("countTeen");
+		myWorld.addTest(VISIBLE,  13,20,10,54);
+		myWorld.addTest(VISIBLE,  20,19,13,15);
+		myWorld.addTest(VISIBLE,  20,10,13,42);
+
+		myWorld.addTest(INVISIBLE, 1,20,12,54);
+		myWorld.addTest(INVISIBLE, 19,20,42,12);
+		myWorld.addTest(INVISIBLE, 12,16,20,19);
+		myWorld.addTest(INVISIBLE, 42,12,9,20);
+		myWorld.addTest(INVISIBLE, 12,18,19,14);
+		myWorld.addTest(INVISIBLE, 14,2,20,99);
+		myWorld.addTest(INVISIBLE, 4,11,2,20);
+		myWorld.addTest(INVISIBLE, 11,11,11,11);
+		myWorld.addTest(INVISIBLE, 15,15,15,15);
+
+		templatePython("countTeen", 
+				"def countTeen(a, b, c, d):\n",
+				"		ret=0\n"+
+				"		if (a>12 and a<20):\n"+
+				"			ret+=1\n"+
+				"		if (b>12 and b<20):\n"+
+				"			ret+=1\n"+
+				"		if (c>12 and c<20):\n"+
+				"			ret+=1\n"+
+				"		if (d>12 and d<20):\n"+
+				"			ret+=1\n"+
+				"		return ret\n");
+		templateScala("countTeen", new String[] {"Integer","Integer","Integer","Integer"}, 
+			"def countTeen(a:Int, b:Int,c:Int,d:Int): Int = {\n",
+			  "  var ret=0;\n"
+			+ "  if (a>12&&a<20)\n"
+			+ "	   ret+=1;\n"
+			+ "  if (b>12&&b<20)\n"
+			+ "	   ret+=1;\n"
+			+ "  if (c>12&&c<20)\n"
+			+ "	   ret+=1;\n"
+			+ "  if (d>12&&d<20)\n"
+			+ "	   ret+=1;\n"
+			+ "  return ret\n"
+			+ "}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( countTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Integer)t.getParameter(2),(Integer)t.getParameter(3)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int countTeen(int a, int b, int c,int d) {
+		/* BEGIN SOLUTION */
+		int ret=0;
+		if (a>12&&a<20)
+			ret+=1;
+		if (b>12&&b<20)
+			ret+=1;
+		if (c>12&&c<20)
+			ret+=1;
+		if (d>12&&d<20)
+			ret+=1;
+		return ret; 
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/Diff21.fr.html b/src/lessons/welcome/bat/bool1/Diff21.fr.html
new file mode 100644
index 0000000..49ef18d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Diff21.fr.html
@@ -0,0 +1,6 @@
+<h1>Diff 21</h1>
+Étant donné un entier n, retournez la différence absolue entre n et 21, sauf
+si n est plus grand que 21. Dans ce cas, doublez la différence absolue. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/Diff21.html b/src/lessons/welcome/bat/bool1/Diff21.html
new file mode 100644
index 0000000..a65f885
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Diff21.html
@@ -0,0 +1,5 @@
+<h1>Diff 21</h1>
+Given an int n, return the absolute difference between n and 21,
+except return double the absolute difference if n is over 21. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/Diff21.java b/src/lessons/welcome/bat/bool1/Diff21.java
new file mode 100644
index 0000000..5f42e92
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Diff21.java
@@ -0,0 +1,57 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class Diff21 extends BatExercise {
+
+	public Diff21(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("diff21");
+		myWorld.addTest(VISIBLE,  2);
+		myWorld.addTest(VISIBLE,  11);
+		myWorld.addTest(VISIBLE,  0);
+
+		myWorld.addTest(INVISIBLE, 19);
+		myWorld.addTest(INVISIBLE, 10);
+		myWorld.addTest(INVISIBLE, 21);
+		myWorld.addTest(INVISIBLE, 22);
+		myWorld.addTest(INVISIBLE, 25);
+		myWorld.addTest(INVISIBLE, 30);
+		myWorld.addTest(INVISIBLE, -21);
+
+		templatePython("diff21", 
+				"def diff21(n):\n",
+				"   if (n>21):\n"+
+				"      return 2*(n-21)\n"+
+				"   return 21-n\n");
+		templateScala("diff21", new String[] {"Integer"}, 
+				"def diff21(n:Int): Int = {\n",
+				"  if (n>21)\n"
+			  + "    return 2*(n-21)\n"
+			  + "  return 21-n\n"
+			  + "}");
+
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( diff21((Integer)t.getParameter(0)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int diff21(int n) {
+		/* BEGIN SOLUTION */
+		if (n>21)
+			return 2*(n-21);
+		return 21-n;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/HasTeen.fr.html b/src/lessons/welcome/bat/bool1/HasTeen.fr.html
new file mode 100644
index 0000000..189109f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/HasTeen.fr.html
@@ -0,0 +1,7 @@
+<h1>A des ados</h1>
+On dira qu'un nombre est "ado" s'il appartient à l'intervale [13;19]. Étant
+donné trois nombres entiers, retournez vrai ssi un ou plusieurs d'entre eux
+sont ados. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/HasTeen.html b/src/lessons/welcome/bat/bool1/HasTeen.html
new file mode 100644
index 0000000..83f6d9a
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/HasTeen.html
@@ -0,0 +1,6 @@
+<h1>Has Teen</h1>
+We'll say that a number is "teen" if it is in the range 13..19
+inclusive. Given 3 int values, return true if 1 or more of them are
+teen. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/HasTeen.java b/src/lessons/welcome/bat/bool1/HasTeen.java
new file mode 100644
index 0000000..0cffbaf
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/HasTeen.java
@@ -0,0 +1,53 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class HasTeen extends BatExercise {
+
+	public HasTeen(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("hasTeen");
+		myWorld.addTest(VISIBLE,  13,20,10);		
+		myWorld.addTest(VISIBLE,  20,19,10);
+		myWorld.addTest(VISIBLE,  20,10,13);
+
+		myWorld.addTest(INVISIBLE, 1,20,12);
+		myWorld.addTest(INVISIBLE, 19,20,12);
+		myWorld.addTest(INVISIBLE, 12,20,19);
+		myWorld.addTest(INVISIBLE, 12,9,20);
+		myWorld.addTest(INVISIBLE, 12,18,20);
+		myWorld.addTest(INVISIBLE, 14,2,20);
+		myWorld.addTest(INVISIBLE, 4,2,20);
+		myWorld.addTest(INVISIBLE, 11,22,22);
+
+
+		templatePython("hasTeen", 
+				"def hasTeen(a, b, c):\n",
+				"   return (a>12 and a<20) or (b>12 and b<20) or (c>12 and c<20)\n");
+		templateScala("hasTeen", new String[] {"Int","Int","Int"}, 
+				"def hasTeen(a:Int, b:Int, c:Int): Boolean = {\n",
+				"   return (a>12 && a<20) || (b>12 && b<20) || (c>12 && c<20)\n"
+		  	  + "}");
+
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( hasTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Integer)t.getParameter(2)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean hasTeen(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		return a>12&&a<20 || b>12&&b<20 || c>12&&c<20;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/IcyHot.fr.html b/src/lessons/welcome/bat/bool1/IcyHot.fr.html
new file mode 100644
index 0000000..b9b1045
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/IcyHot.fr.html
@@ -0,0 +1,6 @@
+<h1>Feu glacé</h1>
+Étant donné deux températures, retournez vrai si l'une est inférieure à zéro
+et l'autre supérieure à 100. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/IcyHot.html b/src/lessons/welcome/bat/bool1/IcyHot.html
new file mode 100644
index 0000000..9db018b
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/IcyHot.html
@@ -0,0 +1,5 @@
+<h1>Icy Hot</h1>
+Given two temperatures, return true if one is less than 0 and the
+other is greater than 100. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/IcyHot.java b/src/lessons/welcome/bat/bool1/IcyHot.java
new file mode 100644
index 0000000..41b7a24
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/IcyHot.java
@@ -0,0 +1,47 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class IcyHot extends BatExercise {
+
+	public IcyHot(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("icyHot");
+		myWorld.addTest(VISIBLE, 120,-1);
+		myWorld.addTest(VISIBLE, -1,120);
+		myWorld.addTest(VISIBLE, 2,120);
+
+		myWorld.addTest(INVISIBLE, -1,100);
+		myWorld.addTest(INVISIBLE, -2,-2);
+		myWorld.addTest(INVISIBLE, 120,120);
+
+		templatePython("icyHot", 
+				"def icyHot(temp1, temp2):\n",
+				"   return temp1<0 and temp2>100 or temp1>100 and temp2<0\n");
+		templateScala("icyHot",new String[]{"Int","Int"}, 
+				"def icyHot(temp1:Int, temp2:Int):Boolean = {\n",
+				"   return temp1<0 && temp2>100 || temp1>100 && temp2<0\n"+
+				"}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( icyHot((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean icyHot(int temp1, int temp2) {
+
+		/* BEGIN SOLUTION */
+		return temp1<0&&temp2>100 || temp1>100&&temp2<0;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/In1020.fr.html b/src/lessons/welcome/bat/bool1/In1020.fr.html
new file mode 100644
index 0000000..846bacf
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In1020.fr.html
@@ -0,0 +1,6 @@
+<h1>Dans [10;20]</h1>
+Étant donné deux nombres entiers, retournez vrai s'un d'entre eux est dans
+l'intervale [10;20]. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/In1020.html b/src/lessons/welcome/bat/bool1/In1020.html
new file mode 100644
index 0000000..ba98f46
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In1020.html
@@ -0,0 +1,5 @@
+<h1>In [10;20]</h1>
+Given 2 int values, return true if either of them is in the range
+10..20 inclusive. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/In1020.java b/src/lessons/welcome/bat/bool1/In1020.java
new file mode 100644
index 0000000..ce3c27e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In1020.java
@@ -0,0 +1,50 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class In1020 extends BatExercise {
+
+	public In1020(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("in1020");
+		myWorld.addTest(VISIBLE,  12,99);
+		myWorld.addTest(VISIBLE,  21,12);
+		myWorld.addTest(VISIBLE,  8,99);
+
+		myWorld.addTest(INVISIBLE, 99,10);
+		myWorld.addTest(INVISIBLE, 20,20);
+		myWorld.addTest(INVISIBLE, 21,21);
+		myWorld.addTest(INVISIBLE, 9,9);
+		myWorld.addTest(INVISIBLE, 10,42);
+		myWorld.addTest(INVISIBLE, 12,-2);
+
+		templatePython("in1020", 
+				"def in1020(a, b):\n",
+				"   return (a>9 and a<21) or (b>9 and b<21)");
+		templateScala("in1020", new String[] {"Int","Int"},
+				"def in1020(a:Int, b:Int):Boolean = {\n",
+				"   return (a>9 && a<21) || (b>9 && b<21)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+
+	@Override
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( in1020((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean in1020(int a, int b) {
+		/* BEGIN SOLUTION */
+		return a>9&&a<21 || b>9&&b<21;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/In3050.fr.html b/src/lessons/welcome/bat/bool1/In3050.fr.html
new file mode 100644
index 0000000..e5f5791
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In3050.fr.html
@@ -0,0 +1,7 @@
+<h1>Dans [30;50]</h1>
+Étant donné deux nombres entiers, retournez vrai s'ils sont tous les deux
+dans l'intervale [30;40], ou s'ils sont tous les deux dans l'intervale
+[40;50]. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/In3050.html b/src/lessons/welcome/bat/bool1/In3050.html
new file mode 100644
index 0000000..64ed407
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In3050.html
@@ -0,0 +1,5 @@
+<h1>In [30;50]</h1>
+Given 2 int values, return true if they are both in the range 30..40
+inclusive, or they are both in the range 40..50 inclusive. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/In3050.java b/src/lessons/welcome/bat/bool1/In3050.java
new file mode 100644
index 0000000..a918520
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/In3050.java
@@ -0,0 +1,53 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class In3050 extends BatExercise {
+
+	public In3050(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("in3050");
+		myWorld.addTest(VISIBLE,  30,31);
+		myWorld.addTest(VISIBLE,  30,41);
+		myWorld.addTest(VISIBLE,  40,50);
+
+		myWorld.addTest(INVISIBLE, 40,51);
+		myWorld.addTest(INVISIBLE, 39,50);
+		myWorld.addTest(INVISIBLE, 50,39);
+		myWorld.addTest(INVISIBLE, 40,39);
+		myWorld.addTest(INVISIBLE, 49,48);
+		myWorld.addTest(INVISIBLE, 50,40);
+		myWorld.addTest(INVISIBLE, 50,51);
+		myWorld.addTest(INVISIBLE, 35,36);
+		myWorld.addTest(INVISIBLE, 35,45);
+
+
+		templatePython("in3050", 
+				"def in3050(a, b):\n",
+				"   return (a>29 and a<41 and b>29 and b<41) or (a>39 and a<51 and b>39 and b<51)\n");
+		templateScala("in3050", new String[] {"Int","Int"},
+				"def in3050(a:Int, b:Int):Boolean = {\n",
+				"   return (a>29 && a<41 && b>29 && b<41) || (a>39 && a<51 && b>39 && b<51)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( in3050((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean in3050(int a, int b) {
+		/* BEGIN SOLUTION */
+		return (a>29&&a<41 && b>29&&b<41) || (a>39&&a<51 && b>39&&b<51);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/LastDigit.fr.html b/src/lessons/welcome/bat/bool1/LastDigit.fr.html
new file mode 100644
index 0000000..94e552f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LastDigit.fr.html
@@ -0,0 +1,9 @@
+<h1>Dernier chiffre</h1>
+Étant donné deux nombres entiers positifs, retournez vrai s'ils ont le même
+dernier chiffre, comme 27 et 57. Remarquez que l'opérateur % (modulo)
+calcule le reste de la division entière (donc 17 % 10 vaut 7).
+
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/LastDigit.html b/src/lessons/welcome/bat/bool1/LastDigit.html
new file mode 100644
index 0000000..9d05d04
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LastDigit.html
@@ -0,0 +1,9 @@
+<h1>LastDigit</h1>
+Given two
+non-negative int values, return true if they have the same last digit,
+such as with 27 and 57. Note that the % "mod" operator computes
+remainders, so 17 % 10 is 7.
+
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/LastDigit.java b/src/lessons/welcome/bat/bool1/LastDigit.java
new file mode 100644
index 0000000..e1a7c8d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LastDigit.java
@@ -0,0 +1,44 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class LastDigit extends BatExercise {
+	public LastDigit(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("lastDigit");
+		myWorld.addTest(VISIBLE, 7, 17) ;
+		myWorld.addTest(VISIBLE, 6, 17) ;
+		myWorld.addTest(VISIBLE, 3, 113) ;
+		myWorld.addTest(INVISIBLE, 114, 113) ;
+		myWorld.addTest(INVISIBLE, 114, 4) ;
+		myWorld.addTest(INVISIBLE, 10, 0) ;
+		myWorld.addTest(INVISIBLE, 11, 0) ;
+
+		templatePython("lastDigit", 
+				"def lastDigit(a, b):\n",
+				"   return a%10 == b%10\n");
+		templateScala("lastDigit", new String[] {"Int", "Int"},
+				"def lastDigit(a:Int, b:Int):Boolean = {\n",
+				"   return a%10 == b%10\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( lastDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean lastDigit(int a, int b) {
+		/* BEGIN SOLUTION */
+		return a%10 == b%10;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/LoneTeen.fr.html b/src/lessons/welcome/bat/bool1/LoneTeen.fr.html
new file mode 100644
index 0000000..8eec9aa
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LoneTeen.fr.html
@@ -0,0 +1,7 @@
+<h1>Ado solitaire</h1>
+On dira qu'un nombre est "ado" s'il appartient à l'intervale [13;19]. Étant
+donné deux nombres entiers, retournez vrai si l'un d'entre eux est ado, mais
+pas les deux. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/LoneTeen.html b/src/lessons/welcome/bat/bool1/LoneTeen.html
new file mode 100644
index 0000000..bb74ed1
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LoneTeen.html
@@ -0,0 +1,6 @@
+<h1>Lone Teen</h1>
+We'll say that a number is "teen" if it is in the range 13..19
+inclusive. Given 2 int values, return true if one or the other is
+teen, but not both. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/LoneTeen.java b/src/lessons/welcome/bat/bool1/LoneTeen.java
new file mode 100644
index 0000000..28d833c
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/LoneTeen.java
@@ -0,0 +1,59 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class LoneTeen extends BatExercise {
+
+	public LoneTeen(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("loneTeen");
+		myWorld.addTest(VISIBLE,  13,42);
+		myWorld.addTest(VISIBLE,  21,19);
+		myWorld.addTest(VISIBLE,  13,13);
+
+		myWorld.addTest(INVISIBLE, 14,20);
+		myWorld.addTest(INVISIBLE, 20,15);
+		myWorld.addTest(INVISIBLE, 16,17);
+		myWorld.addTest(INVISIBLE, 16,9);
+		myWorld.addTest(INVISIBLE, 16,18);
+		myWorld.addTest(INVISIBLE, 13,19);
+		myWorld.addTest(INVISIBLE, 13,20);
+		myWorld.addTest(INVISIBLE, 6,18);
+		myWorld.addTest(INVISIBLE, 42,13);
+		myWorld.addTest(INVISIBLE, 42,42);
+
+		templatePython("loneTeen", 
+				"def loneTeen(a, b):\n",
+				"	teenA = a>12 and a<20\n"+
+				"	teenB = b>12 and b<20\n"+
+				"	return  (teenA and not teenB) or (teenB and not teenA)\n");
+		templateScala("loneTeen",new String[] {"Int","Int"}, 
+				"def loneTeen(a:Int, b:Int):Boolean = {\n",
+				"	val teenA = a>12 && a<20\n"+
+				"	val teenB = b>12 && b<20\n"+
+				"	return  (teenA && !teenB) || (teenB && !teenA)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( loneTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean loneTeen(int a, int b) {
+		/* BEGIN SOLUTION */
+		boolean teenA = a>12&&a<20;
+		boolean teenB = b>12&&b<20;
+		return  (teenA&&!teenB) || (teenB&&!teenA);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/Main.fr.html b/src/lessons/welcome/bat/bool1/Main.fr.html
new file mode 100644
index 0000000..d404670
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Main.fr.html
@@ -0,0 +1,12 @@
+<h1>Jeux booléens</h1>
+
+<p>Les opérations booléennes sont l'une des fondements de la
+programmation. Tant que vous ne pourrez pas écrire des tests booléens (même
+non triviaux) en moins d'une minute, il vous sera difficile d'écrire un vrai
+programme.</p>
+   
+<p>C'est pourquoi cette leçon vous propose une certaine quantité de tels
+exercices pour vous permettre de vous entrainer.</p>
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/Main.html b/src/lessons/welcome/bat/bool1/Main.html
new file mode 100644
index 0000000..32a725f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Main.html
@@ -0,0 +1,11 @@
+<h1>Boolean fun</h1>
+
+<p>Boolean operations are one of the very basic task in programming.
+   As long as you cannot write a not so simple boolean test under the
+   minute, you probably will have a very bad time writing a real
+   program.</p>
+   
+<p>That is why this lesson provides you a bunch of such exercises, so
+   that you can get trained in this.</p>
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/Makes10.fr.html b/src/lessons/welcome/bat/bool1/Makes10.fr.html
new file mode 100644
index 0000000..cf0d6cc
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Makes10.fr.html
@@ -0,0 +1,6 @@
+<h1>Font 10</h1>
+Étant donné deux nombres entiers, retournez vrai si l'un d'entre eux vaut
+10, ou si leur somme vaut 10. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/Makes10.html b/src/lessons/welcome/bat/bool1/Makes10.html
new file mode 100644
index 0000000..ccc77c1
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Makes10.html
@@ -0,0 +1,5 @@
+<h1>Makes 10</h1>
+Given 2 ints, a and b, return true if one if them is 10 or if their
+sum is 10. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/Makes10.java b/src/lessons/welcome/bat/bool1/Makes10.java
new file mode 100644
index 0000000..9ae6bcb
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Makes10.java
@@ -0,0 +1,49 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class Makes10 extends BatExercise {
+
+	public Makes10(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("makes10");
+		myWorld.addTest(VISIBLE,  9,10);
+		myWorld.addTest(VISIBLE,  9,9);
+		myWorld.addTest(VISIBLE,  1,9);
+
+		myWorld.addTest(INVISIBLE, 10,1);
+		myWorld.addTest(INVISIBLE, 10,10);
+		myWorld.addTest(INVISIBLE, 8,2);
+		myWorld.addTest(INVISIBLE, 8,3);
+		myWorld.addTest(INVISIBLE, 10,42);
+		myWorld.addTest(INVISIBLE, 12,-2);
+
+		templatePython("makes10", 
+				"def makes10(a, b):\n",
+				"   return a==10 or b==10 or (a+b)==10");
+		templateScala("makes10",new String[]{"Int","Int"},
+				"def makes10(a:Int, b:Int):Boolean = {\n",
+				"   return (a==10) || (b==10) || ((a+b)==10)\n"
+			  + "}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( makes10((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean makes10(int a, int b) {
+		/* BEGIN SOLUTION */
+		return a==10||b==10||(a+b)==10;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/Max1020.fr.html b/src/lessons/welcome/bat/bool1/Max1020.fr.html
new file mode 100644
index 0000000..542f7f6
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Max1020.fr.html
@@ -0,0 +1,10 @@
+<h1>Max1020</h1>
+<p>Étant donné deux nombres entiers, retournez la plus grande valeur dans
+l'intervale 10..20 inclus, ou retournez 0 si aucun des nombres n'est dans
+cet intervale.</p>
+
+[!scala]<p>Notez que Math.max(Int,Int):Int et Math.min(Int,Int):Int retournent
+respectivement le maximum et le minimum de deux entiers.</p>[/!] 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/Max1020.html b/src/lessons/welcome/bat/bool1/Max1020.html
new file mode 100644
index 0000000..d4b6096
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Max1020.html
@@ -0,0 +1,7 @@
+<h1>Max1020</h1>
+<p>Given 2 positive int values, return the larger value that is in the
+range 10..20 inclusive, or return 0 if neither is in that range.</p>
+
+[!scala]<p>Note that Math.max(Int,Int):Int and Math.min(Int,Int):Int return the maximum and minimum of two integers</p>[/!] 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/Max1020.java b/src/lessons/welcome/bat/bool1/Max1020.java
new file mode 100644
index 0000000..4bd680d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/Max1020.java
@@ -0,0 +1,65 @@
+package lessons.welcome.bat.bool1;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class Max1020 extends BatExercise {
+	public Max1020(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("max1020");
+		myWorld.addTest(VISIBLE, 11, 19) ;
+		myWorld.addTest(VISIBLE, 19, 11) ;
+		myWorld.addTest(VISIBLE, 11, 9) ;
+		myWorld.addTest(INVISIBLE, 9, 21) ;
+		myWorld.addTest(INVISIBLE, 10, 21) ;
+		myWorld.addTest(INVISIBLE, 21, 10) ;
+		myWorld.addTest(INVISIBLE, 9, 11) ;
+		myWorld.addTest(INVISIBLE, 23, 10) ;
+		myWorld.addTest(INVISIBLE, 20, 10) ;
+		myWorld.addTest(INVISIBLE, 7, 20) ;
+		myWorld.addTest(INVISIBLE, 17, 16) ;
+
+		templatePython("max1020", 
+				"def max1020(a, b):\n",
+				"	A = max(a,b)\n"+
+				"	B = min(a,b)\n"+
+				"	if (A<21 and A>9):\n"+
+				"		return A\n"+
+				"	if (B<21 and B>9):\n"+
+				"		return B\n"+
+				"	return 0\n");
+		templateScala("max1020",new String[] {"Int","Int"}, 
+				"def max1020(a:Int, b:Int):Int = {\n",
+				"	val A = Math.max(a,b)\n"+
+				"	val B = Math.min(a,b)\n"+
+				"	if (A<21 && A>9)\n"+
+				"		return A\n"+
+				"	if (B<21 && B>9)\n"+
+				"		return B\n"+
+				"	return 0\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( max1020((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int max1020(int a, int b) {
+		/* BEGIN SOLUTION */
+		int A = a>b?a:b;
+		int B = a>b?b:a;
+		if (A<21 && A>9)
+			return A;
+		if (B<21 && B>9)
+			return B;
+		return 0;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/MonkeyTrouble.fr.html b/src/lessons/welcome/bat/bool1/MonkeyTrouble.fr.html
new file mode 100644
index 0000000..8b173c3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/MonkeyTrouble.fr.html
@@ -0,0 +1,9 @@
+<h1>Problème de singe</h1>
+
+Nous avons deux singes, a et b, et les paramètres aSmile et bSmile indiquent
+s'ils sourient. Nous avons un problème s'ils sourient tous les deux en même
+temps, ou si aucun des deux ne sourit. Retournez vrai si nous avons un
+problème. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/MonkeyTrouble.html b/src/lessons/welcome/bat/bool1/MonkeyTrouble.html
new file mode 100644
index 0000000..ebe38b8
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/MonkeyTrouble.html
@@ -0,0 +1,7 @@
+<h1>MonkeyTrouble</h1>
+
+We have two monkeys, a and b, and the parameters aSmile and bSmile indicate if each is smiling. 
+We are in trouble if they are both smiling or if neither of them is smiling. 
+Return true if we are in trouble. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/MonkeyTrouble.java b/src/lessons/welcome/bat/bool1/MonkeyTrouble.java
new file mode 100644
index 0000000..9ef4aa0
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/MonkeyTrouble.java
@@ -0,0 +1,52 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class MonkeyTrouble extends BatExercise {
+
+	public MonkeyTrouble(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("monkeyTrouble");
+		myWorld.addTest(VISIBLE, true, true);
+		myWorld.addTest(VISIBLE, false, false);
+		myWorld.addTest(VISIBLE, true, false);
+		myWorld.addTest(INVISIBLE, false, true);
+
+		templatePython("monkeyTrouble", 
+				"def monkeyTrouble(aSmile, bSmile):\n",
+				"   return (aSmile and bSmile) or (not aSmile and not bSmile)\n");
+		templateScala("monkeyTrouble", new String[] {"Boolean","Boolean"}, 
+				"def monkeyTrouble(aSmile:Boolean, bSmile:Boolean): Boolean = {\n",
+				"   return ((aSmile && bSmile) || (!aSmile && !bSmile))\n"
+		  	  + "}");
+
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( monkeyTrouble((Boolean)t.getParameter(0),(Boolean)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	public boolean monkeyTrouble(boolean aSmile, boolean bSmile) {
+		/* BEGIN SOLUTION */
+		if (aSmile && bSmile) {
+			return true;
+		}
+		if (!aSmile && !bSmile) {
+			return true;
+		}
+		return false;
+		// This all can be shortened to just:
+		// return ((aSmile && bSmile) || (!aSmile && !bSmile));
+		/* END SOLUTION */		  
+	}	
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/NearHundred.fr.html b/src/lessons/welcome/bat/bool1/NearHundred.fr.html
new file mode 100644
index 0000000..9b363cf
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/NearHundred.fr.html
@@ -0,0 +1,11 @@
+<h1>Presque 100</h1>
+<p>Étant donné deux nombres entiers, retourner la valeur la plus proche de 10,
+ou 0 en cas de match nul.
+[!java|scala]Remarquez que Math.abs(n) retourne la valeur absolue d'un
+nombre.[/!]
+[!python]Remarquez que math.fabs(n) retourne la valeur absolue d'un
+nombre. Remarquez également que vous ne pouvez utiliser cette fonction que
+si vous avez importé le module math.[/!]</p>
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/NearHundred.html b/src/lessons/welcome/bat/bool1/NearHundred.html
new file mode 100644
index 0000000..152aa0d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/NearHundred.html
@@ -0,0 +1,7 @@
+<h1>Near Hundred</h1>
+<p>Given an int n, return true if it is within 10 of 100 or 200.
+[!java|scala]Note that Math.abs(n) returns the absolute value of a number.[/!]
+[!python]Note that math.fabs(n) returns the absolute value of a number. 
+This function can only be used if you imported the math module.[/!]</p>
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/NearHundred.java b/src/lessons/welcome/bat/bool1/NearHundred.java
new file mode 100644
index 0000000..d53ecc8
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/NearHundred.java
@@ -0,0 +1,51 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class NearHundred extends BatExercise {
+
+	public NearHundred(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("nearHundred");
+		myWorld.addTest(VISIBLE, 93);
+		myWorld.addTest(VISIBLE, 90);
+		myWorld.addTest(VISIBLE, 89);
+
+		myWorld.addTest(INVISIBLE, 110);
+		myWorld.addTest(INVISIBLE, 191);
+		myWorld.addTest(INVISIBLE, 189);
+		myWorld.addTest(INVISIBLE, 200);
+		myWorld.addTest(INVISIBLE, 210);
+		myWorld.addTest(INVISIBLE, 211);
+		myWorld.addTest(INVISIBLE, -100);
+
+		templatePython("nearHundred", 
+				"def nearHundred(n):\n",
+				"   return (90<=n and n<=110) or (190<=n and n<=210)\n");
+		templateScala("nearHundred",new String[]{"Int"},
+				"def nearHundred(n:Int): Boolean = {\n",
+				"  return (90<=n && n<=110)||(190<=n&&n<=210);\n"
+			  + "}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( nearHundred((Integer)t.getParameter(0)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean nearHundred(int n) {
+
+		/* BEGIN SOLUTION */
+		return (90<=n && n<=110)||(190<=n&&n<=210);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/ParotTrouble.fr.html b/src/lessons/welcome/bat/bool1/ParotTrouble.fr.html
new file mode 100644
index 0000000..6bc1311
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/ParotTrouble.fr.html
@@ -0,0 +1,8 @@
+<h1>Problème de perroquet</h1>
+
+Nous avons un perroquet très bruyant. Le paramètre "hour" indique l'heure
+courante (dans l'intervale [0;23]). Nous avons un problème si le perroquet
+parle avant 7h ou après 20h. Retournez vrai si nous avons un problème. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/ParotTrouble.html b/src/lessons/welcome/bat/bool1/ParotTrouble.html
new file mode 100644
index 0000000..1fc0dc3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/ParotTrouble.html
@@ -0,0 +1,8 @@
+<h1>Parot Trouble</h1>
+
+We have a loud talking parrot. The "hour" parameter is the current
+hour time in the range 0..23. We are in trouble if the parrot is
+talking and the hour is before 7 or after 20. Return true if we are in
+trouble. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/ParotTrouble.java b/src/lessons/welcome/bat/bool1/ParotTrouble.java
new file mode 100644
index 0000000..583956d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/ParotTrouble.java
@@ -0,0 +1,49 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class ParotTrouble extends BatExercise {
+
+	public ParotTrouble(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("parotTrouble");
+		myWorld.addTest(VISIBLE,  true,6);
+		myWorld.addTest(VISIBLE,  true,7);
+		myWorld.addTest(VISIBLE,  false,6);
+
+		myWorld.addTest(INVISIBLE, true,21);
+		myWorld.addTest(INVISIBLE, false,21);
+		myWorld.addTest(INVISIBLE, true,23);
+		myWorld.addTest(INVISIBLE, false,23);
+		myWorld.addTest(INVISIBLE, true,20);
+
+
+		templatePython("parotTrouble", 
+				"def parotTrouble(talking, hour):\n",
+				"   return (talking and (hour<7 or hour>20))\n");
+		templateScala("parotTrouble", new String[] {"Boolean","Int"},
+				"def parotTrouble(talking:Boolean, hour:Int):Boolean = {\n",
+				"  return (talking && (hour<7||hour>20))\n"
+			  + "}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( parotTrouble((Boolean)t.getParameter(0),(Integer)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean parotTrouble(boolean talking, int hour) {
+		/* BEGIN SOLUTION */
+		return (talking && (hour<7||hour>20));	
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/PosNeg.fr.html b/src/lessons/welcome/bat/bool1/PosNeg.fr.html
new file mode 100644
index 0000000..ce40177
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/PosNeg.fr.html
@@ -0,0 +1,7 @@
+<h1>Positif Negatif</h1>
+Étant donné deux entiers, retournez vrai si l'un d'entre eux est positif et
+l'autre négatif. Sauf si le paramètre negative est vrai, auquel cas il faut
+que les deux nombres soient négatifs. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/PosNeg.html b/src/lessons/welcome/bat/bool1/PosNeg.html
new file mode 100644
index 0000000..fb26fec
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/PosNeg.html
@@ -0,0 +1,5 @@
+<h1>Positive Negative</h1>
+Given 2 int values, return true if one is negative and one is
+positive. Unless negative is true, then they both must be negative. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/PosNeg.java b/src/lessons/welcome/bat/bool1/PosNeg.java
new file mode 100644
index 0000000..dc4885f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/PosNeg.java
@@ -0,0 +1,60 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class PosNeg extends BatExercise {
+
+	public PosNeg(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("posNeg");
+		myWorld.addTest(VISIBLE, -1,1,false);
+		myWorld.addTest(VISIBLE, 1,-1,false);
+		myWorld.addTest(VISIBLE, 1,1,false);
+
+		myWorld.addTest(INVISIBLE, -1,-1,false);
+		myWorld.addTest(INVISIBLE, 1,-1,true);
+		myWorld.addTest(INVISIBLE, -1,1,true);
+		myWorld.addTest(INVISIBLE, 1,1,true);
+		myWorld.addTest(INVISIBLE, -1,-1,true);
+		myWorld.addTest(INVISIBLE, 5,-5,true);
+		myWorld.addTest(INVISIBLE, -6,6,false);
+		myWorld.addTest(INVISIBLE, -5,-5,false);
+		myWorld.addTest(INVISIBLE, -5,5,true);
+		myWorld.addTest(INVISIBLE, -5,-5,true);
+
+		templatePython("posNeg", 
+				"def posNeg(a, b, negative):\n",
+				"		if (negative):\n"+
+				"			return a<0 and b<0;\n"+
+				"		return (a<0 and b>0) or (a>0 and b<0)");
+		templateScala("posNeg", new String[] { "Int","Int","Boolean"},
+				"def posNeg(a:Int, b:Int, negative:Boolean):Boolean = {\n",
+				"	if (negative)\n"
+			  + "      return a<0&&b<0;\n"
+			  + "	return (a<0&&b>0) || (a>0&&b<0);\n"
+			  + "}");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( posNeg((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Boolean)t.getParameter(2)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean posNeg(int a,int b,boolean negative) {
+
+		/* BEGIN SOLUTION */
+		if (negative)
+			return a<0&&b<0;
+		return (a<0&&b>0) || (a>0&&b<0);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/SleepIn.fr.html b/src/lessons/welcome/bat/bool1/SleepIn.fr.html
new file mode 100644
index 0000000..6f98c4d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SleepIn.fr.html
@@ -0,0 +1,9 @@
+<h1>Grasse matinée</h1>
+
+Le paramètre weekday est vrai si nous sommes un jour de semaine, et le
+paramètre vacation est vrai si nous sommes en vacances. Nous pouvons dormir
+ce matin s'il ne s'agit pas d'un jour de semaine ou si nous sommes en
+vacances. Retournez vrai si nous pouvons faire la grasse matinée. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/SleepIn.html b/src/lessons/welcome/bat/bool1/SleepIn.html
new file mode 100644
index 0000000..3f34a01
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SleepIn.html
@@ -0,0 +1,7 @@
+<h1>SleepDay</h1>
+
+The parameter weekday is true if it is a weekday, and the parameter
+vacation is true if we are on vacation. We sleep in if it is not a
+weekday or we're on vacation. Return true if we sleep in. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/SleepIn.java b/src/lessons/welcome/bat/bool1/SleepIn.java
new file mode 100644
index 0000000..c854610
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SleepIn.java
@@ -0,0 +1,43 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class SleepIn extends BatExercise {
+
+	public SleepIn(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("sleepIn");
+		myWorld.addTest(VISIBLE,  false,false);
+		myWorld.addTest(VISIBLE,  true,false);
+		myWorld.addTest(INVISIBLE, false,true);
+		myWorld.addTest(INVISIBLE, true,true);
+
+		templatePython("sleepIn", 
+				"def sleepIn(weekday, vacation):\n",
+				"    return not weekday or vacation\n");
+		templateScala("sleepIn", new String[] {"Boolean","Boolean"},
+				"def sleepIn(weekday:Boolean, vacation:Boolean): Boolean = {\n",
+				"  return !weekday || vacation;\n"
+				+ "}\n");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( sleepIn((Boolean)t.getParameter(0),(Boolean)t.getParameter(1)) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean sleepIn(boolean weekday, boolean vacation) {
+		/* BEGIN SOLUTION */
+		return !weekday || vacation;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool1/SumDouble.fr.html b/src/lessons/welcome/bat/bool1/SumDouble.fr.html
new file mode 100644
index 0000000..08fe959
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SumDouble.fr.html
@@ -0,0 +1,6 @@
+<h1>Somme doublée</h1>
+Étant donné deux entiers, retournez leur somme. Sauf si les valeurs sont
+égales, auquel cas vous devez retourner le double de leur somme. 
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool1/SumDouble.html b/src/lessons/welcome/bat/bool1/SumDouble.html
new file mode 100644
index 0000000..e8add39
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SumDouble.html
@@ -0,0 +1,5 @@
+<h1>Sum Double</h1>
+Given two int values, return their sum. Unless the two values are the
+same, then return double their sum. 
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool1/SumDouble.java b/src/lessons/welcome/bat/bool1/SumDouble.java
new file mode 100644
index 0000000..c27909b
--- /dev/null
+++ b/src/lessons/welcome/bat/bool1/SumDouble.java
@@ -0,0 +1,55 @@
+package lessons.welcome.bat.bool1;
+
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class SumDouble extends BatExercise {
+
+	public SumDouble(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("sumDouble");
+		myWorld.addTest(VISIBLE,  1,2);
+		myWorld.addTest(VISIBLE,  3,2);
+		myWorld.addTest(VISIBLE,  2,2);
+
+		myWorld.addTest(INVISIBLE, -1,0);
+		myWorld.addTest(INVISIBLE, 0,0);
+		myWorld.addTest(INVISIBLE, 0,1);
+
+		templatePython("sumDouble", 
+				"def sumDouble(a, b):\n",
+				"  if a==b:\n"+
+				"    return (a+b)*2\n"+
+				"  return a+b\n");
+		
+		templateScala("sumDouble", new String[]{"Integer","Integer"}, 
+				"def sumDouble(a: Integer, b: Integer): Integer = {\n",
+				"  if (a==b) {\n"+
+				"    return (a+b)*2\n"+
+				"  }\n"+
+				"  return a+b\n"+
+				"}");
+			//"t.setResult( sumDouble( t.getParameter(0).asInstanceOf[Integer], t.getParameter(1).asInstanceOf[Integer] ) )");
+		setup(myWorld);
+	}
+
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( sumDouble( ((Integer)(t.getParameter(0))),((Integer)(t.getParameter(1)))) );		
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int sumDouble(int a, int b) {
+		/* BEGIN SOLUTION */
+		if (a==b)
+			return (a+b)*2;
+		return a+b;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/AlarmClock.fr.html b/src/lessons/welcome/bat/bool2/AlarmClock.fr.html
new file mode 100644
index 0000000..9258b05
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AlarmClock.fr.html
@@ -0,0 +1,13 @@
+<h1>Radio réveil</h1>
+Étant donné le jour de la semaine, codé de la façon suivante : 0=Dimanche,
+1=Lundi, 2=Mardi, ... 6=Samedi, et un booléen vacation indiquant si nous
+sommes en vacances, retournez une chaine de caractères de la forme "7:00"
+indiquant à quelle heure nous devons régler le radio-réveil. Les jours de la
+semaine, nous devons nous réveiller à 7h tandis que nous pouvons dormir
+jusqu'à 10h le week-end. Pendant les vacances, il nous faut nous lever à 10h
+la semaine tandis que le réglage pour le radio-réveil doit être "off" le
+week-end.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/AlarmClock.html b/src/lessons/welcome/bat/bool2/AlarmClock.html
new file mode 100644
index 0000000..b324897
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AlarmClock.html
@@ -0,0 +1,11 @@
+<h1>AlarmClock</h1>
+Given a day
+of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a boolean
+indicating if we are on vacation, return a string of the form "7:00"
+indicating when the alarm clock should ring. Weekdays, the alarm should
+be "7:00" and on the weekend it should be "10:00". Unless we are on
+vacation -- then on weekdays it should be "10:00" and weekends it
+should be "off".
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/AlarmClock.java b/src/lessons/welcome/bat/bool2/AlarmClock.java
new file mode 100644
index 0000000..1b0bf4e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AlarmClock.java
@@ -0,0 +1,79 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class AlarmClock extends BatExercise {
+	public AlarmClock(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("alarmClock");
+		myWorld.addTest(VISIBLE, 1, false) ;
+		myWorld.addTest(VISIBLE, 5, false) ;
+		myWorld.addTest(VISIBLE, 0, false) ;
+		myWorld.addTest(INVISIBLE, 6, false) ;
+		myWorld.addTest(INVISIBLE, 0, true) ;
+		myWorld.addTest(INVISIBLE, 6, true) ;
+		myWorld.addTest(INVISIBLE, 1, true) ;
+		myWorld.addTest(INVISIBLE, 3, true) ;
+		myWorld.addTest(INVISIBLE, 5, true) ;
+
+		templatePython("alarmClock", 
+				"def alarmClock(day, vacation):\n",
+				"	if not vacation:\n"+
+				"		if (day >= 1 and day <= 5):\n"+
+				"			return '7:00'\n"+
+				"		else:\n"+
+				"			return '10:00'\n"+
+				"	else:\n"+
+				"		if (day >= 1 and day <= 5):\n"+
+				"			return '10:00'\n"+
+				"		else:\n"+
+				"			return 'off'\n");
+		templateScala("alarmClock", new String[] {"Int","Boolean"},
+				"def alarmClock(day:Int, vacation:Boolean): String = {\n",
+				  "  if (! vacation) {\n"
+				+ "    if (day >= 1 && day <= 5) {\n"
+				+ "      return \"7:00\"\n"
+				+ "    } else {\n"
+				+ "      return \"10:00\"\n"
+				+ "    }\n"
+				+ "  } else {\n"
+				+ "    if (day >= 1 && day <= 5) {\n"
+				+ "      return \"10:00\"\n"
+				+ "    } else {\n"
+				+ "      return \"off\"\n"
+				+ "    }\n"
+				+ "  }\n"
+				+ "}");
+
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( alarmClock((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	String alarmClock(int day, boolean vacation) {
+		/* BEGIN SOLUTION */
+		if (! vacation) {  
+			if (day >= 1 && day <= 5)
+				return "7:00";
+			else
+				return "10:00";
+		} else {
+			if (day >= 1 && day <= 5)
+				return "10:00";
+			else
+				return "off";  
+		}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/AnswerCell.fr.html b/src/lessons/welcome/bat/bool2/AnswerCell.fr.html
new file mode 100644
index 0000000..c2eec94
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AnswerCell.fr.html
@@ -0,0 +1,8 @@
+<h1>Répondeur</h1>
+Votre téléphone sonne. Renvoyez vrai si vous décrochez. Vous le faites
+habituellement, sauf le matin où vous ne répondez que si votre mère
+appelle. Dans tous les cas, vous ne répondez pas si vous dormez.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/AnswerCell.html b/src/lessons/welcome/bat/bool2/AnswerCell.html
new file mode 100644
index 0000000..f6c9edb
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AnswerCell.html
@@ -0,0 +1,8 @@
+<h1>AnswerCell</h1>
+Your cell
+phone rings. Return true if you should answer it. Normally you answer,
+except in the morning you only answer if it is your mom calling. In all
+cases, if you are asleep, you do not answer.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/AnswerCell.java b/src/lessons/welcome/bat/bool2/AnswerCell.java
new file mode 100644
index 0000000..5390c20
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/AnswerCell.java
@@ -0,0 +1,44 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class AnswerCell extends BatExercise {
+	public AnswerCell(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("answerCell");
+		myWorld.addTest(VISIBLE, false, false, false) ;
+		myWorld.addTest(VISIBLE, false, false, true) ;
+		myWorld.addTest(VISIBLE, true, false, false) ;
+		myWorld.addTest(INVISIBLE, true, true, false) ;
+		myWorld.addTest(INVISIBLE, false, true, false) ;
+		myWorld.addTest(INVISIBLE, true, true, true) ;
+
+		templatePython("answerCell", 
+				"def answerCell(isMorning, isMom, isAsleep):\n",
+				"   return (not isAsleep) and not (isMorning and not isMom)");
+		templateScala("answerCell",new String[] {"Boolean","Boolean","Boolean"}, 
+				"def answerCell(isMorning:Boolean, isMom:Boolean, isAsleep:Boolean):Boolean = {\n",
+				"   return (! isAsleep) && !(isMorning && !isMom)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( answerCell((Boolean)t.getParameter(0), (Boolean)t.getParameter(1), (Boolean)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean answerCell(boolean isMorning, boolean isMom, boolean isAsleep) {
+		/* BEGIN SOLUTION */
+		return (! isAsleep) && ! (isMorning && ! isMom);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/BlueTicket.fr.html b/src/lessons/welcome/bat/bool2/BlueTicket.fr.html
new file mode 100644
index 0000000..e45186f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/BlueTicket.fr.html
@@ -0,0 +1,11 @@
+<h1>Ticket bleu</h1>
+Vous avez un ticket de loterie bleu, avec des entiers a, b et c inscrits
+dessus. Cela fait trois paires que l'on appellera ab, bc et ac. Considérez
+la somme des nombres de chaque pair. Si la somme de l'une des paires vaut
+exactement 10, le résultat est 10. Sinon, si la somme ab vaut exactement 10
+de plus que les sommes bc ou ac, le résultat est 5. Sinon, le résultat est
+0.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/BlueTicket.html b/src/lessons/welcome/bat/bool2/BlueTicket.html
new file mode 100644
index 0000000..7dd8fc5
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/BlueTicket.html
@@ -0,0 +1,10 @@
+<h1>BlueTicket</h1>
+You have a
+blue lottery ticket, with ints a, b, and c on it. This makes three
+pairs, which we'll call ab, bc, and ac. Consider the sum of the numbers
+in each pair. If any pair sums to exactly 10, the result is 10.
+Otherwise if the ab sum is exactly 10 more than either bc or ac sums,
+the result is 5. Otherwise the result is 0.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/BlueTicket.java b/src/lessons/welcome/bat/bool2/BlueTicket.java
new file mode 100644
index 0000000..4981d8d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/BlueTicket.java
@@ -0,0 +1,75 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class BlueTicket extends BatExercise {
+	public BlueTicket(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("blueTicket");
+		myWorld.addTest(VISIBLE, 9, 1, 0) ;
+		myWorld.addTest(VISIBLE, 9, 2, 0) ;
+		myWorld.addTest(VISIBLE, 6, 1, 4) ;
+		myWorld.addTest(INVISIBLE, 6, 1, 5) ;
+		myWorld.addTest(INVISIBLE, 10, 0, 0) ;
+		myWorld.addTest(INVISIBLE, 15, 0, 5) ;
+		myWorld.addTest(INVISIBLE, 5, 15, 5) ;
+		myWorld.addTest(INVISIBLE, 4, 11, 1) ;
+		myWorld.addTest(INVISIBLE, 13, 2, 3) ;
+		myWorld.addTest(INVISIBLE, 8, 4, 3) ;
+		myWorld.addTest(INVISIBLE, 8, 4, 2) ;
+		myWorld.addTest(INVISIBLE, 8, 4, 1) ;
+
+		templatePython("blueTicket", 
+				"def blueTicket(a, b, c):\n",
+				"	ab = a + b\n"+
+				"	ac = a + c\n"+
+				"	bc = b + c\n"+
+				"	if (ab == 10 or ac == 10 or bc == 10):\n"+
+				"		return 10\n"+
+				"	elif (ab == (bc + 10) or ab == (ac + 10)):\n"+
+				"		return 5\n"+
+				"	else:\n"+
+				"		return 0\n");
+		templateScala("blueTicket",new String[]{"Int","Int","Int"}, 
+				"def blueTicket(a:Int, b:Int, c:Int):Int = {\n",
+				"	val ab = a + b\n"+
+				"	val ac = a + c\n"+
+				"	val bc = b + c\n"+
+				"	if (ab == 10 || ac == 10 || bc == 10)\n"+
+				"		return 10\n"+
+				"	else if (ab == (bc + 10) || ab == (ac + 10))\n"+
+				"		return 5\n"+
+				"	else\n"+
+				"		return 0\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( blueTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int blueTicket(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		int ab = a + b;
+		int ac = a + c;
+		int bc = b + c;
+
+		if (ab == 10 || ac == 10 || bc == 10)
+			return 10;
+		else if (ab == (bc + 10) || ab == (ac + 10))
+			return 5;
+		else 
+			return 0;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/CaughtSpeeding.fr.html b/src/lessons/welcome/bat/bool2/CaughtSpeeding.fr.html
new file mode 100644
index 0000000..aca9727
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CaughtSpeeding.fr.html
@@ -0,0 +1,12 @@
+<h1>Radar de vitesse</h1>
+Vous conduisez un peu trop vite et un officier de police vous
+arrête. Écrivez le code pour calculer le résultat, encodé sous forme d'un
+entier : 0=pas d'amende, 1=petite amende, 2=grosse amende. Si votre vitesse
+est inférieure à 60, le résultat est 0. Si la vitesse est incluse entre 61
+et 80 (inclus), le résultat est 1. Si la vitesse est 81 ou plus, le résultat
+est 2. Tout ceci ne vaut que si ce n'est pas votre anniversaire aujourd'hui,
+car sinon, votre vitesse peut être supérieure de 5 dans tous les cas.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/CaughtSpeeding.html b/src/lessons/welcome/bat/bool2/CaughtSpeeding.html
new file mode 100644
index 0000000..eb114f4
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CaughtSpeeding.html
@@ -0,0 +1,11 @@
+<h1>CaughtSpeeding</h1>
+You are
+driving a little too fast, and a police officer stops you. Write code
+to compute the result, encoded as an int value: 0=no ticket, 1=small
+ticket, 2=big ticket. If speed is 60 or less, the result is 0. If speed
+is between 61 and 80 inclusive, the result is 1. If speed is 81 or
+more, the result is 2. Unless it is your birthday -- on that day, your
+speed can be 5 higher in all cases.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/CaughtSpeeding.java b/src/lessons/welcome/bat/bool2/CaughtSpeeding.java
new file mode 100644
index 0000000..03e5984
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CaughtSpeeding.java
@@ -0,0 +1,65 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class CaughtSpeeding extends BatExercise {
+	public CaughtSpeeding(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("caughtSpeeding");
+		myWorld.addTest(VISIBLE, 60, false) ;
+		myWorld.addTest(VISIBLE, 65, false) ;
+		myWorld.addTest(VISIBLE, 65, true) ;
+		myWorld.addTest(INVISIBLE, 80, false) ;
+		myWorld.addTest(INVISIBLE, 85, false) ;
+		myWorld.addTest(INVISIBLE, 85, true) ;
+		myWorld.addTest(INVISIBLE, 70, false) ;
+		myWorld.addTest(INVISIBLE, 75, false) ;
+		myWorld.addTest(INVISIBLE, 75, true) ;
+		myWorld.addTest(INVISIBLE, 40, false) ;
+		myWorld.addTest(INVISIBLE, 40, true) ;
+		myWorld.addTest(INVISIBLE, 90, false) ;
+
+		templatePython("caughtSpeeding", 
+				"def caughtSpeeding(speed, isBirthday):\n",
+				"	if ((isBirthday and speed <= 65) or (speed <= 60)):\n"+
+				"		return 0\n"+
+				"	elif ((isBirthday and speed <= 85) or (speed <= 80)):\n"+
+				"		return 1\n"+
+				"	else:\n"+
+				"		return 2\n");
+		templateScala("caughtSpeeding",new String[] {"Int","Boolean"}, 
+				"def caughtSpeeding(speed:Int, isBirthday:Boolean):Int = {\n",
+				"	if ((isBirthday && speed <= 65) || (speed <= 60))\n"+
+				"		return 0\n"+
+				"	else if ((isBirthday && speed <= 85) || (speed <= 80))\n"+
+				"		return 1\n"+
+				"	else\n"+
+				"		return 2\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( caughtSpeeding((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int caughtSpeeding(int speed, boolean isBirthday) {
+		/* BEGIN SOLUTION */
+		if ((isBirthday && speed <= 65) || (speed <= 60))
+			return 0;
+		else if ((isBirthday && speed <= 85) || (speed <= 80))
+			return 1;
+		else 
+			return 2;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/CigarParty.fr.html b/src/lessons/welcome/bat/bool2/CigarParty.fr.html
new file mode 100644
index 0000000..611e6aa
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CigarParty.fr.html
@@ -0,0 +1,9 @@
+<h1>Cigares de fête</h1>
+Quand les écureuils font la fête, ils aiment avoir des cigares. Une fête
+d'écureuils est réussie si le nombre de cigares est entre 40 et 60
+(inclus). Sauf si c'est le week-end, auquel cas il n'y a pas de limite
+supérieure au nombre de cigares. Renvoyez vrai si la fête est réussie. 
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/CigarParty.html b/src/lessons/welcome/bat/bool2/CigarParty.html
new file mode 100644
index 0000000..f2eef40
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CigarParty.html
@@ -0,0 +1,9 @@
+<h1>CigarParty</h1>
+When
+squirrels get together for a party, they like to have cigars. A
+squirrel party is successful when the number of cigars is between 40
+and 60, inclusive. Unless it is the weekend, in which case there is no
+upper bound on the number of cigars. Return true if the party with the
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/CigarParty.java b/src/lessons/welcome/bat/bool2/CigarParty.java
new file mode 100644
index 0000000..09aa34e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/CigarParty.java
@@ -0,0 +1,49 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class CigarParty extends BatExercise {
+	public CigarParty(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("cigarParty");
+		myWorld.addTest(VISIBLE, 30, false) ;
+		myWorld.addTest(VISIBLE, 50, false) ;
+		myWorld.addTest(VISIBLE, 70, true) ;
+		myWorld.addTest(INVISIBLE, 30, true) ;
+		myWorld.addTest(INVISIBLE, 50, true) ;
+		myWorld.addTest(INVISIBLE, 60, false) ;
+		myWorld.addTest(INVISIBLE, 61, false) ;
+		myWorld.addTest(INVISIBLE, 40, false) ;
+		myWorld.addTest(INVISIBLE, 39, false) ;
+		myWorld.addTest(INVISIBLE, 40, true) ;
+		myWorld.addTest(INVISIBLE, 39, true) ;
+
+		templatePython("cigarParty", 
+				"def cigarParty(cigars, isWeekend):\n",
+				"   return (isWeekend and cigars >= 40) or (not isWeekend and (cigars >= 40) and (cigars <= 60))\n");
+		templateScala("cigarParty",new String[] {"Int","Boolean"}, 
+				"def cigarParty(cigars:Int, isWeekend:Boolean):Boolean = {\n",
+				"   return (isWeekend && cigars >= 40) || (! isWeekend && (cigars >= 40) && (cigars <= 60))\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( cigarParty((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean cigarParty(int cigars, boolean isWeekend) {
+		/* BEGIN SOLUTION */
+		return (isWeekend && cigars >= 40) || (!isWeekend && (cigars >= 40) && (cigars <= 60));
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/DateFashion.fr.html b/src/lessons/welcome/bat/bool2/DateFashion.fr.html
new file mode 100644
index 0000000..42853c5
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/DateFashion.fr.html
@@ -0,0 +1,13 @@
+<h1>Rendez-vous élégant</h1>
+Vous et votre compagne/compagnon essayez d'obtenir une table au
+restaurant. Le paramètre "you" est l'élégance de vos vêtements, dans
+l'intervalle [0,10], et "date"  est l'élégance des vêtements de votre
+compagne/compagnon. Le résultat obtenir la table est  encodé comme une
+valeur enteur avec 0=non, 1= peut-être et 2=oui. Si l'un de vous deux est
+très élégant, 8 ou plus, alors le résultat est 2 (oui). Avec l'exception que
+si l'un de vous deux a un style de 2 ou moins, alors le résultat est 0
+(no). Sinon, le résultat est 1 (peut-être).
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/DateFashion.html b/src/lessons/welcome/bat/bool2/DateFashion.html
new file mode 100644
index 0000000..976b070
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/DateFashion.html
@@ -0,0 +1,12 @@
+<h1>DateFashion</h1>
+You and your
+date are trying to get a table at a restaurant. The parameter "you" is
+the stylishness of your clothes, in the range 0..10, and "date" is the
+stylishness of your date's clothes. The result getting the table is
+encoded as an int value with 0=no, 1=maybe, 2=yes. If either of you is
+very stylish, 8 or more, then the result is 2 (yes). With the exception
+that if either of you has style of 2 or less, then the result is 0
+(no). Otherwise the result is 1 (maybe).
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/DateFashion.java b/src/lessons/welcome/bat/bool2/DateFashion.java
new file mode 100644
index 0000000..5053da4
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/DateFashion.java
@@ -0,0 +1,65 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class DateFashion extends BatExercise {
+	public DateFashion(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("dateFashion");
+		myWorld.addTest(VISIBLE, 5, 10) ;
+		myWorld.addTest(VISIBLE, 5, 2) ;
+		myWorld.addTest(VISIBLE, 5, 5) ;
+		myWorld.addTest(INVISIBLE, 3, 3) ;
+		myWorld.addTest(INVISIBLE, 10, 2) ;
+		myWorld.addTest(INVISIBLE, 2, 9) ;
+		myWorld.addTest(INVISIBLE, 9, 9) ;
+		myWorld.addTest(INVISIBLE, 10, 5) ;
+		myWorld.addTest(INVISIBLE, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 3, 7) ;
+		myWorld.addTest(INVISIBLE, 2, 7) ;
+		myWorld.addTest(INVISIBLE, 6, 2) ;
+
+		templatePython("dateFashion", 
+				"def dateFashion(you, date):\n",
+				"	if (you <= 2 or date <= 2):\n"+
+				"		return 0\n"+
+				"	elif (you >= 8 or date >= 8):\n"+
+				"		return 2\n"+
+				"	else:\n"+
+				"		return 1\n");
+		templateScala("dateFashion",new String[]{"Int","Int"}, 
+				"def dateFashion(you:Int, date:Int):Int = {\n",
+				"	if (you <= 2 || date <= 2) \n"+
+				"		return 0\n"+
+				"	else if (you >= 8 || date >= 8)\n"+
+				"		return 2\n"+
+				"	else\n"+
+				"		return 1\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( dateFashion((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int dateFashion(int you, int date) {
+		/* BEGIN SOLUTION */
+		if (you <= 2 || date <= 2)
+			return 0;
+		else if (you >= 8 || date >= 8)
+			return 2;
+		else
+			return 1;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/GreenTicket.fr.html b/src/lessons/welcome/bat/bool2/GreenTicket.fr.html
new file mode 100644
index 0000000..2549464
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/GreenTicket.fr.html
@@ -0,0 +1,9 @@
+<h1>Ticket vert</h1>
+Vous avez un ticket de lotterie vert, avec des entiers a, b et c inscrits
+dessus. Si les nombres sont tous différents les uns des autres, le résultat
+est 0. Si tous les nombres sont identiques, le résultat est 20. Si deux des
+nombres sont les mêmes, le résultat est 10.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/GreenTicket.html b/src/lessons/welcome/bat/bool2/GreenTicket.html
new file mode 100644
index 0000000..f079599
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/GreenTicket.html
@@ -0,0 +1,9 @@
+<h1>GreenTicket</h1>
+You have a
+green lottery ticket, with ints a, b, and c on it. If the numbers are
+all different from each other, the result is 0. If all of the numbers
+are the same, the result is 20. If two of the numbers are the same, the
+result is 10.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/GreenTicket.java b/src/lessons/welcome/bat/bool2/GreenTicket.java
new file mode 100644
index 0000000..57d1c6c
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/GreenTicket.java
@@ -0,0 +1,65 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class GreenTicket extends BatExercise {
+	public GreenTicket(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("greenTicket");
+		myWorld.addTest(VISIBLE, 1, 2, 3) ;
+		myWorld.addTest(VISIBLE, 2, 2, 2) ;
+		myWorld.addTest(VISIBLE, 1, 1, 2) ;
+		myWorld.addTest(INVISIBLE, 2, 1, 1) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 1) ;
+		myWorld.addTest(INVISIBLE, 3, 2, 1) ;
+		myWorld.addTest(INVISIBLE, 0, 0, 0) ;
+		myWorld.addTest(INVISIBLE, 2, 0, 0) ;
+		myWorld.addTest(INVISIBLE, 0, 9, 10) ;
+		myWorld.addTest(INVISIBLE, 0, 10, 0) ;
+		myWorld.addTest(INVISIBLE, 9, 9, 9) ;
+		myWorld.addTest(INVISIBLE, 9, 0, 9) ;
+
+		templatePython("greenTicket", 
+				"def greenTicket(a, b, c):\n",
+				"	if (a == b and b == c):\n"+
+				"		return 20\n"+
+				"	elif (a == b or b == c or a == c):\n"+
+				"		return 10\n"+
+				"	else:\n"+
+				"		return 0\n");
+		templateScala("greenTicket",new String[] {"Int","Int","Int"}, 
+				"def greenTicket(a:Int, b:Int, c:Int):Int = {\n",
+				"	if (a == b && b == c)\n"+
+				"		return 20\n"+
+				"	else if (a == b || b == c || a == c)\n"+
+				"		return 10\n"+
+				"	else\n"+
+				"		return 0\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( greenTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int greenTicket(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		if (a == b && b == c)
+			return 20;
+		else if (a == b || b == c || a == c)
+			return 10;
+		else  // (a != b && b != a && c != a)
+			return 0;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/In1To10.fr.html b/src/lessons/welcome/bat/bool2/In1To10.fr.html
new file mode 100644
index 0000000..223c2e3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/In1To10.fr.html
@@ -0,0 +1,8 @@
+<h1>De 1 à 10</h1>
+Soit un nombre n, renvoyez vrai si n est dans l'intervalle [1,10]. Sauf
+si"outsideMode" est vrai, auquel cas renvoyez vrai si le nombre est plus
+petit ou égal à 1 ou bien s'il est plus grand ou égal à 10
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/In1To10.html b/src/lessons/welcome/bat/bool2/In1To10.html
new file mode 100644
index 0000000..1a341c2
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/In1To10.html
@@ -0,0 +1,8 @@
+<h1>In1To10</h1>
+Given a
+number n, return true if n is in the range 1..10, inclusive. Unless
+"outsideMode" is true, in which case return true if the number is less
+or equal to 1, or greater or equal to 10.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/In1To10.java b/src/lessons/welcome/bat/bool2/In1To10.java
new file mode 100644
index 0000000..2a1665e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/In1To10.java
@@ -0,0 +1,50 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class In1To10 extends BatExercise {
+	public In1To10(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("in1To10");
+		myWorld.addTest(VISIBLE, 5, false) ;
+		myWorld.addTest(VISIBLE, 11, false) ;
+		myWorld.addTest(VISIBLE, 11, true) ;
+		myWorld.addTest(INVISIBLE, 10, false) ;
+		myWorld.addTest(INVISIBLE, 10, true) ;
+		myWorld.addTest(INVISIBLE, 9, false) ;
+		myWorld.addTest(INVISIBLE, 9, true) ;
+		myWorld.addTest(INVISIBLE, 1, false) ;
+		myWorld.addTest(INVISIBLE, 1, true) ;
+		myWorld.addTest(INVISIBLE, 0, false) ;
+		myWorld.addTest(INVISIBLE, 0, true) ;
+		myWorld.addTest(INVISIBLE, -1, false) ;
+
+		templatePython("in1To10", 
+				"def in1To10(n, outsideMode):\n",
+				"   return (outsideMode and (n <= 1 or n >= 10)) or ((not outsideMode) and (n >= 1 and n <= 10))\n");
+		templateScala("in1To10",new String[]{"Int","Boolean"}, 
+				"def in1To10(n:Int, outsideMode:Boolean):Boolean = {\n",
+				"   return (outsideMode && (n <= 1 || n >= 10)) || ((! outsideMode) && (n >= 1 && n <= 10))\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( in1To10((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean in1To10(int n, boolean outsideMode) {
+		/* BEGIN SOLUTION */
+		return (outsideMode && (n <= 1 || n >= 10)) || ((! outsideMode) && (n >= 1 && n <= 10));
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/InOrder.fr.html b/src/lessons/welcome/bat/bool2/InOrder.fr.html
new file mode 100644
index 0000000..9486976
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrder.fr.html
@@ -0,0 +1,8 @@
+<h1>Dans l'ordre</h1>
+Soit trois entiers, a b c, renvoyez vrai si b est plus grand que a, et si c
+est plus grand que b. Cependant, avec l'exception que si "bOk" est vrai, b
+n'a pas besoin d'être plus grand que a.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/InOrder.html b/src/lessons/welcome/bat/bool2/InOrder.html
new file mode 100644
index 0000000..51a53e8
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrder.html
@@ -0,0 +1,8 @@
+<h1>InOrder</h1>
+Given three
+ints, a b c, return true if b is greater than a, and c is greater than
+b. However, with the exception that if "bOk" is true, b does not need
+to be greater than a.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/InOrder.java b/src/lessons/welcome/bat/bool2/InOrder.java
new file mode 100644
index 0000000..18d7852
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrder.java
@@ -0,0 +1,50 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class InOrder extends BatExercise {
+	public InOrder(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("inOrder");
+		myWorld.addTest(VISIBLE, 1, 2, 4, false) ;
+		myWorld.addTest(VISIBLE, 1, 2, 1, false) ;
+		myWorld.addTest(VISIBLE, 1, 1, 2, true) ;
+		myWorld.addTest(INVISIBLE, 3, 2, 4, false) ;
+		myWorld.addTest(INVISIBLE, 2, 3, 4, false) ;
+		myWorld.addTest(INVISIBLE, 3, 2, 4, true) ;
+		myWorld.addTest(INVISIBLE, 4, 2, 2, true) ;
+		myWorld.addTest(INVISIBLE, 4, 5, 2, true) ;
+		myWorld.addTest(INVISIBLE, 2, 4, 6, true) ;
+		myWorld.addTest(INVISIBLE, 7, 9, 10, false) ;
+		myWorld.addTest(INVISIBLE, 7, 5, 6, true) ;
+		myWorld.addTest(INVISIBLE, 7, 5, 4, true) ;
+
+		templatePython("inOrder", 
+				"def inOrder(a, b, c, bOk):\n",
+				"		return (bOk or (b > a)) and (c > b)\n");
+		templateScala("inOrder",new String[] {"Int","Int","Int","Boolean"}, 
+				"def inOrder(a:Int, b:Int, c:Int, bOk:Boolean):Boolean = {\n",
+				"		return (bOk || (b > a)) && (c > b)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( inOrder((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2), (Boolean)t.getParameter(3)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean inOrder(int a, int b, int c, boolean bOk) {
+		/* BEGIN SOLUTION */
+		return (bOk || (b > a)) && (c > b);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/InOrderEqual.fr.html b/src/lessons/welcome/bat/bool2/InOrderEqual.fr.html
new file mode 100644
index 0000000..3fd6af3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrderEqual.fr.html
@@ -0,0 +1,9 @@
+<h1>Dans l'ordre croissant</h1>
+Soit trois entiers, a b c, renvoyez vrai si ils sont dans un ordre croissant
+strict, tel que 2 5 11, ou 5 6 7, mais pas 6 5 7 ou 5 5 7. Cependant, avec
+l'exception que si "equalOk" est vrai, alors l'égalité est permise, comme 5
+5 7 ou 5 5 5.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/InOrderEqual.html b/src/lessons/welcome/bat/bool2/InOrderEqual.html
new file mode 100644
index 0000000..0896e0e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrderEqual.html
@@ -0,0 +1,9 @@
+<h1>InOrderEqual</h1>
+Given three
+ints, a b c, return true if they are in strict increasing order, such
+as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the
+exception that if "equalOk" is true, equality is allowed, such as 5 5 7
+or 5 5 5.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/InOrderEqual.java b/src/lessons/welcome/bat/bool2/InOrderEqual.java
new file mode 100644
index 0000000..1c5d6b4
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/InOrderEqual.java
@@ -0,0 +1,52 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class InOrderEqual extends BatExercise {
+	public InOrderEqual(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("inOrderEqual");
+		myWorld.addTest(VISIBLE, 2, 5, 11, false) ;
+		myWorld.addTest(VISIBLE, 5, 7, 6, false) ;
+		myWorld.addTest(VISIBLE, 5, 5, 7, true) ;
+		myWorld.addTest(INVISIBLE, 5, 5, 7, false) ;
+		myWorld.addTest(INVISIBLE, 2, 5, 4, false) ;
+		myWorld.addTest(INVISIBLE, 3, 4, 3, false) ;
+		myWorld.addTest(INVISIBLE, 3, 4, 4, false) ;
+		myWorld.addTest(INVISIBLE, 3, 4, 3, true) ;
+		myWorld.addTest(INVISIBLE, 3, 4, 4, true) ;
+		myWorld.addTest(INVISIBLE, 1, 5, 5, true) ;
+		myWorld.addTest(INVISIBLE, 5, 5, 5, true) ;
+		myWorld.addTest(INVISIBLE, 2, 2, 1, true) ;
+		myWorld.addTest(INVISIBLE, 9, 2, 2, true) ;
+		myWorld.addTest(INVISIBLE, 0, 1, 0, true) ;
+
+		templatePython("inOrderEqual", 
+				"def inOrderEqual(a, b, c, equalOk):\n",
+				"		return (equalOk and ((a <= b) and (b <= c))) or (a < b and b < c)");
+		templateScala("inOrderEqual",new String[] {"Int","Int","Int","Boolean"}, 
+				"def inOrderEqual(a:Int, b:Int, c:Int, equalOk:Boolean):Boolean = {\n",
+				"		return (equalOk && ((a <= b) && (b <= c))) || (a < b && b < c)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( inOrderEqual((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2), (Boolean)t.getParameter(3)) ); 
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean inOrderEqual(int a, int b, int c, boolean equalOk) {
+		/* BEGIN SOLUTION */
+		return (equalOk && ((a <= b) && (b <= c))) || (a < b && b < c);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/LastDigit2.fr.html b/src/lessons/welcome/bat/bool2/LastDigit2.fr.html
new file mode 100644
index 0000000..a6544d6
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LastDigit2.fr.html
@@ -0,0 +1,8 @@
+<h1>L'autre dernier chiffre</h1>
+Soit trois entiers, a b c, renvoyez vrai si deux ou plus d'entre eux ont le
+même chiffre le plus à droite. Les entiers sont positifs. Note: l'opérateur
+% "mod" calcule le reste, i.e. 17 % 10 vaut 7.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/LastDigit2.html b/src/lessons/welcome/bat/bool2/LastDigit2.html
new file mode 100644
index 0000000..e70140b
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LastDigit2.html
@@ -0,0 +1,8 @@
+<h1>LastDigit 2</h1>
+Given three
+ints, a b c, return true if two or more of them have the same rightmost
+digit. The ints are non-negative. Note: the % "mod" operator computes
+the remainder, e.g. 17 % 10 is 7.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/LastDigit2.java b/src/lessons/welcome/bat/bool2/LastDigit2.java
new file mode 100644
index 0000000..c0499a5
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LastDigit2.java
@@ -0,0 +1,60 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class LastDigit2 extends BatExercise {
+	public LastDigit2(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("lastDigit");
+		myWorld.addTest(VISIBLE, 23, 19, 13) ;
+		myWorld.addTest(VISIBLE, 23, 19, 12) ;
+		myWorld.addTest(VISIBLE, 23, 19, 3) ;
+		myWorld.addTest(INVISIBLE, 23, 19, 39) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 3) ;
+		myWorld.addTest(INVISIBLE, 1, 1, 2) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 14, 25, 43) ;
+		myWorld.addTest(INVISIBLE, 14, 25, 45) ;
+		myWorld.addTest(INVISIBLE, 248, 106, 1002) ;
+		myWorld.addTest(INVISIBLE, 248, 106, 1008) ;
+		myWorld.addTest(INVISIBLE, 10, 11, 20) ;
+		myWorld.addTest(INVISIBLE, 0, 11, 0) ;
+
+		templatePython("lastDigit", 
+				"def lastDigit(a, b, c):\n",
+				"	da = a % 10\n"+
+				"	db = b % 10\n"+
+				"	dc = c % 10\n"+
+				"	return da == db or da == dc or dc == db\n");
+		templateScala("lastDigit",new String[]{"Int","Int","Int"}, 
+				"def lastDigit(a:Int, b:Int, c:Int):Boolean = {\n",
+				"	val da = a % 10\n"+
+				"	val db = b % 10\n"+
+				"	val dc = c % 10\n"+
+				"	return da == db || da == dc || dc == db\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( lastDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean lastDigit(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		int da = a % 10;
+		int db = b % 10;
+		int dc = c % 10;
+		return da == db || da == dc || dc == db;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/LessBy10.fr.html b/src/lessons/welcome/bat/bool2/LessBy10.fr.html
new file mode 100644
index 0000000..e5a2e76
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LessBy10.fr.html
@@ -0,0 +1,7 @@
+<h1>Plus petit par 10</h1>
+Soit trois entiers, a b c, renvoyez vrai si l'un d'entre eux est plus petit
+de 10 ou plus que l'un des autres.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/LessBy10.html b/src/lessons/welcome/bat/bool2/LessBy10.html
new file mode 100644
index 0000000..2b75359
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LessBy10.html
@@ -0,0 +1,5 @@
+<h1>LessBy10</h1>
+Given three ints, a b c, return true if one of them is 10 or more less than one of the others.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/LessBy10.java b/src/lessons/welcome/bat/bool2/LessBy10.java
new file mode 100644
index 0000000..0430007
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/LessBy10.java
@@ -0,0 +1,52 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class LessBy10 extends BatExercise {
+	public LessBy10(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("lessBy10");
+		myWorld.addTest(VISIBLE, 1, 7, 11) ;
+		myWorld.addTest(VISIBLE, 1, 7, 10) ;
+		myWorld.addTest(VISIBLE, 11, 1, 7) ;
+		myWorld.addTest(INVISIBLE, 10, 7, 1) ;
+		myWorld.addTest(INVISIBLE, -10, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 2, 11, 11) ;
+		myWorld.addTest(INVISIBLE, 3, 3, 30) ;
+		myWorld.addTest(INVISIBLE, 3, 3, 3) ;
+		myWorld.addTest(INVISIBLE, 10, 1, 11) ;
+		myWorld.addTest(INVISIBLE, 10, 11, 1) ;
+		myWorld.addTest(INVISIBLE, 10, 11, 2) ;
+		myWorld.addTest(INVISIBLE, 3, 30, 3) ;
+		myWorld.addTest(INVISIBLE, 2, 2, -8) ;
+		myWorld.addTest(INVISIBLE, 2, 8, 12) ;
+
+		templatePython("lessBy10", 
+				"def lessBy10(a, b, c):\n",
+				"	return ((a - b) >= 10) or ((b - a) >= 10) or ((b - c) >= 10) or ((c - b) >= 10) or ((a - c) >= 10) or ((c - a) >= 10)\n");
+		templateScala("lessBy10", new String[] {"Int","Int","Int"},
+				"def lessBy10(a:Int, b:Int, c:Int):Boolean = {\n",
+				"	return ((a - b) >= 10) || ((b - a) >= 10) || ((b - c) >= 10) || ((c - b) >= 10) || ((a - c) >= 10) || ((c - a) >= 10)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( lessBy10((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean lessBy10(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		return ((a - b) >= 10) || ((b - a) >= 10) || ((b - c) >= 10) || ((c - b) >= 10) || ((a - c) >= 10) || ((c - a) >= 10);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/Main.fr.html b/src/lessons/welcome/bat/bool2/Main.fr.html
new file mode 100644
index 0000000..4dbbf93
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/Main.fr.html
@@ -0,0 +1,5 @@
+<h1>Encore des jeux booléens</h1>
+   
+<p>Une très bonne introduction à ce type est disponible ici :
+http://javabat.com/doc/ifboolean.html.</p><p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/Main.html b/src/lessons/welcome/bat/bool2/Main.html
new file mode 100644
index 0000000..d972496
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/Main.html
@@ -0,0 +1,4 @@
+<h1>Boolean (even more) fun</h1>
+   
+<p>A very good introduction to this type is available here:
+   http://javabat.com/doc/ifboolean.html.</p><p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/MaxMod5.fr.html b/src/lessons/welcome/bat/bool2/MaxMod5.fr.html
new file mode 100644
index 0000000..8621bdb
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/MaxMod5.fr.html
@@ -0,0 +1,10 @@
+<h1>Maximum Mod 5</h1>
+Soit deux valeurs entières, renvoyez la plus grande des deux. Cependant, si
+les deux valeurs ont le même reste quand elles sont divisées par 5, alors
+renvoyez la plus petite des deux. Cependant, dans tous les cas, si les deux
+valeurs sont égales, renvoyez 0. Note: l'opérateur % "mod" calcule le reste,
+i.e. 7 % 5 vaut 2.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/MaxMod5.html b/src/lessons/welcome/bat/bool2/MaxMod5.html
new file mode 100644
index 0000000..732bdce
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/MaxMod5.html
@@ -0,0 +1,9 @@
+<h1>MaxMod5</h1>
+Given two int
+values, return whichever value is larger. However if the two values
+have the same remainder when divided by 5, then the return the smaller
+value. However, in all cases, if the two values are the same, return 0.
+Note: the % "mod" operator computes the remainder, e.g. 7 % 5 is 2.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/MaxMod5.java b/src/lessons/welcome/bat/bool2/MaxMod5.java
new file mode 100644
index 0000000..7cf77d3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/MaxMod5.java
@@ -0,0 +1,83 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class MaxMod5 extends BatExercise {
+	public MaxMod5(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("maxMod5");
+		myWorld.addTest(VISIBLE, 2, 3) ;
+		myWorld.addTest(VISIBLE, 6, 2) ;
+		myWorld.addTest(VISIBLE, 3, 2) ;
+		myWorld.addTest(INVISIBLE, 8, 12) ;
+		myWorld.addTest(INVISIBLE, 7, 12) ;
+		myWorld.addTest(INVISIBLE, 11, 6) ;
+		myWorld.addTest(INVISIBLE, 2, 7) ;
+		myWorld.addTest(INVISIBLE, 7, 7) ;
+		myWorld.addTest(INVISIBLE, 9, 1) ;
+		myWorld.addTest(INVISIBLE, 9, 14) ;
+		myWorld.addTest(INVISIBLE, 1, 2) ;
+
+		templatePython("maxMod5", 
+				"def maxMod5(a, b):\n",
+				"	if (a == b):\n"+
+				"		return 0\n"+
+				"	elif (a > b):\n"+
+				"		if (a % 5 == b % 5):\n"+
+				"			return b\n"+
+				"		else:\n"+
+				"			return a\n"+
+				"	else:\n"+
+				"		if (a % 5 == b % 5):\n"+
+				"			return a\n"+
+				"		else:\n"+
+				"			return b");  
+		templateScala("maxMod5",new String[]{"Int","Int"}, 
+				"def maxMod5(a:Int, b:Int):Int = {\n",
+				"	if (a == b)\n"+
+				"		return 0\n"+
+				"	else if (a > b) {\n"+
+				"		if (a % 5 == b % 5)\n"+
+				"			return b\n"+
+				"		else\n"+
+				"			return a\n"+
+				"	} else\n"+
+				"		if (a % 5 == b % 5)\n"+
+				"			return a\n"+
+				"		else\n"+
+				"			return b\n"+
+				"}");  
+
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( maxMod5((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int maxMod5(int a, int b) {
+		/* BEGIN SOLUTION */
+		if (a == b)
+			return 0;
+		else if (a > b)
+			if (a % 5 == b % 5)
+				return b;
+			else 
+				return a;
+		else 
+			if (a % 5 == b % 5)
+				return a;
+			else 
+				return b;  
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/NearTen.fr.html b/src/lessons/welcome/bat/bool2/NearTen.fr.html
new file mode 100644
index 0000000..f94b71f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/NearTen.fr.html
@@ -0,0 +1,8 @@
+<h1>Près de dix</h1>
+Soit un entier positif "num", renvoyez vrai si num est à moins de 2 d'un
+multiple de 10. Note: ( a % b ) est le reste de la division de a par b, donc
+(7 % 5) vaut 2.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/NearTen.html b/src/lessons/welcome/bat/bool2/NearTen.html
new file mode 100644
index 0000000..e2d04cd
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/NearTen.html
@@ -0,0 +1,8 @@
+<h1>NearTen</h1>
+Given a
+non-negative number "num", return true if num is within 2 of a multiple
+of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % 5) is
+2.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/NearTen.java b/src/lessons/welcome/bat/bool2/NearTen.java
new file mode 100644
index 0000000..c6e412f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/NearTen.java
@@ -0,0 +1,52 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class NearTen extends BatExercise {
+	public NearTen(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("nearTen");
+		myWorld.addTest(VISIBLE, 12) ;
+		myWorld.addTest(VISIBLE, 17) ;
+		myWorld.addTest(VISIBLE, 19) ;
+		myWorld.addTest(INVISIBLE, 21) ;
+		myWorld.addTest(INVISIBLE, 6) ;
+		myWorld.addTest(INVISIBLE, 10) ;
+		myWorld.addTest(INVISIBLE, 11) ;
+		myWorld.addTest(INVISIBLE, 12) ;
+		myWorld.addTest(INVISIBLE, 13) ;
+		myWorld.addTest(INVISIBLE, 54) ;
+		myWorld.addTest(INVISIBLE, 155) ;
+		myWorld.addTest(INVISIBLE, 158) ;
+		myWorld.addTest(INVISIBLE, 3) ;
+		myWorld.addTest(INVISIBLE, 1) ;
+
+		templatePython("nearTen", 
+				"def nearTen(num):\n",
+				"  return (num % 10) <= 2 or (num % 10) >= 8\n");
+		templateScala("nearTen",new String[]{"Int"}, 
+				"def nearTen(num:Int):Boolean = {\n",
+				"  return (num % 10) <= 2 || (num % 10) >= 8\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( nearTen((Integer)t.getParameter(0)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean nearTen(int num) {
+		/* BEGIN SOLUTION */
+		return (num % 10) <= 2 || (num % 10) >= 8; 
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/RedTicket.fr.html b/src/lessons/welcome/bat/bool2/RedTicket.fr.html
new file mode 100644
index 0000000..e5fa44e
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/RedTicket.fr.html
@@ -0,0 +1,10 @@
+<h1>Ticket rouge</h1>
+Vous avez un ticket de lotterie rouge comportant trois entiers a, b et
+c. Chacun d'entre eux est 0, 1, ou 2. Si ils sont tous comme valeur 2, le
+résultat vaut 10. Sinon, si ils sont égaux, le résultat vaut 5. Sinon, tant
+que b et c sont différents de a, le résultat vaut 1. Sinon, le résultat est
+0.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/RedTicket.html b/src/lessons/welcome/bat/bool2/RedTicket.html
new file mode 100644
index 0000000..0d7fe4c
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/RedTicket.html
@@ -0,0 +1,9 @@
+<h1>RedTicket</h1>
+You have a
+red lottery ticket showing ints a, b, and c, each of which is 0, 1, or
+2. If they are all the value 2, the result is 10. Otherwise if they are
+all the same, the result is 5. Otherwise so long as both b and c are
+different from a, the result is 1. Otherwise the result is 0.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/RedTicket.java b/src/lessons/welcome/bat/bool2/RedTicket.java
new file mode 100644
index 0000000..001663c
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/RedTicket.java
@@ -0,0 +1,70 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class RedTicket extends BatExercise {
+	public RedTicket(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("redTicket");
+		myWorld.addTest(VISIBLE, 2, 2, 2) ;
+		myWorld.addTest(VISIBLE, 2, 2, 1) ;
+		myWorld.addTest(VISIBLE, 0, 0, 0) ;
+		myWorld.addTest(INVISIBLE, 2, 0, 0) ;
+		myWorld.addTest(INVISIBLE, 1, 1, 1) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 1) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 0) ;
+		myWorld.addTest(INVISIBLE, 0, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 1, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 0, 2, 0) ;
+		myWorld.addTest(INVISIBLE, 1, 1, 2) ;
+
+		templatePython("redTicket", 
+				"def redTicket(a, b, c):\n",
+				"	if (a == b and b == c and c == 2):\n"+
+				"		return 10\n"+
+				"	elif (a == b and b == c):\n"+
+				"		return 5\n"+
+				"	elif (b != a and c != a):\n"+
+				"		return 1\n"+
+				"	else:\n"+
+				"		return 0\n");
+		templateScala("redTicket",new String[]{"Int","Int","Int"}, 
+				"def redTicket(a:Int, b:Int, c:Int):Int = {\n",
+				"	if (a == b && b == c && c == 2)\n"+
+				"		return 10\n"+
+				"	else if (a == b && b == c)\n"+
+				"		return 5\n"+
+				"	else if (b != a && c != a)\n"+
+				"		return 1\n"+
+				"	else\n"+
+				"		return 0\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( redTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int redTicket(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		if (a == b && b == c && c == 2)
+			return 10;
+		else if (a == b && b == c)
+			return 5;
+		else if (b != a && c != a)
+			return 1;
+		else
+			return 0;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/ShareDigit.fr.html b/src/lessons/welcome/bat/bool2/ShareDigit.fr.html
new file mode 100644
index 0000000..0c0fa2f
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/ShareDigit.fr.html
@@ -0,0 +1,9 @@
+<h1>Chiffre partagé</h1>
+Soit deux entiers, chacun étant dans l'intervalle [10,99], renvoyez vrai si
+il y a un chiffre qui apparait dans les deux nombres, comme 2 dans 12 et
+23. (Note: division, i.e.  n/10, renvoie le chiffre à gauche tant que le %
+"mod" n%10 renvoye le bon chiffre.)
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/ShareDigit.html b/src/lessons/welcome/bat/bool2/ShareDigit.html
new file mode 100644
index 0000000..36abbe3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/ShareDigit.html
@@ -0,0 +1,9 @@
+<h1>ShareDigit</h1>
+Given two
+ints, each in the range 10..99, return true if there is a digit that
+appears in both numbers, such as the 2 in 12 and 23. (Note: division,
+e.g. n/10, gives the left digit while the % "mod" n%10 gives the right
+digit.)
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/ShareDigit.java b/src/lessons/welcome/bat/bool2/ShareDigit.java
new file mode 100644
index 0000000..0f73903
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/ShareDigit.java
@@ -0,0 +1,48 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class ShareDigit extends BatExercise {
+	public ShareDigit(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("shareDigit");
+		myWorld.addTest(VISIBLE, 12, 23) ;
+		myWorld.addTest(VISIBLE, 12, 43) ;
+		myWorld.addTest(VISIBLE, 12, 44) ;
+		myWorld.addTest(INVISIBLE, 23, 12) ;
+		myWorld.addTest(INVISIBLE, 23, 39) ;
+		myWorld.addTest(INVISIBLE, 23, 19) ;
+		myWorld.addTest(INVISIBLE, 30, 90) ;
+		myWorld.addTest(INVISIBLE, 30, 91) ;
+		myWorld.addTest(INVISIBLE, 55, 55) ;
+		myWorld.addTest(INVISIBLE, 55, 44) ;
+
+		templatePython("shareDigit", 
+				"def shareDigit(a, b):\n",
+				"   return (a/10 == b/10 or a/10 == b%10 or a%10 == b/10 or a%10 == b%10)");
+		templateScala("shareDigit",new String[]{"Int","Int"}, 
+				"def shareDigit(a:Int, b:Int):Boolean = {\n",
+				"   return (a/10 == b/10 || a/10 == b%10 || a%10 == b/10 || a%10 == b%10)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( shareDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1)) ); 
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean shareDigit(int a, int b) {
+		/* BEGIN SOLUTION */
+		return (a/10 == b/10 || a/10 == b%10 || a%10 == b/10 || a%10 == b%10);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/SortaSum.fr.html b/src/lessons/welcome/bat/bool2/SortaSum.fr.html
new file mode 100644
index 0000000..d75b708
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SortaSum.fr.html
@@ -0,0 +1,7 @@
+<h1>Sommes d'entiers</h1>
+Soit deux entiers, a et b, renvoyez leur somme. Cependant, les sommes entre
+10 et 19 inclus sont interdites, dans ce cas, renvoyez 20.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/SortaSum.html b/src/lessons/welcome/bat/bool2/SortaSum.html
new file mode 100644
index 0000000..924ff16
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SortaSum.html
@@ -0,0 +1,7 @@
+<h1>SortaSum</h1>
+Given 2 ints,
+a and b, return their sum. However, sums in the range 10..19 inclusive,
+are forbidden, so in that case just return 20.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/SortaSum.java b/src/lessons/welcome/bat/bool2/SortaSum.java
new file mode 100644
index 0000000..5a6d770
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SortaSum.java
@@ -0,0 +1,59 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class SortaSum extends BatExercise {
+	public SortaSum(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("sortaSum");
+		myWorld.addTest(VISIBLE, 3, 4) ;
+		myWorld.addTest(VISIBLE, 9, 4) ;
+		myWorld.addTest(VISIBLE, 10, 11) ;
+		myWorld.addTest(INVISIBLE, 12, -3) ;
+		myWorld.addTest(INVISIBLE, -3, 12) ;
+		myWorld.addTest(INVISIBLE, 4, 5) ;
+		myWorld.addTest(INVISIBLE, 4, 6) ;
+		myWorld.addTest(INVISIBLE, 14, 7) ;
+		myWorld.addTest(INVISIBLE, 14, 6) ;
+
+		templatePython("sortaSum", 
+				"def sortaSum(a, b):\n",
+				"	sum = a+b\n"+
+				"	if (sum >= 10 and sum <= 19):\n"+
+				"		return 20\n"+
+				"	else:\n"+
+				"		return sum\n");
+		templateScala("sortaSum", new String[]{"Int","Int"},
+				"def sortaSum(a:Int, b:Int):Int = {\n",
+				"	val sum = a+b\n"+
+				"	if (sum >= 10 && sum <= 19)\n"+
+				"		return 20\n"+
+				"	else\n"+
+				"		return sum\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( sortaSum((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int sortaSum(int a, int b) {
+		/* BEGIN SOLUTION */
+		int sum = a+b;
+		if (sum >= 10 && sum <= 19)
+			return 20;
+		else
+			return sum;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/SquirrelPlay.fr.html b/src/lessons/welcome/bat/bool2/SquirrelPlay.fr.html
new file mode 100644
index 0000000..6ee7e8a
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SquirrelPlay.fr.html
@@ -0,0 +1,10 @@
+<h1>Jeu de l'écureuil</h1>
+Les écureuils dans Palo Alto passent la majorité de leurs journées à
+jouer. En particulier, ils jouent si la température est entre 60 et 90 (
+inclus ). A moins que ce soit l'été, alors la limite supérieure est de 100
+au lieu de 90.Soit une température entière et un booléen isSummer.
+Renvoyez vrai si les écureuils jouent et faux sinon.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/SquirrelPlay.html b/src/lessons/welcome/bat/bool2/SquirrelPlay.html
new file mode 100644
index 0000000..1b1dd3c
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SquirrelPlay.html
@@ -0,0 +1,10 @@
+<h1>SquirrelPlay</h1>
+The squirrels
+in Palo Alto spend most of the day playing. In particular, they play if
+the temperature is between 60 and 90 (inclusive). Unless it is summer,
+then the upper limit is 100 instead of 90. Given an int temperature and
+a boolean isSummer, return true if the squirrels play and false
+otherwise.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/SquirrelPlay.java b/src/lessons/welcome/bat/bool2/SquirrelPlay.java
new file mode 100644
index 0000000..3eeb408
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/SquirrelPlay.java
@@ -0,0 +1,51 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class SquirrelPlay extends BatExercise {
+	public SquirrelPlay(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("squirrelPlay");
+		myWorld.addTest(VISIBLE, 70, false) ;
+		myWorld.addTest(VISIBLE, 95, false) ;
+		myWorld.addTest(VISIBLE, 95, true) ;
+		myWorld.addTest(INVISIBLE, 90, false) ;
+		myWorld.addTest(INVISIBLE, 90, true) ;
+		myWorld.addTest(INVISIBLE, 50, false) ;
+		myWorld.addTest(INVISIBLE, 50, true) ;
+		myWorld.addTest(INVISIBLE, 100, false) ;
+		myWorld.addTest(INVISIBLE, 100, true) ;
+		myWorld.addTest(INVISIBLE, 105, true) ;
+		myWorld.addTest(INVISIBLE, 59, false) ;
+		myWorld.addTest(INVISIBLE, 59, true) ;
+		myWorld.addTest(INVISIBLE, 60, false) ;
+
+		templatePython("squirrelPlay", 
+				"def squirrelPlay(temp, isSummer):\n",
+				"   return (temp >= 60 and ((isSummer and temp <= 100) or temp <= 90))");
+		templateScala("squirrelPlay",new String[]{"Int","Boolean"}, 
+				"def squirrelPlay(temp:Int, isSummer:Boolean):Boolean = {\n",
+				"   return (temp >= 60 && ((isSummer && temp <= 100) || temp <= 90))\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( squirrelPlay((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean squirrelPlay(int temp, boolean isSummer) {
+		/* BEGIN SOLUTION */
+		return (temp >= 60 && ((isSummer && temp <= 100) || temp <= 90));
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/TeaParty.fr.html b/src/lessons/welcome/bat/bool2/TeaParty.fr.html
new file mode 100644
index 0000000..3dfdae3
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeaParty.fr.html
@@ -0,0 +1,12 @@
+<h1>Goûter</h1>
+Nous avons un goûter avec quantité de thé et de bonbons. Renvoyez l'entier
+'outcome' du goûter encodé comme 0=mauvais, 1=bien, ou 2=excellent. Un
+goûter est bien (1) si le thé et les bonbons sont à 5 au moins. Cependant,
+si soit le thé soit les bonbons est à au moins le double de la quantité de
+l'autre, le goûter est excellent (2). Cependant, dans tous les cas, si soit
+le thé soit les bonbons sont à moins de 5, le goûter est toujours mauvais
+(0).
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/TeaParty.html b/src/lessons/welcome/bat/bool2/TeaParty.html
new file mode 100644
index 0000000..a6eff3d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeaParty.html
@@ -0,0 +1,11 @@
+<h1>TeaParty</h1>
+We are having
+a party with amounts of tea and candy. Return the int outcome of the
+party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if both
+tea and candy are at least 5. However, if either tea or candy is at
+least double the amount of the other one, the party is great (2).
+However, in all cases, if either tea or candy is less than 5, the party
+is always bad (0).
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/TeaParty.java b/src/lessons/welcome/bat/bool2/TeaParty.java
new file mode 100644
index 0000000..94e00ea
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeaParty.java
@@ -0,0 +1,66 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class TeaParty extends BatExercise {
+	public TeaParty(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("teaParty");
+		myWorld.addTest(VISIBLE, 6, 8) ;
+		myWorld.addTest(VISIBLE, 3, 8) ;
+		myWorld.addTest(VISIBLE, 20, 6) ;
+		myWorld.addTest(INVISIBLE, 12, 6) ;
+		myWorld.addTest(INVISIBLE, 11, 6) ;
+		myWorld.addTest(INVISIBLE, 11, 4) ;
+		myWorld.addTest(INVISIBLE, 4, 5) ;
+		myWorld.addTest(INVISIBLE, 5, 5) ;
+		myWorld.addTest(INVISIBLE, 6, 6) ;
+		myWorld.addTest(INVISIBLE, 5, 10) ;
+		myWorld.addTest(INVISIBLE, 5, 9) ;
+		myWorld.addTest(INVISIBLE, 10, 4) ;
+		myWorld.addTest(INVISIBLE, 10, 20) ;
+
+		templatePython("teaParty", 
+				"def teaParty(tea, candy):\n",
+				"	if (tea < 5 or candy < 5):\n"+
+				"		return 0\n"+
+				"	elif (tea >= 2*candy or candy >= 2*tea):\n"+ 
+				"		return 2\n"+
+				"	else:\n" +
+				"		return 1\n");
+		templateScala("teaParty", new String[]{"Int","Int"}, 
+				"def teaParty(tea:Int, candy:Int): Int = {\n",
+				"	if (tea < 5 || candy < 5)\n"+
+				"		return 0\n"+
+				"	else if (tea >= 2*candy || candy >= 2*tea)\n"+ 
+				"		return 2\n"+
+				"	else\n" +
+				"		return 1\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( teaParty((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int teaParty(int tea, int candy) {
+		/* BEGIN SOLUTION */
+		if (tea < 5 || candy < 5)
+			return 0;
+		else if (tea >= 2*candy || candy >= 2*tea) 
+			return 2;
+		else // (tea >= 5 && candy >= 5)
+			return 1;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/TeenSum.fr.html b/src/lessons/welcome/bat/bool2/TeenSum.fr.html
new file mode 100644
index 0000000..022222a
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeenSum.fr.html
@@ -0,0 +1,8 @@
+<h1>Somme d'ados</h1>
+Étant donné deux nombres entiers (a et b), retournez leur somme. Cependant,
+les valeurs ados (dans l'intervale [13;19]) sont particulièrement
+chanceuse. Donc, si l'un des nombres est ado, retournez simplement 19.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/TeenSum.html b/src/lessons/welcome/bat/bool2/TeenSum.html
new file mode 100644
index 0000000..b34bdc9
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeenSum.html
@@ -0,0 +1,8 @@
+<h1>TeenSum</h1>
+Given 2 ints,
+a and b, return their sum. However, "teen" values in the range 13..19
+inclusive, are extra lucky. So if either value is a teen, just return
+19.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/TeenSum.java b/src/lessons/welcome/bat/bool2/TeenSum.java
new file mode 100644
index 0000000..e6bb5df
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TeenSum.java
@@ -0,0 +1,63 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class TeenSum extends BatExercise {
+	public TeenSum(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("teenSum");
+		myWorld.addTest(VISIBLE, 3, 4) ;
+		myWorld.addTest(VISIBLE, 10, 13) ;
+		myWorld.addTest(VISIBLE, 13, 2) ;
+		myWorld.addTest(INVISIBLE, 3, 19) ;
+		myWorld.addTest(INVISIBLE, 13, 13) ;
+		myWorld.addTest(INVISIBLE, 10, 10) ;
+		myWorld.addTest(INVISIBLE, 6, 14) ;
+		myWorld.addTest(INVISIBLE, 15, 2) ;
+		myWorld.addTest(INVISIBLE, 19, 19) ;
+		myWorld.addTest(INVISIBLE, 19, 20) ;
+		myWorld.addTest(INVISIBLE, 2, 18) ;
+		myWorld.addTest(INVISIBLE, 12, 4) ;
+		myWorld.addTest(INVISIBLE, 2, 20) ;
+		myWorld.addTest(INVISIBLE, 2, 17) ;
+		myWorld.addTest(INVISIBLE, 2, 16) ;
+		myWorld.addTest(INVISIBLE, 6, 7) ;
+
+		templatePython("teenSum", 
+				"def teenSum(a, b):\n",
+				"	if ((a >= 13 and a <= 19) or (b >= 13 and b <= 19)):\n"+
+				"		return 19\n"+
+				"	else:\n"+
+				"		return a+b\n");
+		templateScala("teenSum", new String[]{"Int","Int"},
+				"def teenSum(a:Int, b:Int):Int = {\n",
+				"	if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19))\n"+
+				"		return 19\n"+
+				"	else\n"+
+				"		return a+b\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( teenSum((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int teenSum(int a, int b) {
+		/* BEGIN SOLUTION */
+		if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19))
+			return 19;
+		else
+			return a+b;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/TwoAsOne.fr.html b/src/lessons/welcome/bat/bool2/TwoAsOne.fr.html
new file mode 100644
index 0000000..ca91d2b
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TwoAsOne.fr.html
@@ -0,0 +1,7 @@
+<h1>Deux pour un</h1>
+Soit trois entiers, a b c, renvoyez vrai si il est possible d'en additionner
+deux d'entre eux pour obtenir le troisième.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/TwoAsOne.html b/src/lessons/welcome/bat/bool2/TwoAsOne.html
new file mode 100644
index 0000000..641100d
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TwoAsOne.html
@@ -0,0 +1,5 @@
+<h1>TwoAsOne</h1>
+Given three ints, a b c, return true if it is possible to add two of the ints to get the third.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/TwoAsOne.java b/src/lessons/welcome/bat/bool2/TwoAsOne.java
new file mode 100644
index 0000000..5870b66
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/TwoAsOne.java
@@ -0,0 +1,50 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class TwoAsOne extends BatExercise {
+	public TwoAsOne(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("twoAsOne");
+		myWorld.addTest(VISIBLE, 1, 2, 3) ;
+		myWorld.addTest(VISIBLE, 3, 1, 2) ;
+		myWorld.addTest(VISIBLE, 3, 2, 2) ;
+		myWorld.addTest(INVISIBLE, 2, 3, 1) ;
+		myWorld.addTest(INVISIBLE, 5, 3, -2) ;
+		myWorld.addTest(INVISIBLE, 5, 3, -3) ;
+		myWorld.addTest(INVISIBLE, 2, 5, 3) ;
+		myWorld.addTest(INVISIBLE, 9, 5, 5) ;
+		myWorld.addTest(INVISIBLE, 9, 4, 5) ;
+		myWorld.addTest(INVISIBLE, 5, 4, 9) ;
+		myWorld.addTest(INVISIBLE, 3, 3, 0) ;
+		myWorld.addTest(INVISIBLE, 3, 3, 2) ;
+
+		templatePython("twoAsOne", 
+				"def twoAsOne(a, b, c):\n",
+				"   return (a + b == c) or (a + c == b) or (b + c == a)");
+		templateScala("twoAsOne",new String[]{"Int","Int","Int"}, 
+				"def twoAsOne(a:Int, b:Int, c:Int):Boolean = {\n",
+				"   return (a + b == c) || (a + c == b) || (b + c == a)\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( twoAsOne((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean twoAsOne(int a, int b, int c) {
+		/* BEGIN SOLUTION */
+		return (a + b == c) || (a + c == b) || (b + c == a);
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bat/bool2/WithoutDoubles.fr.html b/src/lessons/welcome/bat/bool2/WithoutDoubles.fr.html
new file mode 100644
index 0000000..9c2bc34
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/WithoutDoubles.fr.html
@@ -0,0 +1,8 @@
+<h1>Sans double</h1>
+Renvoyez la somme du jet de deux dés à six faces. Cependant, si noDoubles
+est vrai et que les deux dés ont la même valeur, incrémentez l'un des dés à
+la valeur suivante, en le mettant à 1 si sa valeur était 6.
+
+
+<p>Cet exercice a été extrait de l'excellent site d'exercices
+http://javabat.com/ pour PLM.</p>
diff --git a/src/lessons/welcome/bat/bool2/WithoutDoubles.html b/src/lessons/welcome/bat/bool2/WithoutDoubles.html
new file mode 100644
index 0000000..9fa4f14
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/WithoutDoubles.html
@@ -0,0 +1,8 @@
+<h1>WithoutDoubles</h1>
+Return the
+sum of two 6-sided dice rolls, each in the range 1..6. However, if
+noDoubles is true, if the two dice show the same value, increment one
+die to the next value, wrapping around to 1 if its value was 6.
+
+
+<p>This exercise was converted to PLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bat/bool2/WithoutDoubles.java b/src/lessons/welcome/bat/bool2/WithoutDoubles.java
new file mode 100644
index 0000000..7104e8a
--- /dev/null
+++ b/src/lessons/welcome/bat/bool2/WithoutDoubles.java
@@ -0,0 +1,68 @@
+/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
+
+package lessons.welcome.bat.bool2;
+import plm.core.model.lesson.Lesson;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+public class WithoutDoubles extends BatExercise {
+	public WithoutDoubles(Lesson lesson) {
+		super(lesson);
+
+		BatWorld myWorld = new BatWorld("withoutDoubles");
+		myWorld.addTest(VISIBLE, 2, 3, true) ;
+		myWorld.addTest(VISIBLE, 3, 3, true) ;
+		myWorld.addTest(VISIBLE, 3, 3, false) ;
+		myWorld.addTest(INVISIBLE, 2, 3, false) ;
+		myWorld.addTest(INVISIBLE, 5, 4, true) ;
+		myWorld.addTest(INVISIBLE, 5, 4, false) ;
+		myWorld.addTest(INVISIBLE, 5, 5, true) ;
+		myWorld.addTest(INVISIBLE, 5, 5, false) ;
+		myWorld.addTest(INVISIBLE, 6, 6, true) ;
+		myWorld.addTest(INVISIBLE, 6, 6, false) ;
+		myWorld.addTest(INVISIBLE, 1, 6, true) ;
+		myWorld.addTest(INVISIBLE, 6, 1, false) ;
+
+		templatePython("withoutDoubles", 
+				"def withoutDoubles(die1, die2, noDoubles):\n",
+				"	if (noDoubles and (die1 == die2)):\n"+
+				"		if (die1 == 6):\n"+
+				"			return 1 + die2\n"+
+				"		else:\n"+
+				"			return die1 + 1 + die2\n"+
+				"	else:\n"+
+				"		return die1 + die2\n");
+		templateScala("withoutDoubles", new String[]{"Int","Int","Boolean"},
+				"def withoutDoubles(die1:Int, die2:Int, noDoubles:Boolean):Int = {\n",
+				"	if (noDoubles && (die1 == die2)) {\n"+
+				"		if (die1 == 6)\n"+
+				"			return 1 + die2\n"+
+				"		else\n"+
+				"			return die1 + 1 + die2\n"+
+				"	} else\n"+
+				"		return die1 + die2\n"+
+				"}");
+		setup(myWorld);
+	}
+
+	public void run(BatTest t) {
+		/* BEGIN SKEL */
+		t.setResult( withoutDoubles((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Boolean)t.getParameter(2)) );
+		/* END SKEL */
+	}
+
+	/* BEGIN TEMPLATE */
+	int withoutDoubles(int die1, int die2, boolean noDoubles) {
+		/* BEGIN SOLUTION */
+		if (noDoubles && (die1 == die2)) {
+			if (die1 == 6)
+				return 1 + die2;
+			else 
+				return die1 + 1 + die2;
+		} else 
+			return die1 + die2;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/bdr/BDR.fr.html b/src/lessons/welcome/bdr/BDR.fr.html
index b201b76..f98430a 100644
--- a/src/lessons/welcome/bdr/BDR.fr.html
+++ b/src/lessons/welcome/bdr/BDR.fr.html
@@ -6,58 +6,63 @@ doit bouger sur un tapis prévu à cet effet en fonction des consignes
 présentées à l'écran en rythme avec la musique. Mais avant cela, nous avons
 quelques détails à étudier.</p>
 
-<h3 class="Java">Conditionnelles sans accolades</h3>
-<p class="Java">
+[!java|scala]
+<h3>Conditionnelles sans accolades</h3>
+<p>
 Il y a un détail que nous avons omis à propos de la syntaxe des
 conditionnelles : si une branche ne contient qu'une seule instruction, les
 accolades sont optionnelles. Ainsi, les deux extraits suivants sont
 équivalents:</p>
 
- <pre class="Java">if (<b>condition</b>) {
+ <pre>if (<b>condition</b>) {
     <b>quoiFaireSiLaConditionEstVraie();</b>
 } else {
     <b>quoiFaireSinon();</b>
 }</pre>
- <pre class="Java">if (<b>condition</b>)
+ <pre>if (<b>condition</b>)
     <b>quoiFaireSiLaConditionEstVraie();</b>
 else
     <b>quoiFaireSinon();</b></pre>
 
-<p class="Java">Mais attention, ceci peut être dangereux si on enchaîne les <tt>if</tt>
-comme dans l'exemple suivant. </p>
-<pre class="Java">if (isOverBaggle())    
+<p>Vous pouvez faire de même avec les boucles dont le corps se réduit à une
+seule instruction. Mais attention, ceci peut être dangereux si on enchaîne
+les <tt>if</tt> comme dans l'exemple suivant. </p>
+<pre>if (estSurBiscuit())    
      if (x == 5)
-          turnLeft();
+          gauche();
 else
-     turnRight();
-forward();</pre>
+     droite();
+avance();</pre>
 
-<p class="Java">En fait, ça ne tourne pas à droite quand il n'y a pas un baggle par terre ET
+<p>En fait, ça ne tourne pas à droite quand il n'y a pas un baggle par terre ET
 que x vaut 5, mais quand la buggle a trouvé un baggle, et que x vaut une
 autre valeur. Autrement dit, la buggle lit le code précédent comme suit
 (notez que le <tt>else</tt> est décalé vers la droite par rapport à
 précédemment) :</p>
-<pre class="Java">if (isOverBaggle())    
+<pre>if (estSurBiscuit())    
         if (x == 5)
-            turnLeft();
+            gauche();
         else
-            turnRight();
-forward();</pre>
-
-<p class="Java">La première leçon, c'est que l'indentation aide les humains à comprendre,
-mais elle est sans importance pour la signification du code. On aurait tout
-aussi bien pu écrire le code suivant et obtenir le même résultat. Mais
-attention, si on veut qu'un humain puisse relire le code, l'indentation
-devient très importante voire indispensable. C'est par exemple le cas si
-votre code doit être relu par un professeur (pour qu'il le note ou pour lui
-poser une question), ou si vous comptez réutiliser votre code plus tard.</p> 
-
-<pre class="Java">if (isOverBaggle()) if (x == 5) turnLeft(); else turnRight(); forward();</pre>
-
-<p class="Java">La seconde leçon, c'est qu'une branche <tt>else</tt> se raccroche toujours
+            droite();
+avance();</pre>
+
+<p>La première leçon, c'est que l'indentation est très importante pour que les
+humains puissent comprendre le code, mais elle ne change pas la
+signification du code pour la machine. On aurait tout aussi bien pu écrire
+le code suivant et obtenir le même résultat. Mais attention, si on veut
+qu'un humain puisse relire le code, l'indentation est quasi
+indispensable. C'est par exemple le cas si votre code doit être relu par un
+professeur (pour qu'il le note ou pour lui poser une question), ou si vous
+comptez réutiliser votre code plus tard, ou même si vous devez debugger
+votre propre code après l'avoir écrit.</p> 
+
+<pre>if (estSurBiscuit()) if (x == 5) gauche(); else droite(); avance();</pre>
+
+<p>La seconde leçon, c'est qu'une branche <tt>else</tt> se raccroche toujours
 au <tt>if</tt> le plus proche. C'est parfois un peu contre-intuitif, et il
 est préférable d'ajouter plus d'accolades que nécessaire pour lever toute
 ambiguïté.</p>
+[/!]
 
 <h3>Enchaînements de conditionnelles</h3>
 
@@ -71,99 +76,90 @@ réalisées. C'est à dire, que s'il pleut un 14 juillet très chaud, on ne veut
 pas que la buggle sorte avec un parapluie, de l'eau et un drapeau, mais
 juste avec un parapluie. Le code suivant est donc faux.</p>
 
-<pre class="Java">if (ilPleut()) {
-  prendreParapluie();
-}
-if (ilFaitChaud()) {
-  prendreDeLEau();
-} 
-if (sommes14Juillet()) {
-  prendreDrapeau();
-}</pre>
-
-<pre class="Python">if ilPleut():
-    prendreParapluie()
+<pre>[!java|scala]if (ilPleut())
+    prendreParapluie();
+if (ilFaitChaud())
+    prendreDeLEau();
+if (sommes14Juillet())
+    prendreDrapeau();[/!][!python]if ilPleut():
+    prendreParapluie()
 if ilFaitChaud():
-    prendreDeLEau()
+    prendreDeLEau()
 if sommes14Juillet():
-    prendreDrapeau()
-</pre>
+    prendreDrapeau()[/!]</pre>
 
 
 <p>En effet, toutes les conditions sont évaluées les unes après les autres, et
 on risque donc d'aller au défilé un jour de pluie. À la place, il faut donc
-écrire quelque chose comme :</p>
+écrire quelque chose comme ce qui suit pour s'assurer que si l'on trouve une
+condition vraie, on n'évalue pas les suivants.</p>
 
-<pre class="Java">if (ilPleut()) {
-    prendreParapluie();
+<pre>[!java|scala]if (ilPleut()) {
+    prendreParapluie();
 } else {
-    if (ilFaitChaud()) {
-        prendreDeLEau();
-    } else {
-        if (sommes14Juillet()) {
-            prendreDrapeau();
-        }
-    }
-}</pre>
-
-<pre class="Python">if ilPleut():
-    prendreParapluie()
+    if (ilFaitChaud()) {
+        prendreDeLEau();
+    } else {
+        if (sommes14Juillet()) {
+            prendreDrapeau();
+        }
+    }
+}[/!][!python]if ilPleut():
+    prendreParapluie()
 else:
-    if ilFaitChaud():
-        prendreDeLEau()
-    else:
-        if sommes14Juillet():
-            prendreDrapeau()
-</pre>
+    if ilFaitChaud():
+        prendreDeLEau()
+    else:
+        if sommes14Juillet():
+            prendreDrapeau()[/!]</pre>
 
 
-<p class="Java">Une telle cascade de conditionnelles est un peu difficile à lire, et il est
-préférable d'omettre les accolades associées aux <tt>else</tt> comme
+<p>Une telle cascade de conditionnelles est un peu difficile à lire, et il est
+préférable
+[!java|scala] d'omettre les accolades associées aux <tt>else</tt> comme
 suit. Il y a même certains langages qui introduisent un mot-clé spécial pour
-ces <tt>else if</tt> (mais pas Java).</p>
-<pre class="Java">if (ilPleut()) {
-  prendreParapluie();
+ces <tt>else if</tt> (mais pas [!thelang]).[/!]
+[!python] d'introduire les sous-blocs avec le mot-clé <code>elif</code>
+(abréviation de «else if») pour expliciter ces branches «sinon si».[/!]
+</p>
+
+<pre>[!java|scala]if (ilPleut()) { 
+    prendreParapluie();
 } else if (ilFaitChaud()) {
-  prendreDeLEau();
+    prendreDeLEau();
 } else if (sommes14Juillet()) {
-  prendreDrapeau();
-}</pre>
-
-<p class="Python">Une telle cascade de conditionnelles est un peu difficile à lire, et il est
-préférable d'omettre les indentations supplémentaires associées aux
-<tt>else</tt> comme suit. Le mot-clé <tt>elif</tt> du langage Python permet
-de
-faire ceci facilement.
-<pre class="Python">if ilPleut():
-    prendreParapluie()
+    prendreDrapeau();
+}[/!][!python]if ilPleut():
+    prendreDrapeau()
 elif ilFaitChaud():
-    prendreDeLEau()
+    prendreDeLEau()
 elif sommes14Juillet():
-    prendreDrapeau()
-</pre>
+    prendreDrapeau()[/!]</pre>
 
 <h3>Les graffitis dans le monde des buggles</h3>
 
-Les buggles peuvent écrire des choses par terre dans leur monde. Pour ce
-faire, elles utilisent les quatre méthodes suivantes:
+<p>Les buggles peuvent écrire des choses par terre dans leur monde. Pour ce
+faire, elles utilisent les quatre méthodes suivantes:</p>
 
 <ul>
-  <li class="Java"><code>boolean isOverMessage()</code> : renvoie vrai (<code>true</code>) si
-et seulement s'il y a un message écrit par terre.</li>
-  <li class="python"><code>boolean isOverMessage()</code> : renvoie vrai (<code>True</code>) si
-et seulement s'il y a un message écrit par terre.</li>
-  <li><code>String readMessage()</code> : renvoie le message qu'il y a écrit par
-terre (s'il y a rien, on obtient une chaîne vide).</li>
-  <li><code>void writeMessage(String msg)</code> : écrit le message spécifié en
-argument par terre. S'il y a déjà quelque chose écrit par terre, on ajoute
-le nouveau message à la fin du précédent.</li>
-  <li><code>void clearMessage()</code> : efface ce qui est écrit par terre.</li>
+  <li><code>[!java]boolean[/!] estSurMessage()[!scala]:Boolean[/!]</code>: renvoie
+<code>[!java|scala]true[/!][!python]True[/!]</code> si et seulement s'il y a
+un message écrit par terre.</li>
+  <li><code>[!java]String [/!]readMessage()[!java]: String[/!]</code> : renvoie le
+message qu'il y a écrit par terre (s'il y a rien, on obtient une chaîne
+vide).</li>
+  <li><code>[!java]void[/!] writeMessage([!java]String [/!]msg[!java]:
+String[/!])</code> : écrit le message spécifié en argument par terre. S'il y
+a déjà quelque chose écrit par terre, on ajoute le nouveau message à la fin
+du précédent.</li>
+  <li><code>[!java]void [/!]clearMessage()</code> : efface ce qui est écrit par
+terre.</li>
 </ul>
 
 
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> L'objectif est donc d'organiser une partie de BDR entre
-les buggles en leur apprenant à bouger en fonction des indications écrites
-par terre.  Ces indications sont des messages au sol, avec le code suivant:
+<h3>Objectif de cet exercice</h3>L'objectif est donc d'organiser une partie de BDR entre les buggles en leur
+apprenant à bouger en fonction des indications écrites par terre.  Ces
+indications sont des messages au sol, avec le code suivant:
 
 <table border="1">
  <tr><td>Indication</td>
@@ -172,7 +168,7 @@ par terre.  Ces indications sont des messages au sol, avec le code suivant:
 
  <tr><td>R</td><td>Tourner à droite et avancer d'une case</td><td>Right</td></tr>
  <tr><td>L</td><td>Tourner à gauche et avancer d'une case</td><td>Left</td></tr>
- <tr><td>I</td><td>Tourner en sens inverse (demi tour) et avancer d'une case</td><td>Inverse</td></tr>
+ <tr><td>I</td><td>Se retourner (demi-tour) et avancer d'une case</td><td>Inverse</td></tr>
 
  <tr><td>A</td><td>Avancer d'une case</td><td>Première lettre de l'alphabet</td></tr>
  <tr><td>B</td><td>Avancer de deux cases</td><td>Deuxième lettre de l'alphabet</td></tr>
@@ -181,58 +177,43 @@ par terre.  Ces indications sont des messages au sol, avec le code suivant:
  <tr><td>Z</td><td>Reculer d'une case</td><td>A une lettre de la fin de l'alphabet</td></tr>
  <tr><td>Y</td><td>Reculer de deux cases</td><td>A deux lettres de la fin de l'alphabet</td></tr>
  <tr><td>X</td><td>Reculer de trois cases</td><td>A trois lettres de la fin de l'alphabet</td></tr>
+ <tr><td><i>(n'importe quoi d'autre)</i></td><td>Arrêter de dancer.</td><td></td></tr>
 </table>
 
-<p>Dans tous les autres cas, il faut s'arrêter.</p>
-
-<p class="Java">Écrivez le code de la danse dans la méthode <code>run()</code> dont le
-prototype se trouve déjà dans l'éditeur.</p>
-
-<p class="python">Ecrivez directement le code de la danse dans l'éditeur, en dehors de toute
-fonction.</p>
-
 <h3>Indications</h3>
 
 Cet exercice peut sembler un peu compliqué, mais il s'agit principalement de
 traduire le contenu du tableau ci-dessus dans un enchaînement de
 conditionnelles.
 
-
-
-<p>La première subtilité est que nous utiliserons la méthode <code>char
-getIndication()</code> à la place de <code>String
-readMessage()</code>. Cette méthode, qui n'est connue que des buggles des
-exercice BDR, renvoie le premier caractère du message au sol (ou ' ' s'il
-n'y a rien d'écrit au sol). </p>
-
-<p class="Java">L'autre subtilité est de travailler tant qu'on du travail à faire, i.e. tant
-qu'on a pas trouvé une case n'étant pas décrite dans le tableau. Le plus
-simple pour cela est d'utiliser une variable booléenne (<code>fini</code>)
-en condition d'arrêt d'une boucle. Cette variable est initialisée à la
-valeur faux (<code>false</code>). Si on trouve une case ne répondant à
-aucune ligne du tableau, on change la valeur de cette variable à vrai
-(<code>true</code>. Cela arrête la boucle, et le programme s'arrête. </p>
-
-<p class="python">L'autre subtilité est de travailler tant qu'on du travail à faire, i.e. tant
-qu'on a pas trouvé une case n'étant pas décrite dans le tableau. Le plus
-simple pour cela est d'utiliser une variable booléenne (<code>fini</code>)
-en condition d'arrêt d'une boucle. Cette variable est initialisée à la
-valeur faux (<code>False</code>). Si on trouve une case ne répondant à
-aucune ligne du tableau, on change la valeur de cette variable à vrai
-(<code>True</code>. Cela arrête la boucle, et le programme s'arrête. </p>
-
-<p>Les fonctions dont le type de retour est <tt>void</tt> peuvent contenir des
-<tt>return</tt> sans valeur associée. Cela interrompt immédiatement leur
-exécution.</p>
+<p>Vous devez continuer à danser tant qu'il reste des pas de danse à
+faire. c-à-d tant qu'on a pas trouvé une case n'étant pas décrite dans le
+tableau. Le plus simple pour cela est d'utiliser une variable booléenne
+(<code>fini</code>) en condition d'arrêt d'une boucle while. Cette variable
+est initialisée à la valeur faux
+(<code>[!java|scala]false[/!][!python]False[/!]</code>). Si on trouve une
+case ne répondant à aucune ligne du tableau, on change la valeur de cette
+variable à vrai (<code>[!java|scala]true[/!][!python]True[/!]</code>). Cela
+arrête la boucle, et le programme. </p>
+
+[!java]
+<p>Une autre subtilité est que déterminer si des chaînes de caractères est un
+peu pénible en Java. Nous utiliserons donc la méthode <code>char
+getIndication()</code> à la place de <code>String litMessage()</code>. Cette
+méthode, qui n'est connue que des buggles des exercice BDR, renvoie le
+premier caractère du message au sol (ou ' ' --une espace-- s'il n'y a rien
+d'écrit au sol). Cela nous permet de travailler avec des caractères
+(<code>char</code>), qui sont moins pénibles que les chaînes.</p>
+[/!]
 
 <h3>Trucs et astuces</h3>
 
 Si vous ne parvenez plus à comprendre pourquoi votre buggle n'exécute pas
-les pas de danse demandés, essayez d'ajouter <code>brushDown()</code> dans
-votre méthode. Cela demandera à la buggle de poser un crayon par terre,
-laissant une trace au sol quand elle avance. Cela devrait vous aider à
-suivre sa trajectoire, mais pensez à retirer cette appel lorsque vous voulez
-tester si votre solution marche : on vous demande de faire danser les
+les pas de danse demandés, essayez d'ajouter <code>baisseBrosse()</code>
+dans votre méthode. Cela demandera à la buggle de poser une brosse par
+terre, laissant une trace au sol quand elle avance. Cela devrait vous aider
+à suivre sa trajectoire, mais pensez à retirer cette appel lorsque vous
+voulez tester si votre solution marche : on vous demande de faire danser les
 buggles, pas de dégrader le dance floor.
 
 <p>Quand votre programme fonctionne enfin, passez à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/bdr/BDR.html b/src/lessons/welcome/bdr/BDR.html
index 842566b..cf81d61 100644
--- a/src/lessons/welcome/bdr/BDR.html
+++ b/src/lessons/welcome/bdr/BDR.html
@@ -1,230 +1,204 @@
-<h2>Buggle Dance Revolution (BDR)</h2>
-
-<p>Today is a great day: we will learn the buggles to play Dance Revolution,
-this game beloved of some students where the player has to move its feet on
-the carpet according to the instructions presented on the screen, and following
-the music. But before that, we have some details to study first.</p>
-
-<h3 class="Java">Conditionals without curly braces</h3>
-<p class="Java">
-There is one detail we omitted about the conditional syntax: if a branch
-contains only one instruction, then the curly braces become optional. So,
-the two chunk of code are equivalent:</p>
-
- <pre class="Java">if (<b>condition</b>) {
-    <b>whatToDoIfTheConditionIsTrue();</b>
-} else {
-    <b>whatToDoElse();</b>
-}</pre>
- <pre class="Java">if (<b>condition</b>) 
-    <b>whatToDoIfTheConditionIsTrue();</b>
-else
-    <b>whatToDoElse();</b></pre>
-
-<p class="Java">But beware, this becomes dangerous if you chain the <tt>if</tt> instructions
-like this: </p>
-<pre class="Java">if (isOverBaggle())    
-     if (x == 5)
-          turnLeft();
-else
-     turnRight();
-forward();</pre>
-
-<p class="Java">In fact, it does not turn right when there is no baggle on the ground AND x
-equals 5, but when the buggle found a baggle on the ground and x equals
-anything but 5. Putting this otherwise, the buggle understands the previous
-code as if it were written the following way (note that the <tt>else</tt>
-were moved to the right):</p>
-<pre class="Java">if (isOverBaggle())    
-        if (x == 5)
-            turnLeft();
-        else
-            turnRight();
-forward();</pre>
-
-<p class="Java">The first lesson of this is that the indentation is very helpful to help
-humans understanding, but it's of no importance for the actual meaning of
-the code. We could have written the following code and obtain the same
-result. But beware, if you want a human to read and review your code, you
-really want to indent it correctly. That's for example the case if you want
-a professor to read it (to grade it or to answer a question about it), or if
-you want to reuse your code later.</p> 
-
-<pre class="Java">if (isOverBaggle()) if (x == 5) turnLeft(); else turnRight(); forward();</pre>
-
-<p class="Java">The second lesson is that a <tt>else</tt> branch always connects to the
-closest <tt>if</tt>. This may be a bit troublesome in some case, and it may
-be easier to add more braces than strictly needed to remove any ambiguity.</p>
-
-<h3>Chaining conditionals</h3>
-
-<p>You sometimes want to ask the buggle something similar to:</p> 
-<pre>if it's raining, take an umbrella;
-if not, and if it's a hot day, take a bottle of water;
-if not and if it's July 4th, take an american flag</pre>
-
-<p>The trap is that we want at most one of these actions to be taken. That is
-to say, if it's raining a very hot July 4th, we don't want the buggle to get
-outside with an umbrella, some water and a flag, but simply with an
-umbrella. The following code is thus WRONG.</p>
-
-<pre class="Java">if (rainy()) {
-    takeUmbrella();
-}
-if (hot()) {
-    takeWater();
-} 
-if (todayIsJuly4th()) {
-    takeFlag();
-}</pre>
-
-<pre class="Python">if rainy():
-    takeUmbrella()
-if hot():
-    takeWater()
-if todayIsJuly4th():
-    takeFlag()
-</pre>
-
-
-<p>Indeed, since the conditions are evaluated one after the other, there is a
-risk that you go to the July 4th march on a rainy day. Instead, we should
-use something like this:</p>
-
-<pre class="Java">if (rainy()) {
-    takeUmbrella();
-} else {
-    if (hotDay()) {
-        takeWater();
-    } else {
-        if (todayIsJuly4th()) {
-            takeFlag();
-        }
-    }
-}</pre>
-
-<pre class="Python">if rainy():
-    takeUmbrella()
-else:
-    if hotDay():
-        takeWater()
-    else:
-        if todayIsJuly4th():
-            takeFlag()
-</pre>
-
-
-<p class="Java">Such a cascade of conditionals are quite difficult to read, and it is better
-to omit the curly braces for the <tt>else</tt> statements. Some languages
-even introduce a specific construct for these <tt>else if</tt> (but Java
-doesn't).</p>
-<pre class="Java">if (rainy()) {
-    takeUmbrella();
-} else if (hotDay()) {
-    takeWater();
-} else if (todayIsJuly4th()) {
-    takeFlag();
-}</pre>
-
-<p class="Python">Such a cascade of conditionals are quite difficult to read, and it is better
-to omit extra indentation for the <tt>else</tt> statements. In Python, there is a specific 
-construct for this: <tt>elif</tt>.
-<pre class="Python">if rainy():
-    takeUmbrella()
-elif hotDay():
-    takeWater()
-elif todayIsJuly4th():
-    takeFlag()
-</pre>
-
-<h3>Graffitis in the Buggle World</h3>
-
-Buggles can write graffitis on the ground of their world. For that, they use
-the four following methods:
-
-<ul>
-  <li class="Java"><code>boolean isOverMessage()</code>: returns <code>true</code> if and only if there is a
-message on the ground.</li>
-  <li class="python"><code>boolean isOverMessage()</code>: returns <code>True</code> if and only if there is a
-message on the ground.</li>
-  <li><code>String readMessage()</code>: returns the message written on the ground
-(or an empty string if nothing is written).</li>
-  <li><code>void writeMessage(String msg)</code>: writes the specified message
-down on the ground. If there is already a message on the ground, the new
-content is added at the end of the existing message.</li>
-  <li><code>void clearMessage()</code>: clears what is written on the ground.</li>
-</ul>
-
-
-<h3>Exercise goal</h3><a name="Objectives">The goal is then to organize a BDR game between the
-buggles by learning them to move according to the instructions written on
-the ground. These instructions are messages written on the ground, with the
-following signification:
-
-<table border="1">
- <tr><td>Message</td>
-     <td>What to do</td>
-     <td>Mnemonic</td></tr>
-
- <tr><td>R</td><td>Turn right and move one step forward</td><td>Right</td></tr>
- <tr><td>L</td><td>Turn left and move one step forward</td><td>Left</td></tr>
- <tr><td>I</td><td>Turn back (U-turn) and move one step forward</td><td>Inverse</td></tr>
-
- <tr><td>A</td><td>Move one step forward</td><td>First letter of the alphabet</td></tr>
- <tr><td>B</td><td>Move two steps forward</td><td>Second letter of the alphabet</td></tr>
- <tr><td>C</td><td>Move three steps forward</td><td>Third letter of the alphabet</td></tr>
-
- <tr><td>Z</td><td>Move one step backward</td><td>One letter before the end of the alphabet</td></tr>
- <tr><td>Y</td><td>Move two steps backward</td><td>Two letters before the end of the alphabet</td></tr>
- <tr><td>X</td><td>Move three steps backward</td><td>Three letters before the end of the alphabet</td></tr>
-</table>
-
-<p>In any other case, you should stop</p>
-
-<p class="Java">Write the code of the dance in the <code>run()</code> method which prototype
-is already in the editor.</p>
-
-<p class="python">Write the code of the dance directly in the editor,
-out of any function.</p>
-
-<h3>Indications</h3>
-
-This exercise may seem a bit complex at the first glance, but it comes down
-to summarizing the information above in a sequence of conditionals.
-
-
-
-<p>The first subtlety is that we use the <code>char getIndication()</code>
-instead of <code>String readMessage()</code>. This method, only known by the
-buggles of this exercise, return the first char of the message written on
-the ground (or ' ' if nothing is written down). </p>
-
-<p class="Java">The other subtlety is to keep working as long as there is some work to do,
-i.e., as long as we did not find a cell which content is not described in
-the table. The easier for that is to use a boolean variable (<code>finished</code>)
-that is initialized to <code>false</code> as termination condition for the loop.
-As soon as the buggle find a cell with a value not described in the table, the boolean variable is set to <code>false</code>.
-Thus the loop, will stop and the program will terminate. </p>
-
-<p class="python">The other subtlety is to keep working as long as there is some work to do,
-i.e., as long as we did not find a cell which content is not described in
-the table. The easier for that is to use a boolean variable (<code>finished</code>)
-that is initialized to <code>False</code> as termination condition for the loop.
-As soon as the buggle find a cell with a value not described in the
-table, the boolean variable is set to <code>False</code>.
-Thus the loop, will stop and the program will terminate. </p>
-
-<p>The functions having <code>void</code> as return type can contain some
-<tt>return</tt> without any associated value. It interrupts immediately
-their execution.</p>
-
-<h3>Tips and Hints</h3>
-
-If you fail understanding why the buggle does not execute the expected
-steps, try adding <code>brushDown()</code> in your method. This asks the
-buggle to put down a brush leaving a trail when it moves. It should help you
-understanding its trajectory, but do not forget to remove this call when you
-want to test whether your code is a valid solution to the exercise: you are
-asked to let the buggle dance, not to vandalize the dance floor.
-
-<p>When your program finally works, move on to the next exercise.</p>
+<h2>Buggle Dance Revolution (BDR)</h2>
+
+<p>Today is a great day: we will learn the buggles to play Dance Revolution,
+this game beloved of some students where the player has to move its feet on
+the carpet according to the instructions presented on the screen, and following
+the music. But before that, we have some details to study first.</p>
+
+[!java|scala]
+<h3>Conditionals without curly braces</h3>
+<p>
+There is one detail we omitted about the conditional syntax: if a branch
+contains only one instruction, then the curly braces become optional. So,
+the two chunk of code are equivalent:</p>
+
+ <pre>if (<b>condition</b>) {
+    <b>whatToDoIfTheConditionIsTrue();</b>
+} else {
+    <b>whatToDoElse();</b>
+}</pre>
+ <pre>if (<b>condition</b>) 
+    <b>whatToDoIfTheConditionIsTrue();</b>
+else
+    <b>whatToDoElse();</b></pre>
+
+<p>Actually, you can do the same for loops body that are reduced to one instruction only. 
+But beware, this becomes dangerous if you chain the <tt>if</tt> instructions like this: </p>
+<pre>if (isOverBaggle())    
+     if (x == 5)
+          left();
+else
+     right();
+forward();</pre>
+
+<p>In fact, it does not turn right when there is no baggle on the ground AND x
+equals 5, but when the buggle found a baggle on the ground and x equals
+anything but 5. Putting this otherwise, the buggle understands the previous
+code as if it were written the following way (note that the <tt>else</tt>
+were moved to the right):</p>
+<pre>if (isOverBaggle())    
+        if (x == 5)
+            left();
+        else
+            right();
+forward();</pre>
+
+<p>The first lesson of this is that the indentation is very important to help
+humans understanding, even if it does not change the actual meaning of
+the code. We could have written the following code and obtain the same
+result. But if you want a human to read and review your code, you
+really want to indent it correctly. That's for example the case if you want
+a professor to read it (to grade it or to answer a question about it), or if
+you want to reuse your code later, or even if you need to debug your code yourself.</p> 
+
+<pre>if (isOverBaggle()) if (x == 5) left(); else right(); forward();</pre>
+
+<p>The second lesson is that a <tt>else</tt> branch always connects to the
+closest <tt>if</tt>. This may be a bit troublesome in some case, and it may
+be easier to add more braces than strictly needed to remove any ambiguity.</p>
+[/!]
+
+<h3>Chaining conditionals</h3>
+
+<p>You sometimes want to ask the buggle something similar to:</p> 
+<pre>if it's raining, take an umbrella;
+if not, and if it's a hot day, take a bottle of water;
+if not and if it's July 4th, take an American flag</pre>
+
+<p>The trap is that we want at most one of these actions to be taken. That is
+to say, if it's raining a very hot July 4th, we don't want the buggle to get
+outside with an umbrella, some water and a flag, but simply with an
+umbrella. The following code is thus WRONG.</p>
+
+<pre>[!java|scala]if (rainy())
+    takeUmbrella();
+if (hot())
+    takeWater();
+if (todayIsJuly4th())
+    takeFlag();[/!][!python]if rainy():
+    takeUmbrella()
+if hot():
+    takeWater()
+if todayIsJuly4th():
+    takeFlag()[/!]</pre>
+
+
+<p>Indeed, since the conditions are evaluated one after the other, there is a
+risk that you go to the July 4th march on a rainy day. Instead, we should
+use something like this to ensure that once we found a true condition, we won't
+evaluate the next ones.</p>
+
+<pre>[!java|scala]if (rainy()) {
+    takeUmbrella();
+} else {
+    if (hotDay()) {
+        takeWater();
+    } else {
+        if (todayIsJuly4th()) {
+            takeFlag();
+        }
+    }
+}[/!][!python]if rainy():
+    takeUmbrella()
+else:
+    if hotDay():
+        takeWater()
+    else:
+        if todayIsJuly4th():
+            takeFlag()[/!]</pre>
+
+
+<p>Unfortunately, such a cascade of conditionals is quite difficult to read. It is better to 
+[!java|scala]omit the curly braces for the <tt>else</tt> statements. Some languages
+even introduce a specific construct for these <tt>else if</tt>, but not [!thelang].[/!]
+[!python]change the sub-blocks using the <code>elif</code> keyword to mark
+explicitly these "else if" branches.[/!]
+</p>
+
+<pre>[!java|scala]if (rainy()) { 
+    takeUmbrella();
+} else if (hotDay()) {
+    takeWater();
+} else if (todayIsJuly4th()) {
+    takeFlag();
+}[/!][!python]if rainy():
+    takeUmbrella()
+elif hotDay():
+    takeWater()
+elif todayIsJuly4th():
+    takeFlag()[/!]</pre>
+
+<h3>Graffiti in the Buggle World</h3>
+
+<p>Buggles can tag graffitis on the ground of their world. For that, they use
+the four following methods:</p>
+
+<ul>
+  <li><code>[!java]boolean[/!] isOverMessage()[!scala]:Boolean[/!]</code>: 
+    returns <code>[!java|scala]true[/!][!python]True[/!]</code> if and only if there is a
+    message on the ground.</li>
+  <li><code>[!java]String[/!] readMessage()[!scala]: String[/!]</code>: 
+    returns the message written on the ground (or an empty string if nothing is written).</li>
+  <li><code>[!java]void[/!] writeMessage([!java]String [/!]msg[!scala]: String[/!])</code>:
+    writes the specified message down on the ground. If there is already a message on the
+    ground, the new content is added at the end of the existing message.</li>
+  <li><code>[!java]void [/!]clearMessage()</code>: clears what is written on the ground.</li>
+</ul>
+
+
+<h3>Exercise goal</h3>The goal is then to organize a BDR game between the
+buggles by learning them to move according to the instructions written on
+the ground. These instructions are messages written on the ground, with the
+following signification:
+
+<table border="1">
+ <tr><td>Message</td>
+     <td>What to do</td>
+     <td>Mnemonic</td></tr>
+
+ <tr><td>R</td><td>Turn right and move one step forward</td><td>Right</td></tr>
+ <tr><td>L</td><td>Turn left and move one step forward</td><td>Left</td></tr>
+ <tr><td>I</td><td>Turn back (U-turn) and move one step forward</td><td>Inverse</td></tr>
+
+ <tr><td>A</td><td>Move one step forward</td><td>First letter of the alphabet</td></tr>
+ <tr><td>B</td><td>Move two steps forward</td><td>Second letter of the alphabet</td></tr>
+ <tr><td>C</td><td>Move three steps forward</td><td>Third letter of the alphabet</td></tr>
+
+ <tr><td>Z</td><td>Move one step backward</td><td>One letter before the end of the alphabet</td></tr>
+ <tr><td>Y</td><td>Move two steps backward</td><td>Two letters before the end of the alphabet</td></tr>
+ <tr><td>X</td><td>Move three steps backward</td><td>Three letters before the end of the alphabet</td></tr>
+ <tr><td><i>(anything else)</i></td><td>Stop dancing.</td><td></td></tr>
+</table>
+
+<h3>Indications</h3>
+
+This exercise may seem a bit complex at the first glance, but it comes down
+to summarizing the information of the table in a sequence of conditionals.
+
+<p>You have to keep dancing as long as there is some dancing steps to do,
+i.e., as long as we are not in cell which content is not described in the table. 
+The easier for that is to use a boolean variable (<code>finished</code>)
+as termination condition to a <code>while</code> loop.
+It should be initialized to <code>[!java|scala]false[/!][!python]False[/!]</code>, and 
+switched to <code>[!java|scala]true[/!][!python]True[/!]</code>
+as soon as the buggle find a cell with a value not described in the table.
+Thus the loop, will stop and the program will terminate. </p>
+
+[!java]
+<p>Another subtlety is that detecting if strings are equals is a bit annoying in Java.
+So, we use the <code>char getIndication()</code> instead of <code>String readMessage()</code>. 
+This method, only known by the buggles of this exercise, returns the first char of the message written on the ground 
+(or ' ' -- the space char --  if nothing is written down). It enables to work with chars instead of strings, that is 
+much simpler in Java.</p>
+[/!]
+
+<h3>Tips and Hints</h3>
+
+If you fail to understand why the buggle does not execute the expected
+steps, try adding <code>brushDown()</code> in your method. This asks the
+buggle to put down a brush leaving a trail when it moves. It should help you
+understanding its trajectory, but do not forget to remove this call when you
+want to test whether your code is a valid solution to the exercise: you are
+asked to let the buggle dance, not to vandalize the dance floor.
+
+<p>When your program finally works, move on to the next exercise.</p>
diff --git a/src/lessons/welcome/bdr/BDR.java b/src/lessons/welcome/bdr/BDR.java
index 19590a3..21f698d 100644
--- a/src/lessons/welcome/bdr/BDR.java
+++ b/src/lessons/welcome/bdr/BDR.java
@@ -2,12 +2,12 @@ package lessons.welcome.bdr;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.BuggleWorldCell;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.BuggleWorldCell;
 
 public class BDR extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/bdr/BDR2.fr.html b/src/lessons/welcome/bdr/BDR2.fr.html
index d59aad6..1d27d50 100644
--- a/src/lessons/welcome/bdr/BDR2.fr.html
+++ b/src/lessons/welcome/bdr/BDR2.fr.html
@@ -1,41 +1,47 @@
 <h2>Buggle Dance Revolution 2 (BDR2)</h2>
 
-<p class="Java">Le BDR, c'est cool, mais c'est un peu le chaos. Tout d'abord, les buggles
+[!java|scala]
+<p>Le BDR, c'est cool, mais c'est un peu le chaos. Tout d'abord, les buggles
 gigotent en tout sens, et en plus, le code que vous avez écrit pour les
 faire bouger est très difficile à lire. Voici un nouveau monde de BDR, où
 les buggles vont faire une gentille petite ronde plus reposante. Nous
 profiterons de cette accalmie pour nettoyer un peu le code grâce aux
-nouveaux éléments que nous allons maintenant étudier.
+nouveaux éléments que nous allons maintenant étudier.</p>
 
-<h3 class="Java">Branchement conditionnel <tt>switch</tt></h3>
+<h3>[!java]Conditionnelle <code>switch</code>[/!][!scala]Les filtrages[/!]</h3>
 
-<p class="Java">
-Le plus difficile à lire du code précédent est certainement la cascade de
+<p>Le plus difficile à lire du code précédent est certainement la cascade de
 conditionnelles. Quelque part dans votre programme, vous avez sans doute
 écrit quelque chose comme:
 
-<pre class="Java">if (getIndication() == 'R') {
-  turnRight();
-  forward();
-} else if (getIndication() == 'L') {
-  turnLeft();
-  forward();
-} else if (getIndication() == 'I') {
-  turnBack();
-  forward();
-/* d'autres else if */
+<pre>if ([!java]getIndication() == 'R'[/!][!scala]litMessage() == "R"[/!]) {
+  droite();
+  avance();
+} else if ([!java]getIndication() == 'L'[/!][!scala]litMessage() == "L"[/!]) {
+  gauche();
+  avance();
+} else if ([!java]getIndication() == 'I'[/!][!scala]litMessage() == "I"[/!]) {
+  retourne();
+  avance();
+<span class="comment">/* d'autre if */</span>
 } else {
-  return;
+  fini = true;
 }
 </pre>
 
-<p class="Java">
-Quand on relit ce programme, on ne voit pas forcément tout de suite qu'il
-s'agit simplement d'un choix à 4 branches selon la valeur de
-getIndication(). Pour faire mieux, on va utiliser la construction
-<tt>switch</tt>, dont la syntaxe est la suivante:
-
-<pre class="Java">
+<p>À la première lecture du code, il n'est pas évident qu'il ne s'agit que d'un
+choix avec 4 branches en fonction du résultat de
+[!java]getIndication()[/!][!scala]litMessage()[/!].
+Pour améliorer ceci, nous allons utiliser [!java]un <code>switch</code>,
+dont la syntaxe est la suivante en Java.[/!]
+[!scala] un filtrage (pattern matching en anglais), qui est une construction
+très agréable qui généralisant le <code>if</code>. Il s'agit sans aucun
+doute de l'un des avantages majeurs du langage Scala par rapport à d'autres
+tels que le Java ou le Python. Cette construction n'est cependant pas
+révolutionnaire puisqu'elle existe depuis assez longtemps dans des langages
+comme OCaml ou Haskell, mais il n'empêche. Elle est carrément cool![/!]</p>
+[/!] [!java]
+<pre>
 switch (<b>expression</b>) {
   case <b>premierValeur</b>: 
     <b>queFaireSiExpressionVautPremiereValeur();</b>
@@ -51,86 +57,96 @@ switch (<b>expression</b>) {
     <b>queFaireSiExpressionVautAucuneDesValeursProposees();</b>
 }</pre>
 
-<p class="Java">
-Remarquez que chaque branche du <tt>switch</tt> doit être terminée par un
+<p>Remarquez que chaque branche du <tt>switch</tt> doit être terminée par un
 <code>break</code>. Si on l'oublie, la machine continue d'exécuter le cas
 suivant dans la liste quand elle a fini le code du cas où elle a sauté dans
 le switch. Il y a même quelques <b>très rares</b> cas où ce comportement est
 pratique.
 
-<p class="Java">On peut réécrire le code BDR précédent bien plus clairement grâce à la
+<p>On peut réécrire le code BDR précédent bien plus clairement grâce à la
 construction <tt>switch</tt> de la façon suivante.</p>
 
-<pre class="Java">switch (getIndication()) {
+<pre>switch (getIndication()) {
   case 'R':
-    turnRight(); 
-    forward(); 
+    droite(); 
+    avance(); 
     break;
   case 'L':
-    turnLeft();
-    forward(); 
+    gauche();
+    avance(); 
     break;
-  case 'U':
-    turnBack();
-    forward();
+  case 'I':
+    retourne();
+    avance();
     break;
   default: 
     return;
 }</pre>
-
-
-<h2 class="Java">Variables partagées par les méthodes</h2>
-
-<p class="Java">
-Un autre problème de votre code est qu'il commence à être un peu long pour
-être dans une seule fonction. On voudrait découper en deux méthodes:
-<ul class="Java">
- <li><code>danceOneStep()</code> s'occuperait de faire un pas de danse</li>
- <li><code>run()</code> s'occuperait de faire la danse en entier, c'est à dire de
-faire des pas de danse tant que l'on n'est pas arrivé à une case ne
-demandant pas d'aller plus loin.</li>
-</ul>
-
-<p class="Java">Le problème est de faire en sorte que <tt>danceOneStep()</tt> prévienne
-<tt>run()</tt> qu'il n'y a plus de pas possible. La solution la plus simple
-est
-encore d'avoir une variable booléenne visible depuis les deux fonctions
-indiquant s'il reste des pas à faire, ou si on a fini. On écrira donc en
-dehors
-de toute méthode :
-<pre class="Java">boolean moreMusic = true;</pre>
-
-<p class="Java">Notez que s'il est possible d'écrire des déclarations en dehors des
-méthodes, les instructions doivent obligatoirement être placées dans des
-méthodes. En Java, on appelle ces variables <i>globales</i> à plusieurs
-méthodes des <b>champs</b>.</p>
-
-<p class="Java">Ensuite, la fonction <tt>danceOneStep()</tt> doit être modifiée pour mettre
-cette valeur à <tt>false</tt> quand il n'y a plus rien à faire. Pour cela,
-ajoutez simplement <code>moreMusic = false;</code> avant tout
-<tt>return</tt>.
-
-<p class="Java">On peut alors utiliser la fonction <tt>run()</tt> suivante:
-<pre class="Java">public void run() {
-  while (moreMusic)
-    danceOneStep();
+[/!] [!scala]
+<pre><i>expression</i> <b>match</b> {
+  <b>case</b> <i>valeur possible</i>  <b>=></b> instructions
+  <b>case</b> <i>autre valeur</i>     <b>=></b> d'autres instructions
+  <b>case</b> <i>troisieme valeur</i> <b>=></b> encore d'autres instructions
+  <b>case _                 =></b> instructions par défaut
+}
+</pre>
+<p>L'expression fournie avant le mot-clé <code>match</code> est évaluée, et
+ensuite, les branches sont évaluées les unes après les autres jusqu'à en
+trouver une où la valeur entre le <code>case</code> et le <code>=></code>
+correspond à la valeur de l'expression. Le symbole <code>_</code> agit comme
+un joker qui correspond à tout. Cela veut dire que la dernière ligne telle
+qu'elle est écrite correspond toujours à la valeur fournie, quelle qu'elle
+soit. Voici un petit exemple où une variable <code>nom</code> est mis en
+correspondance.
+<pre>nom match {
+  case "Martin" => println("Salut Martin, comment vas-tu?")
+  case "Gerald" => println("He Gerald! Ça va?")
+  case _            => println("Bonjour, étranger.")
 }</pre>
 
-<h3>Objectif de cet exercice</h3><a name="Objectifs">
-<p class="Java">Réécrivez le code des buggles en appliquant les améliorations que nous
-venons de voir.</p>
+<p>Il est aussi possible d'avoir plusieurs instructions par branches, et même
+d'avoir plusieurs valeurs sur une branche donnée, séparées par le caractère
+<code>|</code>.</p>
+<pre>nom match {
+  case "Martin" | "Gerald" => println("Bonjour "+nom+", entre."); ouvreLaPorte()
+  case _                            => println("Bonjour étranger. Passe ton chemin sans entrer."); fermeLaPorte()
+}</pre>
 
-<p class="Java">Vous n'avez pas à écrire la fonction <tt>run</tt>, que les buggles
-connaissent déjà. Si vous tentez de la définir malgré tout, le compilateur
-se plaindra de trouver deux définitions de la même fonction, sans se rendre
-compte qu'il s'agit de la même fonction. Contentez vous de déclarer la
-variable <tt>moreMusic</tt> et la méthode <tt>danceOneStep()</tt>.</p>
+<p>Il est même possible d'ajouter des gardes à vos branches. Il s'agit de
+conditions supplémentaires qui doivent être respectées pour que la branche
+soit appliquée. C'est par exemple pratique pour faire du filtrage sur un
+ensemble de valeurs.</p>
+<pre>age match {
+  case i if i<10 => println("Salut gamin!")
+  case i if i<20 => println("Salut mec")
+  case i if i<30 => println("Bonjour jeune home")
+  case _           => println("Bonjour monsieur")
+}</pre>
+<p>Remarquez qu'il n'est pas nécessaire de vérifier à la seconde ligne que la
+valeur est supérieure à 10 puisque les lignes sont considérées dans
+l'ordre. Si la seconde ligne est considérée, c'est que la première ne
+correspondait pas.</p>
+
+<p>Enfin, il est même possible de filtrer sur plusieurs variables à la fois!</p>
+<pre>(x,y) match {
+ case (0,0) => println("C'est le point origine")
+ case (_,0) => println("C'est un point de l'ordonée")
+ case (0,_) => println("C'est un point de l'abscisse")
+ case (_,_) => println("C'est un point quelconque")
+}</pre>
 
-<p class="python">Ce pas de danse est légèrement plus compliqué mais il est plus beau. En
-dehors de cela, c'est la même chose que précédemment.</p>
+<p>Je vous avais bien dit que le filtrage scala était une construction
+surpuissante ! Je l'adore !</p>
+[/!]
 
-<p>Voici les indications au sol à utiliser pour BDR2. Remarquez qu'on peut
-maintenant avancer la buggle de 6 cases d'un coup.
+<h3>Objectif de cet exercice</h3>
+<p>[!java|scala]Appliquez les améliorations que nous venons de voir pour
+adapter le code de votre buggle au nouveau pas de danse explicité
+ci-dessous.[/!]
+[!python]Nous allons maintenant apprendre un nouveau pas de dance à nos
+buggles. Il est un peu plus complexe, mais sinon, c'est toujours la même
+histoire.[/!]
+Remarquez qu'il est maintenant possible d'avancer jusqu'à 6 cases à la fois.</p>
 
 <table border="1">
  <tr><td>Indication</td>
@@ -138,7 +154,7 @@ maintenant avancer la buggle de 6 cases d'un coup.
 
  <tr><td>R</td><td>Tourner à droite et avancer d'une case</td></tr>
  <tr><td>L</td><td>Tourner à gauche et avancer d'une case</td></tr>
- <tr><td>I</td><td>Tourner en sens inverse (demi-tour) et avancer d'une case</td></tr>
+ <tr><td>I</td><td>Se retourner (faire demi-tour) et avancer d'une case</td></tr>
 
  <tr><td>A</td><td>Avancer d'une case</td></tr>
  <tr><td>B</td><td>Avancer de deux cases</td></tr>
@@ -153,8 +169,8 @@ maintenant avancer la buggle de 6 cases d'un coup.
  <tr><td>W</td><td>Reculer de quatre cases</td></tr>
  <tr><td>V</td><td>Reculer de cinq cases</td></tr>
  <tr><td>U</td><td>Reculer de six cases</td></tr>
-</table>
+ <tr><td><i>(n'importe quoi d'autre)</i></td><td>Arrêter de dancer.</td></tr>
 
-<p>Dans tous les autres cas, il faut s'arrêter.</p>
+</table>
 
 <p>Quand votre programme fonctionne de nouveau, passez à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/bdr/BDR2.html b/src/lessons/welcome/bdr/BDR2.html
index fa71b5a..7828f73 100644
--- a/src/lessons/welcome/bdr/BDR2.html
+++ b/src/lessons/welcome/bdr/BDR2.html
@@ -1,151 +1,162 @@
-<h2>Buggle Dance Revolution 2 (BDR2)</h2>
-
-<p class="Java">BDR is cool, but it's a bit chaotic. First, the buggles giggle in any
-directions, and then the code you had to write to let them move is rather
-difficult to read. Here is a new BDR world where the buggle will dance a
-gentle circle. We will benefit this tranquillity to clean up a bit our code
-thanks to the new constructs we will introduce.
-
-<h3 class="Java"><tt>switch</tt> conditionals</h3>
-
-<p class="Java">
-The hardest part of previous code is certainly the conditional
-cascading. Somewhere in your code, you certainly had something similar to:
-
-<pre class="Java">if (getIndication() == 'R') {
-  turnRight();
-  forward();
-} else if (getIndication() == 'L') {
-  turnLeft();
-  forward();
-} else if (getIndication() == 'I') {
-  turnBack();
-  forward();
-/* other else if */
-} else {
-  return;
-}
-</pre>
-
-<p class="Java">
-When you review this code, it may not be clear at the first glance that it
-is simply a choice with 4 branches depending on the value of
-getIndication(). To improve this, we will use a <code>switch</code>
-construct, which Java syntax is the following:
-
-<pre class="Java">
-switch (<b>expression</b>) {
-  case <b>firstValue</b>: 
-    <b>whatToDoIfExpressionEqualsFirstValue();</b>
-    break;
-  case <b>secondValue</b>: 
-    <b>whatToDoIfExpressionEqualsSecondValue();</b>
-    break;
-  case <b>thirdValue</b>: 
-    <b>whatToDoIfExpressionEqualsThirdValue();</b>
-    break;
-    /* as much similar cases as you want */
-  default: 
-    <b>whatToDoIfExpressionDoesNotEqualsAnySeenValues();</b>
-}</pre>
-
-<p class="Java">
-Observe that each branch of a <tt>switch</tt> must be ended by a
-<code>break</code>. If you forget this, the machine keeps going and execute
-the next branch in the list after the branch it jumped to. There is even
-some <b>rare</b> cases where this behavior reveals helpful.
-
-<p class="Java">It is then possible to rewrite previous BDR code in a cleaner way using the
-<tt>switch</tt> construct:</p>
-
-<pre class="Java">switch (getIndication()) {
-  case 'R':
-    turnRight(); 
-    forward(); 
-    break;
-  case 'L':
-    turnLeft();
-    forward(); 
-    break;
-  case 'U':
-    turnBack();
-    forward();
-    break;
-  default: 
-    return;
-}</pre>
-
-
-<h2 class="Java">Variables shared between methods</h2>
-
-<p class="Java">
-Another issue in your code is that it begins to be a bit long to be written
-as a single method. We would like to split it up in two methods:
-<ul class="Java">
- <li><code>danceOneStep()</code> would take care of achieving a single dance step</li>
- <li><code>run()</code> would take care of the dance as a whole. It would do the
-steps while we didn't encounter a cell not asking any further move.</li>
-</ul>
-
-<p class="Java">The difficulty is to make sure that <tt>danceOneStep()</tt> keeps
-<tt>run()</tt> informed that there is no further dance step to achieve. The
-simpler solution is to have a boolean function visible from both methods
-indicating whether there is more steps to do or if we're done. For that, we
-have to write out the following of any method:
-<pre class="Java">boolean moreMusic = true;</pre>
-
-<p class="Java">Note that it is possible to write variable declarations out of any methods,
-but that instructions must be in a method. In Java such <i>global</i>
-variables are called <b>fields</b>.</p>
-
-<p class="Java">Then, the <tt>danceOneStep()</tt> must be changed to update this variable to
-<tt>false</tt> when there is nothing more to do. For that, simply add
-<code>moreMusic = false;</code> before any <tt>return</tt>.
-
-<p class="Java">It is then possible to use the following <tt>run()</tt> method:
-<pre class="Java">public void run() {
-  while (moreMusic)
-    danseOneStep();
-}</pre>
-
-<h3>Exercise goal</h3><a name="Objectives">
-<p class="Java">Apply the improvement we just saw to rewrite your buggle code.</p>
-
-<p class="Java">You don't have to write the <tt>run()</tt> method since the buggle already
-know it. If you put it anyway, the compiler will complain about this
-multiple definition without noticing that both declarations match. Simply
-declare the variable <tt>moreMusic</tt> and the <tt>danceOneStep()</tt>
-method.</p>
-
-<p class="python">This dance step is slightly more complex but
-actually better looking. Beside of that, that's the same old story.</p>
-
-<p>Here are the ground indications to use for BDR2. Note that we can now move a
-buggle up to 6 cells in one dance step.
-
-<table border="1">
- <tr><td>Message</td>
-     <td>What to do</td></tr>
-
- <tr><td>R</td><td>Turn right and move one step forward</td></tr>
- <tr><td>L</td><td>Turn left and move one step forward</td></tr>
- <tr><td>I</td><td>Turn back and move one step forward</td></tr>
-
- <tr><td>A</td><td>Move one step forward</td></tr>
- <tr><td>B</td><td>Move two steps forward</td></tr>
- <tr><td>C</td><td>Move three steps forward</td></tr>
- <tr><td>D</td><td>Move four cells forward</td></tr>
- <tr><td>E</td><td>Move five cells forward</td></tr>
- <tr><td>F</td><td>Move six cells forward</td></tr>
-
- <tr><td>Z</td><td>Move one step backward</td></tr>
- <tr><td>Y</td><td>Move two steps backward</td></tr>
- <tr><td>X</td><td>Move three steps backward</td></tr>
- <tr><td>W</td><td>Move four cells backward</td></tr>
- <tr><td>V</td><td>Move five cells backward</td></tr>
- <tr><td>U</td><td>Move six cells backward</td></tr>
-</table>
-
-<p>In any other case, you should stop</p>
-
-<p>When you program works again, proceed to next exercise.</p>
+<h2>Buggle Dance Revolution 2 (BDR2)</h2>
+
+[!java|scala]
+<p>BDR is cool, but it's a bit chaotic. First, the buggles giggle in any
+directions, and then the code you had to write to let them move is rather
+difficult to read. Here is a new BDR world where the buggle will dance a
+gentle circle. We will benefit this tranquillity to clean up a bit our code
+thanks to the new constructs we will introduce.</p>
+
+<h3>[!java]<code>switch</code> conditionals[/!][!scala]Pattern matching[/!]</h3>
+
+<p>The hardest part of previous code is certainly the conditional
+cascading. Somewhere in your code, you certainly had something similar to:
+
+<pre>if ([!java]getIndication() == 'R'[/!][!scala]readMessage() == "R"[/!]) {
+  right();
+  forward();
+} else if ([!java]getIndication() == 'L'[/!][!scala]readMessage() == "L"[/!]) {
+  left();
+  forward();
+} else if ([!java]getIndication() == 'I'[/!][!scala]readMessage() == "I"[/!]) {
+  back();
+  forward();
+<span class="comment">/* other else if */</span>
+} else {
+  finished = true;
+}
+</pre>
+
+<p>When you review this code, it may not be clear at the first glance that it
+is simply a choice with 4 branches depending on the value of
+[!java]getIndication()[/!][!scala]readMessage()[/!]. 
+To improve this, we will use a 
+[!java]<code>switch</code> construct, which Java syntax is the following:[/!]
+[!scala] pattern matching, which is a very powerful construct that greatly generalizes 
+the <code>if</code>. It is arguably one one the major advantages of Scala when compared to languages such as Java or python. 
+It is not new either, as other languages such as OCaml or Haskell offer this feature since long, but still. 
+It's really cool![/!]</p>
+[/!]
+
+[!java]
+<pre>
+switch (<b>expression</b>) {
+  case <b>firstValue</b>: 
+    <b>whatToDoIfExpressionEqualsFirstValue();</b>
+    break;
+  case <b>secondValue</b>: 
+    <b>whatToDoIfExpressionEqualsSecondValue();</b>
+    break;
+  case <b>thirdValue</b>: 
+    <b>whatToDoIfExpressionEqualsThirdValue();</b>
+    break;
+    /* as much similar cases as you want */
+  default: 
+    <b>whatToDoIfExpressionDoesNotEqualsAnySeenValues();</b>
+}</pre>
+
+<p>Observe that each branch of a <tt>switch</tt> must be ended by a
+<code>break</code>. If you forget this, the machine keeps going and execute
+the next branch in the list after the branch it jumped to. There is even
+some <b>rare</b> cases where this behavior reveals helpful.
+
+<p>It is then possible to rewrite previous BDR code in a cleaner way using the
+<tt>switch</tt> construct:</p>
+
+<pre>switch (getIndication()) {
+  case 'R':
+    right(); 
+    forward(); 
+    break;
+  case 'L':
+    left();
+    forward(); 
+    break;
+  case 'I':
+    back();
+    forward();
+    break;
+  default: 
+    return;
+}</pre>
+[/!]
+[!scala]
+<pre><i>expression</i> <b>match</b> {
+  <b>case</b> <i>possible value</i> <b>=></b> instructions
+  <b>case</b> <i>other value</i>     <b>=></b> other instructions
+  <b>case</b> <i>another value</i> <b>=></b> yet another instructions
+  <b>case _                 =></b> default instructions
+}
+</pre>
+<p>The expression provided before the keyword <code>match</code>, and then
+the branches are evaluated one after the other until we find one which value provided 
+between <code>case</code> and <code>=&gt</code> is equal to the expression's value. 
+The <code>_</code> symbol  acts as a wildcard, so the <code>_</code> branch <i>always</i> matches. 
+Here is an example where a variable <code>name</code> is matched.
+<pre>name match {
+  case "Martin" => println("Hello Martin, how are you?")
+  case "Gerald" => println("Hey Gerald! How are you doing?")
+  case _            => println("Welcome stranger.")
+}</pre>
+
+<p>It is possible to have more than one instruction per branch, and merge branches when the values are 
+separated by a | symbol.</p>
+<pre>name match {
+  case "Martin" | "Gerald" => println("Hello "+name+", how are you?"); openTheDoor()
+  case _                            => println("Hello stranger. Please do not pass."); lockTheDoor()
+}</pre>
+
+<p>You can even add guards to your branches. These are extra conditions that must be respected for the branch 
+to get applied. This is handy if you want match on value ranges, as follows.</p>
+<pre>age match {
+  case i if i<10 => println("Hey kid!")
+  case i if i<20 => println("Hey dude!")
+  case i if i<30 => println("Hello young man")
+  case _           => println("Hello Sir")
+}</pre>
+<p>Note that there is no need to check whether the value is higher than 10 on the second line because the first 
+matching branch is used. So, if the second branch gets evaluated, then the first one did not match.</p>
+
+<p>Finally, it is possible also to match several variables in one shoot!</p>
+<pre>(x,y) match {
+ case (0,0) => println("that's the origin")
+ case (_,0) => println("On the ordinate")
+ case (0,_) => println("On the abscissa")
+ case (_,_) => println("Some random point")
+}</pre>
+
+<p>I told you that scala's pattern matching is very powerful! I actually love this feature!</p>
+[/!]
+
+<h3>Exercise goal</h3>
+<p>[!java|scala]Apply the improvement we just saw to rewrite your buggle code with the following dance steps. [/!]
+[!python]Let's teach a new dance step to the buggles. It is slightly more complex but
+actually better looking. Beside of that, that's the same old story.[/!]
+Note that we can now move up to 6 cells in one dance step.</p>
+
+<table border="1">
+ <tr><td>Message</td>
+     <td>What to do</td></tr>
+
+ <tr><td>R</td><td>Turn right and move one step forward</td></tr>
+ <tr><td>L</td><td>Turn left and move one step forward</td></tr>
+ <tr><td>I</td><td>Turn back and move one step forward</td></tr>
+
+ <tr><td>A</td><td>Move one step forward</td></tr>
+ <tr><td>B</td><td>Move two steps forward</td></tr>
+ <tr><td>C</td><td>Move three steps forward</td></tr>
+ <tr><td>D</td><td>Move four cells forward</td></tr>
+ <tr><td>E</td><td>Move five cells forward</td></tr>
+ <tr><td>F</td><td>Move six cells forward</td></tr>
+
+ <tr><td>Z</td><td>Move one step backward</td></tr>
+ <tr><td>Y</td><td>Move two steps backward</td></tr>
+ <tr><td>X</td><td>Move three steps backward</td></tr>
+ <tr><td>W</td><td>Move four cells backward</td></tr>
+ <tr><td>V</td><td>Move five cells backward</td></tr>
+ <tr><td>U</td><td>Move six cells backward</td></tr>
+ <tr><td><i>(anything else)</i></td><td>Stop dancing.</td></tr>
+
+</table>
+
+<p>When you program works again, proceed to next exercise.</p>
diff --git a/src/lessons/welcome/bdr/BDR2.java b/src/lessons/welcome/bdr/BDR2.java
index 10b0866..79426b3 100644
--- a/src/lessons/welcome/bdr/BDR2.java
+++ b/src/lessons/welcome/bdr/BDR2.java
@@ -2,12 +2,12 @@ package lessons.welcome.bdr;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.BuggleWorldCell;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.BuggleWorldCell;
 
 public class BDR2 extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/bdr/BDR2Entity.java b/src/lessons/welcome/bdr/BDR2Entity.java
index 7dd50b9..fe12fd7 100644
--- a/src/lessons/welcome/bdr/BDR2Entity.java
+++ b/src/lessons/welcome/bdr/BDR2Entity.java
@@ -2,7 +2,7 @@ package lessons.welcome.bdr;
 
 import java.util.Stack;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class BDR2Entity extends SimpleBuggle {
 	public char getIndication() { 
@@ -56,61 +56,56 @@ public class BDR2Entity extends SimpleBuggle {
 		return func+"("+getX()+","+getY()+")";
 	}
 
-
-	/* BEGIN TEMPLATE */
-	boolean moreMusic = true;
-
-	public void danceOneStep() {
+	public void run() { 
+		/* BEGIN HIDDEN (don't put that is student's code) */ 
+		addTODO((String) world.getParameter(0));			
+		/* END HIDDEN */
+		
 		/* BEGIN SOLUTION */
-		char read = getIndication();
-		if (checking) {
-			char todo = ' ';
-			if (todoList.size() == 0) { 
-				if (read != ' ')
-					complain(name+" reads "+fmt(read)+", but it's supposed to be done.");
-			} else
-				todo = todoList.pop();
-
-			if (todo != read) {
-				complain(name+" reads "+fmt(read)+", but it was supposed to do "+fmt(todo)+". Invalid TODO.");			
+		boolean moreMusic = true;
+
+		while (moreMusic) {
+			char read = getIndication();
+			if (checking) {
+				char todo = ' ';
+				if (todoList.size() == 0) { 
+					if (read != ' ')
+						complain(name+" reads "+fmt(read)+", but it's supposed to be done.");
+				} else
+					todo = todoList.pop();
+
+				if (todo != read) {
+					complain(name+" reads "+fmt(read)+", but it was supposed to do "+fmt(todo)+". Invalid TODO.");			
+				}
 			}
-		}
-
-		switch (read) {
-		case 'R': turnRight(); forward(); break;
-		case 'L': turnLeft();  forward(); break;
-		case 'I': turnBack();  forward(); break;
 
-		case 'A': forward(1); break;
-		case 'B': forward(2); break;
-		case 'C': forward(3); break;
-		case 'D': forward(4); break;
-		case 'E': forward(5); break;
-		case 'F': forward(6); break;
-
-		case 'Z': backward(1); break;
-		case 'Y': backward(2); break;
-		case 'X': backward(3); break;
-		case 'W': backward(4); break;
-		case 'V': backward(5); break;
-		case 'U': backward(6); break;
-
-		default: moreMusic = false;
+			switch (read) {
+			case 'R': right(); forward(); break;
+			case 'L': left();  forward(); break;
+			case 'I': back();  forward(); break;
+
+			case 'A': forward(1); break;
+			case 'B': forward(2); break;
+			case 'C': forward(3); break;
+			case 'D': forward(4); break;
+			case 'E': forward(5); break;
+			case 'F': forward(6); break;
+
+			case 'Z': backward(1); break;
+			case 'Y': backward(2); break;
+			case 'X': backward(3); break;
+			case 'W': backward(4); break;
+			case 'V': backward(5); break;
+			case 'U': backward(6); break;
+
+			default: moreMusic = false;
+			}
 		}
 		/* END SOLUTION */
-	}
-
-	public void run() { 
-		/* BEGIN HIDDEN */
-		addTODO((String) world.getParameter(0));			
-		/* END HIDDEN */
 		
-		while (moreMusic)
-			danceOneStep();
-		/* BEGIN HIDDEN */
+		/* BEGIN HIDDEN (don't put that is student's code) */
 		if (checking && todoList.size() != 0) 
 			complain(name+"I'm done, but I was supposed to do "+fmt(todoList.pop())+";");
 		/* END HIDDEN */
 	}
-	/* END TEMPLATE */
 }
diff --git a/src/lessons/welcome/bdr/BDR2Entity.py b/src/lessons/welcome/bdr/BDR2Entity.py
index e073ae6..9978345 100644
--- a/src/lessons/welcome/bdr/BDR2Entity.py
+++ b/src/lessons/welcome/bdr/BDR2Entity.py
@@ -5,9 +5,9 @@ def getIndication():
 		return ' '
 	
 # BEGIN SOLUTION
-def doR(): turnRight(); forward()
-def doL(): turnLeft();  forward()
-def doI(): turnBack();  forward()
+def doR(): right(); forward()
+def doL(): left();  forward()
+def doI(): back();  forward()
 
 
 finished = False
diff --git a/src/lessons/welcome/bdr/BDR2Entity.scala b/src/lessons/welcome/bdr/BDR2Entity.scala
new file mode 100644
index 0000000..e794472
--- /dev/null
+++ b/src/lessons/welcome/bdr/BDR2Entity.scala
@@ -0,0 +1,37 @@
+package lessons.welcome.bdr;
+
+import java.util.Stack;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaBDR2Entity extends SimpleBuggle {
+	override def run() { 
+		/* BEGIN SOLUTION */
+		var moreMusic = true;
+
+		while (moreMusic) {
+			readMessage() match {
+			  case "R" => right(); forward(); 
+			  case "L" => left();  forward(); 
+			  case "I" => back();  forward(); 
+
+			  case "A" => forward(1); 
+			  case "B" => forward(2); 
+			  case "C" => forward(3); 
+			  case "D" => forward(4); 
+			  case "E" => forward(5); 
+			  case "F" => forward(6); 
+
+			  case "Z" => backward(1);
+			  case "Y" => backward(2);
+			  case "X" => backward(3);
+			  case "W" => backward(4); 
+			  case "V" => backward(5); 
+			  case "U" => backward(6); 
+			  
+			  case _ =>  moreMusic = false
+			}
+		}
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/bdr/BDREntity.java b/src/lessons/welcome/bdr/BDREntity.java
index d17812d..80b1462 100644
--- a/src/lessons/welcome/bdr/BDREntity.java
+++ b/src/lessons/welcome/bdr/BDREntity.java
@@ -1,6 +1,6 @@
 package lessons.welcome.bdr;
 
-public class BDREntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class BDREntity extends plm.universe.bugglequest.SimpleBuggle {
 	public char getIndication() { 
 		if (isOverMessage()) { 
 			return readMessage().charAt(0); 
@@ -9,18 +9,17 @@ public class BDREntity extends jlm.universe.bugglequest.SimpleBuggle {
 		} 
 	}
 
-	/* BEGIN TEMPLATE */
 	public void run() {
 		/* BEGIN SOLUTION */
 		while (true) {
 			char c = getIndication();
 
 			if (c == 'R') { 
-				turnRight(); forward();
+				right(); forward();
 			} else if (c == 'L') {
-				turnLeft(); forward();
+				left(); forward();
 			} else if (c == 'I') {
-				turnBack(); forward(); 
+				back(); forward(); 
 			} else if (c == 'A')
 				forward();
 			else if (c == 'B')
@@ -38,5 +37,4 @@ public class BDREntity extends jlm.universe.bugglequest.SimpleBuggle {
 		}		
 		/* END SOLUTION */
 	}
-	/* END TEMPLATE */
 }
diff --git a/src/lessons/welcome/bdr/BDREntity.py b/src/lessons/welcome/bdr/BDREntity.py
index 0d2da61..4b2c2c3 100644
--- a/src/lessons/welcome/bdr/BDREntity.py
+++ b/src/lessons/welcome/bdr/BDREntity.py
@@ -1,21 +1,15 @@
-def getIndication():
-    if isOverMessage():
-        return readMessage()[0]
-    else:
-        return ''
-
 # BEGIN SOLUTION
-finished = False
-while not finished:
-    c = getIndication()
+done = False
+while not done:
+    c = readMessage()
     if c == 'R':
-        turnRight()
+        right()
         forward()
     elif c == 'L':
-        turnLeft()
+        left()
         forward()
     elif c == 'I':
-        turnBack()
+        back()
         forward()
     elif c == 'A':
         forward()
@@ -30,6 +24,6 @@ while not finished:
     elif c == 'X':
         backward(3)
     else:        
-        finished = True
+        done = True
 # END SOLUTION
 
diff --git a/src/lessons/welcome/bdr/BDREntity.scala b/src/lessons/welcome/bdr/BDREntity.scala
new file mode 100644
index 0000000..5f8d2d4
--- /dev/null
+++ b/src/lessons/welcome/bdr/BDREntity.scala
@@ -0,0 +1,34 @@
+package lessons.welcome.bdr;
+
+class ScalaBDREntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	override def run() {
+		/* BEGIN SOLUTION */
+	    var done = false
+		while (!done) {
+			var c = readMessage()
+
+			if (c == "R") { 
+				right(); forward();
+			} else if (c == "L") {
+				left(); forward();
+			} else if (c == "I") {
+				back(); forward(); 
+			} else if (c == "A")
+				forward();
+			else if (c == "B")
+				forward(2);  
+			else if (c == "C")
+				forward(3);
+			else if (c == "Z")
+				backward();
+			else if (c == "Y")
+				backward(2);  
+			else if (c == "X")
+				backward(3);
+			else 
+				done = true ;
+		}		
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/bool1/Close10.fr.html b/src/lessons/welcome/bool1/Close10.fr.html
deleted file mode 100644
index 0977963..0000000
--- a/src/lessons/welcome/bool1/Close10.fr.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>Proche de 10</h1>
-<p class="Java">Étant donné deux nombres entiers, retourner la valeur la plus proche de 10,
-ou 0 en cas de match nul. Remarquez que Math.abs(n) retourne la valeur
-absolue d'un nombre.</p>
-<p class="Python">Étant donné deux nombres entiers, retourner la valeur la plus proche de 10,
-ou 0 en cas de match nul. Remarquez que math.fabs(n) retourne la valeur
-absolue d'un nombre. Remarquez également que vous ne pouvez utiliser cette
-fonction que si vous avez importé le module math.</p>
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/Close10.html b/src/lessons/welcome/bool1/Close10.html
deleted file mode 100644
index 196b312..0000000
--- a/src/lessons/welcome/bool1/Close10.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>Close to 10</h1>
-<p class="Java">Given 2 int values, return whichever value is nearest to the value 10,
-or return 0 in the event of a tie. Note that Math.abs(n) returns the
-absolute value of a number.</p>
-<p class="Python">Given 2 int values, return whichever value is nearest to the value 10,
-or return 0 in the event of a tie. Note that math.fabs(n) returns the
-absolute value of a number. Note also that this function can only be used if you 
-imported the math module.</p>
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/Close10.java b/src/lessons/welcome/bool1/Close10.java
deleted file mode 100644
index 2904e7c..0000000
--- a/src/lessons/welcome/bool1/Close10.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class Close10 extends BatExercise {
-
-	public Close10(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("close10");
-
-		myWorld.addTest(VISIBLE,  8,13);
-		myWorld.addTest(VISIBLE,  13,8);
-		myWorld.addTest(VISIBLE,  13,7);
-
-		myWorld.addTest(INVISIBLE, 7,13);
-		myWorld.addTest(INVISIBLE, 5,21);
-		myWorld.addTest(INVISIBLE, 0,20);
-		myWorld.addTest(INVISIBLE, 10,10);
-
-		langTemplate(Game.PYTHON, "close10", 
-				"import math\ndef close10(a, b):\n",
-				"   if math.fabs(10-a) == math.fabs(10-b):\n"+
-				"      return 0\n"+
-				"   elif math.fabs(10-a) < math.fabs(10-b):\n"+
-				"      return a\n"+
-				"   else:\n"+
-				"      return b\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult(close10((Integer)t.getParameter(0),(Integer)t.getParameter(1)));
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int close10(int a, int b) {
-		/* BEGIN SOLUTION */
-		if (Math.abs(a-10)==Math.abs(b-10))
-			return 0;
-		if (Math.abs(a-10)<Math.abs(b-10))
-			return a;
-		return b;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/CountTeen.fr.html b/src/lessons/welcome/bool1/CountTeen.fr.html
deleted file mode 100644
index ae5976d..0000000
--- a/src/lessons/welcome/bool1/CountTeen.fr.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<h1>Compter les ados</h1>
-<p>On dira qu'un nombre est "ado" s'il appartient à l'intervale [13;19]. Étant
-donné quatre nombres entiers, retournez combien d'entre eux sont ados.</p>
diff --git a/src/lessons/welcome/bool1/CountTeen.java b/src/lessons/welcome/bool1/CountTeen.java
deleted file mode 100644
index d626ef6..0000000
--- a/src/lessons/welcome/bool1/CountTeen.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class CountTeen extends BatExercise {
-
-	public CountTeen(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("countTeen");
-		myWorld.addTest(VISIBLE,  13,20,10,54);
-		myWorld.addTest(VISIBLE,  20,19,13,15);
-		myWorld.addTest(VISIBLE,  20,10,13,42);
-
-		myWorld.addTest(INVISIBLE, 1,20,12,54);
-		myWorld.addTest(INVISIBLE, 19,20,42,12);
-		myWorld.addTest(INVISIBLE, 12,16,20,19);
-		myWorld.addTest(INVISIBLE, 42,12,9,20);
-		myWorld.addTest(INVISIBLE, 12,18,19,14);
-		myWorld.addTest(INVISIBLE, 14,2,20,99);
-		myWorld.addTest(INVISIBLE, 4,11,2,20);
-		myWorld.addTest(INVISIBLE, 11,11,11,11);
-		myWorld.addTest(INVISIBLE, 15,15,15,15);
-
-		langTemplate(Game.PYTHON, "countTeen", 
-				"def countTeen(a, b, c, d):\n",
-				"		ret=0\n"+
-				"		if (a>12 and a<20):\n"+
-				"			ret+=1\n"+
-				"		if (b>12 and b<20):\n"+
-				"			ret+=1\n"+
-				"		if (c>12 and c<20):\n"+
-				"			ret+=1\n"+
-				"		if (d>12 and d<20):\n"+
-				"			ret+=1\n"+
-				"		return ret\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( countTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Integer)t.getParameter(2),(Integer)t.getParameter(3)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int countTeen(int a, int b, int c,int d) {
-		/* BEGIN SOLUTION */
-		int ret=0;
-		if (a>12&&a<20)
-			ret+=1;
-		if (b>12&&b<20)
-			ret+=1;
-		if (c>12&&c<20)
-			ret+=1;
-		if (d>12&&d<20)
-			ret+=1;
-		return ret; 
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/Diff21.fr.html b/src/lessons/welcome/bool1/Diff21.fr.html
deleted file mode 100644
index 4361a7e..0000000
--- a/src/lessons/welcome/bool1/Diff21.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Diff 21</h1>
-Étant donné un entier n, retournez la différence absolue entre n et 21, sauf
-si n est plus grand que 21. Dans ce cas, doublez la différence absolue. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/Diff21.html b/src/lessons/welcome/bool1/Diff21.html
deleted file mode 100644
index 0a0ba3c..0000000
--- a/src/lessons/welcome/bool1/Diff21.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Diff 21</h1>
-Given an int n, return the absolute difference between n and 21,
-except return double the absolute difference if n is over 21. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/Diff21.java b/src/lessons/welcome/bool1/Diff21.java
deleted file mode 100644
index bd5119b..0000000
--- a/src/lessons/welcome/bool1/Diff21.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class Diff21 extends BatExercise {
-
-	public Diff21(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("diff21");
-		myWorld.addTest(VISIBLE,  2);
-		myWorld.addTest(VISIBLE,  11);
-		myWorld.addTest(VISIBLE,  0);
-
-		myWorld.addTest(INVISIBLE, 19);
-		myWorld.addTest(INVISIBLE, 10);
-		myWorld.addTest(INVISIBLE, 21);
-		myWorld.addTest(INVISIBLE, 22);
-		myWorld.addTest(INVISIBLE, 25);
-		myWorld.addTest(INVISIBLE, 30);
-		myWorld.addTest(INVISIBLE, -21);
-
-		langTemplate(Game.PYTHON, "diff21", 
-				"def diff21(n):\n",
-				"   if (n>21):\n"+
-				"      return 2*(n-21)\n"+
-				"   return 21-n\n");		
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( diff21((Integer)t.getParameter(0)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int diff21(int n) {
-		/* BEGIN SOLUTION */
-		if (n>21)
-			return 2*(n-21);
-		return 21-n;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/HasTeen.fr.html b/src/lessons/welcome/bool1/HasTeen.fr.html
deleted file mode 100644
index dea9995..0000000
--- a/src/lessons/welcome/bool1/HasTeen.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>A des ados</h1>
-On dira qu'un nombre est "ado" s'il appartient à l'intervale [13;19]. Étant
-donné trois nombres entiers, retournez vrai ssi un ou plusieurs d'entre eux
-sont ados. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/HasTeen.html b/src/lessons/welcome/bool1/HasTeen.html
deleted file mode 100644
index 04342dc..0000000
--- a/src/lessons/welcome/bool1/HasTeen.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Has Teen</h1>
-We'll say that a number is "teen" if it is in the range 13..19
-inclusive. Given 3 int values, return true if 1 or more of them are
-teen. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/HasTeen.java b/src/lessons/welcome/bool1/HasTeen.java
deleted file mode 100644
index 45df926..0000000
--- a/src/lessons/welcome/bool1/HasTeen.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class HasTeen extends BatExercise {
-
-	public HasTeen(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("hasTeen");
-		myWorld.addTest(VISIBLE,  13,20,10);		
-		myWorld.addTest(VISIBLE,  20,19,10);
-		myWorld.addTest(VISIBLE,  20,10,13);
-
-		myWorld.addTest(INVISIBLE, 1,20,12);
-		myWorld.addTest(INVISIBLE, 19,20,12);
-		myWorld.addTest(INVISIBLE, 12,20,19);
-		myWorld.addTest(INVISIBLE, 12,9,20);
-		myWorld.addTest(INVISIBLE, 12,18,20);
-		myWorld.addTest(INVISIBLE, 14,2,20);
-		myWorld.addTest(INVISIBLE, 4,2,20);
-		myWorld.addTest(INVISIBLE, 11,22,22);
-
-
-		langTemplate(Game.PYTHON, "hasTeen", 
-				"def hasTeen(a, b, c):\n",
-				"   return (a>12 and a<20) or (b>12 and b<20) or (c>12 and c<20)\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( hasTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Integer)t.getParameter(2)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean hasTeen(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		return a>12&&a<20 || b>12&&b<20 || c>12&&c<20;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/IcyHot.fr.html b/src/lessons/welcome/bool1/IcyHot.fr.html
deleted file mode 100644
index b06ca28..0000000
--- a/src/lessons/welcome/bool1/IcyHot.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Feu glacé</h1>
-Étant donné deux températures, retournez vrai si l'une est inférieure à zéro
-et l'autre supérieure à 100. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/IcyHot.html b/src/lessons/welcome/bool1/IcyHot.html
deleted file mode 100644
index 03caf7e..0000000
--- a/src/lessons/welcome/bool1/IcyHot.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Icy Hot</h1>
-Given two temperatures, return true if one is less than 0 and the
-other is greater than 100. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/IcyHot.java b/src/lessons/welcome/bool1/IcyHot.java
deleted file mode 100644
index 80f03a9..0000000
--- a/src/lessons/welcome/bool1/IcyHot.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class IcyHot extends BatExercise {
-
-	public IcyHot(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("icyHot");
-		myWorld.addTest(VISIBLE, 120,-1);
-		myWorld.addTest(VISIBLE, -1,120);
-		myWorld.addTest(VISIBLE, 2,120);
-
-		myWorld.addTest(INVISIBLE, -1,100);
-		myWorld.addTest(INVISIBLE, -2,-2);
-		myWorld.addTest(INVISIBLE, 120,120);
-
-		langTemplate(Game.PYTHON, "icyHot", 
-				"def icyHot(temp1, temp2):\n",
-				"   return temp1<0 and temp2>100 or temp1>100 and temp2<0\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( icyHot((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean icyHot(int temp1, int temp2) {
-
-		/* BEGIN SOLUTION */
-		return temp1<0&&temp2>100 || temp1>100&&temp2<0;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/In1020.fr.html b/src/lessons/welcome/bool1/In1020.fr.html
deleted file mode 100644
index b55924f..0000000
--- a/src/lessons/welcome/bool1/In1020.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Dans [10;20]</h1>
-Étant donné deux nombres entiers, retournez vrai s'un d'entre eux est dans
-l'intervale [10;20]. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/In1020.html b/src/lessons/welcome/bool1/In1020.html
deleted file mode 100644
index c860ccd..0000000
--- a/src/lessons/welcome/bool1/In1020.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>In [10;20]</h1>
-Given 2 int values, return true if either of them is in the range
-10..20 inclusive. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/In1020.java b/src/lessons/welcome/bool1/In1020.java
deleted file mode 100644
index 47b468f..0000000
--- a/src/lessons/welcome/bool1/In1020.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class In1020 extends BatExercise {
-
-	public In1020(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("in1020");
-		myWorld.addTest(VISIBLE,  12,99);
-		myWorld.addTest(VISIBLE,  21,12);
-		myWorld.addTest(VISIBLE,  8,99);
-
-		myWorld.addTest(INVISIBLE, 99,10);
-		myWorld.addTest(INVISIBLE, 20,20);
-		myWorld.addTest(INVISIBLE, 21,21);
-		myWorld.addTest(INVISIBLE, 9,9);
-		myWorld.addTest(INVISIBLE, 10,42);
-		myWorld.addTest(INVISIBLE, 12,-2);
-
-		langTemplate(Game.PYTHON, "in1020", 
-				"def in1020(a, b):\n",
-				"   return (a>9 and a<21) or (b>9 and b<21)");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	@Override
-	public void run(BatTest t) {
-		t.setResult( in1020((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean in1020(int a, int b) {
-		/* BEGIN SOLUTION */
-		return a>9&&a<21 || b>9&&b<21;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/In3050.fr.html b/src/lessons/welcome/bool1/In3050.fr.html
deleted file mode 100644
index 303d53e..0000000
--- a/src/lessons/welcome/bool1/In3050.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Dans [30;50]</h1>
-Étant donné deux nombres entiers, retournez vrai s'ils sont tous les deux
-dans l'intervale [30;40], ou s'ils sont tous les deux dans l'intervale
-[40;50]. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/In3050.html b/src/lessons/welcome/bool1/In3050.html
deleted file mode 100644
index ee72f9a..0000000
--- a/src/lessons/welcome/bool1/In3050.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>In [30;50]</h1>
-Given 2 int values, return true if they are both in the range 30..40
-inclusive, or they are both in the range 40..50 inclusive. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/In3050.java b/src/lessons/welcome/bool1/In3050.java
deleted file mode 100644
index f10e381..0000000
--- a/src/lessons/welcome/bool1/In3050.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class In3050 extends BatExercise {
-
-	public In3050(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("in3050");
-		myWorld.addTest(VISIBLE,  30,31);
-		myWorld.addTest(VISIBLE,  30,41);
-		myWorld.addTest(VISIBLE,  40,50);
-
-		myWorld.addTest(INVISIBLE, 40,51);
-		myWorld.addTest(INVISIBLE, 39,50);
-		myWorld.addTest(INVISIBLE, 50,39);
-		myWorld.addTest(INVISIBLE, 40,39);
-		myWorld.addTest(INVISIBLE, 49,48);
-		myWorld.addTest(INVISIBLE, 50,40);
-		myWorld.addTest(INVISIBLE, 50,51);
-		myWorld.addTest(INVISIBLE, 35,36);
-		myWorld.addTest(INVISIBLE, 35,45);
-
-
-		langTemplate(Game.PYTHON, "in3050", 
-				"def in3050(a, b):\n",
-				"   return (a>29 and a<41 and b>29 and b<41) or (a>39 and a<51 and b>39 and b<51)\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( in3050((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean in3050(int a, int b) {
-		/* BEGIN SOLUTION */
-		return (a>29&&a<41 && b>29&&b<41) || (a>39&&a<51 && b>39&&b<51);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/LastDigit.fr.html b/src/lessons/welcome/bool1/LastDigit.fr.html
deleted file mode 100644
index f51f1b7..0000000
--- a/src/lessons/welcome/bool1/LastDigit.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Dernier chiffre</h1>
-Étant donné deux nombres entiers positifs, retournez vrai s'ils ont le même
-dernier chiffre, comme 27 et 57. Remarquez que l'opérateur % (modulo)
-calcule le reste de la division entière (donc 17 % 10 vaut 7).
-
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/LastDigit.html b/src/lessons/welcome/bool1/LastDigit.html
deleted file mode 100644
index 8a09dab..0000000
--- a/src/lessons/welcome/bool1/LastDigit.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>LastDigit</h1>
-Given two
-non-negative int values, return true if they have the same last digit,
-such as with 27 and 57. Note that the % "mod" operator computes
-remainders, so 17 % 10 is 7.
-
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/LastDigit.java b/src/lessons/welcome/bool1/LastDigit.java
deleted file mode 100644
index b416d6f..0000000
--- a/src/lessons/welcome/bool1/LastDigit.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class LastDigit extends BatExercise {
-	public LastDigit(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("lastDigit");
-		myWorld.addTest(VISIBLE, 7, 17) ;
-		myWorld.addTest(VISIBLE, 6, 17) ;
-		myWorld.addTest(VISIBLE, 3, 113) ;
-		myWorld.addTest(INVISIBLE, 114, 113) ;
-		myWorld.addTest(INVISIBLE, 114, 4) ;
-		myWorld.addTest(INVISIBLE, 10, 0) ;
-		myWorld.addTest(INVISIBLE, 11, 0) ;
-
-		langTemplate(Game.PYTHON, "lastDigit", 
-				"def lastDigit(a, b):\n",
-				"   return a%10 == b%10\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( lastDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean lastDigit(int a, int b) {
-		/* BEGIN SOLUTION */
-		return a%10 == b%10;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/LoneTeen.fr.html b/src/lessons/welcome/bool1/LoneTeen.fr.html
deleted file mode 100644
index d6ce53a..0000000
--- a/src/lessons/welcome/bool1/LoneTeen.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Ado solitaire</h1>
-On dira qu'un nombre est "ado" s'il appartient à l'intervale [13;19]. Étant
-donné deux nombres entiers, retournez vrai si l'un d'entre eux est ado, mais
-pas les deux. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/LoneTeen.html b/src/lessons/welcome/bool1/LoneTeen.html
deleted file mode 100644
index 6b24455..0000000
--- a/src/lessons/welcome/bool1/LoneTeen.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Lone Teen</h1>
-We'll say that a number is "teen" if it is in the range 13..19
-inclusive. Given 2 int values, return true if one or the other is
-teen, but not both. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/LoneTeen.java b/src/lessons/welcome/bool1/LoneTeen.java
deleted file mode 100644
index 27ce688..0000000
--- a/src/lessons/welcome/bool1/LoneTeen.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class LoneTeen extends BatExercise {
-
-	public LoneTeen(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("loneTeen");
-		myWorld.addTest(VISIBLE,  13,42);
-		myWorld.addTest(VISIBLE,  21,19);
-		myWorld.addTest(VISIBLE,  13,13);
-
-		myWorld.addTest(INVISIBLE, 14,20);
-		myWorld.addTest(INVISIBLE, 20,15);
-		myWorld.addTest(INVISIBLE, 16,17);
-		myWorld.addTest(INVISIBLE, 16,9);
-		myWorld.addTest(INVISIBLE, 16,18);
-		myWorld.addTest(INVISIBLE, 13,19);
-		myWorld.addTest(INVISIBLE, 13,20);
-		myWorld.addTest(INVISIBLE, 6,18);
-		myWorld.addTest(INVISIBLE, 42,13);
-		myWorld.addTest(INVISIBLE, 42,42);
-
-		langTemplate(Game.PYTHON, "loneTeen", 
-				"def loneTeen(a, b):\n",
-				"	teenA = a>12 and a<20\n"+
-				"	teenB = b>12 and b<20\n"+
-				"	return  (teenA and not teenB) or (teenB and not teenA)\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( loneTeen((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean loneTeen(int a, int b) {
-		/* BEGIN SOLUTION */
-		boolean teenA = a>12&&a<20;
-		boolean teenB = b>12&&b<20;
-		return  (teenA&&!teenB) || (teenB&&!teenA);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/Main.fr.html b/src/lessons/welcome/bool1/Main.fr.html
deleted file mode 100644
index 54b74e8..0000000
--- a/src/lessons/welcome/bool1/Main.fr.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h1>Jeux booléens</h1>
-
-<p>Les opérations booléennes sont l'une des fondements de la
-programmation. Tant que vous ne pourrez pas écrire des tests booléens (même
-non triviaux) en moins d'une minute, il vous sera difficile d'écrire un vrai
-programme.</p>
-   
-<p>C'est pourquoi cette leçon vous propose une certaine quantité de tels
-exercices pour vous permettre de vous entrainer.</p>
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/Main.html b/src/lessons/welcome/bool1/Main.html
deleted file mode 100644
index 3814d44..0000000
--- a/src/lessons/welcome/bool1/Main.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>Boolean fun</h1>
-
-<p>Boolean operations are one of the very basic task in programming.
-   As long as you cannot write a not so simple boolean test under the
-   minute, you probably will have a very bad time writing a real
-   program.</p>
-   
-<p>That is why this lesson provides you a bunch of such exercises, so
-   that you can get trained in this.</p>
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/Makes10.fr.html b/src/lessons/welcome/bool1/Makes10.fr.html
deleted file mode 100644
index ef8d31f..0000000
--- a/src/lessons/welcome/bool1/Makes10.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Font 10</h1>
-Étant donné deux nombres entiers, retournez vrai si l'un d'entre eux vaut
-10, ou si leur somme vaut 10. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/Makes10.html b/src/lessons/welcome/bool1/Makes10.html
deleted file mode 100644
index e3c81b8..0000000
--- a/src/lessons/welcome/bool1/Makes10.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Makes 10</h1>
-Given 2 ints, a and b, return true if one if them is 10 or if their
-sum is 10. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/Makes10.java b/src/lessons/welcome/bool1/Makes10.java
deleted file mode 100644
index 73d58bc..0000000
--- a/src/lessons/welcome/bool1/Makes10.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class Makes10 extends BatExercise {
-
-	public Makes10(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("makes10");
-		myWorld.addTest(VISIBLE,  9,10);
-		myWorld.addTest(VISIBLE,  9,9);
-		myWorld.addTest(VISIBLE,  1,9);
-
-		myWorld.addTest(INVISIBLE, 10,1);
-		myWorld.addTest(INVISIBLE, 10,10);
-		myWorld.addTest(INVISIBLE, 8,2);
-		myWorld.addTest(INVISIBLE, 8,3);
-		myWorld.addTest(INVISIBLE, 10,42);
-		myWorld.addTest(INVISIBLE, 12,-2);
-
-		langTemplate(Game.PYTHON, "makes10", 
-				"def makes10(a, b):\n",
-				"   return a==10 or b==10 or (a+b)==10");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( makes10((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean makes10(int a, int b) {
-		/* BEGIN SOLUTION */
-		return a==10||b==10||(a+b)==10;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/Max1020.fr.html b/src/lessons/welcome/bool1/Max1020.fr.html
deleted file mode 100644
index 9ddbf48..0000000
--- a/src/lessons/welcome/bool1/Max1020.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Max1020</h1>
-Étant donné deux nombres entiers, retournez la plus grande valeur dans
-l'intervale [10;20], ou retournez 0 si aucun des nombres n'est dans cet
-intervale.
-
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/Max1020.html b/src/lessons/welcome/bool1/Max1020.html
deleted file mode 100644
index c0bfd9e..0000000
--- a/src/lessons/welcome/bool1/Max1020.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Max1020</h1>
-Given 2
-positive int values, return the larger value that is in the range
-10..20 inclusive, or return 0 if neither is in that range.
-
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/Max1020.java b/src/lessons/welcome/bool1/Max1020.java
deleted file mode 100644
index c26fb2e..0000000
--- a/src/lessons/welcome/bool1/Max1020.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package lessons.welcome.bool1;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class Max1020 extends BatExercise {
-	public Max1020(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("max1020");
-		myWorld.addTest(VISIBLE, 11, 19) ;
-		myWorld.addTest(VISIBLE, 19, 11) ;
-		myWorld.addTest(VISIBLE, 11, 9) ;
-		myWorld.addTest(INVISIBLE, 9, 21) ;
-		myWorld.addTest(INVISIBLE, 10, 21) ;
-		myWorld.addTest(INVISIBLE, 21, 10) ;
-		myWorld.addTest(INVISIBLE, 9, 11) ;
-		myWorld.addTest(INVISIBLE, 23, 10) ;
-		myWorld.addTest(INVISIBLE, 20, 10) ;
-		myWorld.addTest(INVISIBLE, 7, 20) ;
-		myWorld.addTest(INVISIBLE, 17, 16) ;
-
-		langTemplate(Game.PYTHON, "max1020", 
-				"def max1020(a, b):\n",
-				"	A = max(a,b)\n"+
-				"	B = min(a,b)\n"+
-				"	if (A<21 and A>9):\n"+
-				"		return A\n"+
-				"	if (B<21 and B>9):\n"+
-				"		return B\n"+
-				"	return 0\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( max1020((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int max1020(int a, int b) {
-		/* BEGIN SOLUTION */
-		int A = a>b?a:b;
-		int B = a>b?b:a;
-		if (A<21 && A>9)
-			return A;
-		if (B<21 && B>9)
-			return B;
-		return 0;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/MonkeyTrouble.fr.html b/src/lessons/welcome/bool1/MonkeyTrouble.fr.html
deleted file mode 100644
index 830b48b..0000000
--- a/src/lessons/welcome/bool1/MonkeyTrouble.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Problème de singe</h1>
-
-Nous avons deux singes, a et b, et les paramètres aSmile et bSmile indiquent
-s'ils sourient. Nous avons un problème s'ils sourient tous les deux en même
-temps, ou si aucun des deux ne sourit. Retournez vrai si nous avons un
-problème. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/MonkeyTrouble.html b/src/lessons/welcome/bool1/MonkeyTrouble.html
deleted file mode 100644
index bc3a6f6..0000000
--- a/src/lessons/welcome/bool1/MonkeyTrouble.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>MonkeyTrouble</h1>
-
-We have two monkeys, a and b, and the parameters aSmile and bSmile indicate if each is smiling. 
-We are in trouble if they are both smiling or if neither of them is smiling. 
-Return true if we are in trouble. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/MonkeyTrouble.java b/src/lessons/welcome/bool1/MonkeyTrouble.java
deleted file mode 100644
index 4eef0ec..0000000
--- a/src/lessons/welcome/bool1/MonkeyTrouble.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class MonkeyTrouble extends BatExercise {
-
-	public MonkeyTrouble(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("monkeyTrouble");
-		myWorld.addTest(VISIBLE, true, true);
-		myWorld.addTest(VISIBLE, false, false);
-		myWorld.addTest(VISIBLE, true, false);
-		myWorld.addTest(INVISIBLE, false, true);
-
-		langTemplate(Game.PYTHON, "monkeyTrouble", 
-				"def monkeyTrouble(aSmile, bSmile):\n",
-				"   return (aSmile and bSmile) or (not aSmile and not bSmile)\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( monkeyTrouble((Boolean)t.getParameter(0),(Boolean)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	public boolean monkeyTrouble(boolean aSmile, boolean bSmile) {
-		/* BEGIN SOLUTION */
-		if (aSmile && bSmile) {
-			return true;
-		}
-		if (!aSmile && !bSmile) {
-			return true;
-		}
-		return false;
-		// This all can be shortened to just:
-		// return ((aSmile && bSmile) || (!aSmile && !bSmile));
-		/* END SOLUTION */		  
-	}	
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/NearHundred.fr.html b/src/lessons/welcome/bool1/NearHundred.fr.html
deleted file mode 100644
index e9c1b18..0000000
--- a/src/lessons/welcome/bool1/NearHundred.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Presque 100</h1>
-<p>Étant donné un entier n, retournez vrai s'il est à 10 près de 100 ou de
-200. Remarquez que Math.abs(n) retourne la valeur absolue d'un nombre.</p>
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/NearHundred.html b/src/lessons/welcome/bool1/NearHundred.html
deleted file mode 100644
index 86c60f3..0000000
--- a/src/lessons/welcome/bool1/NearHundred.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Near Hundred</h1>
-<p>Given an int n, return true if it is within 10 of 100 or 200. Note
-Math.abs(n) returns the absolute value of a number.</p>
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/NearHundred.java b/src/lessons/welcome/bool1/NearHundred.java
deleted file mode 100644
index 4f39976..0000000
--- a/src/lessons/welcome/bool1/NearHundred.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class NearHundred extends BatExercise {
-
-	public NearHundred(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("nearHundred");
-		myWorld.addTest(VISIBLE, 93);
-		myWorld.addTest(VISIBLE, 90);
-		myWorld.addTest(VISIBLE, 89);
-
-		myWorld.addTest(INVISIBLE, 110);
-		myWorld.addTest(INVISIBLE, 191);
-		myWorld.addTest(INVISIBLE, 189);
-		myWorld.addTest(INVISIBLE, 200);
-		myWorld.addTest(INVISIBLE, 210);
-		myWorld.addTest(INVISIBLE, 211);
-		myWorld.addTest(INVISIBLE, -100);
-
-		langTemplate(Game.PYTHON, "nearHundred", 
-				"def nearHundred(n):\n",
-				"   return (90<=n and n<=110) or (190<=n and n<=210)\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( nearHundred((Integer)t.getParameter(0)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean nearHundred(int n) {
-
-		/* BEGIN SOLUTION */
-		return (90<=n && n<=110)||(190<=n&&n<=210);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/ParotTrouble.fr.html b/src/lessons/welcome/bool1/ParotTrouble.fr.html
deleted file mode 100644
index 02f7309..0000000
--- a/src/lessons/welcome/bool1/ParotTrouble.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Problème de perroquet</h1>
-
-Nous avons un perroquet très bruyant. Le paramètre "hour" indique l'heure
-courante (dans l'intervale [0;23]). Nous avons un problème si le perroquet
-parle avant 7h ou après 20h. Retournez vrai si nous avons un problème. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/ParotTrouble.html b/src/lessons/welcome/bool1/ParotTrouble.html
deleted file mode 100644
index d5cb19a..0000000
--- a/src/lessons/welcome/bool1/ParotTrouble.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Parot Trouble</h1>
-
-We have a loud talking parrot. The "hour" parameter is the current
-hour time in the range 0..23. We are in trouble if the parrot is
-talking and the hour is before 7 or after 20. Return true if we are in
-trouble. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/ParotTrouble.java b/src/lessons/welcome/bool1/ParotTrouble.java
deleted file mode 100644
index fe5a60a..0000000
--- a/src/lessons/welcome/bool1/ParotTrouble.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class ParotTrouble extends BatExercise {
-
-	public ParotTrouble(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("parotTrouble");
-		myWorld.addTest(VISIBLE,  true,6);
-		myWorld.addTest(VISIBLE,  true,7);
-		myWorld.addTest(VISIBLE,  false,6);
-
-		myWorld.addTest(INVISIBLE, true,21);
-		myWorld.addTest(INVISIBLE, false,21);
-		myWorld.addTest(INVISIBLE, true,23);
-		myWorld.addTest(INVISIBLE, false,23);
-		myWorld.addTest(INVISIBLE, true,20);
-
-
-		langTemplate(Game.PYTHON, "parotTrouble", 
-				"def parotTrouble(talking, hour):\n",
-				"   return (talking and (hour<7 or hour>20))\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( parotTrouble((Boolean)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean parotTrouble(boolean talking, int hour) {
-		/* BEGIN SOLUTION */
-		return (talking && (hour<7||hour>20));	
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/PosNeg.fr.html b/src/lessons/welcome/bool1/PosNeg.fr.html
deleted file mode 100644
index 7bced8f..0000000
--- a/src/lessons/welcome/bool1/PosNeg.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Positif Negatif</h1>
-Étant donné deux entiers, retournez vrai si l'un d'entre eux est positif et
-l'autre négatif. Sauf si le paramètre negative est vrai, auquel cas il faut
-que les deux nombres soient négatifs. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/PosNeg.html b/src/lessons/welcome/bool1/PosNeg.html
deleted file mode 100644
index 4d69b0a..0000000
--- a/src/lessons/welcome/bool1/PosNeg.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Positive Negative</h1>
-Given 2 int values, return true if one is negative and one is
-positive. Unless negative is true, then they both must be negative. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/PosNeg.java b/src/lessons/welcome/bool1/PosNeg.java
deleted file mode 100644
index 5861fb7..0000000
--- a/src/lessons/welcome/bool1/PosNeg.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class PosNeg extends BatExercise {
-
-	public PosNeg(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("posNeg");
-		myWorld.addTest(VISIBLE, -1,1,false);
-		myWorld.addTest(VISIBLE, 1,-1,false);
-		myWorld.addTest(VISIBLE, 1,1,false);
-
-		myWorld.addTest(INVISIBLE, -1,-1,false);
-		myWorld.addTest(INVISIBLE, 1,-1,true);
-		myWorld.addTest(INVISIBLE, -1,1,true);
-		myWorld.addTest(INVISIBLE, 1,1,true);
-		myWorld.addTest(INVISIBLE, -1,-1,true);
-		myWorld.addTest(INVISIBLE, 5,-5,true);
-		myWorld.addTest(INVISIBLE, -6,6,false);
-		myWorld.addTest(INVISIBLE, -5,-5,false);
-		myWorld.addTest(INVISIBLE, -5,5,true);
-		myWorld.addTest(INVISIBLE, -5,-5,true);
-
-		langTemplate(Game.PYTHON, "posNeg", 
-				"def posNeg(a, b, negative):\n",
-				"		if (negative):\n"+
-				"			return a<0 and b<0;\n"+
-				"		return (a<0 and b>0) or (a>0 and b<0)");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( posNeg((Integer)t.getParameter(0),(Integer)t.getParameter(1),(Boolean)t.getParameter(2)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean posNeg(int a,int b,boolean negative) {
-
-		/* BEGIN SOLUTION */
-		if (negative)
-			return a<0&&b<0;
-		return (a<0&&b>0) || (a>0&&b<0);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/SleepIn.fr.html b/src/lessons/welcome/bool1/SleepIn.fr.html
deleted file mode 100644
index eebb200..0000000
--- a/src/lessons/welcome/bool1/SleepIn.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Grasse matinée</h1>
-
-Le paramètre weekday est vrai si nous sommes un jour de semaine, et le
-paramètre vacation est vrai si nous sommes en vacances. Nous pouvons dormir
-ce matin s'il ne s'agit pas d'un jour de semaine ou si nous sommes en
-vacances. Retournez vrai si nous pouvons faire la grasse matinée. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/SleepIn.html b/src/lessons/welcome/bool1/SleepIn.html
deleted file mode 100644
index a291dc4..0000000
--- a/src/lessons/welcome/bool1/SleepIn.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>SleepDay</h1>
-
-The parameter weekday is true if it is a weekday, and the parameter
-vacation is true if we are on vacation. We sleep in if it is not a
-weekday or we're on vacation. Return true if we sleep in. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/SleepIn.java b/src/lessons/welcome/bool1/SleepIn.java
deleted file mode 100644
index 3f84e17..0000000
--- a/src/lessons/welcome/bool1/SleepIn.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class SleepIn extends BatExercise {
-
-	public SleepIn(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("sleepIn");
-		myWorld.addTest(VISIBLE,  false,false);
-		myWorld.addTest(VISIBLE,  true,false);
-		myWorld.addTest(INVISIBLE, false,true);
-		myWorld.addTest(INVISIBLE, true,true);
-
-		langTemplate(Game.PYTHON, "sleepIn", 
-				"def sleepIn(weekday, vacation):\n",
-				"    return not weekday or vacation\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( sleepIn((Boolean)t.getParameter(0),(Boolean)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean sleepIn(boolean weekday, boolean vacation) {
-		/* BEGIN SOLUTION */
-		if (!weekday || vacation) {
-			return true;
-		} else {
-			return false;
-		}
-		// This can be shortened to: return(!weekday || vacation);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool1/SumDouble.fr.html b/src/lessons/welcome/bool1/SumDouble.fr.html
deleted file mode 100644
index d6251c2..0000000
--- a/src/lessons/welcome/bool1/SumDouble.fr.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<h1>Somme doublée</h1>
-Étant donné deux entiers, retournez leur somme. Sauf si les valeurs sont
-égales, auquel cas vous devez retourner le double de leur somme. 
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool1/SumDouble.html b/src/lessons/welcome/bool1/SumDouble.html
deleted file mode 100644
index e20a65d..0000000
--- a/src/lessons/welcome/bool1/SumDouble.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Sum Double</h1>
-Given two int values, return their sum. Unless the two values are the
-same, then return double their sum. 
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool1/SumDouble.java b/src/lessons/welcome/bool1/SumDouble.java
deleted file mode 100644
index 5308e2f..0000000
--- a/src/lessons/welcome/bool1/SumDouble.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package lessons.welcome.bool1;
-
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class SumDouble extends BatExercise {
-
-	public SumDouble(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("sumDouble");
-		myWorld.addTest(VISIBLE,  1,2);
-		myWorld.addTest(VISIBLE,  3,2);
-		myWorld.addTest(VISIBLE,  2,2);
-
-		myWorld.addTest(INVISIBLE, -1,0);
-		myWorld.addTest(INVISIBLE, 0,0);
-		myWorld.addTest(INVISIBLE, 0,1);
-
-		langTemplate(Game.PYTHON, "sumDouble", 
-				"def sumDouble(a, b):\n",
-				"  if a==b:\n"+
-				"    return (a+b)*2\n"+
-				"  return a+b\n");
-		setup(myWorld);
-	}
-
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( sumDouble((Integer)t.getParameter(0),(Integer)t.getParameter(1)) );		
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int sumDouble(int a, int b) {
-		/* BEGIN SOLUTION */
-		if (a==b)
-			return (a+b)*2;
-		return a+b;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/AlarmClock.fr.html b/src/lessons/welcome/bool2/AlarmClock.fr.html
deleted file mode 100644
index 9739221..0000000
--- a/src/lessons/welcome/bool2/AlarmClock.fr.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<h1>Radio réveil</h1>
-Étant donné le jour de la semaine, codé de la façon suivante : 0=Dimanche,
-1=Lundi, 2=Mardi, ... 6=Samedi, et un booléen vacation indiquant si nous
-sommes en vacances, retournez une chaine de caractères de la forme "7:00"
-indiquant à quelle heure nous devons régler le radio-réveil. Les jours de la
-semaine, nous devons nous réveiller à 7h tandis que nous pouvons dormir
-jusqu'à 10h le week-end. Pendant les vacances, il nous faut nous lever à 10h
-la semaine tandis que le réglage pour le radio-réveil doit être "off" le
-week-end.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/AlarmClock.html b/src/lessons/welcome/bool2/AlarmClock.html
deleted file mode 100644
index f40c39d..0000000
--- a/src/lessons/welcome/bool2/AlarmClock.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>AlarmClock</h1>
-Given a day
-of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a boolean
-indicating if we are on vacation, return a string of the form "7:00"
-indicating when the alarm clock should ring. Weekdays, the alarm should
-be "7:00" and on the weekend it should be "10:00". Unless we are on
-vacation -- then on weekdays it should be "10:00" and weekends it
-should be "off".
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/AlarmClock.java b/src/lessons/welcome/bool2/AlarmClock.java
deleted file mode 100644
index 081422e..0000000
--- a/src/lessons/welcome/bool2/AlarmClock.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class AlarmClock extends BatExercise {
-	public AlarmClock(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("alarmClock");
-		myWorld.addTest(VISIBLE, 1, false) ;
-		myWorld.addTest(VISIBLE, 5, false) ;
-		myWorld.addTest(VISIBLE, 0, false) ;
-		myWorld.addTest(INVISIBLE, 6, false) ;
-		myWorld.addTest(INVISIBLE, 0, true) ;
-		myWorld.addTest(INVISIBLE, 6, true) ;
-		myWorld.addTest(INVISIBLE, 1, true) ;
-		myWorld.addTest(INVISIBLE, 3, true) ;
-		myWorld.addTest(INVISIBLE, 5, true) ;
-
-		langTemplate(Game.PYTHON, "alarmClock", 
-				"def alarmClock(day, vacation):\n",
-				"	if not vacation:\n"+
-				"		if (day >= 1 and day <= 5):\n"+
-				"			return '7:00'\n"+
-				"		else:\n"+
-				"			return '10:00'\n"+
-				"	else:\n"+
-				"		if (day >= 1 and day <= 5):\n"+
-				"			return '10:00'\n"+
-				"		else:\n"+
-				"			return 'off'\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( alarmClock((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	String alarmClock(int day, boolean vacation) {
-		/* BEGIN SOLUTION */
-		if (! vacation) {  
-			if (day >= 1 && day <= 5)
-				return "7:00";
-			else
-				return "10:00";
-		} else {
-			if (day >= 1 && day <= 5)
-				return "10:00";
-			else
-				return "off";  
-		}
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/AnswerCell.fr.html b/src/lessons/welcome/bool2/AnswerCell.fr.html
deleted file mode 100644
index 1218d2f..0000000
--- a/src/lessons/welcome/bool2/AnswerCell.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Répondeur</h1>
-Votre téléphone sonne. Renvoyez vrai si vous décrochez. Vous le faites
-habituellement, sauf le matin où vous ne répondez que si votre mère
-appelle. Dans tous les cas, vous ne répondez pas si vous dormez.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/AnswerCell.html b/src/lessons/welcome/bool2/AnswerCell.html
deleted file mode 100644
index 265940a..0000000
--- a/src/lessons/welcome/bool2/AnswerCell.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>AnswerCell</h1>
-Your cell
-phone rings. Return true if you should answer it. Normally you answer,
-except in the morning you only answer if it is your mom calling. In all
-cases, if you are asleep, you do not answer.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/AnswerCell.java b/src/lessons/welcome/bool2/AnswerCell.java
deleted file mode 100644
index b9111ee..0000000
--- a/src/lessons/welcome/bool2/AnswerCell.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class AnswerCell extends BatExercise {
-	public AnswerCell(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("answerCell");
-		myWorld.addTest(VISIBLE, false, false, false) ;
-		myWorld.addTest(VISIBLE, false, false, true) ;
-		myWorld.addTest(VISIBLE, true, false, false) ;
-		myWorld.addTest(INVISIBLE, true, true, false) ;
-		myWorld.addTest(INVISIBLE, false, true, false) ;
-		myWorld.addTest(INVISIBLE, true, true, true) ;
-
-		langTemplate(Game.PYTHON, "answerCell", 
-				"def answerCell(isMorning, isMom, isAsleep):\n",
-				"   return (not isAsleep) and not (isMorning and not isMom)");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( answerCell((Boolean)t.getParameter(0), (Boolean)t.getParameter(1), (Boolean)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean answerCell(boolean isMorning, boolean isMom, boolean isAsleep) {
-		/* BEGIN SOLUTION */
-		return (! isAsleep) && ! (isMorning && ! isMom);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/BlueTicket.fr.html b/src/lessons/welcome/bool2/BlueTicket.fr.html
deleted file mode 100644
index 3e2c211..0000000
--- a/src/lessons/welcome/bool2/BlueTicket.fr.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>Ticket bleu</h1>
-Vous avez un ticket de loterie bleu, avec des entiers a, b et c inscrits
-dessus. Cela fait trois paires que l'on appellera ab, bc et ac. Considérez
-la somme des nombres de chaque pair. Si la somme de l'une des paires vaut
-exactement 10, le résultat est 10. Sinon, si la somme ab vaut exactement 10
-de plus que les sommes bc ou ac, le résultat est 5. Sinon, le résultat est
-0.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/BlueTicket.html b/src/lessons/welcome/bool2/BlueTicket.html
deleted file mode 100644
index 6f456fd..0000000
--- a/src/lessons/welcome/bool2/BlueTicket.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>BlueTicket</h1>
-You have a
-blue lottery ticket, with ints a, b, and c on it. This makes three
-pairs, which we'll call ab, bc, and ac. Consider the sum of the numbers
-in each pair. If any pair sums to exactly 10, the result is 10.
-Otherwise if the ab sum is exactly 10 more than either bc or ac sums,
-the result is 5. Otherwise the result is 0.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/BlueTicket.java b/src/lessons/welcome/bool2/BlueTicket.java
deleted file mode 100644
index 567c8cf..0000000
--- a/src/lessons/welcome/bool2/BlueTicket.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class BlueTicket extends BatExercise {
-	public BlueTicket(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("blueTicket");
-		myWorld.addTest(VISIBLE, 9, 1, 0) ;
-		myWorld.addTest(VISIBLE, 9, 2, 0) ;
-		myWorld.addTest(VISIBLE, 6, 1, 4) ;
-		myWorld.addTest(INVISIBLE, 6, 1, 5) ;
-		myWorld.addTest(INVISIBLE, 10, 0, 0) ;
-		myWorld.addTest(INVISIBLE, 15, 0, 5) ;
-		myWorld.addTest(INVISIBLE, 5, 15, 5) ;
-		myWorld.addTest(INVISIBLE, 4, 11, 1) ;
-		myWorld.addTest(INVISIBLE, 13, 2, 3) ;
-		myWorld.addTest(INVISIBLE, 8, 4, 3) ;
-		myWorld.addTest(INVISIBLE, 8, 4, 2) ;
-		myWorld.addTest(INVISIBLE, 8, 4, 1) ;
-
-		langTemplate(Game.PYTHON, "blueTicket", 
-				"def blueTicket(a, b, c):\n",
-				"	ab = a + b\n"+
-				"	ac = a + c\n"+
-				"	bc = b + c\n"+
-				"	if (ab == 10 or ac == 10 or bc == 10):\n"+
-				"		return 10\n"+
-				"	elif (ab == (bc + 10) or ab == (ac + 10)):\n"+
-				"		return 5\n"+
-				"	else:\n"+
-				"		return 0\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( blueTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int blueTicket(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		int ab = a + b;
-		int ac = a + c;
-		int bc = b + c;
-
-		if (ab == 10 || ac == 10 || bc == 10)
-			return 10;
-		else if (ab == (bc + 10) || ab == (ac + 10))
-			return 5;
-		else 
-			return 0;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/CaughtSpeeding.fr.html b/src/lessons/welcome/bool2/CaughtSpeeding.fr.html
deleted file mode 100644
index bd308cd..0000000
--- a/src/lessons/welcome/bool2/CaughtSpeeding.fr.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h1>Radar de vitesse</h1>
-Vous conduisez un peu trop vite et un officier de police vous
-arrête. Écrivez le code pour calculer le résultat, encodé sous forme d'un
-entier : 0=pas d'amende, 1=petite amende, 2=grosse amende. Si votre vitesse
-est inférieure à 60, le résultat est 0. Si la vitesse est incluse entre 61
-et 80 (inclus), le résultat est 1. Si la vitesse est 81 ou plus, le résultat
-est 2. Tout ceci ne vaut que si ce n'est pas votre anniversaire aujourd'hui,
-car sinon, votre vitesse peut être supérieure de 5 dans tous les cas.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/CaughtSpeeding.html b/src/lessons/welcome/bool2/CaughtSpeeding.html
deleted file mode 100644
index 870c447..0000000
--- a/src/lessons/welcome/bool2/CaughtSpeeding.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>CaughtSpeeding</h1>
-You are
-driving a little too fast, and a police officer stops you. Write code
-to compute the result, encoded as an int value: 0=no ticket, 1=small
-ticket, 2=big ticket. If speed is 60 or less, the result is 0. If speed
-is between 61 and 80 inclusive, the result is 1. If speed is 81 or
-more, the result is 2. Unless it is your birthday -- on that day, your
-speed can be 5 higher in all cases.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/CaughtSpeeding.java b/src/lessons/welcome/bool2/CaughtSpeeding.java
deleted file mode 100644
index 18e526f..0000000
--- a/src/lessons/welcome/bool2/CaughtSpeeding.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class CaughtSpeeding extends BatExercise {
-	public CaughtSpeeding(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("caughtSpeeding");
-		myWorld.addTest(VISIBLE, 60, false) ;
-		myWorld.addTest(VISIBLE, 65, false) ;
-		myWorld.addTest(VISIBLE, 65, true) ;
-		myWorld.addTest(INVISIBLE, 80, false) ;
-		myWorld.addTest(INVISIBLE, 85, false) ;
-		myWorld.addTest(INVISIBLE, 85, true) ;
-		myWorld.addTest(INVISIBLE, 70, false) ;
-		myWorld.addTest(INVISIBLE, 75, false) ;
-		myWorld.addTest(INVISIBLE, 75, true) ;
-		myWorld.addTest(INVISIBLE, 40, false) ;
-		myWorld.addTest(INVISIBLE, 40, true) ;
-		myWorld.addTest(INVISIBLE, 90, false) ;
-
-		langTemplate(Game.PYTHON, "caughtSpeeding", 
-				"def caughtSpeeding(speed, isBirthday):\n",
-				"	if ((isBirthday and speed <= 65) or (speed <= 60)):\n"+
-				"		return 0\n"+
-				"	elif ((isBirthday and speed <= 85) or (speed <= 80)):\n"+
-				"		return 1\n"+
-				"	else:\n"+
-				"		return 2\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( caughtSpeeding((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int caughtSpeeding(int speed, boolean isBirthday) {
-		/* BEGIN SOLUTION */
-		if ((isBirthday && speed <= 65) || (speed <= 60))
-			return 0;
-		else if ((isBirthday && speed <= 85) || (speed <= 80))
-			return 1;
-		else 
-			return 2;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/CigarParty.fr.html b/src/lessons/welcome/bool2/CigarParty.fr.html
deleted file mode 100644
index b6829cf..0000000
--- a/src/lessons/welcome/bool2/CigarParty.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Cigares de fête</h1>
-Quand les écureuils font la fête, ils aiment avoir des cigares. Une fête
-d'écureuils est réussie si le nombre de cigares est entre 40 et 60
-(inclus). Sauf si c'est le week-end, auquel cas il n'y a pas de limite
-supérieure au nombre de cigares. Renvoyez vrai si la fête est réussie. 
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/CigarParty.html b/src/lessons/welcome/bool2/CigarParty.html
deleted file mode 100644
index aedbd3b..0000000
--- a/src/lessons/welcome/bool2/CigarParty.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>CigarParty</h1>
-When
-squirrels get together for a party, they like to have cigars. A
-squirrel party is successful when the number of cigars is between 40
-and 60, inclusive. Unless it is the weekend, in which case there is no
-upper bound on the number of cigars. Return true if the party with the
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/CigarParty.java b/src/lessons/welcome/bool2/CigarParty.java
deleted file mode 100644
index da27dc4..0000000
--- a/src/lessons/welcome/bool2/CigarParty.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class CigarParty extends BatExercise {
-	public CigarParty(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("cigarParty");
-		myWorld.addTest(VISIBLE, 30, false) ;
-		myWorld.addTest(VISIBLE, 50, false) ;
-		myWorld.addTest(VISIBLE, 70, true) ;
-		myWorld.addTest(INVISIBLE, 30, true) ;
-		myWorld.addTest(INVISIBLE, 50, true) ;
-		myWorld.addTest(INVISIBLE, 60, false) ;
-		myWorld.addTest(INVISIBLE, 61, false) ;
-		myWorld.addTest(INVISIBLE, 40, false) ;
-		myWorld.addTest(INVISIBLE, 39, false) ;
-		myWorld.addTest(INVISIBLE, 40, true) ;
-		myWorld.addTest(INVISIBLE, 39, true) ;
-
-		langTemplate(Game.PYTHON, "cigarParty", 
-				"def cigarParty(cigars, isWeekend):\n",
-				"   return (isWeekend and cigars >= 40) or (not isWeekend and (cigars >= 40) and (cigars <= 60))\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( cigarParty((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean cigarParty(int cigars, boolean isWeekend) {
-		/* BEGIN SOLUTION */
-		return (isWeekend && cigars >= 40) || (!isWeekend && (cigars >= 40) && (cigars <= 60));
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/DateFashion.fr.html b/src/lessons/welcome/bool2/DateFashion.fr.html
deleted file mode 100644
index 231688b..0000000
--- a/src/lessons/welcome/bool2/DateFashion.fr.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<h1>Rendez-vous élégant</h1>
-Vous et votre compagne/compagnon essayez d'obtenir une table au
-restaurant. Le paramètre "you" est l'élégance de vos vêtements, dans
-l'intervalle [0,10], et "date"  est l'élégance des vêtements de votre
-compagne/compagnon. Le résultat obtenir la table est  encodé comme une
-valeur enteur avec 0=non, 1= peut-être et 2=oui. Si l'un de vous deux est
-très élégant, 8 ou plus, alors le résultat est 2 (oui). Avec l'exception que
-si l'un de vous deux a un style de 2 ou moins, alors le résultat est 0
-(no). Sinon, le résultat est 1 (peut-être).
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/DateFashion.html b/src/lessons/welcome/bool2/DateFashion.html
deleted file mode 100644
index 3613c74..0000000
--- a/src/lessons/welcome/bool2/DateFashion.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h1>DateFashion</h1>
-You and your
-date are trying to get a table at a restaurant. The parameter "you" is
-the stylishness of your clothes, in the range 0..10, and "date" is the
-stylishness of your date's clothes. The result getting the table is
-encoded as an int value with 0=no, 1=maybe, 2=yes. If either of you is
-very stylish, 8 or more, then the result is 2 (yes). With the exception
-that if either of you has style of 2 or less, then the result is 0
-(no). Otherwise the result is 1 (maybe).
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/DateFashion.java b/src/lessons/welcome/bool2/DateFashion.java
deleted file mode 100644
index c25708b..0000000
--- a/src/lessons/welcome/bool2/DateFashion.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class DateFashion extends BatExercise {
-	public DateFashion(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("dateFashion");
-		myWorld.addTest(VISIBLE, 5, 10) ;
-		myWorld.addTest(VISIBLE, 5, 2) ;
-		myWorld.addTest(VISIBLE, 5, 5) ;
-		myWorld.addTest(INVISIBLE, 3, 3) ;
-		myWorld.addTest(INVISIBLE, 10, 2) ;
-		myWorld.addTest(INVISIBLE, 2, 9) ;
-		myWorld.addTest(INVISIBLE, 9, 9) ;
-		myWorld.addTest(INVISIBLE, 10, 5) ;
-		myWorld.addTest(INVISIBLE, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 3, 7) ;
-		myWorld.addTest(INVISIBLE, 2, 7) ;
-		myWorld.addTest(INVISIBLE, 6, 2) ;
-
-		langTemplate(Game.PYTHON, "dateFashion", 
-				"def dateFashion(you, date):\n",
-				"	if (you <= 2 or date <= 2):\n"+
-				"		return 0\n"+
-				"	elif (you >= 8 or date >= 8):\n"+
-				"		return 2\n"+
-				"	else:\n"+
-				"		return 1\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( dateFashion((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int dateFashion(int you, int date) {
-		/* BEGIN SOLUTION */
-		if (you <= 2 || date <= 2)
-			return 0;
-		else if (you >= 8 || date >= 8)
-			return 2;
-		else
-			return 1;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/GreenTicket.fr.html b/src/lessons/welcome/bool2/GreenTicket.fr.html
deleted file mode 100644
index 57c6a20..0000000
--- a/src/lessons/welcome/bool2/GreenTicket.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Ticket vert</h1>
-Vous avez un ticket de lotterie vert, avec des entiers a, b et c inscrits
-dessus. Si les nombres sont tous différents les uns des autres, le résultat
-est 0. Si tous les nombres sont identiques, le résultat est 20. Si deux des
-nombres sont les mêmes, le résultat est 10.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/GreenTicket.html b/src/lessons/welcome/bool2/GreenTicket.html
deleted file mode 100644
index 0bb3fff..0000000
--- a/src/lessons/welcome/bool2/GreenTicket.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>GreenTicket</h1>
-You have a
-green lottery ticket, with ints a, b, and c on it. If the numbers are
-all different from each other, the result is 0. If all of the numbers
-are the same, the result is 20. If two of the numbers are the same, the
-result is 10.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/GreenTicket.java b/src/lessons/welcome/bool2/GreenTicket.java
deleted file mode 100644
index 11fbe4f..0000000
--- a/src/lessons/welcome/bool2/GreenTicket.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class GreenTicket extends BatExercise {
-	public GreenTicket(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("greenTicket");
-		myWorld.addTest(VISIBLE, 1, 2, 3) ;
-		myWorld.addTest(VISIBLE, 2, 2, 2) ;
-		myWorld.addTest(VISIBLE, 1, 1, 2) ;
-		myWorld.addTest(INVISIBLE, 2, 1, 1) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 1) ;
-		myWorld.addTest(INVISIBLE, 3, 2, 1) ;
-		myWorld.addTest(INVISIBLE, 0, 0, 0) ;
-		myWorld.addTest(INVISIBLE, 2, 0, 0) ;
-		myWorld.addTest(INVISIBLE, 0, 9, 10) ;
-		myWorld.addTest(INVISIBLE, 0, 10, 0) ;
-		myWorld.addTest(INVISIBLE, 9, 9, 9) ;
-		myWorld.addTest(INVISIBLE, 9, 0, 9) ;
-
-		langTemplate(Game.PYTHON, "greenTicket", 
-				"def greenTicket(a, b, c):\n",
-				"	if (a == b and b == c):\n"+
-				"		return 20\n"+
-				"	elif (a == b or b == c or a == c):\n"+
-				"		return 10\n"+
-				"	else:\n"+
-				"		return 0\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( greenTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int greenTicket(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		if (a == b && b == c)
-			return 20;
-		else if (a == b || b == c || a == c)
-			return 10;
-		else  // (a != b && b != a && c != a)
-			return 0;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/In1To10.fr.html b/src/lessons/welcome/bool2/In1To10.fr.html
deleted file mode 100644
index 1319c9f..0000000
--- a/src/lessons/welcome/bool2/In1To10.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>De 1 à 10</h1>
-Soit un nombre n, renvoyez vrai si n est dans l'intervalle [1,10]. Sauf
-si"outsideMode" est vrai, auquel cas renvoyez vrai si le nombre est plus
-petit ou égal à 1 ou bien s'il est plus grand ou égal à 10
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/In1To10.html b/src/lessons/welcome/bool2/In1To10.html
deleted file mode 100644
index adbdc36..0000000
--- a/src/lessons/welcome/bool2/In1To10.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>In1To10</h1>
-Given a
-number n, return true if n is in the range 1..10, inclusive. Unless
-"outsideMode" is true, in which case return true if the number is less
-or equal to 1, or greater or equal to 10.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/In1To10.java b/src/lessons/welcome/bool2/In1To10.java
deleted file mode 100644
index 68e2c83..0000000
--- a/src/lessons/welcome/bool2/In1To10.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class In1To10 extends BatExercise {
-	public In1To10(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("in1To10");
-		myWorld.addTest(VISIBLE, 5, false) ;
-		myWorld.addTest(VISIBLE, 11, false) ;
-		myWorld.addTest(VISIBLE, 11, true) ;
-		myWorld.addTest(INVISIBLE, 10, false) ;
-		myWorld.addTest(INVISIBLE, 10, true) ;
-		myWorld.addTest(INVISIBLE, 9, false) ;
-		myWorld.addTest(INVISIBLE, 9, true) ;
-		myWorld.addTest(INVISIBLE, 1, false) ;
-		myWorld.addTest(INVISIBLE, 1, true) ;
-		myWorld.addTest(INVISIBLE, 0, false) ;
-		myWorld.addTest(INVISIBLE, 0, true) ;
-		myWorld.addTest(INVISIBLE, -1, false) ;
-
-		langTemplate(Game.PYTHON, "in1To10", 
-				"def in1To10(n, outsideMode):\n",
-				"   return (outsideMode and (n <= 1 or n >= 10)) or ((not outsideMode) and (n >= 1 and n <= 10))\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( in1To10((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean in1To10(int n, boolean outsideMode) {
-		/* BEGIN SOLUTION */
-		return (outsideMode && (n <= 1 || n >= 10)) || ((! outsideMode) && (n >= 1 && n <= 10));
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/InOrder.fr.html b/src/lessons/welcome/bool2/InOrder.fr.html
deleted file mode 100644
index 0e11112..0000000
--- a/src/lessons/welcome/bool2/InOrder.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Dans l'ordre</h1>
-Soit trois entiers, a b c, renvoyez vrai si b est plus grand que a, et si c
-est plus grand que b. Cependant, avec l'exception que si "bOk" est vrai, b
-n'a pas besoin d'être plus grand que a.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/InOrder.html b/src/lessons/welcome/bool2/InOrder.html
deleted file mode 100644
index 5ad5955..0000000
--- a/src/lessons/welcome/bool2/InOrder.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>InOrder</h1>
-Given three
-ints, a b c, return true if b is greater than a, and c is greater than
-b. However, with the exception that if "bOk" is true, b does not need
-to be greater than a.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/InOrder.java b/src/lessons/welcome/bool2/InOrder.java
deleted file mode 100644
index 616b63f..0000000
--- a/src/lessons/welcome/bool2/InOrder.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class InOrder extends BatExercise {
-	public InOrder(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("inOrder");
-		myWorld.addTest(VISIBLE, 1, 2, 4, false) ;
-		myWorld.addTest(VISIBLE, 1, 2, 1, false) ;
-		myWorld.addTest(VISIBLE, 1, 1, 2, true) ;
-		myWorld.addTest(INVISIBLE, 3, 2, 4, false) ;
-		myWorld.addTest(INVISIBLE, 2, 3, 4, false) ;
-		myWorld.addTest(INVISIBLE, 3, 2, 4, true) ;
-		myWorld.addTest(INVISIBLE, 4, 2, 2, true) ;
-		myWorld.addTest(INVISIBLE, 4, 5, 2, true) ;
-		myWorld.addTest(INVISIBLE, 2, 4, 6, true) ;
-		myWorld.addTest(INVISIBLE, 7, 9, 10, false) ;
-		myWorld.addTest(INVISIBLE, 7, 5, 6, true) ;
-		myWorld.addTest(INVISIBLE, 7, 5, 4, true) ;
-
-		langTemplate(Game.PYTHON, "inOrder", 
-				"def inOrder(a, b, c, bOk):\n",
-				"		return (bOk or (b > a)) and (c > b)\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( inOrder((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2), (Boolean)t.getParameter(3)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean inOrder(int a, int b, int c, boolean bOk) {
-		/* BEGIN SOLUTION */
-		return (bOk || (b > a)) && (c > b);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/InOrderEqual.fr.html b/src/lessons/welcome/bool2/InOrderEqual.fr.html
deleted file mode 100644
index ce2eb36..0000000
--- a/src/lessons/welcome/bool2/InOrderEqual.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Dans l'ordre croissant</h1>
-Soit trois entiers, a b c, renvoyez vrai si ils sont dans un ordre croissant
-strict, tel que 2 5 11, ou 5 6 7, mais pas 6 5 7 ou 5 5 7. Cependant, avec
-l'exception que si "equalOk" est vrai, alors l'égalité est permise, comme 5
-5 7 ou 5 5 5.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/InOrderEqual.html b/src/lessons/welcome/bool2/InOrderEqual.html
deleted file mode 100644
index 58e9f72..0000000
--- a/src/lessons/welcome/bool2/InOrderEqual.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>InOrderEqual</h1>
-Given three
-ints, a b c, return true if they are in strict increasing order, such
-as 2 5 11, or 5 6 7, but not 6 5 7 or 5 5 7. However, with the
-exception that if "equalOk" is true, equality is allowed, such as 5 5 7
-or 5 5 5.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/InOrderEqual.java b/src/lessons/welcome/bool2/InOrderEqual.java
deleted file mode 100644
index b5a3484..0000000
--- a/src/lessons/welcome/bool2/InOrderEqual.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class InOrderEqual extends BatExercise {
-	public InOrderEqual(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("inOrderEqual");
-		myWorld.addTest(VISIBLE, 2, 5, 11, false) ;
-		myWorld.addTest(VISIBLE, 5, 7, 6, false) ;
-		myWorld.addTest(VISIBLE, 5, 5, 7, true) ;
-		myWorld.addTest(INVISIBLE, 5, 5, 7, false) ;
-		myWorld.addTest(INVISIBLE, 2, 5, 4, false) ;
-		myWorld.addTest(INVISIBLE, 3, 4, 3, false) ;
-		myWorld.addTest(INVISIBLE, 3, 4, 4, false) ;
-		myWorld.addTest(INVISIBLE, 3, 4, 3, true) ;
-		myWorld.addTest(INVISIBLE, 3, 4, 4, true) ;
-		myWorld.addTest(INVISIBLE, 1, 5, 5, true) ;
-		myWorld.addTest(INVISIBLE, 5, 5, 5, true) ;
-		myWorld.addTest(INVISIBLE, 2, 2, 1, true) ;
-		myWorld.addTest(INVISIBLE, 9, 2, 2, true) ;
-		myWorld.addTest(INVISIBLE, 0, 1, 0, true) ;
-
-		langTemplate(Game.PYTHON, "inOrderEqual", 
-				"def inOrderEqual(a, b, c, equalOk):\n",
-				"		return (equalOk and ((a <= b) and (b <= c))) or (a < b and b < c)");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( inOrderEqual((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2), (Boolean)t.getParameter(3)) ); 
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean inOrderEqual(int a, int b, int c, boolean equalOk) {
-		/* BEGIN SOLUTION */
-		return (equalOk && ((a <= b) && (b <= c))) || (a < b && b < c);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/LastDigit2.fr.html b/src/lessons/welcome/bool2/LastDigit2.fr.html
deleted file mode 100644
index ca8b95a..0000000
--- a/src/lessons/welcome/bool2/LastDigit2.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>L'autre dernier chiffre</h1>
-Soit trois entiers, a b c, renvoyez vrai si deux ou plus d'entre eux ont le
-même chiffre le plus à droite. Les entiers sont positifs. Note: l'opérateur
-% "mod" calcule le reste, i.e. 17 % 10 vaut 7.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/LastDigit2.html b/src/lessons/welcome/bool2/LastDigit2.html
deleted file mode 100644
index 2a53b14..0000000
--- a/src/lessons/welcome/bool2/LastDigit2.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>LastDigit 2</h1>
-Given three
-ints, a b c, return true if two or more of them have the same rightmost
-digit. The ints are non-negative. Note: the % "mod" operator computes
-the remainder, e.g. 17 % 10 is 7.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/LastDigit2.java b/src/lessons/welcome/bool2/LastDigit2.java
deleted file mode 100644
index 3c51a3e..0000000
--- a/src/lessons/welcome/bool2/LastDigit2.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class LastDigit2 extends BatExercise {
-	public LastDigit2(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("lastDigit");
-		myWorld.addTest(VISIBLE, 23, 19, 13) ;
-		myWorld.addTest(VISIBLE, 23, 19, 12) ;
-		myWorld.addTest(VISIBLE, 23, 19, 3) ;
-		myWorld.addTest(INVISIBLE, 23, 19, 39) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 3) ;
-		myWorld.addTest(INVISIBLE, 1, 1, 2) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 14, 25, 43) ;
-		myWorld.addTest(INVISIBLE, 14, 25, 45) ;
-		myWorld.addTest(INVISIBLE, 248, 106, 1002) ;
-		myWorld.addTest(INVISIBLE, 248, 106, 1008) ;
-		myWorld.addTest(INVISIBLE, 10, 11, 20) ;
-		myWorld.addTest(INVISIBLE, 0, 11, 0) ;
-
-		langTemplate(Game.PYTHON, "lastDigit", 
-				"def lastDigit(a, b, c):\n",
-				"	da = a % 10\n"+
-				"	db = b % 10\n"+
-				"	dc = c % 10\n"+
-				"	return da == db or da == dc or dc == db\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( lastDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean lastDigit(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		int da = a % 10;
-		int db = b % 10;
-		int dc = c % 10;
-		return da == db || da == dc || dc == db;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/LessBy10.fr.html b/src/lessons/welcome/bool2/LessBy10.fr.html
deleted file mode 100644
index 4242518..0000000
--- a/src/lessons/welcome/bool2/LessBy10.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Plus petit par 10</h1>
-Soit trois entiers, a b c, renvoyez vrai si l'un d'entre eux est plus petit
-de 10 ou plus que l'un des autres.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/LessBy10.html b/src/lessons/welcome/bool2/LessBy10.html
deleted file mode 100644
index 1e67a6d..0000000
--- a/src/lessons/welcome/bool2/LessBy10.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>LessBy10</h1>
-Given three ints, a b c, return true if one of them is 10 or more less than one of the others.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/LessBy10.java b/src/lessons/welcome/bool2/LessBy10.java
deleted file mode 100644
index 23f6650..0000000
--- a/src/lessons/welcome/bool2/LessBy10.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class LessBy10 extends BatExercise {
-	public LessBy10(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("lessBy10");
-		myWorld.addTest(VISIBLE, 1, 7, 11) ;
-		myWorld.addTest(VISIBLE, 1, 7, 10) ;
-		myWorld.addTest(VISIBLE, 11, 1, 7) ;
-		myWorld.addTest(INVISIBLE, 10, 7, 1) ;
-		myWorld.addTest(INVISIBLE, -10, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 2, 11, 11) ;
-		myWorld.addTest(INVISIBLE, 3, 3, 30) ;
-		myWorld.addTest(INVISIBLE, 3, 3, 3) ;
-		myWorld.addTest(INVISIBLE, 10, 1, 11) ;
-		myWorld.addTest(INVISIBLE, 10, 11, 1) ;
-		myWorld.addTest(INVISIBLE, 10, 11, 2) ;
-		myWorld.addTest(INVISIBLE, 3, 30, 3) ;
-		myWorld.addTest(INVISIBLE, 2, 2, -8) ;
-		myWorld.addTest(INVISIBLE, 2, 8, 12) ;
-
-		langTemplate(Game.PYTHON, "lessBy10", 
-				"def lessBy10(a, b, c):\n",
-				"	return ((a - b) >= 10) or ((b - a) >= 10) or ((b - c) >= 10) or ((c - b) >= 10) or ((a - c) >= 10) or ((c - a) >= 10)\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( lessBy10((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean lessBy10(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		return ((a - b) >= 10) || ((b - a) >= 10) || ((b - c) >= 10) || ((c - b) >= 10) || ((a - c) >= 10) || ((c - a) >= 10);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/Main.fr.html b/src/lessons/welcome/bool2/Main.fr.html
deleted file mode 100644
index 35dfad6..0000000
--- a/src/lessons/welcome/bool2/Main.fr.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Encore des jeux booléens</h1>
-   
-<p>Une très bonne introduction à ce type est disponible ici :
-http://javabat.com/doc/ifboolean.html.</p><p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/Main.html b/src/lessons/welcome/bool2/Main.html
deleted file mode 100644
index 07f4fd7..0000000
--- a/src/lessons/welcome/bool2/Main.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<h1>Boolean (even more) fun</h1>
-   
-<p>A very good introduction to this type is available here:
-   http://javabat.com/doc/ifboolean.html.</p><p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/MaxMod5.fr.html b/src/lessons/welcome/bool2/MaxMod5.fr.html
deleted file mode 100644
index 28a34eb..0000000
--- a/src/lessons/welcome/bool2/MaxMod5.fr.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>Maximum Mod 5</h1>
-Soit deux valeurs entières, renvoyez la plus grande des deux. Cependant, si
-les deux valeurs ont le même reste quand elles sont divisées par 5, alors
-renvoyez la plus petite des deux. Cependant, dans tous les cas, si les deux
-valeurs sont égales, renvoyez 0. Note: l'opérateur % "mod" calcule le reste,
-i.e. 7 % 5 vaut 2.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/MaxMod5.html b/src/lessons/welcome/bool2/MaxMod5.html
deleted file mode 100644
index 85fb3e1..0000000
--- a/src/lessons/welcome/bool2/MaxMod5.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>MaxMod5</h1>
-Given two int
-values, return whichever value is larger. However if the two values
-have the same remainder when divided by 5, then the return the smaller
-value. However, in all cases, if the two values are the same, return 0.
-Note: the % "mod" operator computes the remainder, e.g. 7 % 5 is 2.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/MaxMod5.java b/src/lessons/welcome/bool2/MaxMod5.java
deleted file mode 100644
index ded7ffb..0000000
--- a/src/lessons/welcome/bool2/MaxMod5.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class MaxMod5 extends BatExercise {
-	public MaxMod5(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("maxMod5");
-		myWorld.addTest(VISIBLE, 2, 3) ;
-		myWorld.addTest(VISIBLE, 6, 2) ;
-		myWorld.addTest(VISIBLE, 3, 2) ;
-		myWorld.addTest(INVISIBLE, 8, 12) ;
-		myWorld.addTest(INVISIBLE, 7, 12) ;
-		myWorld.addTest(INVISIBLE, 11, 6) ;
-		myWorld.addTest(INVISIBLE, 2, 7) ;
-		myWorld.addTest(INVISIBLE, 7, 7) ;
-		myWorld.addTest(INVISIBLE, 9, 1) ;
-		myWorld.addTest(INVISIBLE, 9, 14) ;
-		myWorld.addTest(INVISIBLE, 1, 2) ;
-
-		langTemplate(Game.PYTHON, "maxMod5", 
-				"def maxMod5(a, b):\n",
-				"	if (a == b):\n"+
-				"		return 0\n"+
-				"	elif (a > b):\n"+
-				"		if (a % 5 == b % 5):\n"+
-				"			return b\n"+
-				"		else:\n"+
-				"			return a\n"+
-				"	else:\n"+
-				"		if (a % 5 == b % 5):\n"+
-				"			return a\n"+
-				"		else:\n"+
-				"			return b");  
-
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( maxMod5((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int maxMod5(int a, int b) {
-		/* BEGIN SOLUTION */
-		if (a == b)
-			return 0;
-		else if (a > b)
-			if (a % 5 == b % 5)
-				return b;
-			else 
-				return a;
-		else 
-			if (a % 5 == b % 5)
-				return a;
-			else 
-				return b;  
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/NearTen.fr.html b/src/lessons/welcome/bool2/NearTen.fr.html
deleted file mode 100644
index 9aeecf3..0000000
--- a/src/lessons/welcome/bool2/NearTen.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Près de dix</h1>
-Soit un entier positif "num", renvoyez vrai si num est à moins de 2 d'un
-multiple de 10. Note: ( a % b ) est le reste de la division de a par b, donc
-(7 % 5) vaut 2.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/NearTen.html b/src/lessons/welcome/bool2/NearTen.html
deleted file mode 100644
index de47c8e..0000000
--- a/src/lessons/welcome/bool2/NearTen.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>NearTen</h1>
-Given a
-non-negative number "num", return true if num is within 2 of a multiple
-of 10. Note: (a % b) is the remainder of dividing a by b, so (7 % 5) is
-2.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/NearTen.java b/src/lessons/welcome/bool2/NearTen.java
deleted file mode 100644
index 84b3752..0000000
--- a/src/lessons/welcome/bool2/NearTen.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class NearTen extends BatExercise {
-	public NearTen(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("nearTen");
-		myWorld.addTest(VISIBLE, 12) ;
-		myWorld.addTest(VISIBLE, 17) ;
-		myWorld.addTest(VISIBLE, 19) ;
-		myWorld.addTest(INVISIBLE, 21) ;
-		myWorld.addTest(INVISIBLE, 6) ;
-		myWorld.addTest(INVISIBLE, 10) ;
-		myWorld.addTest(INVISIBLE, 11) ;
-		myWorld.addTest(INVISIBLE, 12) ;
-		myWorld.addTest(INVISIBLE, 13) ;
-		myWorld.addTest(INVISIBLE, 54) ;
-		myWorld.addTest(INVISIBLE, 155) ;
-		myWorld.addTest(INVISIBLE, 158) ;
-		myWorld.addTest(INVISIBLE, 3) ;
-		myWorld.addTest(INVISIBLE, 1) ;
-
-		langTemplate(Game.PYTHON, "nearTen", 
-				"def nearTen(num):\n",
-				"  return (num % 10) <= 2 or (num % 10) >= 8\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( nearTen((Integer)t.getParameter(0)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean nearTen(int num) {
-		/* BEGIN SOLUTION */
-		return (num % 10) <= 2 || (num % 10) >= 8; 
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/RedTicket.fr.html b/src/lessons/welcome/bool2/RedTicket.fr.html
deleted file mode 100644
index e29cb45..0000000
--- a/src/lessons/welcome/bool2/RedTicket.fr.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>Ticket rouge</h1>
-Vous avez un ticket de lotterie rouge comportant trois entiers a, b et
-c. Chacun d'entre eux est 0, 1, ou 2. Si ils sont tous comme valeur 2, le
-résultat vaut 10. Sinon, si ils sont égaux, le résultat vaut 5. Sinon, tant
-que b et c sont différents de a, le résultat vaut 1. Sinon, le résultat est
-0.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/RedTicket.html b/src/lessons/welcome/bool2/RedTicket.html
deleted file mode 100644
index 30ce022..0000000
--- a/src/lessons/welcome/bool2/RedTicket.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>RedTicket</h1>
-You have a
-red lottery ticket showing ints a, b, and c, each of which is 0, 1, or
-2. If they are all the value 2, the result is 10. Otherwise if they are
-all the same, the result is 5. Otherwise so long as both b and c are
-different from a, the result is 1. Otherwise the result is 0.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/RedTicket.java b/src/lessons/welcome/bool2/RedTicket.java
deleted file mode 100644
index fa1e2b1..0000000
--- a/src/lessons/welcome/bool2/RedTicket.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class RedTicket extends BatExercise {
-	public RedTicket(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("redTicket");
-		myWorld.addTest(VISIBLE, 2, 2, 2) ;
-		myWorld.addTest(VISIBLE, 2, 2, 1) ;
-		myWorld.addTest(VISIBLE, 0, 0, 0) ;
-		myWorld.addTest(INVISIBLE, 2, 0, 0) ;
-		myWorld.addTest(INVISIBLE, 1, 1, 1) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 1) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 0) ;
-		myWorld.addTest(INVISIBLE, 0, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 1, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 0, 2, 0) ;
-		myWorld.addTest(INVISIBLE, 1, 1, 2) ;
-
-		langTemplate(Game.PYTHON, "redTicket", 
-				"def redTicket(a, b, c):\n",
-				"	if (a == b and b == c and c == 2):\n"+
-				"		return 10\n"+
-				"	elif (a == b and b == c):\n"+
-				"		return 5\n"+
-				"	elif (b != a and c != a):\n"+
-				"		return 1\n"+
-				"	else:\n"+
-				"		return 0\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( redTicket((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int redTicket(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		if (a == b && b == c && c == 2)
-			return 10;
-		else if (a == b && b == c)
-			return 5;
-		else if (b != a && c != a)
-			return 1;
-		else
-			return 0;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/ShareDigit.fr.html b/src/lessons/welcome/bool2/ShareDigit.fr.html
deleted file mode 100644
index 4c060b5..0000000
--- a/src/lessons/welcome/bool2/ShareDigit.fr.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Chiffre partagé</h1>
-Soit deux entiers, chacun étant dans l'intervalle [10,99], renvoyez vrai si
-il y a un chiffre qui apparait dans les deux nombres, comme 2 dans 12 et
-23. (Note: division, i.e.  n/10, renvoie le chiffre à gauche tant que le %
-"mod" n%10 renvoye le bon chiffre.)
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/ShareDigit.html b/src/lessons/welcome/bool2/ShareDigit.html
deleted file mode 100644
index 2a4a63c..0000000
--- a/src/lessons/welcome/bool2/ShareDigit.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>ShareDigit</h1>
-Given two
-ints, each in the range 10..99, return true if there is a digit that
-appears in both numbers, such as the 2 in 12 and 23. (Note: division,
-e.g. n/10, gives the left digit while the % "mod" n%10 gives the right
-digit.)
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/ShareDigit.java b/src/lessons/welcome/bool2/ShareDigit.java
deleted file mode 100644
index 7e42ad3..0000000
--- a/src/lessons/welcome/bool2/ShareDigit.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class ShareDigit extends BatExercise {
-	public ShareDigit(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("shareDigit");
-		myWorld.addTest(VISIBLE, 12, 23) ;
-		myWorld.addTest(VISIBLE, 12, 43) ;
-		myWorld.addTest(VISIBLE, 12, 44) ;
-		myWorld.addTest(INVISIBLE, 23, 12) ;
-		myWorld.addTest(INVISIBLE, 23, 39) ;
-		myWorld.addTest(INVISIBLE, 23, 19) ;
-		myWorld.addTest(INVISIBLE, 30, 90) ;
-		myWorld.addTest(INVISIBLE, 30, 91) ;
-		myWorld.addTest(INVISIBLE, 55, 55) ;
-		myWorld.addTest(INVISIBLE, 55, 44) ;
-
-		langTemplate(Game.PYTHON, "shareDigit", 
-				"def shareDigit(a, b):\n",
-				"   return (a/10 == b/10 or a/10 == b%10 or a%10 == b/10 or a%10 == b%10)");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( shareDigit((Integer)t.getParameter(0), (Integer)t.getParameter(1)) ); 
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean shareDigit(int a, int b) {
-		/* BEGIN SOLUTION */
-		return (a/10 == b/10 || a/10 == b%10 || a%10 == b/10 || a%10 == b%10);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/SortaSum.fr.html b/src/lessons/welcome/bool2/SortaSum.fr.html
deleted file mode 100644
index b64a6b8..0000000
--- a/src/lessons/welcome/bool2/SortaSum.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Sommes d'entiers</h1>
-Soit deux entiers, a et b, renvoyez leur somme. Cependant, les sommes entre
-10 et 19 inclus sont interdites, dans ce cas, renvoyez 20.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/SortaSum.html b/src/lessons/welcome/bool2/SortaSum.html
deleted file mode 100644
index ee6a905..0000000
--- a/src/lessons/welcome/bool2/SortaSum.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>SortaSum</h1>
-Given 2 ints,
-a and b, return their sum. However, sums in the range 10..19 inclusive,
-are forbidden, so in that case just return 20.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/SortaSum.java b/src/lessons/welcome/bool2/SortaSum.java
deleted file mode 100644
index 8fabd59..0000000
--- a/src/lessons/welcome/bool2/SortaSum.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class SortaSum extends BatExercise {
-	public SortaSum(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("sortaSum");
-		myWorld.addTest(VISIBLE, 3, 4) ;
-		myWorld.addTest(VISIBLE, 9, 4) ;
-		myWorld.addTest(VISIBLE, 10, 11) ;
-		myWorld.addTest(INVISIBLE, 12, -3) ;
-		myWorld.addTest(INVISIBLE, -3, 12) ;
-		myWorld.addTest(INVISIBLE, 4, 5) ;
-		myWorld.addTest(INVISIBLE, 4, 6) ;
-		myWorld.addTest(INVISIBLE, 14, 7) ;
-		myWorld.addTest(INVISIBLE, 14, 6) ;
-
-		langTemplate(Game.PYTHON, "sortaSum", 
-				"def sortaSum(a, b):\n",
-				"	sum = a+b\n"+
-				"	if (sum >= 10 and sum <= 19):\n"+
-				"		return 20\n"+
-				"	else:\n"+
-				"		return sum\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( sortaSum((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int sortaSum(int a, int b) {
-		/* BEGIN SOLUTION */
-		int sum = a+b;
-		if (sum >= 10 && sum <= 19)
-			return 20;
-		else
-			return sum;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/SquirrelPlay.fr.html b/src/lessons/welcome/bool2/SquirrelPlay.fr.html
deleted file mode 100644
index b438667..0000000
--- a/src/lessons/welcome/bool2/SquirrelPlay.fr.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>Jeu de l'écureuil</h1>
-Les écureuils dans Palo Alto passent la majorité de leurs journées à
-jouer. En particulier, ils jouent si la température est entre 60 et 90 (
-inclus ). A moins que ce soit l'été, alors la limite supérieure est de 100
-au lieu de 90.Soit une température entière et un booléen isSummer.
-Renvoyez vrai si les écureuils jouent et faux sinon.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/SquirrelPlay.html b/src/lessons/welcome/bool2/SquirrelPlay.html
deleted file mode 100644
index e959897..0000000
--- a/src/lessons/welcome/bool2/SquirrelPlay.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>SquirrelPlay</h1>
-The squirrels
-in Palo Alto spend most of the day playing. In particular, they play if
-the temperature is between 60 and 90 (inclusive). Unless it is summer,
-then the upper limit is 100 instead of 90. Given an int temperature and
-a boolean isSummer, return true if the squirrels play and false
-otherwise.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/SquirrelPlay.java b/src/lessons/welcome/bool2/SquirrelPlay.java
deleted file mode 100644
index 5a42a6b..0000000
--- a/src/lessons/welcome/bool2/SquirrelPlay.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class SquirrelPlay extends BatExercise {
-	public SquirrelPlay(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("squirrelPlay");
-		myWorld.addTest(VISIBLE, 70, false) ;
-		myWorld.addTest(VISIBLE, 95, false) ;
-		myWorld.addTest(VISIBLE, 95, true) ;
-		myWorld.addTest(INVISIBLE, 90, false) ;
-		myWorld.addTest(INVISIBLE, 90, true) ;
-		myWorld.addTest(INVISIBLE, 50, false) ;
-		myWorld.addTest(INVISIBLE, 50, true) ;
-		myWorld.addTest(INVISIBLE, 100, false) ;
-		myWorld.addTest(INVISIBLE, 100, true) ;
-		myWorld.addTest(INVISIBLE, 105, true) ;
-		myWorld.addTest(INVISIBLE, 59, false) ;
-		myWorld.addTest(INVISIBLE, 59, true) ;
-		myWorld.addTest(INVISIBLE, 60, false) ;
-
-		langTemplate(Game.PYTHON, "squirrelPlay", 
-				"def squirrelPlay(temp, isSummer):\n",
-				"   return (temp >= 60 and ((isSummer and temp <= 100) or temp <= 90))");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( squirrelPlay((Integer)t.getParameter(0), (Boolean)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean squirrelPlay(int temp, boolean isSummer) {
-		/* BEGIN SOLUTION */
-		return (temp >= 60 && ((isSummer && temp <= 100) || temp <= 90));
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/TeaParty.fr.html b/src/lessons/welcome/bool2/TeaParty.fr.html
deleted file mode 100644
index 7254b00..0000000
--- a/src/lessons/welcome/bool2/TeaParty.fr.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h1>Goûter</h1>
-Nous avons un goûter avec quantité de thé et de bonbons. Renvoyez l'entier
-'outcome' du goûter encodé comme 0=mauvais, 1=bien, ou 2=excellent. Un
-goûter est bien (1) si le thé et les bonbons sont à 5 au moins. Cependant,
-si soit le thé soit les bonbons est à au moins le double de la quantité de
-l'autre, le goûter est excellent (2). Cependant, dans tous les cas, si soit
-le thé soit les bonbons sont à moins de 5, le goûter est toujours mauvais
-(0).
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/TeaParty.html b/src/lessons/welcome/bool2/TeaParty.html
deleted file mode 100644
index 7b04a57..0000000
--- a/src/lessons/welcome/bool2/TeaParty.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h1>TeaParty</h1>
-We are having
-a party with amounts of tea and candy. Return the int outcome of the
-party encoded as 0=bad, 1=good, or 2=great. A party is good (1) if both
-tea and candy are at least 5. However, if either tea or candy is at
-least double the amount of the other one, the party is great (2).
-However, in all cases, if either tea or candy is less than 5, the party
-is always bad (0).
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/TeaParty.java b/src/lessons/welcome/bool2/TeaParty.java
deleted file mode 100644
index db5d872..0000000
--- a/src/lessons/welcome/bool2/TeaParty.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class TeaParty extends BatExercise {
-	public TeaParty(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("teaParty");
-		myWorld.addTest(VISIBLE, 6, 8) ;
-		myWorld.addTest(VISIBLE, 3, 8) ;
-		myWorld.addTest(VISIBLE, 20, 6) ;
-		myWorld.addTest(INVISIBLE, 12, 6) ;
-		myWorld.addTest(INVISIBLE, 11, 6) ;
-		myWorld.addTest(INVISIBLE, 11, 4) ;
-		myWorld.addTest(INVISIBLE, 4, 5) ;
-		myWorld.addTest(INVISIBLE, 5, 5) ;
-		myWorld.addTest(INVISIBLE, 6, 6) ;
-		myWorld.addTest(INVISIBLE, 5, 10) ;
-		myWorld.addTest(INVISIBLE, 5, 9) ;
-		myWorld.addTest(INVISIBLE, 10, 4) ;
-		myWorld.addTest(INVISIBLE, 10, 20) ;
-
-		langTemplate(Game.PYTHON, "teaParty", 
-				"def teaParty(tea, candy):\n",
-				"	if (tea < 5 or candy < 5):\n"+
-				"		return 0\n"+
-				"	elif (tea >= 2*candy or candy >= 2*tea):\n"+ 
-				"		return 2\n"+
-				"	else:\n" +
-				"		return 1\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( teaParty((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int teaParty(int tea, int candy) {
-		/* BEGIN SOLUTION */
-		if (tea < 5 || candy < 5)
-			return 0;
-		else if (tea >= 2*candy || candy >= 2*tea) 
-			return 2;
-		else // (tea >= 5 && candy >= 5)
-			return 1;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/TeenSum.fr.html b/src/lessons/welcome/bool2/TeenSum.fr.html
deleted file mode 100644
index 4bd42b7..0000000
--- a/src/lessons/welcome/bool2/TeenSum.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Somme d'ados</h1>
-Étant donné deux nombres entiers (a et b), retournez leur somme. Cependant,
-les valeurs ados (dans l'intervale [13;19]) sont particulièrement
-chanceuse. Donc, si l'un des nombres est ado, retournez simplement 19.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/TeenSum.html b/src/lessons/welcome/bool2/TeenSum.html
deleted file mode 100644
index 3da9933..0000000
--- a/src/lessons/welcome/bool2/TeenSum.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>TeenSum</h1>
-Given 2 ints,
-a and b, return their sum. However, "teen" values in the range 13..19
-inclusive, are extra lucky. So if either value is a teen, just return
-19.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/TeenSum.java b/src/lessons/welcome/bool2/TeenSum.java
deleted file mode 100644
index d53f8bd..0000000
--- a/src/lessons/welcome/bool2/TeenSum.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class TeenSum extends BatExercise {
-	public TeenSum(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("teenSum");
-		myWorld.addTest(VISIBLE, 3, 4) ;
-		myWorld.addTest(VISIBLE, 10, 13) ;
-		myWorld.addTest(VISIBLE, 13, 2) ;
-		myWorld.addTest(INVISIBLE, 3, 19) ;
-		myWorld.addTest(INVISIBLE, 13, 13) ;
-		myWorld.addTest(INVISIBLE, 10, 10) ;
-		myWorld.addTest(INVISIBLE, 6, 14) ;
-		myWorld.addTest(INVISIBLE, 15, 2) ;
-		myWorld.addTest(INVISIBLE, 19, 19) ;
-		myWorld.addTest(INVISIBLE, 19, 20) ;
-		myWorld.addTest(INVISIBLE, 2, 18) ;
-		myWorld.addTest(INVISIBLE, 12, 4) ;
-		myWorld.addTest(INVISIBLE, 2, 20) ;
-		myWorld.addTest(INVISIBLE, 2, 17) ;
-		myWorld.addTest(INVISIBLE, 2, 16) ;
-		myWorld.addTest(INVISIBLE, 6, 7) ;
-
-		langTemplate(Game.PYTHON, "teenSum", 
-				"def teenSum(a, b):\n",
-				"	if ((a >= 13 and a <= 19) or (b >= 13 and b <= 19)):\n"+
-				"		return 19\n"+
-				"	else:\n"+
-				"		return a+b\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( teenSum((Integer)t.getParameter(0), (Integer)t.getParameter(1)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int teenSum(int a, int b) {
-		/* BEGIN SOLUTION */
-		if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19))
-			return 19;
-		else
-			return a+b;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/TwoAsOne.fr.html b/src/lessons/welcome/bool2/TwoAsOne.fr.html
deleted file mode 100644
index b65ed1f..0000000
--- a/src/lessons/welcome/bool2/TwoAsOne.fr.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<h1>Deux pour un</h1>
-Soit trois entiers, a b c, renvoyez vrai si il est possible d'en additionner
-deux d'entre eux pour obtenir le troisième.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/TwoAsOne.html b/src/lessons/welcome/bool2/TwoAsOne.html
deleted file mode 100644
index 365713b..0000000
--- a/src/lessons/welcome/bool2/TwoAsOne.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>TwoAsOne</h1>
-Given three ints, a b c, return true if it is possible to add two of the ints to get the third.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/TwoAsOne.java b/src/lessons/welcome/bool2/TwoAsOne.java
deleted file mode 100644
index 8e42916..0000000
--- a/src/lessons/welcome/bool2/TwoAsOne.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class TwoAsOne extends BatExercise {
-	public TwoAsOne(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("twoAsOne");
-		myWorld.addTest(VISIBLE, 1, 2, 3) ;
-		myWorld.addTest(VISIBLE, 3, 1, 2) ;
-		myWorld.addTest(VISIBLE, 3, 2, 2) ;
-		myWorld.addTest(INVISIBLE, 2, 3, 1) ;
-		myWorld.addTest(INVISIBLE, 5, 3, -2) ;
-		myWorld.addTest(INVISIBLE, 5, 3, -3) ;
-		myWorld.addTest(INVISIBLE, 2, 5, 3) ;
-		myWorld.addTest(INVISIBLE, 9, 5, 5) ;
-		myWorld.addTest(INVISIBLE, 9, 4, 5) ;
-		myWorld.addTest(INVISIBLE, 5, 4, 9) ;
-		myWorld.addTest(INVISIBLE, 3, 3, 0) ;
-		myWorld.addTest(INVISIBLE, 3, 3, 2) ;
-
-		langTemplate(Game.PYTHON, "twoAsOne", 
-				"def twoAsOne(a, b, c):\n",
-				"   return (a + b == c) or (a + c == b) or (b + c == a)");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( twoAsOne((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Integer)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	boolean twoAsOne(int a, int b, int c) {
-		/* BEGIN SOLUTION */
-		return (a + b == c) || (a + c == b) || (b + c == a);
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/bool2/WithoutDoubles.fr.html b/src/lessons/welcome/bool2/WithoutDoubles.fr.html
deleted file mode 100644
index 4dce41e..0000000
--- a/src/lessons/welcome/bool2/WithoutDoubles.fr.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>Sans double</h1>
-Renvoyez la somme du jet de deux dés à six faces. Cependant, si noDoubles
-est vrai et que les deux dés ont la même valeur, incrémentez l'un des dés à
-la valeur suivante, en le mettant à 1 si sa valeur était 6.
-
-
-<p>Cet exercice a été extrait de l'excellent site d'exercices
-http://javabat.com/ pour JLM.</p>
diff --git a/src/lessons/welcome/bool2/WithoutDoubles.html b/src/lessons/welcome/bool2/WithoutDoubles.html
deleted file mode 100644
index 6f70a64..0000000
--- a/src/lessons/welcome/bool2/WithoutDoubles.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<h1>WithoutDoubles</h1>
-Return the
-sum of two 6-sided dice rolls, each in the range 1..6. However, if
-noDoubles is true, if the two dice show the same value, increment one
-die to the next value, wrapping around to 1 if its value was 6.
-
-
-<p>This exercise was converted to JLM from the excellent exercising site http://javabat.com/</p>
diff --git a/src/lessons/welcome/bool2/WithoutDoubles.java b/src/lessons/welcome/bool2/WithoutDoubles.java
deleted file mode 100644
index b065f26..0000000
--- a/src/lessons/welcome/bool2/WithoutDoubles.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* automatically converted from the Nick Parlante's excellent exercising site http://javabat.com/ */
-
-package lessons.welcome.bool2;
-import jlm.core.model.Game;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.bat.BatExercise;
-import jlm.universe.bat.BatTest;
-import jlm.universe.bat.BatWorld;
-
-public class WithoutDoubles extends BatExercise {
-	public WithoutDoubles(Lesson lesson) {
-		super(lesson);
-
-		BatWorld myWorld = new BatWorld("withoutDoubles");
-		myWorld.addTest(VISIBLE, 2, 3, true) ;
-		myWorld.addTest(VISIBLE, 3, 3, true) ;
-		myWorld.addTest(VISIBLE, 3, 3, false) ;
-		myWorld.addTest(INVISIBLE, 2, 3, false) ;
-		myWorld.addTest(INVISIBLE, 5, 4, true) ;
-		myWorld.addTest(INVISIBLE, 5, 4, false) ;
-		myWorld.addTest(INVISIBLE, 5, 5, true) ;
-		myWorld.addTest(INVISIBLE, 5, 5, false) ;
-		myWorld.addTest(INVISIBLE, 6, 6, true) ;
-		myWorld.addTest(INVISIBLE, 6, 6, false) ;
-		myWorld.addTest(INVISIBLE, 1, 6, true) ;
-		myWorld.addTest(INVISIBLE, 6, 1, false) ;
-
-		langTemplate(Game.PYTHON, "withoutDoubles", 
-				"def withoutDoubles(die1, die2, noDoubles):\n",
-				"	if (noDoubles and (die1 == die2)):\n"+
-				"		if (die1 == 6):\n"+
-				"			return 1 + die2\n"+
-				"		else:\n"+
-				"			return die1 + 1 + die2\n"+
-				"	else:\n"+
-				"		return die1 + die2\n");
-		setup(myWorld);
-	}
-
-	/* BEGIN SKEL */
-	public void run(BatTest t) {
-		t.setResult( withoutDoubles((Integer)t.getParameter(0), (Integer)t.getParameter(1), (Boolean)t.getParameter(2)) );
-	}
-	/* END SKEL */
-
-	/* BEGIN TEMPLATE */
-	int withoutDoubles(int die1, int die2, boolean noDoubles) {
-		/* BEGIN SOLUTION */
-		if (noDoubles && (die1 == die2)) {
-			if (die1 == 6)
-				return 1 + die2;
-			else 
-				return die1 + 1 + die2;
-		} else 
-			return die1 + die2;
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/conditions/Conditions.fr.html b/src/lessons/welcome/conditions/Conditions.fr.html
index 27f84c9..02f012c 100644
--- a/src/lessons/welcome/conditions/Conditions.fr.html
+++ b/src/lessons/welcome/conditions/Conditions.fr.html
@@ -6,153 +6,144 @@ ne peuvent pas réagir aux conditions extérieurs. Une <b>instruction
 conditionnelle</b> permet au programme de s'adapter en disant quelque chose
 comme <i>S'il pleut, prend un parapluie</i>. 
 
-<p class="Java">La syntaxe Java est la suivante :</p>
-<p class="Python">La syntaxe Python est la suivante :</p>
- <pre class="Java">if (<b>condition</b>) {
-    <b>quoiFaire();</b>
-}</pre>
- <pre class="Python">if <b>condition</b>:
-    <b>quoiFaire()</b></pre>
-
-<p class="Java">Si la condition est vraie, tout le code compris entre le { et le }
-correspondant sera exécuté. Si non, il sera ignoré. Bien entendu, il est
-possible d'écrire plusieurs instructions entre les deux accolades (voire un
-autre test).</p>
-<p class="Python">Si la condition est vraie, tout le code du bloc placé après les deux points
-(:)
-sera exécuté. Si non, il sera ignoré. Bien entendu, il est possible d'écrire
-plusieurs instructions dans le sous-bloc (voire un autre test).</p>
-
-<p class="Python">
-Python utilise l'indentation pour définir les blocs de code. L'indentation
-standard en Python est de quatre espaces. Veuillez noter que les blocs de
-code n'ont pas besoin de terminaison. Indenter commence un bloc et
-désindenter le termine. Dans le code suivant, les instructions
-<b>whatToDo()</b> et <b>whatToDoNext()</b> seront executées si la condition
-est vraie, ensuite l'instruction <b>whatToDoAnyway()</b> sera exécutée dans
-tous les cas.
-
-<pre class="Python">if <b>condition</b>:
+<p>La syntaxe en [!thelang] est la suivante :</p>
+
+<pre>[!java|scala]if (<b>condition</b>) {
+    <b>aFaireSiVraie();</b>
+    <b>aFaireEnsuiteSiVraie();</b>
+}[/!][!python]if <b>condition</b>:
+    <b>aFaireSiVraie()</b>
+    <b>aFaireEnsuiteSiVraie()</b>[/!]
+<b>aFaireDansTousLesCas()[!java];[/!]</b></pre>
+
+<p>Le mot <code>if</code> signifie «si» en anglais. Si la condition est vraie,
+alors le code du bloc suivant sera exécuté, puis l'exécution se poursuivra
+avec la suite du code, après le bloc. Sinon, si la condition est fausse, le
+bloc suivant sera ignoré et l'exécution passera directement au code placé
+après lui. Le bloc conditionnel peut contenir plusieurs instructions. Il
+peut même contenir d'autre tests, avec leurs sous-blocs associés.</p>
+
+<p>Dans cet exemple, les instructions <code>aFaireSiVraie()</code> et
+<code>aFaireSiVraie()</code> seront exécutée si (et seulement si) la
+condition est vraie tandis que l'instruction
+<code>aFaireDansTousLesCas()</code> sera exécutée que la condition soit
+vraie ou fausse. 
+</p>
+
+<p>En [!thelang], les blocs sont
+[!java|scala]délimités par des accolades : le symbole { commence un bloc
+tandis
+que le symbole } le ferme.  Les caractères blancs ne sont pas pris en
+compte[/!][!java].[/!][!scala], tant que les instructions restent séparées
+soit par des points-virgules, soit par des retour à la ligne.[/!]
+[!java|scala]Il reste très important d'indenter correctement votre code pour
+qu'il reste lisible.[/!]
+[!python]marqués par l'indentation : toutes les lignes indentés (=décalées
+vers la droite par des espaces) font partie du bloc. Il est assez courant
+d'utiliser quatre espaces pour indenter le code, mais cela fonctionne quel
+que soit le nombre de caractères blancs utilisés pour celà. Simplement,
+toutes les lignes d'un bloc donné doivent utiliser le même nombre de
+blancs. La fin des blocs de code n'est pas marquée par un symbole
+particulier: il s'arrête dès que les lignes ne sont plus
+indentées. N'oubliez pas les deux points (:) à la fin de la ligne
+<code>if</code>, python en a besoin pour savoir qu'un nouveau bloc commence.
+Le fait que python utilise l'indentation pour maquer les blocs est un
+avantage pour les débutants: cela vous forcera à respecter des critères
+stricts de mise en forme de votre code.[/!]
+Il est très facile de se perdre dans un code qui n'est pas correctement
+indenté. Il est donc important que vous fassiez en sorte que votre code
+reste clair et lisible pour que le relire et le modifier reste plaisant et
+productif.
+
+
+<p class="python">Toutes les instructions d'un bloc doivent avoir la même indentation, et il
+n'est pas possible de couper un bloc. Les deux exemples suivants de code
+sont incorrects et vont générer des erreurs.</p>
+<pre class="python">if <b>condition</b>:
     <b>quoiFaire()</b>
-    <b>quoiFaireEnsuite()</b>
+      <b>quoiFaireEnsuite()</b> <span class="comment"># une espace de trop</span>
 <b>quoiFaireDansTousLesCas()</b>
 </pre>
-
-<p class="Python">Les fonctions Pythons n'ont pas de début ou de fin explicite, ni d'accolade
-pour indiquer où le code commence et où il se termine. Le seul délimiteur
-est un double points (:) et l'indentation du code lui même.</p>
-
-<p class="Python">Exemple 2.5. Indenter la fonction buildConnectionString</p>
-
-<pre class="Python">
-def buildConnectionString(params):
-    """Construit une connection string à partir d'un dictionnaire de paramètres.
-
-    Renvoie une chaîne de caractères."""
-    return ";".join(["%s=%s" % (k, v) for k, v in params.items()])
-</pre>
-
-<p class="Python">Les blocs de code sont définis par leur indentation. Par "bloc de code", je
-veux dire les fonctions, les branchements conditionnels if, les boucles for,
-les boucles while, etc. Indenter commence un bloc et désindenter le
-termine. Il n'y a pas de parenthèses, d'accolades, ou de mots clés. Cela
-signifie qu'un espace est significatif et doit être cohérent. Dans cet
-exemple, le code de la fonction (en comptant la documentation) est indenté
-avec quatre espaces. Il n'est pas nécessaire que cela soit quatre espaces,
-il faut juste que cela soit cohérent. La première ligne qui n'est pas
-indentée est en dehors de la fonction.</p>
-
-<p class="Python">Il est important que l'indentation de toutes les instructions d'un bloc soit
-cohérente, et il n'est pas possible de couper un bloc. Les deux exemples
-suivants de code sont incorrects et vont générer des erreurs.</p>
-<pre class="Python">if <b>condition</b>:
+<pre class="python">if <b>condition</b>:
     <b>quoiFaire()</b>
-     <b>quoiFaireEnsuite()</b>
 <b>quoiFaireDansTousLesCas()</b>
+    <b>quoiFaireEnsuite()</b> <span class="comment"># Ce bloc n'est rataché à aucune ligne de condition</span>
 </pre>
-<pre class="Python">if <b>condition</b>:
-    <b>quoiFaire()</b>
-<b>quoiFaireDansTousLesCas()</b>
-    <b>quoiFaireEnsuite()</b>
-</pre>
-
-<p class="Java">Une condition peut être une variable de type <tt>boolean</tt>. Le code entre
-accolades sera exécuté si la variable vaut la valeur <tt>true</tt> (vrai),
-et il sera ignoré si elle vaut <tt>false</tt> (faux).</p>
 
-<p class="Python">Une condition peut être une variable de type <tt>boolean</tt>. Le code dans
-le
-bloc indenté sera exécuté si la variable vaut la valeur <tt>True</tt>
-(vrai), et il sera ignoré si elle vaut <tt>False</tt> (faux).</p> 
-
-<p>La condition peut aussi être un test arithmétique, comme <tt>x</tt>
-<b>==</b> <tt>5</tt>, qui vérifie si la valeur actuelle de <tt>x</tt> est 5,
-ou bien comme <b>!=</b> (teste l'inégalité), <b><</b> (inférieur à),
-<b>></b> (supérieur à), <b><=</b> (inférieur ou égal à), <b>>=</b>
-(supérieur ou égal à).</p>
+<p>La condition doit être une expression de type
+<code>[!java]boolean[/!][!scala|python]Boolean[/!]</code> (expression
+booléenne).  Le sous-bloc sera exécuté seulement si cette expression vaut
+<code>[!java|scala]true[/!][!python]True[/!]</code> (vrai), et il sera
+ignoré si sa valeur est
+<code>[!java|scala]false[/!][!python]False[/!]</code> (faux).
+<code>[!java|scala]true[/!][!python]True[/!]</code> et
+<code>[!java|scala]false[/!][!python]False[/!]</code> sont des constantes
+définies directement par [!thelang], tout comme 0 ou 1 en mathématiques.</p>
+
+<p>La condition peut aussi être une variable booléenne (nous reviendrons sur
+les variables dans un autre exercice, pas de panique) ou un test
+arithmétique,comme <code>x == 5</code>, qui teste si la valeur actuelle de
+<tt>x</tt> est 5, ou bien comme <b>!=</b> (teste l'inégalité, càd si le
+membre gauche a une valeur différente du membre droit), <b><</b>
+(inférieur à), <b>></b> (supérieur à), <b><=</b> (inférieur ou égal
+à), <b>>=</b> (supérieur ou égal à).</p>
 
 <p>Attention au piège classique, qui consiste à tester l'égalité d'une variable
-avec = au lieu de ==. Heureusement, le compilateur vous indique le plus
-souvent ce problème, mais pas tout le temps. Si la variable est de type
-booléen, il peut se faire prendre au piège, et il convient donc d'être
-attentif...
+avec = au lieu de ==. Heureusement, [!java|scala]le
+compilateur[/!][!python]l'interpréteur[/!] détecte le plus souvent ce
+problème et vous le signale, mais pas tout le temps. Si la variable est de
+type booléen, il peut se faire prendre au piège, et il convient donc d'être
+attentif...</p>
 
 <p>La condition peut également être un appel à certaines méthodes
 particulières, dont le résultat est un booléen. Par exemple, la méthode
-<tt>isFacingWall()</tt> de la buggle renvoie vrai si la buggle est face à un
-mur, et faux sinon.
+<tt>estFaceMur()</tt> de la buggle renvoie vrai si la buggle est face à un
+mur, et faux sinon.</p>
 
 <p>Enfin, il est possible de construire une condition composée de plusieurs
-sous-conditions reliées par des opérations booléennes.
-<ul class="Java">
-  <li><tt>cond1 && cond2</tt> est vraie si <tt>cond1</tt> <b>et</b> <tt>cond2</tt>
-est vraie (si <tt>cond1</tt> est fausse, <tt>cond2</tt> n'est même pas
-évaluée).</li> 
-  <li><tt>cond1 || cond2</tt> est vraie si <tt>cond1</tt> <b>ou</b> <tt>cond2</tt>
-est vraie (si <tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas
-évaluée).</li>
-  <li><tt>!cond</tt> est vraie si <tt>cond</tt> ne l'est pas.</li>
-  <li>On peut forcer l'ordre d'évaluation en ajoutant des parenthèses. En cas de
-doute, n'hésitez pas à mettre plus de parenthèses que nécessaire pour lever
-les ambiguïtés sur l'ordre d'évaluation.</li>
-</ul> 
-
-<ul class="Python">
-  <li><tt>cond1 and cond2</tt> est vraie si <tt>cond1</tt> <b>et</b>
-<tt>cond2</tt> est vraie (si <tt>cond1</tt> est fausse, <tt>cond2</tt> n'est
-même pas évaluée).</li> 
-  <li><tt>cond1 or cond2</tt> est vraie si <tt>cond1</tt> <b>ou</b> <tt>cond2</tt>
-est vraie (si <tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas
-évaluée).</li> 
-  <li><tt>not cond</tt> est vraie si <tt>cond</tt> ne l'est pas.</li>
-  <li>On peut forcer l'ordre d'évaluation en ajoutant des parenthèses. En cas de
-doute, n'hésitez pas à mettre plus de parenthèses que nécessaire pour lever
-les ambiguïtés sur l'ordre d'évaluation.</li>
+sous-conditions reliées par des opérations booléennes:</p>
+<ul>
+  <li><code>cond1 [!java|scala]&&[/!][!python]and[/!] cond2</code> est vraie si
+<tt>cond1</tt> <b>et</b> <tt>cond2</tt> est vraie (d'ailleurs, si
+<tt>cond1</tt> est fausse, <tt>cond2</tt> n'est même pas évaluée puisqu'on
+sait déjà que la conjonction des deux propositions ne peut pas être vraie).</li> 
+  <li><code>cond1 [!java|scala]||[/!][!python]or[/!] cond2</code> est vraie si
+<tt>cond1</tt> <b>ou</b> <tt>cond2</tt> est vraie (d'ailleurs, si
+<tt>cond1</tt> est vraie, <tt>cond2</tt> n'est même pas évaluée puisqu'on
+sait déjà que la disjonction des deux propositions est vraie).</li>
+  <li><code>[!java|scala]![/!][!python]not [/!]cond</code> est vraie si
+<tt>cond</tt> ne l'est pas.</li>
+  <li>Quand les expressions deviennent compliquées, il est préférable d'ajouter
+quelques parenthèses pour lever toute ambiguïté sur l'ordre
+d'évaluation. N'hésitez pas à mettre suffisamment de parenthèses pour la
+rendre plus lisible.</li>
 </ul> 
 
 <p>Pour finir, il est possible de spécifier ce qu'il faut faire quand la
-condition est fausse, en utilisant la syntaxe suivante :
- <pre class="Java">if (<b>condition</b>) {
-    <b>quoiFaireSiLaConditionEstVraie();</b>
+condition est fausse, en utilisant la syntaxe suivante («else» signifie
+«sinon» en anglais). Dans ce cas, l'instruction
+<code>aFaireSiLaConditionEstFausse()</code> ne sera exécutée que si la
+condition est fausse.</p>
+ <pre>[!java|scala]if (<b>condition</b>) {
+    <b>aFaireSiLaConditionEstVraie();</b>
 } else {
-    <b>quoiFaireSinon();</b>
-}</pre>
-
- <pre class="Python">if (<b>condition</b>):
-    <b>quoiFaireSiLaConditionEstVraie()</b>
+    <b>aFaireSiElleEstFausse();</b>
+}[/!][!python]if (<b>condition</b>):
+    <b>aFaireSiLaConditionEstVraie()</b>
 else:
-    <b>quoiFaireSinon()</b>
-</pre>
+    <b>aFaireSiElleEstFausse()</b>[/!]</pre>
 
 <p class="Python">N'oubliez pas les deux points (:) après le else, ils indiquent qu'un nouveau
 bloc débute.</p>
 
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> Si la buggle est face à un mur (prédicat
-<tt>isFacingWall()</tt>), il faut reculer d'un pas. Sinon, il faut avancer
-d'un pas.
+<h3>Objectif de cet exercice</h3><a name="Objectifs"> Si la buggle est face à un mur, il faut reculer d'un
+pas; Sinon, il faut avancer d'un pas.
+Pour savoir si on est face à un mur, il suffit d'utiliser la méthode
+prédéfinie des buggles nommée <code>estFaceMur()</code>. 
 
 <p>Cet exercice est un peu particulier : il faut que votre programme fonctionne
 pour plusieurs buggles, chacune étant dans une situation initiale
 différente. Le même code sera utilisé pour chacune d'entre elles.</p>
 
-<p>Quand votre programme fonctionne, passez à l'exercice suivant.</p>
+<p>Quand votre programme fonctionne, passez à l'exercice suivant (qui est caché
+par défaut dans un sous-arbre de la fenêtre de sélection).</p>
diff --git a/src/lessons/welcome/conditions/Conditions.html b/src/lessons/welcome/conditions/Conditions.html
index 966ec9c..c8425cd 100644
--- a/src/lessons/welcome/conditions/Conditions.html
+++ b/src/lessons/welcome/conditions/Conditions.html
@@ -5,151 +5,113 @@ are quite boring. They always do the same thing, and cannot react to
 external conditions. A <b>conditional</b> let the program adapt by doing
 something like <i>if it's raining, take an umbrella</i>. 
 
-<p class="Java">The Java syntax is the following:</p>
-<p class="Python">The Python syntax is the following:</p>
- <pre class="Java">if (<b>condition</b>) {
-    <b>whatToDo();</b>
-}</pre>
- <pre class="Python">if <b>condition</b>:
-    <b>whatToDo()</b></pre>
-
-<p class="Java">If the condition is true, any code enclosed between the { and the
-corresponding } will be executed. If not, it will be ignored. Of course, it
-is possible to write more than one instruction between the curly brackets
-(even another test).</p>
-<p class="Python">If the condition is true, any code in the block following the 
-colon symbol will be executed. If not, it will be ignored. Of course, it
-is possible to write more than one instruction in the sub-block
-(even another test).</p>
-
-<p class="Python">
-Python uses indentation to define code blocks. The standard Python indentation
-is 4 spaces. Notice that code blocks do not need any termination. Indenting starts
-a block and unindenting ends it. In the
-following code the instructions <b>whatToDo()</b> and <b>whatToDoNext()</b>
-will be exectuded if the condition is true, then the instruction
-<b>whatToDoAnyway()</b> will be executed anyway.
-
-<pre class="Python">if <b>condition</b>:
-    <b>whatToDo()</b>
-    <b>whatToDoNext()</b>
-<b>whatToDoAnyway()</b>
-</pre>
-
-<p class="Python">Python functions have no explicit begin or end, and
-no curly braces to mark where the function code starts and stops. The
-only delimiter is a colon (:) and the indentation of the code
-itself.</p>
-
-<p class="Python">Example 2.5. Indenting the buildConnectionString
-Function</p>
-
-<pre class="Python">
-def buildConnectionString(params):
-    """Build a connection string from a dictionary of parameters.
-
-    Returns string."""
-    return ";".join(["%s=%s" % (k, v) for k, v in params.items()])
-</pre>
-
-<p class="Python">Code blocks are defined by their indentation. By
-"code block", I mean functions, if statements, for loops, while loops,
-and so forth. Indenting starts a block and unindenting ends it. There
-are no explicit braces, brackets, or keywords. This means that
-whitespace is significant, and must be consistent. In this example,
-the function code (including the doc string) is indented four spaces.
-It doesn't need to be four spaces, it just needs to be consistent. The
-first line that is not indented is outside the function.</p>
-
-<p class="Python">It is important that the indentations of all the
-instructions of a block are consistent, and it is not possible to cut
-a block. The two following codes are incorrect and will raise
+<p>The [!thelang] syntax is the following:</p>
+
+<pre>[!java|scala]if (<b>condition</b>) {
+    <b>whatToDoIfTrue();</b>
+    <b>whatToDoNextIfTrue();</b>
+}[/!][!python]if <b>condition</b>:
+    <b>whatToDoIfTrue()</b>
+    <b>whatToDoNextIfTrue()</b>[/!]
+<b>whatToDoAnyway()[!java];[/!]</b></pre>
+
+<p>If the condition is true, the code of the next block will be executed and then it will continue with the rest of the code.
+If the condition is false, the next block is ignored and the execution continues after it.
+The conditional block can contain several instructions, it can even contain other tests, along with their sub-blocks.</p>
+
+<p>In this example, the instructions <code>whatToDoIfTrue()</code> and <code>whatToDoNextIfTrue()</code> 
+will be executed if and only if the condition is true, 
+while the instruction <code>whatToDoAnyway()</code> will be executed whether or not the condition is true. 
+</p>
+
+<p>In [!thelang], the blocks of code are
+[!java|scala]enclosed between curly brackets: a { sign opens the block, while a } sign closes it. 
+White spaces are not important[/!][!java].[/!][!scala], provided that your instructions are still separated with a semi-column or an end of line.[/!]
+[!java|scala]It is still very important to correctly indent your code to keep it readable.[/!]
+[!python]marked by the indentation: every lines that are a bit shifted to the right with 
+white spaces belong to the block. Quite often, people use 4 spaces for indentation, 
+but it works if you use more or less spaces. Simply, any lines of the block must use the same amount of spaces.
+The end of Python code blocks are not marked by any specific char.
+Indenting lines starts a block and unindenting ends it. Do not forget the colon (:) at the end of 
+the <code>if</code> line, python needs it to know that a new block begins. The fact that python relies on 
+indentation to delimit blocks is a very good property for beginners: it will force your to adhere to strict 
+code presentation standards.[/!]
+It is very easy to get lost in your own code if it's not properly indented, so you want to clean it up so that 
+working on your code remains pleasant and productive.
+
+
+<p class="python">All indentations of a given block must be consistent, and it is not 
+possible to cut a block. The two following codes are incorrect and will raise
 errors.</p>
-<pre class="Python">if <b>condition</b>:
+<pre class="python">if <b>condition</b>:
     <b>whatToDo()</b>
-     <b>whatToDoNext()</b>
+     <b>whatToDoNext()</b> <span class="comment"># one space too much </span>
 <b>whatToDoAnyway()</b>
 </pre>
-<pre class="Python">if <b>condition</b>:
+<pre class="python">if <b>condition</b>:
     <b>whatToDo()</b>
 <b>whatToDoAnyway()</b>
-    <b>whatToDoNext()</b>
+    <b>whatToDoNext()</b> <span class="comment"># this block is not hanging to a condition line</span>
 </pre>
 
-<p class="Java">A condition can be a variable of type <tt>boolean</tt>. The code between
-curly braces will get executed if the variable is <tt>true</tt> and it will
-be ignored if it is <tt>false</tt>.</p>
-
-<p class="Python">A condition can be a variable of type
-<tt>boolean</tt>. The code in the inner bloc will get executed if the
-variable is <tt>True</tt> and it will be ignored if it is
-<tt>False</tt>.</p> 
+<p>The condition must be a <code>[!java]boolean[/!][!scala|python]Boolean[/!]</code> expression. 
+The inner block of code will get executed if the expression is evaluated to  <code>[!java|scala]true[/!][!python]True[/!]</code> 
+and it will be ignored if it is <code>[!java|scala]false[/!][!python]False[/!]</code>.
+<code>[!java|scala]true[/!][!python]True[/!]</code> and <code>[!java|scala]false[/!][!python]False[/!]</code> are constant values 
+defined by [!thelang] directly, just as 0 or 1 in mathematics.</p>
 
-<p>The condition can also be an arithmetic test, such as <tt>x</tt> <b>==</b>
-<tt>5</tt>, which checks whether the current value of <tt>x</tt> is 5, or
-such as <b>!=</b> (checking inequality), <b><</b> (smaller than),
-<b>></b> (larger than), <b><=</b> (smaller or equal to), <b>>=</b>
-(larger or equal to).</p>
+<p>The condition can be a <code>[!java]boolean[/!][!scala|python]Boolean[/!]</code> variable 
+(we will come back on variables in a latter exercise, don't worry) or 
+an arithmetic test, such as <code>x == 5</code>, which checks whether the current value of 
+<code>x</code> is 5, or such as <b>!=</b> (checking inequality, that is, returning [!java|scala]true[/!][!python]True[/!] 
+only if the left hand-side is different from the right hand-side), <b><</b> (smaller than), 
+<b>></b> (larger than), <b><=</b> (smaller or equal to), <b>>=</b> (larger or equal to).</p>
 
 <p>Beware of the classical trap, which consists in testing the equality of a
-variable using = instead of ==. Hopefully, the compiler detects this
-problem most of the time, but not always. If the variable is of type
-boolean, it can get trapped, so you have to be careful...
+variable using = instead of ==. Hopefully, the [!java|scala]compiler[/!][!python]interpreter[/!] 
+detects this problem most of the time, but it could get trapped is some cases (such as when you are 
+affecting a boolean variable). So you'd better to be careful...</p>
 
-<p>The condition can also be a call to some perticular methods returning a
-boolean. For example, the <tt>isFacingWall()</tt> method of the buggle
-returns true if the buggle is facing a wall, and false in the other case.
+<p>The condition can also be a call to some particular methods returning a
+boolean. For example, the <code>isFacingWall()</code> method of the buggle
+returns true if the buggle is facing a wall, and false in the other case.</p>
 
 <p>Finally, a condition can be composed of several sub-conditions connected by
-boolean operations.
-<ul class="Java">
-  <li><tt>cond1 && cond2</tt> is true when <tt>cond1</tt> <b>and</b>
+boolean operations:</p>
+<ul>
+  <li><code>cond1 [!java|scala]&&[/!][!python]and[/!] cond2</code> is true when <tt>cond1</tt> <b>and</b>
       <tt>cond2</tt> are both true (if <tt>cond1</tt> is false,
-      <tt>cond2</tt> is not even evaluated).</li> 
-  <li><tt>cond1 || cond2</tt> is true if <tt>cond1</tt> <b>or</b> <tt>cond2</tt>
-      are true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated).</li>
-  <li><tt>!cond</tt> is true if <tt>cond</tt> is false.</li>
-  <li>It is possible to force the order of evaluation by adding parenthesis. In
-ambigous cases, do not hesitate to add more parenthesis to remove any
-ambiguities on evaluation order.</li>
+      <tt>cond2</tt> is not even evaluated as we already know that the conjunction of both propositions cannot be true).</li> 
+  <li><code>cond1 [!java|scala]||[/!][!python]or[/!] cond2</code> is true if <tt>cond1</tt> <b>or</b> 
+      <tt>cond2</tt> is true (if <tt>cond1</tt> is true, <tt>cond2</tt> is not even evaluated
+      as we already know that the disjunction of both propositions cannot be true).</li>
+  <li><code>[!java|scala]![/!][!python]not [/!]cond</code> is true if <tt>cond</tt> is false.</li>
+  <li>When the expression becomes complicated, it is better to add parenthesis to force the order of evaluation.
+      Do not hesitate to add more parenthesis to remove any ambiguities that may appear in an expression.</li>
 </ul> 
 
-<ul class="Python">
-  <li><tt>cond1 and cond2</tt> is true when <tt>cond1</tt> <b>and</b>
-      <tt>cond2</tt> are both true (if <tt>cond1</tt> is false,
-      <tt>cond2</tt> is not even evaluated).</li> 
-  <li><tt>cond1 or cond2</tt> is true if <tt>cond1</tt> <b>or</b>
-      <tt>cond2</tt> are true (if <tt>cond1</tt> is true,
-      <tt>cond2</tt> is not even evaluated).</li> 
-  <li><tt>not cond</tt> is true if <tt>cond</tt> is false.</li>
-  <li>It is possible to force the order of evaluation by adding parenthesis. In
-ambigous cases, do not hesitate to add more parenthesis to remove any
-ambiguities on evaluation order.</li>
-</ul> 
-
-<p>Finally, it is possible to specify what to do when the condition is false
-using the following syntax:
- <pre class="Java">if (<b>condition</b>) {
+<p>Last, it is possible to specify what to do when the condition is false
+using the following syntax. In this case, the instruction <code>whatToDoIfItsFalse</code>
+will be executed only if the condition is false.</p>
+ <pre>[!java|scala]if (<b>condition</b>) {
     <b>whatToDoIfTheConditionIsTrue();</b>
 } else {
     <b>whatToDoIfItsFalse();</b>
-}</pre>
-
- <pre class="Python">if (<b>condition</b>):
+}[/!][!python]if (<b>condition</b>):
     <b>whatToDoIfTheConditionIsTrue()</b>
 else:
-    <b>whatToDoIfItsFalse()</b>
-</pre>
+    <b>whatToDoIfItsFalse()</b>[/!]</pre>
 
 <p class="Python">Don't forget the colon (:) after the else, it is indicating 
 that a new block is beginning.</p>
 
-<h3>Exercise goal</h3><a name="Objectives">If the buggle is facing a wall (predicate
-<tt>isFacingWall()</tt>), you must move one step back. If not, you must move
-one step forward.
+<h3>Exercise goal</h3><a name="Objectives">If the buggle is facing a wall, 
+you must move one step back. If not, you must move one step forward. To detect 
+whether you are facing a wall, simply use the <code>isFacingWall()</code> built-in, 
+that every buggle understands. 
 
 <p>This exercise is a bit different: your code has to work for several buggles,
 each of them being in a specific initial condition. The same code will be
 executed for each of them.</p>
 
-<p>When your program works, move forward to the next exercise.</p>
+<p>When your program works, move forward to the next exercise, that is hidden in a sub-tree of the selection window.</p>
diff --git a/src/lessons/welcome/conditions/Conditions.java b/src/lessons/welcome/conditions/Conditions.java
index 959b92a..fe68d83 100644
--- a/src/lessons/welcome/conditions/Conditions.java
+++ b/src/lessons/welcome/conditions/Conditions.java
@@ -2,11 +2,11 @@ package lessons.welcome.conditions;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class Conditions extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/conditions/ConditionsEntity.java b/src/lessons/welcome/conditions/ConditionsEntity.java
index acc3ace..f741957 100644
--- a/src/lessons/welcome/conditions/ConditionsEntity.java
+++ b/src/lessons/welcome/conditions/ConditionsEntity.java
@@ -1,6 +1,6 @@
 package lessons.welcome.conditions;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class ConditionsEntity extends SimpleBuggle {
 	@Override
diff --git a/src/lessons/welcome/conditions/ConditionsEntity.scala b/src/lessons/welcome/conditions/ConditionsEntity.scala
new file mode 100644
index 0000000..57eca4a
--- /dev/null
+++ b/src/lessons/welcome/conditions/ConditionsEntity.scala
@@ -0,0 +1,14 @@
+package lessons.welcome.conditions;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaConditionsEntity extends SimpleBuggle {
+	override def run() { 
+		/* BEGIN SOLUTION */
+		if (isFacingWall())
+			backward();
+		else
+			forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/environment/Environment.fr.html b/src/lessons/welcome/environment/Environment.fr.html
index 28a4149..e0de1bb 100644
--- a/src/lessons/welcome/environment/Environment.fr.html
+++ b/src/lessons/welcome/environment/Environment.fr.html
@@ -1,11 +1,13 @@
   <h2>Bienvenue dans le monde des buggles</h2>
 
-  Vous venez de lancer la Java Learning Machine.  Il s'agit d'une plate-forme
-pédagogique destinée à simplifier l'apprentissage de la programmation.  Il
-est constitué d'un ensemble d'exercices groupés par leçons, pour vous
-permettre de progresser à votre rythme. Par défaut, l'outil est configuré
-pour vous permettre de programmer en Java, mais vous pouvez changer de
-langage de programmation grâce au menu Langage si vous le désirez.
+<p>Vous venez de lancer PLM, l'exerciseur du programmeur (Programmer's Learning
+Machine).  Il s'agit d'une plate-forme pédagogique destinée à simplifier
+l'apprentissage de la programmation.  Il est constitué d'un ensemble
+d'exercices groupés par leçons, pour vous permettre de progresser à votre
+rythme. Pour l'instant, l'outil est configuré pour vous permettre de
+programmer en [!thelang/], mais vous pouvez changer de langage de
+programmation grâce au menu Langage si vous le désirez, ou en cliquant sur
+l'icône du [!thelang/] à droite de la barre d'état (en bas de la fenêtre).</p>
 
 <p>Dans cette première leçon, les buggles guideront vos premiers pas en
 programmation.</p>
@@ -17,10 +19,9 @@ donnez. Dans chaque exercice, vous devez donner des ordres à vos buggles
 pour faire en sorte que le monde ressemble à l'objectif de l'exercice. Par
 exemple dans cet exercice, vous devez instruire votre buggle pour qu'elle
 avance d'un pas. Observez la différence entre l'état initial et l'objectif
-en utilisant les panneaux à droite. Selon la leçon (et vos réglages dans le
-menu Language), vous devez écrire vos programme dans l'un des langages de
-programmation suivant : Java, JavaScript, Python ou Ruby (en fonction de
-l'exercice).</p>
+en utilisant les panneaux à droite. Selon la leçon (et vos réglages), vous
+devez écrire vos programme dans l'un des langages de programmation suivant :
+Java, Python ou Scala (en fonction de l'exercice).</p>
   
   <h3>L'environnement de travail</h3>
 
@@ -31,7 +32,11 @@ zone blanche en bas est la console : c'est là que les erreurs et messages
 sont affichés. Si vous avez accès à internet, connectez vous au forum par le
 menu d'aide pour voir si d'autres personnes sont connectés. Notez que quand
 vous réussissez un exercice, la bonne nouvelle est envoyée sur
-twitter. Suivez les progrès de vos amis en suivant #jlmlovers :)</p>
+twitter. Suivez les progrès de vos amis en suivant jlmlovers :)</p>
+  
+  <p>Si vous préférez ne pas poster vos progrès sur internet, changez simplement
+la propriété correspondante dans votre fichier de configuration, qui est
+[!configfile] dans votre cas.</p>
 
   <p>Si votre code contient des erreurs (et les programmes finissent toujours par
 en contenir), l'ordinateur affichera les messages d'erreur sur la
@@ -40,7 +45,7 @@ exercices. Les messages affichés peuvent paraître inquiétant au premier
 abord, mais pas de panique. Le compilateur est seulement pas très doué pour
 communiquer, il n'est pas fondamentalement méchant. En regardant de plus
 près, la solution pour corriger les problèmes est inscrite dans ces messages
-cryptiques. Vous verrez, avec un peu d'entraînement, vous vous y habituerez.
+cryptiques. Vous verrez, avec un peu d'entraînement, vous vous y habituerez.</p>
   
   <h3>Que dois-je faire ?</h3>
   
@@ -48,13 +53,10 @@ cryptiques. Vous verrez, avec un peu d'entraînement, vous vous y habituerez.
 un pas en avant dans le panneau de Code Source. Pour cela, écrivez
 simplement le code suivant. Cliquer sur les contrôles interactifs ne suffit
 pas. Il faut écrire le code après avoir expérimenté interactivement.
-   <pre class="Java">forward();</pre>
-   <pre class="Python">forward()</pre>
+   <pre>avance()[!java];[/!]</pre>
   <p class="Java">N'oubliez pas le <code>;</code> final, car cela indique au compilateur que
 l'instruction est terminée (oui, les ordinateurs sont si stupides qu'il faut
 leur préciser des choses aussi simples).</p>
   
-  <p>Une fois terminé, cliquez sur "run", et passez à l'exercice suivant avec le
-menu File.</p>
-
-   (ou restez ici pour expérimenter un peu si vous le voulez). 
\ No newline at end of file
+  <p>Une fois terminé, cliquez sur «Exécuter». Quand cela fonctionne, vous pouvez
+passer à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/environment/Environment.html b/src/lessons/welcome/environment/Environment.html
index eb8c4a9..d347d75 100644
--- a/src/lessons/welcome/environment/Environment.html
+++ b/src/lessons/welcome/environment/Environment.html
@@ -1,10 +1,11 @@
   <h2>Welcome in the Buggles' World</h2>
 
-  You just started the Java Learning Machine. This is a Learning Management
-System (LMS) aiming at teaching the art of computer programming through interactive
+<p>You just started the Programmer's Learning Machine. This is a Learning Management
+System  aiming at teaching the art of computer programming through interactive
 exercises. It is constituted by a set of exercises grouped by lessons, allowing you 
-to practice at your own pace. By default, the environment is configured to be programmed 
-in the Java programming language, but you can change it from the Language menu if you want.
+to practice at your own pace. Currently, the environment is configured to be programmed 
+in the [!thelang/] programming language, but you can change it from the Language menu 
+if you want, or by clicking on the [!thelang/] icon at the right of the status bar below.</p>
 
 <p>In this first lesson, the buggles will lead your first steps in programming.</p>
 
@@ -16,8 +17,7 @@ in the Java programming language, but you can change it from the Language menu i
   you show instruct your buggle to move forward once. You can see that by checking 
   the difference between the <i>World</i> view and the <i>Objective</i> one. 
   Depending on the lessons (and your settings in the Language menu), your code must 
-  be written in either Java, JavaScript, Python or Ruby (depending on
-  the exercise).</p>
+  be written in either Java, Python or Scala (depending on the exercise).</p>
   
   <h3>Working environment</h3>
 
@@ -25,10 +25,12 @@ in the Java programming language, but you can change it from the Language menu i
   look at the several elements composing the main window, move your mouse over 
   them to show the tooltip, and experiment with the elements to see what they do.
   The white area below is the console: this is where errors and messages get 
-  displayed. If you have access to the net, try to open the forum in the help 
-  menu to check if other people are connected right now. Note that when you 
-  successfully solve an exercise, the good news is spread on twitter. 
+  displayed. Note that when you 
+  successfully solve an exercise, the good news is spread on twitter.
   Keep posted to the progress of your friends by following @jlmlovers :)</p>
+  
+  <p>If you prefer not to post your successes online, just change the relevant 
+  properties in your config file, that is [!configfile] in your case.</p>
 
   <p>If your code contains errors (and code always do at some point), the 
    computer will display error messages in the console. You obviously have to 
@@ -36,7 +38,7 @@ in the Java programming language, but you can change it from the Language menu i
    sound scary at first glance, but don't panic. The compiler is only somehow 
    limited in its communication abilities, but he's not mean. If you look closer, 
    the solution to solve your issue is written in the middle of those cryptic
-   messages. You'll see, with a bit of habit, we get used to it.
+   messages. You will see, with a bit of habit, we get used to it.</p>
   
   <h3>What am I supposed to do?</h3>
   
@@ -44,12 +46,9 @@ in the Java programming language, but you can change it from the Language menu i
   forward using the Source Code pane. For that, simply write the following code
   (clicking on the interactive controls is not enough: You have to write the code 
   after experimenting interactively).
-   <pre class="Java">forward();</pre>
-   <pre class="Python">forward()</pre>
+   <pre>forward()[!java];[/!]</pre>
   <p class="Java">Do not forget the final <code>;</code> which tells the compiler that the
   instruction is over (yes, computers are so dumb that they cannot <i>guess</i> 
   obvious stuff like this).</p>
   
-  <p>Once done, clic on run, and proceed to next exercise using the File menu entry</p>
-
-   (or keep around to experiment further if you feel so). 
\ No newline at end of file
+  <p>Once done, clic on run. You can proceed to next exercise once it works.</p>
diff --git a/src/lessons/welcome/environment/Environment.java b/src/lessons/welcome/environment/Environment.java
index 107d11f..1597191 100644
--- a/src/lessons/welcome/environment/Environment.java
+++ b/src/lessons/welcome/environment/Environment.java
@@ -2,11 +2,11 @@ package lessons.welcome.environment;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class Environment extends ExerciseTemplated {
 	public Environment(Lesson lesson) {
diff --git a/src/lessons/welcome/environment/EnvironmentEntity.java b/src/lessons/welcome/environment/EnvironmentEntity.java
index 8109c80..7594517 100644
--- a/src/lessons/welcome/environment/EnvironmentEntity.java
+++ b/src/lessons/welcome/environment/EnvironmentEntity.java
@@ -1,6 +1,6 @@
 package lessons.welcome.environment;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class EnvironmentEntity extends SimpleBuggle {
 	@Override
diff --git a/src/lessons/welcome/environment/EnvironmentEntity.scala b/src/lessons/welcome/environment/EnvironmentEntity.scala
new file mode 100644
index 0000000..615f18d
--- /dev/null
+++ b/src/lessons/welcome/environment/EnvironmentEntity.scala
@@ -0,0 +1,11 @@
+package lessons.welcome.environment;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaEnvironmentEntity extends SimpleBuggle {
+	protected def run() { 
+		/* BEGIN SOLUTION */
+		forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/basics/Basics-answer0.map b/src/lessons/welcome/instructions/Instructions-answer0.map
similarity index 100%
rename from src/lessons/welcome/basics/Basics-answer0.map
rename to src/lessons/welcome/instructions/Instructions-answer0.map
diff --git a/src/lessons/welcome/instructions/Instructions.fr.html b/src/lessons/welcome/instructions/Instructions.fr.html
new file mode 100644
index 0000000..35da683
--- /dev/null
+++ b/src/lessons/welcome/instructions/Instructions.fr.html
@@ -0,0 +1,83 @@
+<h2>Instructions</h2>
+
+Félicitations ! Vous venez d'écrire votre premier programme ! Vous avez
+compris l'idée maintenant : programmer, c'est simplement donner des
+instructions à l'ordinateur, qui les applique aveuglément. La plus grande
+difficulté est d'expliquer quoi faire à quelque chose d'aussi bête que
+l'ordinateur...  
+  
+  <p>Le programme le plus simple est formé d'une suite d'ordres simples donnés à
+la machine. C'est assez comparable à une recette de cuisine où l'on dit
+<i>cassez les oeufs puis ajoutez du sel puis mélangez le tout puis faites
+cuire</i>. Dans les programmes, de tels instructions  sont appellées
+fonctions ou méthodes, et vous devez les doter de parenthèses:</p>  
+		<pre>nomDeLaMethode()</pre>
+		
+   <p>[!thelang] veut que les instructions soient séparées [!python|scala]soit
+[/!]par des points-virgules (;)[!python|scala], soit par des retours à la
+ligne[/!].
+L'exemple ci-dessus de recette s'écrirait donc à peu près comme ci-dessous.
+[!python|scala] (vous pouvez aussi ajouter des points-virgules en fin de
+lignes, mais ce n'est pas indispensable)[/!].</p>
+    
+<pre>
+casserLesOeufs()[!java];[/!]
+ajouterDuSel()[!java];[/!]
+melangerLeTout()[!java];[/!]
+faireCuire()[!java];[/!]
+</pre>
+    
+[!python|scala]
+   <p>Il serait également possible de l'écrire sous la forme suivante, mais placer
+plusieurs instructions sur la même ligne est généralement considéré comme
+une très mauvaise habitude car cela complique grandement la relecture du
+code après coup.</p>
+<pre>
+casserLesOeufs(); ajouterDuSel(); melangerLeTout(); faireCuire();
+</pre>
+[/!]
+
+  <p>Bien entendu, ces méthodes n'existent pas en
+[!java]Java[/!][!scala]Scala[/!][!python]Python[/!], mais il serait possible
+de les définir par vous même (nous verrons plus tard comment définir vos
+propres méthodes).</p>
+  
+  <p>Pour l'instant, nous allons utiliser les instructions de la buggle. Il
+y a une méthode pour chaque bouton du contrôle interactif.  Pour faire la
+même
+chose que le bouton <b>avance</b> (faire avancer la buggle d'un pas), il
+faut
+écrire dans l'éditeur : 
+  <pre>avance()[!java];[/!]</pre>
+  De même, pour faire l'équivalent des boutons <b>recule</b>, <b>gauche</b> et
+<b>droite</b>, il faut utiliser respectivement : 
+<pre>
+recule()[!java];[/!]
+gauche()[!java];[/!]
+droite()[!java];[/!]
+</pre>
+
+	 Le bouton <b>marquer</b> est un peu particulier, puisqu'il correspond à deux
+méthodes : la première lève le crayon, tandis que la seconde le baisse.
+<pre>
+leveCrayon()[!java];[/!]
+baisseCrayon()[!java];[/!]
+</pre>
+  <p>La buggle offre d'autres méthodes, présentées dans le menu "Aide/À propos de
+ce monde". Elles seront introduites au fur et à mesure des besoins.</p>
+
+
+  <h3>Objectif de cet exercice</h3><a name="Objectives"> Notre second programme sera un peu plus compliqué,
+mais pas tellement. L'objectif de votre buggle est simplement de se dessiner
+une maison (une boîte), et de se cacher dedans. Vérifiez le monde objectif
+pour voir exactement ce que cela veut dire. 
+
+<p>Quand vous changerez d'exercice, n'oubliez pas l'exercice d'application qui
+suit. Par défaut, il n'est pas visible dans la fenêtre de sélection, et il
+faut ouvrir le sous-arbre pour le voir. Lorsque vous ouvrez la fenêtre de
+sélection des exercices, la plupart d'entre eux sont cachés, comme cela:</p>
+<img src="sub-exercise-folded.png"/> 
+
+<p>Vous devez cliquer sur le petit symbole à gauche de la buggle pour déplier
+l'arbre, comme cela :</p>
+<img src="sub-exercise-unfolded.png"/> 
diff --git a/src/lessons/welcome/instructions/Instructions.html b/src/lessons/welcome/instructions/Instructions.html
new file mode 100644
index 0000000..bd85029
--- /dev/null
+++ b/src/lessons/welcome/instructions/Instructions.html
@@ -0,0 +1,75 @@
+<h2>Instructions</h2>
+
+Congratulations! You just wrote your first program! You got the idea now: 
+programming is nothing more than giving simple instructions to the computer that 
+blindly apply them. The main difficulty is to explain stuff to something as stupid 
+as a computer...  
+  
+  <p>Programs are mainly suites of method calls, which are no more than a list of
+   simple order given to the machine. It is very similar to a recipe stating
+   <i>Melt the chocolate pieces, add sugar, cool the mix and serve</i>. 
+   In your programs, such built instructions are called functions or methods, and you 
+   should add parenthesis to invoke them:</p>  
+		<pre>nameOfTheMethod()</pre>
+		
+   <p>[!thelang] wants to have the instructions separated by semi-columns 
+    (;)[!python|scala] or by new lines[/!].
+    The previous example would thus be written in the following 
+    way[!python|scala] (you can also add semi-columns at the end of the lines, but this is not mandatory)[/!].</p>
+    
+<pre>
+meltTheChocolatePieces()[!java];[/!]
+addSugar()[!java];[/!]
+coolMix()[!java];[/!]
+serve()[!java];[/!]
+</pre>
+    
+[!python|scala]
+   <p>It could also be written in the following way, but it's generally considered as a bad 
+   practice to group several instructions on the same line since it greatly hinders the 
+   readability.</p>
+<pre>
+meltTheChocolatePieces(); addSugar(); coolMix(); serve()
+</pre>
+[/!]
+
+  <p>Of course, these specific methods do not exist by default in [!java]Java[/!][!scala]Scala[/!][!python]Python[/!], 
+  but it may be possible 
+  to define them by yourself (we'll see later how to define your how methods).</p>
+  
+  <p>For now, 
+  we'll simply go for the buggle instructions. There is a method for each button of the 
+  interactive control panel. To achieve the same effect than the <b>forward</b> button 
+  (making the buggle moving one step forward), you need to write the following in the
+  editor: 
+  <pre>forward()[!java];[/!]</pre>
+  Likewise, to achieve the same effect than the <b>backward</b>, <b>left</b>
+  and <b>right</b> buttons, you need to use respectively: 
+<pre>
+backward()[!java];[/!]
+left()[!java];[/!]
+right()[!java];[/!]
+</pre>
+
+	 The <b>mark</b> button is a bit particular, since it correspond to two
+methods: the first one moves the pen up while the second moves it down.
+<pre>
+brushUp()[!java];[/!]
+brushDown()[!java];[/!]
+</pre>
+  <p>The buggle offers other methods, that are presented from the "Help/about
+   this world" menu and will be introduced on need.</p>
+
+
+  <h3>Exercise goal</h3><a name="Objectives">
+  Our second program will be a bit more complicated, but not much. The goal for 
+  your buggle is simply to draw a house (a box), and hide inside. Check the 
+  objective world to see exactly what this means. 
+
+<p>When switching to the next exercise, please note that there is a sub-exercise following this one. 
+By default, it is hidden in the menu and you have to open the sub-menu to see it. 
+When you switch the exercise, most of the exercises are hidden because the tree is folded, as follows:</p>
+<img src="sub-exercise-folded.png"/> 
+
+<p>You have to click on the little symbol to the left of the buggle to unfold the tree, as follows:</p>
+<img src="sub-exercise-unfolded.png"/> 
diff --git a/src/lessons/welcome/instructions/Instructions.java b/src/lessons/welcome/instructions/Instructions.java
new file mode 100644
index 0000000..de0a135
--- /dev/null
+++ b/src/lessons/welcome/instructions/Instructions.java
@@ -0,0 +1,22 @@
+package lessons.welcome.instructions;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Instructions extends ExerciseTemplated {
+
+	public Instructions(Lesson lesson) {
+		super(lesson);
+		tabName="Program";
+
+		BuggleWorld myWorld = new BuggleWorld("Training World", 7,7);
+		new Buggle(myWorld, "Rookie", 2, 4, Direction.NORTH, Color.black, Color.lightGray);
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/basicsdrawg/BasicsDrawG-answer0.map b/src/lessons/welcome/instructions/InstructionsDrawG-answer0.map
similarity index 100%
rename from src/lessons/welcome/basicsdrawg/BasicsDrawG-answer0.map
rename to src/lessons/welcome/instructions/InstructionsDrawG-answer0.map
diff --git a/src/lessons/welcome/instructions/InstructionsDrawG.fr.html b/src/lessons/welcome/instructions/InstructionsDrawG.fr.html
new file mode 100644
index 0000000..e36d2f7
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawG.fr.html
@@ -0,0 +1,49 @@
+<h2>Écrire des programmes plus complexes</h2>
+  Maintenant que vous savez écrire des choses sur le sol, nous allons utiliser
+cette compétence pour dessiner un merveilleux G par terre. Consultez le
+panneau d'objectif pour les détails de ce qui est attendu. 
+
+  <p>Quand vous écrivez un programme un peu complexe, il est souvent pratique
+d'ajouter des <b>commentaires</b> pour simplifier la relecture du code après
+coup. Ici par exemple, il est assez facile de se perdre dans les ordres
+nécessaires au dessin. Il peut être pratique d'ajouter des commentaires
+comme <i>fin de la barre verticale</i> ou <i>Fini de dessiner le
+G. Retournons à la position initiale</i>. Documenter votre code est presque
+toujours nécessaire si quelqu'un (vous ou quelqu'un d'autre) veut le lire
+après coup. Cependant, commenter des choses triviales est une mauvaise idée
+car cela dilue les informations dans des commentaires trop verbeux. En
+anglais, ce travers s'appelle <i>over-commenting</i>.</p>
+   
+  <p>Il y a [!java]three[/!][!python|scala]two[/!] sortes de commentaires en
+[!thelang], indiquant au
+[!java|scala]compilateur[/!][!python]interpréteur[/!] qu'il ne doit pas lire
+le texte ajouté pour les humains.</p>
+   
+  <ul>
+    <li><b>Commentaires sur une seule ligne</b>. Quand le
+[!java|scala]compilateur[/!][!python]interpréteur[/!] rencontre le symbole
+[!java|scala]//[/!][!python]#[/!], il ignore la fin de la ligne.</li>      
+    <li><b>Commentaires sur plusieurs lignes</b>. [!java|scala]Le
+compilateur[/!][!python]L'interpréteur[/!] ignore tout ce qui se trouve
+entre [!java|scala]les symboles /* et */, même s'ils sont sur des lignes
+différentes.[/!]
+[!python]une ligne commençant par ''' et la prochaine ligne terminant par
+'''.[/!]</li>
+  </ul>
+
+<pre>
+methodCallReadByThe[!java|scala]Compilateur[/!][!python]Interpreteur[/!]()[!java];[/!] <span class="comment">[!java|scala]//[/!][!python]#[/!] tout ceci est ignoré</span>
+otherCall()[!java];[/!] [!java|scala]<span class="comment">/* Ceci est</span>
+              <span class="comment"> également ignoré */</span>[/!]
+[!python]<span class="comment">''' Ceci est</span>
+<span class="comment">également ignoré '''</span>[/!]
+yetAnotherCall()[!java];[/!]
+</pre>  
+  <p class="Java">Il existe une troisième forme de commentaires en Java, entre /** et */, qui
+sont lus par un programme nommé JavaDoc pour générer automatiquement la
+documentation expliquant comment utiliser le code. Ces commentaires doivent
+suivre un formalisme précis.</p>
+
+  <p class="Python">Les commentaires sur plusieurs lignes sont souvent utilisés pour documenter
+comment utiliser le code, tandis que les autres types de commentaires sont
+souvent utilisés pour documenter comment le code fonctionne.</p>
diff --git a/src/lessons/welcome/instructions/InstructionsDrawG.html b/src/lessons/welcome/instructions/InstructionsDrawG.html
new file mode 100644
index 0000000..e6f10e7
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawG.html
@@ -0,0 +1,40 @@
+<h2>Writing more complex programs</h2>
+  Now that we know how to draw things on the board, we'll enjoy this ability and 
+  draw a beautiful G on the board (check Objective panel for details on what is 
+  expected). 
+
+  <p>When you write a quite complex program, it is sometimes useful to <b>add
+   comments</b> to simplify the code reviews afterward. Here for example, it's 
+   quite easy to get lost in the drawing process, and you may want to add 
+   comments like <i>vertical bar done</i> or <i>finished drawing the G. Time to 
+   move back to initial position</i>. Commenting your code is almost mandatory if you 
+   (or someone else) want to read it afterward, although over-commenting 
+   (describing obvious stuff) is a bad idea as the important idea get lost in the noise.</p>
+   
+  <p>There is [!java]three[/!][!python|scala]two[/!] types of comments in [!thelang], instructing 
+  the [!java|scala]compiler[/!][!python]interpreter[/!] to not read the text you add for humans:</p>
+   
+  <ul>
+    <li><b>Comments on a single line</b>. When the [!java|scala]compiler[/!][!python]interpreter[/!]
+      encounters the symbol [!java|scala]//[/!][!python]#[/!], it ignores the end of the line.</li>      
+    <li><b>Comments on several lines</b>. The [!java|scala]compiler[/!][!python]interpreter[/!]
+      ignores anything placed between 
+      [!java|scala]the symbols /* and */ even if they are placed on differing lines.[/!]
+      [!python]a line beginning with ''' and the next line ending with '''.[/!]</li>
+  </ul>
+
+<pre>
+methodCallReadByThe[!java|scala]Compiler[/!][!python]Interpreter[/!]()[!java];[/!] <span class="comment">[!java|scala]//[/!][!python]#[/!] all this is ignored</span>
+otherCall()[!java];[/!] [!java|scala]<span class="comment">/* This is</span>
+              <span class="comment"> also ignored */</span>[/!]
+[!python]<span class="comment">''' This is</span>
+<span class="comment">also ignored  '''</span>[/!]
+yetAnotherCall()[!java];[/!]
+</pre>  
+  <p class="Java">There is a third kind of comments in Java, between /** and */, which are read by a
+specific program called JavaDoc to generate automatically the documentation
+explaining how to use the code. These comments must follow a very precise
+formalism.</p>
+
+  <p class="Python">The comments on several lines are often used to document how to use the code, while others 
+  are more used to describe how this code works.</p>
diff --git a/src/lessons/welcome/instructions/InstructionsDrawG.java b/src/lessons/welcome/instructions/InstructionsDrawG.java
new file mode 100644
index 0000000..6f79bba
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawG.java
@@ -0,0 +1,22 @@
+package lessons.welcome.instructions;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class InstructionsDrawG extends ExerciseTemplated {
+
+	public InstructionsDrawG(Lesson lesson) {
+		super(lesson);
+		tabName = "Source";
+
+		BuggleWorld myWorld = new BuggleWorld("Training World", 7, 7);
+		new Buggle(myWorld, "Rookie", 5, 1, Direction.NORTH, Color.black, Color.blue);
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/instructions/InstructionsDrawGEntity.java b/src/lessons/welcome/instructions/InstructionsDrawGEntity.java
new file mode 100644
index 0000000..9a4e4ea
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawGEntity.java
@@ -0,0 +1,42 @@
+package lessons.welcome.instructions;
+
+
+public class InstructionsDrawGEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	@Override
+	public void run() {
+		/* BEGIN TEMPLATE */
+		/* BEGIN SOLUTION */
+		brushDown();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		left();
+		forward();
+		/* back home */
+		brushUp();
+		right();
+		forward(2);
+		right();
+		forward();
+		left();
+		/* END SOLUTION */
+		/* END TEMPLATE */
+	}
+
+}
diff --git a/src/lessons/welcome/instructions/InstructionsDrawGEntity.py b/src/lessons/welcome/instructions/InstructionsDrawGEntity.py
new file mode 100644
index 0000000..eb0d8e6
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawGEntity.py
@@ -0,0 +1,22 @@
+# BEGIN SOLUTION
+brushDown()
+left()
+forward(4)
+left()
+forward(4)
+left()
+forward(4)
+left()
+forward()
+forward()
+left()
+forward()
+# back home 
+brushUp()
+right()
+forward(2)
+right()
+forward()
+left()
+# END SOLUTION
+
diff --git a/src/lessons/welcome/instructions/InstructionsDrawGEntity.scala b/src/lessons/welcome/instructions/InstructionsDrawGEntity.scala
new file mode 100644
index 0000000..88685bd
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsDrawGEntity.scala
@@ -0,0 +1,38 @@
+package lessons.welcome.instructions;
+
+
+class ScalaInstructionsDrawGEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	protected def run() {
+		/* BEGIN SOLUTION */
+		brushDown();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		forward();
+		forward();
+		left();
+		forward();
+		forward();
+		left();
+		forward();
+		/* back home */
+		brushUp();
+		right();
+		forward(2);
+		right();
+		forward();
+		left();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/instructions/InstructionsEntity.java b/src/lessons/welcome/instructions/InstructionsEntity.java
new file mode 100644
index 0000000..4c2fd31
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsEntity.java
@@ -0,0 +1,25 @@
+package lessons.welcome.instructions;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class InstructionsEntity extends SimpleBuggle {
+
+	@Override
+	public void run() {
+		/* BEGIN TEMPLATE */
+		/* BEGIN SOLUTION */
+		brushDown();
+		for (int i=0;i<4;i++) {
+			forward(2);
+			right();
+		}
+		brushUp();
+		forward();
+		right();
+		forward();
+		left();
+		/* END SOLUTION */
+		/* END TEMPLATE */
+	}
+
+}
diff --git a/src/lessons/welcome/instructions/InstructionsEntity.js b/src/lessons/welcome/instructions/InstructionsEntity.js
new file mode 100644
index 0000000..86bb664
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsEntity.js
@@ -0,0 +1,19 @@
+# BEGIN TEMPLATE 
+function side(){
+    forward()
+    forward()
+    right()
+}
+
+brushDown()
+
+for (var i=0;i<3;i++) 
+    side()
+                
+forward()
+right()
+
+brushUp()
+forward()
+# END TEMPLATE
+
diff --git a/src/lessons/welcome/instructions/InstructionsEntity.py b/src/lessons/welcome/instructions/InstructionsEntity.py
new file mode 100644
index 0000000..4607fb4
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsEntity.py
@@ -0,0 +1,16 @@
+# BEGIN SOLUTION
+
+brushDown()
+
+for i in range(4):
+    forward()
+    forward()
+    right()
+                
+brushUp()
+forward()
+right()
+forward()
+left()
+# END SOLUTION
+
diff --git a/src/lessons/welcome/instructions/InstructionsEntity.scala b/src/lessons/welcome/instructions/InstructionsEntity.scala
new file mode 100644
index 0000000..406eef7
--- /dev/null
+++ b/src/lessons/welcome/instructions/InstructionsEntity.scala
@@ -0,0 +1,24 @@
+package lessons.welcome.basics;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaInstructionsEntity extends SimpleBuggle {
+
+	protected def run() {
+		/* BEGIN TEMPLATE */
+		/* BEGIN SOLUTION */
+		brushDown();
+		for (i <- 0 to 3) {
+			forward(2);
+			right();
+		}
+		brushUp();
+		forward();
+		right();
+		forward();
+		left();
+		/* END SOLUTION */
+		/* END TEMPLATE */
+	}
+
+}
diff --git a/src/lessons/welcome/instructions/sub-exercise-folded.png b/src/lessons/welcome/instructions/sub-exercise-folded.png
new file mode 100644
index 0000000..9ea575f
Binary files /dev/null and b/src/lessons/welcome/instructions/sub-exercise-folded.png differ
diff --git a/src/lessons/welcome/instructions/sub-exercise-unfolded.png b/src/lessons/welcome/instructions/sub-exercise-unfolded.png
new file mode 100644
index 0000000..ac49182
Binary files /dev/null and b/src/lessons/welcome/instructions/sub-exercise-unfolded.png differ
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.fr.html b/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.fr.html
deleted file mode 100644
index abab930..0000000
--- a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.fr.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<h2>Boucles jusqu'à<tt> (do ... while)</tt></h2>
-
-<p class="Python">Il y a ici un autre petit exercice sur les boucles. Il est légèrement plus
-complexe comme nous voulons que l'action soit exécutée dans tous les cas,
-même si la condition est directement fausse. Certains langages ont des
-constructions spécifiques pour cela, mais pas le langage Python. Mais il n'y
-a pas de problème, je suis sûr que vous pouvez faire sans, n'est-ce pas ?</p>
-
-<p class="Python">Une mauvaise solution serait de dupliquer le contenu de la boucle avant la
-boucle à proprement parlé, mais c'est une <b>très mauvaise</b> habitude de
-dupliquer du code, et il faut toujours éviter. Une meilleure solution est
-d'avoir une variable dédiée qui indique si c'est la première fois que l'on
-rentre dans la boucle :</p>
-<pre class="Python">premiereFois = True
-while premiereFois or (les autres conditions):
-  premiereFois = False
-  (le corps de la boucle)</pre>
-
-<p class="Java">Dans une boucle <tt>while</tt>, la condition est évaluée avant toute chose,
-et si elle est fausse, le corps de la boucle n'est jamais exécuté. Il arrive
-parfois que l'on veuille que le corps de la boucle soit évalué au moins une
-fois, même si la condition est initialement fausse. On utilise pour cela une
-variante de la boucle <tt>while</tt>, dont la syntaxe Java est la suivante :
-<pre class="Java">do {
-  <b>action()</b>;
-} while (<b>condition</b>);</pre></p>
-
-<h3>Objectif de cet exercice</h3>
-<p>Certaines cases du monde sont jaunes, mais les buggles ne supportent pas de
-s'y trouver. Écrivez le code nécessaire pour avancer jusqu'à ce que le sol
-devienne blanc. Vous pourrez utiliser la méthode
-<code>isGroundWhite()</code> qui retourne vrai si le sol est blanc..</p>
-
-<p>Le truc est que la plupart des buggles de ce monde se trouvent actuellement
-sur ce sol jaune qui les énerve tant. Cela explique sans doute leur état de
-panique, et le fait que toutes les buggles se ruent vers l'avant au début,
-même la buggle qui ne se trouve pas sur du jaune. En d'autres mots, même si
-le sol est blanc le premier coup, il faut quand même avancer d'un pas.</p>    
-
-<p>L'idée général est donc de faire: 
-<pre>avancer jusqu'à se trouver sur une case blanche</pre>
-
-<p class="Java"><i>Remarque :</i> il est également possible de résoudre cet exercice avec
-une boucle <tt>while</tt> classique, mais ce n'est pas l'objectif.</p>
-
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html b/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html
deleted file mode 100644
index a176f7d..0000000
--- a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<h2>Do .. while loops</h2>
-
-<p class="Python">Here is another little exercise about loops. It is slightly more complex as we want the action 
-to be executed in any case, even if the condition is false right away. Some languages have specific 
-constructs for that, but not the Python language. No problem, I'm sure you can do it without them, can't you?</p>
-
-<p class="Python">A bad solution would be to duplicate the loop content before the loop, but code duplication 
-is a <b>very</b> bad habit, and you should always avoid it. A better solution is to have a dedicated variable 
-indicating whether we are taking the loop for the first time, as follows:</p>
-<pre class="Python">firstTime = True
-while firstTime or (other conditions):
-  firstTime = False
-  (loop body)
-</pre>
-
-<p class="Java">In a <tt>while</tt> loop, the condition is evaluated before anything else,
-and if it's false, the loop body is never evaluated. Sometimes (although not 
-that often), you would prefer the
-loop body to get evaluated at least once, even if the condition is initially
-false. For that, a variation of the <tt>while</tt> loop gets used, using the
-following syntax in Java:
-<pre class="Java">do {
-  <b>action()</b>;
-} while (<b>condition</b>);</pre></p>
-
-<h3>Exercise goal</h3>
-<p>Some cells of the world are yellow, but your buggle cannot stand being in 
-such cells. Write the necessary code to move forward until the ground 
-gets white. For that, use the provided method <code>isGroundWhite()</code>.</p>
-
-<p>The trick is that most buggles of this world are currently on this yellow ground 
-that they dislike so much. That is why they are in panic, and every buggle rushes 
-one cell forward, even the buggle that was not on a yellow cell at first. In other worlds,  
-even if the ground is white on the first cell, you still want to move forward to the next cell.</p>    
-
-<p>The general idea is to do something like: 
-<pre>move forward until located in a white cell</pre>
-
-<p class="Java"><i>Remark:</i> it is also possible to solve this exercise with a classical
-<tt>while</tt> loop, but it's not the goal.</p>
-
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.java b/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.java
deleted file mode 100644
index 0909789..0000000
--- a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package lessons.welcome.loop.dowhileloop;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class LoopDoWhile extends ExerciseTemplated {
-
-	public LoopDoWhile(Lesson lesson) {
-		super(lesson);
-		tabName = "Program";
-				
-		BuggleWorld myWorld = new BuggleWorld("Yellow Submarine",13,7);
-		for (int i=0;i<7;i++) {
-			new Buggle(myWorld, "Beatles"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
-		    for (int j=6; j>i; j--)
-		    	myWorld.setColor(i, j,Color.yellow);
-		}
-		for (int i=7;i<13;i++) {
-			new Buggle(myWorld, "Beatles"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
-		    for (int j=0; j<i-6; j++)
-		    	myWorld.setColor(i, 6-j,Color.yellow);
-		}
-
-    	setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.java b/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.java
deleted file mode 100644
index 0fae847..0000000
--- a/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package lessons.welcome.loop.dowhileloop;
-
-import java.awt.Color;
-
-public class LoopDoWhileEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	boolean isGroundWhite() { 
-		return getGroundColor().equals(Color.white)?true:false;
-	}
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		do {
-			forward();
-		} while (!isGroundWhite());
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.py b/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.py
deleted file mode 100644
index eb92e71..0000000
--- a/src/lessons/welcome/loop/dowhileloop/LoopDoWhileEntity.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import java.awt.Color
-def isGroundWhite():
-  return getGroundColor().equals(java.awt.Color.white)
-
-# BEGIN SOLUTION
-more = True
-while more:
-  forward()
-  if isGroundWhite():
-  	more = False 
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet.fr.html b/src/lessons/welcome/loop/dowhileloop/Poucet.fr.html
deleted file mode 100644
index e6e7471..0000000
--- a/src/lessons/welcome/loop/dowhileloop/Poucet.fr.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<h2>La buggle Petite Poucette</h2>
-
-<p>Votre buggle est perdue dans un étrange labyrinthe, et elle a besoin de vous
-pour trouver la sortie (représentée par les cases orange). Vous ne pouvez
-pas lui donner son chemin tout simplement avec quelque chose comme
-<code>turnRight();forward();forward();</code> parce qu'il faut secourir deux
-buggles à la fois, perdues dans des labyrinthes similaires mais
-différents. Vous pouvez passer à l'autre monde en cliquant sur le menu
-défilant au dessus de l'endroit où est dessiné le monde. C'est là où est
-écrit "Deep Forest" pour l'instant (forêt profonde), et si vous passez à
-"Deeper Forest" (forêt encore plus profonde), vous verrez l'autre monde. </p>
-
-<p>La bonne nouvelle est que le chemin vers la sortie est en quelque sorte
-écrit au sol. Ces mondes sont composés de plusieurs corridors, avec des
-baggles par terre. À chaque embranchement, il faut prendre à gauche si le
-corridor qu'on vient de parcourir contient 3 baggles ou plus, ou à droite
-s'il contient 2 baggles ou moins.</p>     
-
-<p>La forme générale de votre code doit donc être quelque chose comme «tant que
-je n'ai pas trouvé la sortie, prendre le prochain couloir pour décider s'il
-faut tourner à gauche ou à droite au prochain embranchement». Vous pouvez
-déterminer si vous avez rejoint la sortie (indiquée en orange) avec la
-méthode <code>exitReached()</code> fournie.</p>
-
-<p>Pour prendre un couloir, il suffit de courir d'une intersection à l'autre
-tout en comptant les baggles en chemin. La méthode <code>crossing()</code>
-indique si vous vous trouvez actuellement à un embranchement. Ce qui
-complique un peu, c'est qu'au début du couloir, vous vous trouvez bien
-entendu à une intersection, mais vous souhaitez avancer quand même.</p> 
-
-<p class="Java">Pour cela, le plus simple est d'utiliser une boucle <code>do / while</code>
-au lieu d'une boucle <code>while</code> pour se déplacer d'une intersection
-à l'autre.</p>
-
-<p class="Python">Pour cela, utilisez une variable supplémentaire indiquant si vous êtes déjà
-entré dans le couloir, comme dans l'exemple suivant. Ainsi, vous exécuterez
-le corps de la boucle au moins une fois (quand <code>premiereFois</code> est
-vrai) tandis qu'aux tours de boucles suivants, c'est la valeur de retour de
-<code>crossing()</code> qui détermine s'il faut s'arrêter ou non.</p>
-<pre class="Python">premiereFois = True
-while premiereFois or not crossing():
-  premiereFois = False
-  <your body>  
-</pre> 
-
-<p><div class="tip" id="tip-1" alt="Je n'arrive pas à imaginer comment compter les baggles que je vois">
-Il vous faut une variable initialisée à zéro et incrémentée à chaque fois
-que vous voyez un baggle. Une variable utilisée ainsi est souvent appelée un
-<i>accumulateur</i>.<br/><br/>
-N'oubliez pas de remettre l'accumulateur à 0 au début de chaque couloir! 
-</div></p>
-
-<p>Oh, et quand vous parviendrez à trouver la sortie, n'oubliez pas de faire un
-pas de plus pour vous échapper effectivement.</p> 
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet.html b/src/lessons/welcome/loop/dowhileloop/Poucet.html
deleted file mode 100644
index 2c1e051..0000000
--- a/src/lessons/welcome/loop/dowhileloop/Poucet.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<h2>Tracks of buggles</h2>
-
-<p>Your buggle got lost in a strange maze, and you must help it finding the exit that is represented in orange.
-You cannot simply explain the path to the exit in something like <code>turnRight();forward;forward();forward()</code> 
-because you have to save two buggles at the same time, that are lost in similar but not identical worlds. 
-You can switch to the other world by using the combobox above the world representation (where it's written 
-'Deep Forest' right now), and selecting the other entry (that should read 'Deeper Forest').</p>
-
-<p>The good news is that the path to the exit is written on the ground. As you can see, the world is made 
-of several corridors, with baggles on the ground. After each corridor, you should turn left if the corridor contains
-three baggels or more, and you have to turn right if there is only 2 baggles or less.</p>     
-
-<p>So, the general form of your code must be something like "while I did not find the exit, take the next corridor 
-to decide whether I should turn left or right at the next intersection". You can determine whether you are on the 
-exit cell (that is orange) with the provided <code>exitReached()</code> method.</p>
-
-<p>To take one corridor, you simply have to run from one intersection to another while counting the baggles you see 
-on your path. The method <code>crossing()</code> tells you whether your buggle currently stands on an intersection. 
-The extra complexity is that at the beginning of a corridor, you obviously stand on an intersection, but you still 
-want to move on.</p> 
-
-<p class="Java">For that, the easiest is to use a <code>do / while</code> loop instead of a regular
-<code>while</code> loop to move until the next intersection.</p>
-
-<p class="Python">For that, use an extra variable indicating whether you already entered the corridor, 
-as follows. This will ensure that you execute the loop body at least once (when <code>firstTime</code> is true) 
-before we actually use the value returned by <code>crossing()</code> to determine to continue or not.</p>
-<pre class="Python">firstTime = True
-while firstTime or not crossing():
-  firstTime = False
-  <your body>  
-</pre> 
-
-<p><div class="tip" id="tip-1" alt="I cannot imagine how to count the baggles I see.">
-You need a variable that is initialized to 0, and incremented each time you see a 
-baggle on the ground. A variable used this way is often called <i>accumulator</i>.<br/><br/>
-Don't forget to reset your accumulator to 0 at the beginning of each corridor! 
-</div></p>
-
-<p>Oh, and when you reach the exit, don't forget to take an extra step to actually exit the maze!</p> 
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet.java b/src/lessons/welcome/loop/dowhileloop/Poucet.java
deleted file mode 100644
index 37775e6..0000000
--- a/src/lessons/welcome/loop/dowhileloop/Poucet.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package lessons.welcome.loop.dowhileloop;
-
-import java.io.IOException;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class Poucet extends ExerciseTemplated {
-
-	public Poucet(Lesson lesson) throws IOException, BrokenWorldFileException {
-		super(lesson);
-		tabName = "Poucet";
-		
-		/* Create initial situation */
-		World[] myWorlds = new World[] {
-				BuggleWorld.newFromFile("lessons/welcome/loop/dowhileloop/Poucet"),
-				BuggleWorld.newFromFile("lessons/welcome/loop/dowhileloop/Poucet2"),
-		};
-		for (World w: myWorlds)
-			w.setDelay(50); // moving a bit faster than usual
-		
-		setup(myWorlds);
-	}
-}
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/dowhileloop/PoucetEntity.java b/src/lessons/welcome/loop/dowhileloop/PoucetEntity.java
deleted file mode 100644
index 5316fe5..0000000
--- a/src/lessons/welcome/loop/dowhileloop/PoucetEntity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package lessons.welcome.loop.dowhileloop;
-
-import java.awt.Color;
-
-public class PoucetEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-
-	public boolean crossing() {
-		return getX()%5== 1 && getY()%5==1;
-	}
-	public boolean exitReached() {
-		return getGroundColor().equals(Color.orange);
-	}
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		while (!exitReached()) {
-			int seen = 0;
-			
-			do {
-				forward();
-				if (isOverBaggle())
-					seen++;
-			} while (! crossing());
-			
-			if (seen>2)
-				turnLeft();
-			else
-				turnRight();
-		}
-		forward();
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/dowhileloop/PoucetEntity.py b/src/lessons/welcome/loop/dowhileloop/PoucetEntity.py
deleted file mode 100644
index 8a65286..0000000
--- a/src/lessons/welcome/loop/dowhileloop/PoucetEntity.py
+++ /dev/null
@@ -1,34 +0,0 @@
-def forward(i=-1):
-    if i==-1:
-      entity.forward()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use forward with argument")
-def backward(i=-1):
-    if i==-1:
-      entity.backward()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use backward with argument")
-
-def crossing():
-    return (entity.getX() % 5 == 1) and ( entity.getY()%5==1 )
-    
-def exitReached():
-    return getGroundColor().equals(Color.orange)
-
-# BEGIN SOLUTION
-while not exitReached() :
-    seen = 0
-    within = False
-    
-    while not within or not crossing():
-        within = True
-        forward()
-        if isOverBaggle():
-            seen += 1
-    
-    if seen > 2:
-        turnLeft()
-    else:
-        turnRight()
-forward()
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/forloop/LoopCourse.html b/src/lessons/welcome/loop/forloop/LoopCourse.html
deleted file mode 100644
index 01f92a9..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourse.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h2>Training Buggle</h2>
-
-<p>Today, your buggle wants to get some serious exercise: It wants to run 'till the track burns!
-Its super-shoes are just perfect to run like hell, but unfortunately, they can actually damage the track on the long run...</p>
-
-<p>Your goal is to run the track 10 times, no matter what happens. 
-Even if the track suffers, you <b>really HAVE</b> to take that run.
-Remember, the track has four sides, that take eight steps each to run along.
-Now go, and show them what these super shoes can do.</p>
- 
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/forloop/LoopCourse.java b/src/lessons/welcome/loop/forloop/LoopCourse.java
deleted file mode 100644
index eb89c79..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourse.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.io.IOException;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class LoopCourse extends ExerciseTemplated{
-	
-		public LoopCourse(Lesson lesson) throws IOException, BrokenWorldFileException {
-			super(lesson);
-			tabName = "Runner";
-					
-			/* Create initial situation */
-			World[] myWorlds = new World[] {
-					BuggleWorld.newFromFile("lessons/welcome/loop/forloop/LoopCourse")
-			};
-			for (World w: myWorlds)
-				w.setDelay(10); // runners are moving faster than usual
-			
-			setup(myWorlds);
-		}
-
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseEntity.java b/src/lessons/welcome/loop/forloop/LoopCourseEntity.java
deleted file mode 100644
index 3bd3e48..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourseEntity.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.awt.Color;
-
-public class LoopCourseEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	Color[] colors = new Color[] {
-			Color.white,
-			new Color(255,240,240),new Color(255,220,220),new Color(255,205,205),
-			new Color(255,190,190),new Color(255,170,170),new Color(255,150,150),
-			new Color(255,130,130),new Color(255,110,110),new Color(255,45,45),
-			new Color(255,5,5)};
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-	@Override
-	public void forward()  {
-		super.forward();
-		Color c = getGroundColor();
-		for (int i=0;i<colors.length-1;i++)
-			if (colors[i].equals(c)) {
-				c = colors[i+1];
-				break;
-			}
-		setBrushColor(c);
-		brushDown();
-		brushUp();
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-	
-
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		for (int i = 0; i<10;i++) 
-			for (int side=0;side<4;side++){
-				for (int step=0;step<8;step++)
-					forward();
-				turnLeft();
-			}
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseEntity.py b/src/lessons/welcome/loop/forloop/LoopCourseEntity.py
deleted file mode 100644
index b3e8624..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourseEntity.py
+++ /dev/null
@@ -1,30 +0,0 @@
-colors = [Color.white, Color(255,240,240), Color(255,220,220), Color(255,205,205),
-             Color(255,190,190), Color(255,170,170), Color(255,150,150),
-             Color(255,130,130), Color(255,110,110), Color(255,45,45),
-             Color(255,5,5)]
-
-def forward(i=-1):
-    if i==-1:
-      entity.forward()
-      c = getGroundColor()
-      for i in range(len(colors)-1):
-          if colors[i] == c:
-              c = colors[i+1]
-              break
-      setBrushColor(c)    
-      brushDown()
-      brushUp()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use forward with argument")
-def backward(i=-1):
-    if i==-1:
-      entity.backward()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use backward with argument")
-# BEGIN SOLUTION
-for i in range(10):
-    for side in range(4):
-        for step in range(8):
-            forward()
-        turnLeft()
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForest.java b/src/lessons/welcome/loop/forloop/LoopCourseForest.java
deleted file mode 100644
index 3c9a2df..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourseForest.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.io.IOException;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class LoopCourseForest extends ExerciseTemplated{
-	
-		public LoopCourseForest(Lesson lesson) throws IOException, BrokenWorldFileException {
-			super(lesson);
-			tabName = "Runner";
-					
-			/* Create initial situation */
-			World[] myWorlds = new World[] {
-					BuggleWorld.newFromFile("lessons/welcome/loop/forloop/LoopCourseForest")
-			};
-			for (World w: myWorlds)
-				w.setDelay(10); // runners are moving faster than usual
-			
-			setup(myWorlds);
-		}
-
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.java b/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.java
deleted file mode 100644
index 4ccb93b..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.awt.Color;
-
-public class LoopCourseForestEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	Color[] colors = new Color[] {
-			new Color(0,155,0),
-			new Color(50,155,0),
-			new Color(100,155,0),
-			new Color(140,155,0),
-			new Color(160,155,0),
-			new Color(180,155,0),
-			new Color(200,155,0),
-			new Color(210,155,0),
-	};
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-	@Override
-	public void forward()  {
-		if (!haveSeenError())
-			super.forward();
-		Color c = getGroundColor();
-		if (c.equals(Color.blue)) {
-			if (!haveSeenError())
-				javax.swing.JOptionPane.showMessageDialog(null, "You fall into water.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE);
-			seenError();
-		}
-		for (int i=0;i<colors.length-1;i++)
-			if (colors[i].equals(c)) {
-				c = colors[i+1];
-				break;
-			}
-		setBrushColor(c);
-		brushDown();
-		brushUp();
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-	
-
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		for (int i = 0; i<7;i++) 
-			for (int side=0;side<4;side++){
-				for (int step=0;step<4;step++)
-					forward();
-				turnLeft();
-				for (int step=0;step<2;step++)
-					forward();
-				turnRight();
-				for (int step=0;step<4;step++)
-					forward();
-				turnRight();
-				forward();
-				forward();
-				turnLeft();
-				for (int step=0;step<4;step++)
-					forward();
-				turnLeft();
-			}
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.py b/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.py
deleted file mode 100644
index 1abb4c8..0000000
--- a/src/lessons/welcome/loop/forloop/LoopCourseForestEntity.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import javax.swing.JOptionPane;
-
-colors = [Color(0,155,0), Color(50,155,0), Color(100,155,0), Color(140,155,0),
-          Color(160,155,0), Color(180,155,0), Color(200,155,0), Color(210,155,0)]
-
-def forward(i=-1):
-    if i==-1:
-      entity.forward()
-      c = getGroundColor()
-      
-      if c.equals( Color.blue ):
-          if not entity.haveSeenError():
-              javax.swing.JOptionPane.showMessageDialog(None, "You fall into water.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE)
-          entity.seenError()
-
-      for i in range(len(colors)-1):
-          if colors[i].equals(c):
-              c = colors[i+1]
-              break
-      setBrushColor(c)    
-      brushDown()
-      brushUp()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use forward with argument")
-def backward(i=-1):
-    if i==-1:
-      entity.backward()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use backward with argument")
-# BEGIN SOLUTION
-for i in range(7):
-    for side in range(4):
-        for step in range(4):
-            forward()
-        turnLeft();
-        for step in range(2):
-            forward()
-        turnRight();
-        for step in range(4):
-            forward()
-        turnRight()
-        forward()
-        forward()
-        turnLeft()
-        for step in range(4):
-            forward()
-        turnLeft()
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/forloop/LoopFor.fr.html b/src/lessons/welcome/loop/forloop/LoopFor.fr.html
deleted file mode 100644
index ca21fdc..0000000
--- a/src/lessons/welcome/loop/forloop/LoopFor.fr.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<h2>Boucles pour <tt>(for)</tt></h2>
-
-<p>Les boucles <tt>while</tt> sont bien adaptées aux situations où l'on veut
-réaliser une action tant qu'une condition est réalisée, mais elles sont
-moins pratiques pour réaliser une action un nombre prédéterminé de fois. Par
-exemple, lorsque nous voulions reculer de <code>nbPas</code> dans l'exercice
-précédent, il fallait créer une nouvelle variable, l'initialiser, et
-demander à reculer tant que la nouvelle variable n'était pas égale à
-<code>nbPas</code>, en incrémentant cette variable à la main à la fin du
-corps de la boucle.</p> 
-
-<p>Dans ce genre de cas, les boucles de type <code>for</code> sont plus
-pratique. Leur syntaxe est la suivante : 
-<pre class="Java">for (<b>initialisation</b>; <b>condition</b>; <b>incrémentation</b>) {
-   <b>action</b>();
-}</pre>
-
-<pre class="Python">for <b>variable</b> in <b>séquence de valeurs</b>:
-   <b>action</b>()
-</pre>
-
-Ce code est parfaitement équivalent à celui-ci :
-<pre class="Java"><b>initialisation</b>;
-while (<b>condition</b>) {
-   <b>action</b>();
-   <b>incrémentation</b>;
-}</pre>
-<pre class="Python">
-while <b> il y a une valeur dans la séquence </b>: 
-   <b>mettre la variable à la prochaine valeur non traitée de la séquence</b>
-   <b>action</b>()
-</pre>
-
-<p class="Python">Veuillez noter qu'en Python, l'instruction <code>range(n)</code> permet
-d'obtenir une séquence de n entiers allant de 0 à n-1.</p>
-
-
-<p>Par exemple, les deux codes suivants sont équivalents. Avouez que la seconde
-forme est plus lisible, non ?
-
-<pre class="Java">int dejaFait = 0;
-while (dejaFait < nbPas) {
-   backward();
-   dejaFait++;
-}</pre>
-<pre class="Java">for (int dejaFait = 0; dejaFait < nbPas; dejaFait++) {
-   backward();
-}</pre>
-
-<pre class="Python">dejaFait = 0
-while dejaFait < nbPas:
-   backward()
-   dejaFait = dejaFait + 1
-</pre>
-<pre class="Python">for done in range(nbPas):
-   backward()
-</pre>
-
-
-
-<p class="Java">On peut imaginer des utilisations bien plus avancées des boucles
-<tt>for</tt> car toute instruction valide peut être utilisée comme
-initialisation, condition et incrémentation. L'exemple suivant est un peu
-extrême, puisqu'elle calcule le PGCD de deux nombres sans avoir ni de corps
-de boucle, ni d'initialisation (tout est fait dans la condition et
-l'incrémentation).
-
-<pre class="Java">int x=20, y=3, tmp;
-for (; y!=0 ; tmp=x, x=y, y=tmp%y) { }
- <span class="comment">/* le PGCD est stocké dans x */</span></pre>
-
-<p class="Java">Si vous ne comprenez pas tous les détails de cet exemple, pas de panique,
-c'est assez logique puisqu'il utilise des points de syntaxe que nous n'avons
-pas encore vu.</p>
-
-
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> Il s'agit de refaire le même exercice que précédemment
-(avancer jusqu'à trouver un baggle, le ramasser, revenir là où on était au
-début puis reposer le baggle), mais en utilisant une boucle <tt>for</tt>
-pour revenir au point de départ à la place d'une boucle <tt>while</tt>.
-
-<p>Une fois ceci fait, passez à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/loop/forloop/LoopFor.html b/src/lessons/welcome/loop/forloop/LoopFor.html
deleted file mode 100644
index c624a96..0000000
--- a/src/lessons/welcome/loop/forloop/LoopFor.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<h2>For loops</h2>
-
-<p>While loops are well adapted to situations where you want to achieve an
-action while a condition stays true, but it is less adapted to achieve a
-given action a predetermined amount of time. For example, when we wanted to
-move <code>stepAmount</code> steps backward in previous exercise, you had to
-create a new variable, initialize it, and move backward until the new
-variable became equal to <code>stepAmount</code>, incrementing the new
-variable manually at the end of the loop.</p> 
-
-<p>In such situations, <code>for</code> loops become handy. Their syntax is the
-following: 
-<pre class="Java">for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {
-   <b>action</b>();
-}</pre>
-
-<pre class="Python">for <b>variable</b> in <b>sequence of values</b>:
-   <b>action</b>()
-</pre>
-
-This code is perfectly equivalent to the following:
-<pre class="Java"><b>initializing</b>;
-while (<b>condition</b>) {
-   <b>action</b>();
-   <b>incrementing</b>;
-}</pre>
-<pre class="Python">
-while <b>there is a value in the sequence</b>: 
-   <b>set variable to the next unseen value of the sequence</b>
-   <b>action</b>()
-</pre>
-
-<p class="Python">Please note that in Python the instruction <code>range(n)</code> allows to get a sequence n integer value from 0 to n-1.</p>
-
-
-<p>For example, both following codes are equivalent. The latter is easier to
-read, don't you think?
-
-<pre class="Java">int done = 0;
-while (done < stepAmount) {
-   backward();
-   done++;
-}</pre>
-<pre class="Java">for (int done = 0; done < stepAmount; done++) {
-   backward();
-}</pre>
-
-<pre class="Python">done = 0
-while done < stepAmount:
-   backward()
-   done = done + 1
-</pre>
-<pre class="Python">for done in range(stepAmount):
-   backward()
-</pre>
-
-
-
-<p class="Java">It is possible to build more advanced <tt>for</tt> loops since any valid
-instruction can be used as initialization, condition and incrementation. The
-following example is a bit extreme since it compute the gcd (greatest common
-divisor) of two numbers without loop body and initialization (everything is
-in the condition and incrementation).
-
-<pre class="Java">int x=20, y=3, tmp;
-for (; y!=0 ; tmp=x, x=y, y=tmp%y) { }
- <span class="comment">/* the gcd is stored in x */</span></pre>
-
-<p class="Java">If you don't understand every details of this example, don't panic. That's
-quite logic since it uses some syntax details that we did not introduce yet.</p>
-
-
-<h3>Exercise goal</h3><a name="Objectives"> You now have to redo the same exercise than previously
-(move forward until being over a baggle, pick it up, move back to your
-original location, drop the baggle), but using a <tt>for</tt> loop instead
-of a <tt>while</tt> loop to move back to the initial location.
-
-<p>Once done, proceed to next exercise.</p>
diff --git a/src/lessons/welcome/loop/forloop/LoopFor.java b/src/lessons/welcome/loop/forloop/LoopFor.java
deleted file mode 100644
index 555e379..0000000
--- a/src/lessons/welcome/loop/forloop/LoopFor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-public class LoopFor extends ExerciseTemplated {
-
-	public LoopFor(Lesson lesson) {
-		super(lesson);
-		tabName = "Program";
-		
-		BuggleWorld myWorld = new BuggleWorld("Kitchen",7,7);
-		for (int i=0;i<7;i++) {
-			new Buggle(myWorld, "Hungry"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
-		    
-		    try {
-				myWorld.newBaggle(i, 6-i);
-			} catch (AlreadyHaveBaggleException e) {
-				e.printStackTrace();
-			}
-		}
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopForEntity.java b/src/lessons/welcome/loop/forloop/LoopForEntity.java
deleted file mode 100644
index d18d6c2..0000000
--- a/src/lessons/welcome/loop/forloop/LoopForEntity.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-public class LoopForEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		int cpt = 0;
-		while (!isOverBaggle()) {
-			cpt++;
-			forward();
-		}
-		pickupBaggle();
-		for (int cpt2=0 ; cpt2<cpt ; cpt2++) {
-			backward();
-		}
-		dropBaggle();
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopStairs.html b/src/lessons/welcome/loop/forloop/LoopStairs.html
deleted file mode 100644
index 0690190..0000000
--- a/src/lessons/welcome/loop/forloop/LoopStairs.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<h2>Stairway to Heaven</h2>
-
-<p>Your buggle feels a bit depressed today, but it's currently facing a magic stair: 
-It leads directly to heaven, and each time you walk on it, joyful colors spur all around.</p>
-
-<p>Your goal is to take this stair, one step after the other. 
-First devise the four instructions you have to give you buggle to take one stair step, 
-and then put them in a loop to take the whole stair.</p>
-
-<p>And before that, walk a bit forward to reach that stair, and ensure that you are in 
-the right situation for your loop content to run properly. And once you reach the heaven, 
-take some steps in your new home.</p>
- 
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/forloop/LoopStairs.java b/src/lessons/welcome/loop/forloop/LoopStairs.java
deleted file mode 100644
index 6a540bd..0000000
--- a/src/lessons/welcome/loop/forloop/LoopStairs.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.io.IOException;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class LoopStairs extends ExerciseTemplated{
-	
-		public LoopStairs(Lesson lesson) throws IOException, BrokenWorldFileException {
-			super(lesson);
-			tabName = "Runner";
-					
-			/* Create initial situation */
-			World[] myWorlds = new World[] {
-					BuggleWorld.newFromFile("lessons/welcome/loop/forloop/LoopStairs")
-			};
-			
-			setup(myWorlds);
-		}
-
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopStairsEntity.java b/src/lessons/welcome/loop/forloop/LoopStairsEntity.java
deleted file mode 100644
index 587c96b..0000000
--- a/src/lessons/welcome/loop/forloop/LoopStairsEntity.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package lessons.welcome.loop.forloop;
-
-import java.awt.Color;
-
-public class LoopStairsEntity extends jlm.universe.bugglequest.SimpleBuggle {
-	Color[] colors = new Color[] {
-			Color.blue,    Color.cyan, Color.green,  Color.yellow,
-			Color.orange,  Color.red,  Color.magenta,Color.pink,};
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-	
-	int step = -3;
-	@Override
-	public void forward()  {
-		super.forward();
-		if (step<0 || step%2 == 1 || (step/2)>=colors.length) {
-			if (step < 0)
-				setBrushColor(Color.lightGray);
-			else if ((step/2)>=colors.length)
-				setBrushColor(Color.pink);
-			else
-				setBrushColor(colors[(step/2)%colors.length]);
-			brushDown();
-			brushUp();
-		}
-		step++;
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-	
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		forward();
-		forward();
-		forward();
-		turnLeft();
-		for (int i = 0; i<8;i++) { 
-			forward();
-			turnRight();
-			forward();
-			turnLeft();
-		}
-		turnRight();
-		forward();
-		forward();
-		forward();
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/forloop/LoopStairsEntity.py b/src/lessons/welcome/loop/forloop/LoopStairsEntity.py
deleted file mode 100644
index a94f033..0000000
--- a/src/lessons/welcome/loop/forloop/LoopStairsEntity.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import javax.swing.JOptionPane;
-
-colors = [Color.blue,    Color.cyan, Color.green,  Color.yellow,
-          Color.orange,  Color.red,  Color.magenta,Color.pink]
-
-step = -3
-def forward(i=-1):
-    global step
-    if i==-1:
-      entity.forward()
-      if step<0 or step%2 == 1 or (step/2)>=len(colors):
-          if step < 0:
-              setBrushColor(Color.lightGray)
-          elif (step/2)>=len(colors):
-              setBrushColor(Color.pink)
-          else:
-              setBrushColor(colors[(step/2)%len(colors)])
-          brushDown()
-          brushUp()
-      step += 1
-    else:
-      errorMsg("Sorry Dave, I cannot let you use forward with argument")
-def backward(i=-1):
-    if i==-1:
-      entity.backward()
-    else:
-      errorMsg("Sorry Dave, I cannot let you use backward with argument")
-      
-# BEGIN SOLUTION
-forward()
-forward()
-forward()
-turnLeft()
-for i in range(8): 
-    forward()   
-    turnRight()
-    forward()
-    turnLeft()
-        
-turnRight()
-forward()
-forward()
-forward()
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhile.fr.html b/src/lessons/welcome/loop/whileloop/LoopWhile.fr.html
deleted file mode 100644
index 229c261..0000000
--- a/src/lessons/welcome/loop/whileloop/LoopWhile.fr.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<h2>Boucles tant que <tt>(while)</tt></h2>
-		
-<p>En plus des instructions conditionnelles, une autre construction pratique
-est de pouvoir demander à la buggle de répéter une action tant qu'une
-condition particulière n'est pas arrivée. On utilise pour cela une boucle
-<tt>while</tt>, dont la syntaxe est la suivante :
- <pre class="Java">while (<b>condition</b>) {
-  <b>action()</b>;
-}</pre>
- <pre class="Python">while (<b>condition</b>) {
-  <b>action()</b>;
-}</pre>
-
-<p>Evidement, si l'action en question ne modifie pas la valeur de la condition,
-la buggle va exécuter l'action à l'infini. C'est dans ce genre de cas que le
-bouton <b>stop</b> de l'interface devient utile. Pour tester cela, vous
-pouvez essayer de taper le code suivant dans l'éditeur :
-
- <pre class="Java">while (true) {
-  turnLeft();
-}</pre>
- <pre class="Python">while (true) {
-  turnLeft();
-}</pre>
-
-La buggle va tourner vers la gauche tant que <code>true</code> est vrai
-(sans fin donc) jusqu'à ce que vous l'arrêtiez manuellement avec le bouton
-stop.</p>
-
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> Il vous faut maintenant écrire le code nécessaire pour
-que vos buggles avancent jusqu'à rencontrer un mur. L'idée est donc de faire
-:
-<pre>tant que l'on est pas face à un mur, faire :
-  avancer();</pre>
-
-<p>Quand votre programme fonctionne, passez à l'exercice suivant.</p>
-
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhile.html b/src/lessons/welcome/loop/whileloop/LoopWhile.html
deleted file mode 100644
index cb21fe9..0000000
--- a/src/lessons/welcome/loop/whileloop/LoopWhile.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<h2>While loops</h2>
-		
-<p>In addition to conditionals, another handy construction is the ability to
-repeat an action while a specific condition does not appear. A while loop is
-used for that, with the following syntax:
- <pre class="Java">while (<b>condition</b>) {
-  <b>action()</b>;
-}</pre>
- <pre class="Python">while <b>condition</b>:
-  <b>action()</b></pre>
-
-<p>Naturally, if the chosen action does not modify the value of the condition,
-the buggle will do the action endlessly. The <b>stop</b> button of the
-interface becomes then handy. To test this, you can try to type the
-following code in the editor:
-
- <pre class="Java">while (true) {
-  turnLeft();
-}</pre>
- <pre class="Python">while True:
-  turnLeft()</pre>
-
-The buggle will turn left while true is true (ie, endlessly),
-or until you stop it manually using the stop button.</p>
-
-<h3>Exercise goal</h3><a name="Objective">You now have to write some code so that your buggles
-move forward until they encounter a wall. The idea is thus to do something
-like:
-<pre>while we are not facing a wall, do:
-  moveForward()</pre>
-
-<p>When your program works, move forward to the next exercise.</p>
-
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhile.java b/src/lessons/welcome/loop/whileloop/LoopWhile.java
deleted file mode 100644
index 3947474..0000000
--- a/src/lessons/welcome/loop/whileloop/LoopWhile.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package lessons.welcome.loop.whileloop;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class LoopWhile extends ExerciseTemplated {
-
-	public LoopWhile(Lesson lesson) {
-		super(lesson);
-		tabName = "Program";
-
-		BuggleWorld myWorld = new BuggleWorld("Closed world",7,7);
-		for (int i=0;i<7;i++) {
-			new Buggle(myWorld, "Joker "+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
-			myWorld.putTopWall (i, 6-i);
-			myWorld.putLeftWall(i, 6-i);
-			myWorld.putLeftWall(0, i  );
-			myWorld.putTopWall (i, 0  );
-		}
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhileEntity.java b/src/lessons/welcome/loop/whileloop/LoopWhileEntity.java
deleted file mode 100644
index 4e7b8a7..0000000
--- a/src/lessons/welcome/loop/whileloop/LoopWhileEntity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package lessons.welcome.loop.whileloop;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class LoopWhileEntity extends SimpleBuggle {
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		while (!isFacingWall())
-			forward();
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoria.fr.html b/src/lessons/welcome/loop/whileloop/WhileMoria.fr.html
deleted file mode 100644
index 3c84cf5..0000000
--- a/src/lessons/welcome/loop/whileloop/WhileMoria.fr.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<h2>Perdu dans la Moria</h2>
-		
-<p>Votre buggle est coincé dans une mine ! Des rochers bloquent la sortie, et
-il va falloir dégager le chemin pour passer. Bon, ok, ce ne sont pas
-vraiment des rochers mais juste des baggles, et votre buggle pourrait
-facilement passer au dessus sans se fatiguer. Mais il est probablement plus
-simple de programmer votre buggle pour qu'elle déplace ces «rochers» plutôt
-que de tenter de la convaincre de passer à la suite sans avoir résolu le
-problème...</p>
-   
-<p>Donc, il vous faut trouver le premier baggle en travers de votre chemin
-(marchez vers l'est jusqu'à vous trouver au dessus d'un baggle), le
-ramasser, et retourner à l'autre extrémité du couloir pour le déposer
-(marchez vers l'ouest jusqu'à vous trouver au dessus d'un baggle puis
-reculez d'un pas). Il faut ensuite faire de même pour tous les baggles
-jusqu'à trouver la sortie. Une fois ceci fait, marchez vers l'air frais
-comme dans le monde objectif.</p>
-    
-<p>Quand vous serez parvenu à sortir de ce piège, passez à l'exercice suivant.</p>
-
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoria.html b/src/lessons/welcome/loop/whileloop/WhileMoria.html
deleted file mode 100644
index 54d8852..0000000
--- a/src/lessons/welcome/loop/whileloop/WhileMoria.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<h2>Lost in the Moria</h2>
-		
-<p>You buggle got stuck in a mine! Some rocks are blocking the exit, 
-and you will have to clear your way to the exit. Well of course these 
-are only baggles and you could simply walk away, but it will be easier 
-to program your buggle so that it moves those "rocks" than convincing your buggle 
-that it could easily walk away without solving the problem...</p>
-   
-<p>So, you have to find the first baggle blocking the exit (simply walk 
-to the east until you are over a baggle), take it and move it back to the 
-other side of the tunnel (walk to the west while you are not over a baggle, 
-and then move back one step to the east and drop your baggle), and iterate 
-until you find the exit (that is, the wall to the east side). Afterward, 
-move out as in the objective world.</p>
-    
-<p>Once you manage to escape this trap, move forward to the next exercise.</p>
-
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoria.java b/src/lessons/welcome/loop/whileloop/WhileMoria.java
deleted file mode 100644
index 914cce1..0000000
--- a/src/lessons/welcome/loop/whileloop/WhileMoria.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package lessons.welcome.loop.whileloop;
-
-import java.io.IOException;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class WhileMoria extends ExerciseTemplated {
-
-	public WhileMoria(Lesson lesson) throws IOException, BrokenWorldFileException {
-		super(lesson);
-		tabName = "Balin";
-		
-		/* Create initial situation */
-		World[] myWorlds = new World[] {
-				BuggleWorld.newFromFile("lessons/welcome/loop/whileloop/WhileMoria"),
-		};
-		for (World w: myWorlds)
-			w.setDelay(50); // moving a bit faster than usual
-		
-		setup(myWorlds);
-	}
-}
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.java b/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.java
deleted file mode 100644
index 97b697f..0000000
--- a/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package lessons.welcome.loop.whileloop;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class WhileMoriaEntity extends SimpleBuggle {
-	@Override
-	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
-	}
-
-	@Override
-	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
-	}
-
-	@Override
-	/* BEGIN TEMPLATE */
-	public void run() { 
-		/* BEGIN SOLUTION */
-		turnBack();
-		while (!isFacingWall()) {
-			while (!isOverBaggle() && !isFacingWall())
-				forward();
-			if (isOverBaggle()) {
-				pickupBaggle();
-				turnBack();
-				while (!isOverBaggle())
-					forward();
-				backward();
-				dropBaggle();
-				turnBack();
-				forward();
-			}
-		}
-		turnRight();
-		forward();
-		turnLeft();
-		forward();
-		/* END SOLUTION */
-	}
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.py b/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.py
deleted file mode 100644
index b1f0b23..0000000
--- a/src/lessons/welcome/loop/whileloop/WhileMoriaEntity.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# BEGIN SOLUTION
-turnBack()
-while not isFacingWall():
-    while (not isOverBaggle()) and (not isFacingWall()):
-        forward()
-    if isOverBaggle():
-        pickupBaggle()
-        turnBack()
-        while not isOverBaggle():
-            forward()
-        backward()
-        dropBaggle()
-        turnBack()
-        forward()
-turnRight()
-forward()
-turnLeft()
-forward()
-# END SOLUTION
diff --git a/src/lessons/welcome/loop/dowhileloop/LoopDoWhile-answer0.map b/src/lessons/welcome/loopdowhile/LoopDoWhile-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/dowhileloop/LoopDoWhile-answer0.map
rename to src/lessons/welcome/loopdowhile/LoopDoWhile-answer0.map
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhile.fr.html b/src/lessons/welcome/loopdowhile/LoopDoWhile.fr.html
new file mode 100644
index 0000000..3f8e55a
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhile.fr.html
@@ -0,0 +1,59 @@
+<h2>Boucles jusqu'à<tt> (do ... while)</tt></h2>
+
+<p>Certaines cases du monde sont jaunes, mais les buggles ne supportent pas de
+s'y trouver. Écrivez le code nécessaire pour avancer jusqu'à ce que le sol
+devienne blanc. Vous pourrez utiliser la méthode <code>estSurBlanc()</code>
+qui retourne vrai si le sol est blanc..</p>
+
+<p>Le truc est que la plupart des buggles de ce monde se trouvent actuellement
+sur ce sol jaune qui les énerve tant. Cela explique sans doute leur état de
+panique, et le fait que toutes les buggles se ruent vers l'avant au début,
+même la buggle qui ne se trouve pas sur du jaune. En d'autres mots, même si
+le sol est blanc le premier coup, il faut quand même avancer d'un pas.</p>    
+
+<p>L'idée général est donc de faire: </p>
+<pre>avancer jusqu'à se trouver sur une case blanche</pre>
+
+<p>La principale difficulté est que nous voulons exécuter le corps de boucle au
+moins une fois, même si la buggle se trouve déjà sur une case blanche. Il
+serait facile de dupliquer le corps de la boucle avant la boucle pour cela,
+mais  ça serait une <b>très mauvaise idée</b>. Dupliquer du code est une
+<b>très mauvaise habitude</b> et il faut toujours éviter de le faire.</p>
+
+<p>Quand on duplique le code, sa maintenance tourne facilement au cauchemar :
+la lecture du code est très pénible puisque le lecteur doit s'assurer qu'il
+n'y a effectivement aucune différence, même minime, entre les versions du
+même code. Debugger le code devient plus long, puisqu'il faut corriger
+toutes les versions. En fait, toutes les modifications deviennent
+pénibles. Alors, vraiment, vous devrez <b>toujours</b> vous efforcer
+d'éviter la duplication du code quand c'est possible. Et la bonne nouvelle
+est que c'est toujours possible...</p>
+
+<h3>Exécuter le corps de boucle au moins une fois</h3>
+[!python]
+<p>Certain langage ont une construction spécifique pour cela, mais pas
+Python. Qu'à cela ne tienne, on s'en sort très bien sans. Une bonne manière
+est d'avoir une variable dédiée indiquant si c'est la première fois que l'on
+rentre dans la boucle :</p>
+<pre>premiereFois = True
+while premiereFois or (les autres conditions):
+  premiereFois = False
+  (le corps de la boucle)
+</pre>
+
+<p>Quand <code>premiereFois</code> est vraie, le corps de la boucle est exécuté
+même si les autres conditions impliqueraient le contraire. Une fois que le
+corps de boucle a été exécuté, <code>premiereFois</code> est mis à faux et
+n'influe plus jamais la décision d'entrer dans le corps de boucle.</p>
+[/!] [!java|scala]
+<p>Dans une boucle <tt>while</tt>, la condition est évaluée avant toute chose,
+et si elle est fausse, le corps de la boucle n'est jamais exécuté. Il arrive
+parfois que l'on veuille que le corps de la boucle soit évalué au moins une
+fois, même si la condition est initialement fausse. On utilise pour cela une
+variante de la boucle <tt>while</tt>, dont la syntaxe est la suivante en
+[!thelang].
+
+<pre>do {
+    <b>action()</b>[!java];[/!]
+} while (<b>condition</b>)[!java];[/!]</pre></p>
+[/!]
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhile.html b/src/lessons/welcome/loopdowhile/LoopDoWhile.html
new file mode 100644
index 0000000..d7dc3ae
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhile.html
@@ -0,0 +1,53 @@
+<h2>Do .. while loops</h2>
+
+<p>Some cells of the world are yellow, but your buggle cannot stand being in 
+such cells. Write the necessary code to move forward until the ground 
+gets white. For that, use the provided method <code>isGroundWhite()</code>.</p>
+
+<p>The trick is that most buggles of this world are currently on this yellow ground 
+that they dislike so much. That is why they are in panic, and every buggle rushes 
+one cell forward, even the buggle that was not on a yellow cell at first. In other worlds,  
+even if the ground is white on the first cell, you still want to move forward to the next cell.</p>    
+
+<p>The general idea is to do something like: </p>
+<pre>move forward until located in a white cell</pre>
+
+<p>The main difficulty is that we want this loop body to be executed once, even we are already on a white cell. 
+It would be easy to do so by duplicating the loop content before the actual loop, but this would be a bad idea: 
+code duplication is a <b>very</b> bad habit, and you should <b>always</b> avoid it.</p>
+
+<p>Code duplication easily turns code maintenance into a nightmare: reading the code becomes difficult as the reader must ensure 
+that no slight difference exist between the versions. Debugging the code becomes difficult, as bugs have to be fixed 
+in all versions. Actually, every modification of the code becomes difficult. So, really, you should <b>always</b> 
+strive to not duplicate you code if you can avoid. And the good news is that you always can...</p>
+
+<h3>Executing the loop body at least once</h3>
+[!python]
+<p>Some languages
+have specific constructs for that, but not the Python language. No problem, we can do it
+on our own! A good way is to have a dedicated variable indicating whether we are taking
+the loop for the first time or not, as follows.</p>
+<pre>firstTime = True
+while firstTime or (other conditions):
+  firstTime = False
+  (loop body)
+</pre>
+
+<p>When <code>firstTime</code> is true, the loop body is executed even if the other conditions would imply the contrary. 
+Once the loop body has been executed once, it is set to false and never impact again the decision to enter the body or not.</p>
+[/!]
+
+
+[!java|scala]
+<p>In a <tt>while</tt> loop, the condition is evaluated before anything else,
+and if it's false, the loop body is never evaluated. Sometimes (although not 
+that often), you would prefer the
+loop body to get evaluated at least once, even if the condition is initially
+false. For that, a variation of the <tt>while</tt> loop gets used, using the
+following syntax in [!thelang]. 
+[!java]Do not forget the semi-column (;) after the condition, it is mandatory.[/!]
+
+<pre>do {
+    <b>action()</b>[!java];[/!]
+} while (<b>condition</b>)[!java];[/!]</pre></p>
+[/!]
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhile.java b/src/lessons/welcome/loopdowhile/LoopDoWhile.java
new file mode 100644
index 0000000..7d88910
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhile.java
@@ -0,0 +1,31 @@
+package lessons.welcome.loopdowhile;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class LoopDoWhile extends ExerciseTemplated {
+
+	public LoopDoWhile(Lesson lesson) {
+		super(lesson);
+		tabName = "Program";
+				
+		BuggleWorld myWorld = new BuggleWorld("Yellow Submarine",13,7);
+		for (int i=0;i<7;i++) {
+			new Buggle(myWorld, "Beatles"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
+		    for (int j=6; j>i; j--)
+		    	myWorld.setColor(i, j,Color.yellow);
+		}
+		for (int i=7;i<13;i++) {
+			new Buggle(myWorld, "Beatles"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
+		    for (int j=0; j<i-6; j++)
+		    	myWorld.setColor(i, 6-j,Color.yellow);
+		}
+
+    	setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.java b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.java
new file mode 100644
index 0000000..391168f
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.java
@@ -0,0 +1,22 @@
+package lessons.welcome.loopdowhile;
+
+import java.awt.Color;
+
+public class LoopDoWhileEntity extends plm.universe.bugglequest.SimpleBuggle {
+	boolean isGroundWhite() { 
+		return getGroundColor().equals(Color.white)?true:false;
+	}
+	/* BINDINGS TRANSLATION */
+	boolean estSurBlanc() { return isGroundWhite() ; }
+	
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		do {
+			forward();
+		} while (!isGroundWhite());
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.py b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.py
new file mode 100644
index 0000000..1af8742
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.py
@@ -0,0 +1,14 @@
+import java.awt.Color
+def isGroundWhite():
+    return getGroundColor().equals(java.awt.Color.white)
+
+def estSurBlanc(): # BINDINGS TRANSLATION
+    return isGroundWhite() 
+
+# BEGIN SOLUTION
+more = True
+while more:
+    forward()
+    if isGroundWhite():
+  	     more = False 
+# END SOLUTION
diff --git a/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.scala b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.scala
new file mode 100644
index 0000000..ca81ecf
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/LoopDoWhileEntity.scala
@@ -0,0 +1,21 @@
+package lessons.welcome.loopdowhile;
+
+import java.awt.Color;
+
+class ScalaLoopDoWhileEntity extends plm.universe.bugglequest.SimpleBuggle {
+	def isGroundWhite():Boolean = {
+	  if (getGroundColor() == Color.white)
+	    return true;
+	  return false;
+	}
+	/* BINDINGS TRANSLATION */
+	def estSurBlanc():Boolean = { return isGroundWhite(); }
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		do {
+			forward();
+		} while (!isGroundWhite());
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet-answer0.map b/src/lessons/welcome/loopdowhile/Poucet-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/dowhileloop/Poucet-answer0.map
rename to src/lessons/welcome/loopdowhile/Poucet-answer0.map
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet-answer1.map b/src/lessons/welcome/loopdowhile/Poucet-answer1.map
similarity index 100%
rename from src/lessons/welcome/loop/dowhileloop/Poucet-answer1.map
rename to src/lessons/welcome/loopdowhile/Poucet-answer1.map
diff --git a/src/lessons/welcome/loopdowhile/Poucet.fr.html b/src/lessons/welcome/loopdowhile/Poucet.fr.html
new file mode 100644
index 0000000..aa60f20
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/Poucet.fr.html
@@ -0,0 +1,57 @@
+<h2>La buggle Petite Poucette</h2>
+
+<p>Votre buggle est perdue dans un étrange labyrinthe, et elle a besoin de vous
+pour trouver la sortie (représentée par les cases orange). Vous ne pouvez
+pas lui donner son chemin tout simplement avec quelque chose comme
+<code>droite();avance();avance();</code> parce qu'il faut secourir deux
+buggles à la fois, perdues dans des labyrinthes similaires mais
+différents. Vous pouvez passer à l'autre monde en cliquant sur le menu
+défilant au dessus de l'endroit où est dessiné le monde. C'est là où il est
+écrit "Deep Forest" pour l'instant (forêt profonde), et si vous passez à
+"Deeper Forest" (forêt encore plus profonde), vous verrez l'autre monde. </p>
+
+<p>La bonne nouvelle est que le chemin vers la sortie est en quelque sorte
+écrit au sol. Ces mondes sont composés de plusieurs corridors, avec des
+baggles par terre. À chaque embranchement, il faut prendre à gauche si le
+corridor qu'on vient de parcourir contient 3 baggles ou plus, ou à droite
+s'il contient 2 baggles ou moins.</p>     
+
+<p>La forme générale de votre code doit donc être quelque chose comme «tant que
+je n'ai pas trouvé la sortie, prendre le prochain couloir pour décider s'il
+faut tourner à gauche ou à droite au prochain embranchement». Vous pouvez
+déterminer si vous avez rejoint la sortie (indiquée en orange) avec la
+méthode <code>sortieTrouvee()</code> fournie.</p>
+
+<p>Pour prendre un couloir, il suffit de courir d'une intersection à l'autre
+tout en comptant les biscuits en chemin. La méthode
+<code>croisement()</code> indique si vous vous trouvez actuellement à un
+embranchement. Ce qui complique un peu, c'est qu'au début du couloir, vous
+vous trouvez bien entendu à une intersection, mais vous souhaitez avancer
+quand même.
+[!java|scala]Le plus simple pour cela est d'utiliser une boucle <code>do /
+while</code> à la place d'une simple boucle <code>while</code> pour se
+déplacer d'une intersection à l'autre.[/!]
+[!python]Pour cela, utilisez une variable supplémentaire indiquant si vous
+êtes déjà entré dans le couloir, comme dans l'exemple suivant. Ainsi, vous
+exécuterez le corps de la boucle au moins une fois (quand
+<code>premiereFois</code> est vrai) tandis qu'aux tours de boucles suivants,
+c'est la valeur de retour de <code>croisement()</code> qui détermine s'il
+faut s'arrêter ou non.[/!]</p>
+
+[!python]
+<pre>premiereFois = True
+while premiereFois or not croisement():
+  premiereFois = False
+  (le corps de votre boucle)
+</pre>
+[/!] 
+
+<p><div class="tip" id="tip-1" alt="Je n'arrive pas à imaginer comment compter les baggles que je vois">
+Il vous faut une variable initialisée à zéro et incrémentée à chaque fois
+que vous voyez un baggle. Une variable utilisée ainsi est souvent appelée un
+<i>compteur</i>.<br/><br/>
+N'oubliez pas de remettre le compteur à 0 au début de chaque couloir! 
+</div></p>
+
+<p>Oh, et quand vous parviendrez à trouver la sortie, n'oubliez pas de faire un
+pas de plus pour vous échapper effectivement.</p> 
diff --git a/src/lessons/welcome/loopdowhile/Poucet.html b/src/lessons/welcome/loopdowhile/Poucet.html
new file mode 100644
index 0000000..eb4ecfb
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/Poucet.html
@@ -0,0 +1,41 @@
+<h2>Tracks of buggles</h2>
+
+<p>Your buggle got lost in a strange maze, and you must help it finding the exit that is represented in orange.
+You cannot simply explain the path to the exit in something like <code>right();forward;forward();forward()</code> 
+because you have to save two buggles at the same time, that are lost in similar but not identical worlds. 
+You can switch to the other world by using the combobox above the world representation (where it's written 
+'Deep Forest' right now), and selecting the other entry (that should read 'Deeper Forest').</p>
+
+<p>The good news is that the path to the exit is written on the ground. As you can see, the world is made 
+of several corridors, with baggles on the ground. After each corridor, you should turn left if the corridor contains
+three baggels or more, and you have to turn right if there is only 2 baggles or less.</p>     
+
+<p>So, the general form of your code must be something like "while I did not find the exit, take the next corridor 
+to decide whether I should turn left or right at the next intersection". You can determine whether you are on the 
+exit cell (that is orange) with the provided <code>exitReached()</code> method.</p>
+
+<p>To take one corridor, you simply have to run from one intersection to another while counting the baggles you see 
+on your path. The method <code>crossing()</code> tells you whether your buggle currently stands on an intersection. 
+The extra complexity is that at the beginning of a corridor, you obviously stand on an intersection, but you still want to move on.
+[!java|scala]For that, the easiest is to use a <code>do / while</code> loop instead of 
+a regular <code>while</code> loop to move until the next intersection.[/!]
+[!python]For that, use an extra variable indicating whether you already entered the
+corridor,  as follows. This will ensure that you execute the loop body at least once (when
+<code>firstTime</code> is true) before we actually use the value returned by
+<code>crossing()</code> to determine to continue or not.[/!]</p>
+
+[!python]
+<pre>firstTime = True
+while firstTime or not crossing():
+  firstTime = False
+  (your body)
+</pre>
+[/!] 
+
+<p><div class="tip" id="tip-1" alt="I cannot imagine how to count the baggles I see.">
+You need a variable that is initialized to 0, and incremented each time you see a 
+baggle on the ground. A variable used this way is often called <i>counter</i>.<br/><br/>
+Don't forget to reset your counter to 0 at the beginning of each corridor! 
+</div></p>
+
+<p>Oh, and when you reach the exit, don't forget to take an extra step to actually exit the maze!</p> 
diff --git a/src/lessons/welcome/loopdowhile/Poucet.java b/src/lessons/welcome/loopdowhile/Poucet.java
new file mode 100644
index 0000000..26b87ef
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/Poucet.java
@@ -0,0 +1,27 @@
+package lessons.welcome.loopdowhile;
+
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Poucet extends ExerciseTemplated {
+
+	public Poucet(Lesson lesson) throws IOException, BrokenWorldFileException {
+		super(lesson);
+		tabName = "Poucet";
+		
+		/* Create initial situation */
+		World[] myWorlds = new World[] {
+				BuggleWorld.newFromFile("lessons/welcome/loopdowhile/Poucet"),
+				BuggleWorld.newFromFile("lessons/welcome/loopdowhile/Poucet2"),
+		};
+		for (World w: myWorlds)
+			w.setDelay(50); // moving a bit faster than usual
+		
+		setup(myWorlds);
+	}
+}
\ No newline at end of file
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet.map b/src/lessons/welcome/loopdowhile/Poucet.map
similarity index 100%
rename from src/lessons/welcome/loop/dowhileloop/Poucet.map
rename to src/lessons/welcome/loopdowhile/Poucet.map
diff --git a/src/lessons/welcome/loop/dowhileloop/Poucet2.map b/src/lessons/welcome/loopdowhile/Poucet2.map
similarity index 100%
rename from src/lessons/welcome/loop/dowhileloop/Poucet2.map
rename to src/lessons/welcome/loopdowhile/Poucet2.map
diff --git a/src/lessons/welcome/loopdowhile/PoucetEntity.java b/src/lessons/welcome/loopdowhile/PoucetEntity.java
new file mode 100644
index 0000000..40511bf
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/PoucetEntity.java
@@ -0,0 +1,51 @@
+package lessons.welcome.loopdowhile;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+
+public class PoucetEntity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+	
+	public boolean crossing() {
+		return getX()%5== 1 && getY()%5==1;
+	}
+	public boolean exitReached() {
+		return getGroundColor().equals(Color.orange);
+	}	
+	/* BINDINGS TRANSLATION */
+	boolean sortieTrouvee() { return exitReached(); }
+	boolean croisement() { return crossing(); }
+
+	
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		while (!exitReached()) {
+			int seen = 0;
+			
+			do {
+				forward();
+				if (isOverBaggle())
+					seen++;
+			} while (! crossing());
+			
+			if (seen>2)
+				left();
+			else
+				right();
+		}
+		forward();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopdowhile/PoucetEntity.py b/src/lessons/welcome/loopdowhile/PoucetEntity.py
new file mode 100644
index 0000000..06e2c18
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/PoucetEntity.py
@@ -0,0 +1,41 @@
+def forward(i=-1):
+    if i==-1:
+      entity.forward()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use forward with argument")
+def backward(i=-1):
+    if i==-1:
+      entity.backward()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use backward with argument")
+
+def crossing():
+    return (entity.getX() % 5 == 1) and ( entity.getY()%5==1 )
+    
+def exitReached():
+    return getGroundColor().equals(Color.orange)
+
+# BINDINGS TRANSLATION 
+def croisement():
+    return crossing()
+def sortieTrouvee():
+    return exitReached()
+
+
+# BEGIN SOLUTION
+while not exitReached() :
+    seen = 0
+    within = False
+    
+    while not within or not crossing():
+        within = True
+        forward()
+        if isOverBaggle():
+            seen += 1
+    
+    if seen > 2:
+        left()
+    else:
+        right()
+forward()
+# END SOLUTION
diff --git a/src/lessons/welcome/loopdowhile/PoucetEntity.scala b/src/lessons/welcome/loopdowhile/PoucetEntity.scala
new file mode 100644
index 0000000..20ce2a8
--- /dev/null
+++ b/src/lessons/welcome/loopdowhile/PoucetEntity.scala
@@ -0,0 +1,43 @@
+package lessons.welcome.loopdowhile;
+
+import java.awt.Color;
+import plm.core.model.Game
+
+class ScalaPoucetEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	def crossing(): Boolean = {
+		return getX()%5== 1 && getY()%5==1;
+	}
+	def exitReached(): Boolean = {
+		return getGroundColor().equals(Color.orange);
+	}
+	/* BINDINGS TRANSLATION */
+	def sortieTrouvee(): Boolean = { return exitReached() }
+	def croisement(): Boolean = { return crossing() }
+
+	override def run() { 
+		/* BEGIN SOLUTION */
+		while (!exitReached()) {
+			var count = 0;
+			
+			do {
+				forward();
+				if (isOverBaggle())
+					count+=1;
+			} while (! crossing());
+			
+			if (count>2)
+				left();
+			else
+				right();
+		}
+		forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourse-answer0.map b/src/lessons/welcome/loopfor/LoopCourse-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourse-answer0.map
rename to src/lessons/welcome/loopfor/LoopCourse-answer0.map
diff --git a/src/lessons/welcome/loop/forloop/LoopCourse.fr.html b/src/lessons/welcome/loopfor/LoopCourse.fr.html
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourse.fr.html
rename to src/lessons/welcome/loopfor/LoopCourse.fr.html
diff --git a/src/lessons/welcome/loopfor/LoopCourse.html b/src/lessons/welcome/loopfor/LoopCourse.html
new file mode 100644
index 0000000..50a9e34
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourse.html
@@ -0,0 +1,10 @@
+<h2>Training Buggle</h2>
+
+<p>Today, your buggle wants to get some serious exercise: It wants to run 'till the track burns!
+Its super-shoes are just perfect to run like hell, but unfortunately, they can actually damage the track on the long run...</p>
+
+<p>Your goal is to run the track 10 times, no matter what happens. 
+Even if the track suffers, you <b>really HAVE</b> to take that run.
+Remember, the track has four sides, that take eight steps each to run along.
+Now go, and show them what these super shoes can do.</p>
+ 
\ No newline at end of file
diff --git a/src/lessons/welcome/loopfor/LoopCourse.java b/src/lessons/welcome/loopfor/LoopCourse.java
new file mode 100644
index 0000000..53321ff
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourse.java
@@ -0,0 +1,27 @@
+package lessons.welcome.loopfor;
+
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class LoopCourse extends ExerciseTemplated{
+	
+		public LoopCourse(Lesson lesson) throws IOException, BrokenWorldFileException {
+			super(lesson);
+			tabName = "Runner";
+					
+			/* Create initial situation */
+			World[] myWorlds = new World[] {
+					BuggleWorld.newFromFile("lessons/welcome/loopfor/LoopCourse")
+			};
+			for (World w: myWorlds)
+				w.setDelay(10); // runners are moving faster than usual
+			
+			setup(myWorlds);
+		}
+
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourse.map b/src/lessons/welcome/loopfor/LoopCourse.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourse.map
rename to src/lessons/welcome/loopfor/LoopCourse.map
diff --git a/src/lessons/welcome/loopfor/LoopCourseEntity.java b/src/lessons/welcome/loopfor/LoopCourseEntity.java
new file mode 100644
index 0000000..0c62ed6
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseEntity.java
@@ -0,0 +1,50 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+
+public class LoopCourseEntity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+	Color[] colors = new Color[] {
+			Color.white,
+			new Color(255,240,240),new Color(255,220,220),new Color(255,205,205),
+			new Color(255,190,190),new Color(255,170,170),new Color(255,150,150),
+			new Color(255,130,130),new Color(255,110,110),new Color(255,45,45),
+			new Color(255,5,5)};
+	@Override
+	public void forward()  {
+		super.forward();
+		Color c = getGroundColor();
+		for (int i=0;i<colors.length-1;i++)
+			if (colors[i].equals(c)) {
+				c = colors[i+1];
+				break;
+			}
+		setBrushColor(c);
+		brushDown();
+		brushUp();
+	}
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		for (int i = 0; i<10;i++) 
+			for (int side=0;side<4;side++){
+				for (int step=0;step<8;step++)
+					forward();
+				left();
+			}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopfor/LoopCourseEntity.py b/src/lessons/welcome/loopfor/LoopCourseEntity.py
new file mode 100644
index 0000000..3743def
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseEntity.py
@@ -0,0 +1,30 @@
+colors = [Color.white, Color(255,240,240), Color(255,220,220), Color(255,205,205),
+             Color(255,190,190), Color(255,170,170), Color(255,150,150),
+             Color(255,130,130), Color(255,110,110), Color(255,45,45),
+             Color(255,5,5)]
+
+def forward(i=-1):
+    if i==-1:
+      entity.forward()
+      c = getGroundColor()
+      for i in range(len(colors)-1):
+          if colors[i] == c:
+              c = colors[i+1]
+              break
+      setBrushColor(c)    
+      brushDown()
+      brushUp()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use forward with argument")
+def backward(i=-1):
+    if i==-1:
+      entity.backward()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use backward with argument")
+# BEGIN SOLUTION
+for i in range(10):
+    for side in range(4):
+        for step in range(8):
+            forward()
+        left()
+# END SOLUTION
diff --git a/src/lessons/welcome/loopfor/LoopCourseEntity.scala b/src/lessons/welcome/loopfor/LoopCourseEntity.scala
new file mode 100644
index 0000000..3874fe1
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseEntity.scala
@@ -0,0 +1,45 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color
+import plm.universe.bugglequest.SimpleBuggle
+import plm.core.model.Game
+
+class ScalaLoopCourseEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	var colors = Array(
+			Color.white,
+			new Color(255,240,240),new Color(255,220,220),new Color(255,205,205),
+			new Color(255,190,190),new Color(255,170,170),new Color(255,150,150),
+			new Color(255,130,130),new Color(255,110,110),new Color(255,45,45),
+			new Color(255,5,5))
+
+	override def forward() {
+		super.forward();
+		var c = getGroundColor();
+		var nextColor:Color = null;
+		for (i <- 0 to colors.length-1)
+			if (colors(i).equals(c)) { 
+				nextColor = colors(i+1);
+			}
+		setBrushColor(nextColor);
+		brushDown();
+		brushUp();
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 10; side <- 1 to 4) {
+			for (step <- 1 to 8) {
+				forward()
+			}
+			left()
+		} 
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForest-answer0.map b/src/lessons/welcome/loopfor/LoopCourseForest-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourseForest-answer0.map
rename to src/lessons/welcome/loopfor/LoopCourseForest-answer0.map
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForest.fr.html b/src/lessons/welcome/loopfor/LoopCourseForest.fr.html
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourseForest.fr.html
rename to src/lessons/welcome/loopfor/LoopCourseForest.fr.html
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForest.html b/src/lessons/welcome/loopfor/LoopCourseForest.html
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourseForest.html
rename to src/lessons/welcome/loopfor/LoopCourseForest.html
diff --git a/src/lessons/welcome/loopfor/LoopCourseForest.java b/src/lessons/welcome/loopfor/LoopCourseForest.java
new file mode 100644
index 0000000..1056bd4
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseForest.java
@@ -0,0 +1,27 @@
+package lessons.welcome.loopfor;
+
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class LoopCourseForest extends ExerciseTemplated{
+	
+		public LoopCourseForest(Lesson lesson) throws IOException, BrokenWorldFileException {
+			super(lesson);
+			tabName = "Runner";
+					
+			/* Create initial situation */
+			World[] myWorlds = new World[] {
+					BuggleWorld.newFromFile("lessons/welcome/loopfor/LoopCourseForest")
+			};
+			for (World w: myWorlds)
+				w.setDelay(10); // runners are moving faster than usual
+			
+			setup(myWorlds);
+		}
+
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopCourseForest.map b/src/lessons/welcome/loopfor/LoopCourseForest.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopCourseForest.map
rename to src/lessons/welcome/loopfor/LoopCourseForest.map
diff --git a/src/lessons/welcome/loopfor/LoopCourseForestEntity.java b/src/lessons/welcome/loopfor/LoopCourseForestEntity.java
new file mode 100644
index 0000000..e0bd01a
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseForestEntity.java
@@ -0,0 +1,74 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+
+public class LoopCourseForestEntity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+	Color[] colors = new Color[] {
+			new Color(0,155,0),
+			new Color(50,155,0),
+			new Color(100,155,0),
+			new Color(140,155,0),
+			new Color(160,155,0),
+			new Color(180,155,0),
+			new Color(200,155,0),
+			new Color(210,155,0),
+	};
+	@Override
+	public void forward()  {
+		if (!haveSeenError())
+			super.forward();
+		Color c = getGroundColor();
+		if (c.equals(Color.blue)) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, Game.i18n.tr("You fall into water."), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+		for (int i=0;i<colors.length-1;i++)
+			if (colors[i].equals(c)) {
+				c = colors[i+1];
+				break;
+			}
+		setBrushColor(c);
+		brushDown();
+		brushUp();
+	}
+
+	
+
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		for (int i = 0; i<7;i++) 
+			for (int side=0;side<4;side++){
+				for (int step=0;step<4;step++)
+					forward();
+				left();
+				for (int step=0;step<2;step++)
+					forward();
+				right();
+				for (int step=0;step<4;step++)
+					forward();
+				right();
+				forward();
+				forward();
+				left();
+				for (int step=0;step<4;step++)
+					forward();
+				left();
+			}
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopfor/LoopCourseForestEntity.py b/src/lessons/welcome/loopfor/LoopCourseForestEntity.py
new file mode 100644
index 0000000..34324c3
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseForestEntity.py
@@ -0,0 +1,48 @@
+import javax.swing.JOptionPane;
+
+colors = [Color(0,155,0), Color(50,155,0), Color(100,155,0), Color(140,155,0),
+          Color(160,155,0), Color(180,155,0), Color(200,155,0), Color(210,155,0)]
+
+def forward(i=-1):
+    if i==-1:
+      entity.forward()
+      c = getGroundColor()
+      
+      if c.equals( Color.blue ):
+          if not entity.haveSeenError():
+              javax.swing.JOptionPane.showMessageDialog(None, "You fall into water.", "Test failed", javax.swing.JOptionPane.ERROR_MESSAGE)
+          entity.seenError()
+
+      for i in range(len(colors)-1):
+          if colors[i].equals(c):
+              c = colors[i+1]
+              break
+      setBrushColor(c)    
+      brushDown()
+      brushUp()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use forward with argument")
+def backward(i=-1):
+    if i==-1:
+      entity.backward()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use backward with argument")
+# BEGIN SOLUTION
+for i in range(7):
+    for side in range(4):
+        for step in range(4):
+            forward()
+        left();
+        for step in range(2):
+            forward()
+        right();
+        for step in range(4):
+            forward()
+        right()
+        forward()
+        forward()
+        left()
+        for step in range(4):
+            forward()
+        left()
+# END SOLUTION
diff --git a/src/lessons/welcome/loopfor/LoopCourseForestEntity.scala b/src/lessons/welcome/loopfor/LoopCourseForestEntity.scala
new file mode 100644
index 0000000..b119188
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopCourseForestEntity.scala
@@ -0,0 +1,64 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+import plm.universe.bugglequest.SimpleBuggle
+import plm.core.model.Game
+
+class ScalaLoopCourseForestEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	var colors = Array(
+			new Color(0,155,0),
+			new Color(50,155,0),
+			new Color(100,155,0),
+			new Color(140,155,0),
+			new Color(160,155,0),
+			new Color(180,155,0),
+			new Color(200,155,0),
+			new Color(210,155,0))
+	
+	override def forward()  {
+		if (!haveSeenError())
+			super.forward();
+		var c = getGroundColor();
+		if (c.equals(Color.blue) && !haveSeenError()) {
+			javax.swing.JOptionPane.showMessageDialog(null, Game.i18n.tr("You fall into water."), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+		var nextColor:Color = null;
+		for (i <- 0 to colors.length-1)
+			if (colors(i).equals(c)) { 
+				nextColor = colors(i+1);
+			}
+		setBrushColor(nextColor);
+		brushDown();
+		brushUp();
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 7;  side <- 1 to 4){
+				for (step <- 1 to 4)
+					forward();
+				left();
+				for (step <- 1 to 2)
+					forward();
+				right();
+				for (step <- 1 to 4)
+					forward();
+				right();
+				forward();
+				forward();
+				left();
+				for (step <- 1 to 4)
+					forward();
+				left();
+		}
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopFor-answer0.map b/src/lessons/welcome/loopfor/LoopFor-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopFor-answer0.map
rename to src/lessons/welcome/loopfor/LoopFor-answer0.map
diff --git a/src/lessons/welcome/loopfor/LoopFor.fr.html b/src/lessons/welcome/loopfor/LoopFor.fr.html
new file mode 100644
index 0000000..9f02c8c
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopFor.fr.html
@@ -0,0 +1,80 @@
+<h2>Boucles pour <tt>(for)</tt></h2>
+
+<p>Les boucles <tt>while</tt> sont bien adaptées aux situations où l'on veut
+réaliser une action tant qu'une condition est réalisée, mais elles sont
+moins pratiques pour réaliser une action un nombre prédéterminé de fois. Par
+exemple, lorsque nous voulions reculer de <code>nbPas</code> dans l'exercice
+précédent, il fallait créer une nouvelle variable, l'initialiser, et
+demander à reculer tant que la nouvelle variable n'était pas égale à
+<code>nbPas</code>, en incrémentant cette variable à la main à la fin du
+corps de la boucle.</p> 
+
+<p>Dans ce genre de cas, les boucles de type <code>for</code> sont plus
+pratique. Leur syntaxe est la suivante :</p> 
+<pre>[!java]for (<b>initialisation</b>; <b>condition</b>; <b>increment</b>) {
+    <b>action</b>();
+}[/!][!python]for <b>variable</b> in <b>sequence de valeurs</b>:
+    <b>action</b>()[/!][!scala] for (<b>variable</b> <- <b>premiereValeur</b> to <b>derniereValeur</b>) { 
+    <b>action</b>();
+}[/!]</pre>
+
+<p>Par exemple, pour répéter le corps de boucle <code>n</code> fois,
+[!python]il est pratique d'utiliser l'instruction <code>range(n)</code>
+  pour générer la séquence de n entiers allant de 0 à n-1.[/!]
+[!java|scala]il faut écrire:[/!]</p>
+<pre>[!java]for (int compteur=0; compteur<n; compteur++) {
+    <b>action</b>();
+}[/!][!python]for <b>compteur</b> in <b>range(n)</b>:
+    <b>action</b>()[/!][!scala] for (var <b>compteur</b> <- <b>1</b> to <b>10</b>) { 
+    <b>action</b>();
+}[/!]</pre>
+
+<p>Ce code est parfaitement équivalent à celui-ci :</p>
+<pre>[!java]int compteur = 0;
+while (compteur < n) {
+    <b>action</b>();
+    <b>compteur++</b>;
+}[/!][!python]compteur=0
+while compteur < n: 
+    action()
+    compteur = compteur + 1[/!][!scala]
+var compteur = 0
+while (compteur < n) {
+    <b>action</b>()
+    compteur = compteur + 1
+}[/!]</pre>
+
+<p>Le code avec une boucle <code>for</code> est plus simple à lire, non?</p>
+
+[!java]
+<p>On peut imaginer des utilisations bien plus avancées des boucles
+<tt>for</tt> car toute instruction valide peut être utilisée comme
+initialisation, condition et incrémentation. L'exemple suivant est un peu
+extrême, puisqu'il n'y a même pas de corps de boucle. La buggle est avancée
+jusqu'à se retrouver face au mur dans la condition et l'incrémentation.
+
+<pre>for (; !estFaceMur() ; avance()) { 
+   <span class="comment">/* rien dans le corps de boucle */</span>
+}
+<span class="comment">/* la buggle est maintenant face à un mur */</span></pre>
+[/!] [!scala]
+<p>Si vous avez l'intention d'imbriquer plusieurs boucles, il est possible de
+l'écrire en une seule ligne en Scala. Les deux morceaux de code sont
+équivalents:</p>
+<pre>for (compteur1 <- 1 to n) {
+    for (compteur2 <- 1 to m) {
+       actions()
+    }
+}</pre> 
+<pre>for (compteur1 <- 1 to n; compteur2 <- 1 to m) { <span class="comment">// Séparez simplement les deux conditions de boucle par un point-virgule (;)</span>
+    actions()
+}</pre> 
+[/!]
+
+<h3>Objectif de cet exercice</h3>
+<p> Il s'agit maintenant de refaire le même exercice que précédemment (avancer
+jusqu'à trouver un baggle, le ramasser, revenir là où on était au début puis
+reposer le baggle), mais en utilisant une boucle <tt>for</tt> pour revenir
+au point de départ à la place d'une boucle <code>while</code>.</p
+
+<p>Une fois ceci fait, vous pouvez passez à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/loopfor/LoopFor.html b/src/lessons/welcome/loopfor/LoopFor.html
new file mode 100644
index 0000000..aab0304
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopFor.html
@@ -0,0 +1,77 @@
+<h2>For loops</h2>
+
+<p>While loops are well adapted to situations where you want to achieve an
+action while a condition stays true, but it is less adapted to achieve a
+given action a predetermined amount of time. For example, when we wanted to
+move <code>stepAmount</code> steps backward in a previous exercise, we had to
+create a new variable, initialize it, and move backward while incrementing 
+this variable until it became equal to <code>stepAmount</code>.</p> 
+
+<p>In such situations, <code>for</code> loops become handy. Their syntax is the
+following:</p> 
+<pre>[!java]for (<b>initializing</b>; <b>condition</b>; <b>incrementing</b>) {
+    <b>action</b>();
+}[/!][!python]for <b>variable</b> in <b>sequence of values</b>:
+    <b>action</b>()[/!][!scala] for (<b>variable</b> <- <b>firstValue</b> to <b>lastValue</b>) { 
+    <b>action</b>();
+}[/!]</pre>
+
+<p>For example to repeat the the loop body <code>n</code> times, 
+[!python] it is handy to use the instruction <code>range(n)</code> to generate the sequence n integer value from 0 to n-1.[/!]
+[!java|scala] one should write:[/!]</p>
+<pre>[!java]for (int stepper=0; stepper<n; stepper++) {
+    <b>action</b>();
+}[/!][!python]for <b>stepper</b> in <b>range(n)</b>:
+    <b>action</b>()[/!][!scala] for (var <b>stepper</b> <- <b>1</b> to <b>n</b>) { 
+    <b>action</b>();
+}[/!]</pre>
+
+<p>This code is then perfectly equivalent to the following one.</p>
+<pre>[!java]int stepper = 0;
+while (stepper < n) {
+    <b>action</b>();
+    <b>stepper++</b>;
+}[/!][!python]stepper=0
+while stepper < n: 
+    action()
+    stepper = stepper + 1[/!][!scala]
+var stepper = 1
+while (stepper <= n) {
+    <b>action</b>()
+    stepper = stepper + 1
+}[/!]</pre>
+
+<p>The <code>for</code> loop is easier to read, don't you think?</p>
+
+[!java]
+<p>It is possible to build more advanced <tt>for</tt> loops since any valid
+instruction can be used as initialization, condition and incrementing instruction. The
+following example is a bit extreme as there is no need for a loop body to move 
+the buggle forward until it reaches the wall, but it works well: all the work is 
+done in the condition and incrementing instruction.
+
+<pre>for (; !isFacingWall() ; forward()) { 
+   <span class="comment">/* nothing in the loop body */</span>
+}
+<span class="comment">/* the buggle now faces a wall */</span></pre>
+[/!]
+
+[!scala]
+<p>If you want to nest several loops, you can do it on one line in Scala. This means that the two following chunks are equivalent:</p>
+<pre>for (stepper1 <- 1 to n) {
+    for (stepper2 <- 1 to m) {
+       actions()
+    }
+}</pre> 
+<pre>for (stepper1 <- 1 to n; stepper2 <- 1 to m) { <span class="comment">// Simply separate both loop conditions with a semi-column</span>
+    actions()
+}</pre> 
+[/!]
+
+<h3>Exercise goal</h3>
+<p> You now have to redo the same exercise than previously
+(move forward until being over a baggle, pick it up, move back to your
+original location, drop the baggle), but using a <code>for</code> loop instead
+of a <code>while</code> loop to move back to the initial location.</p
+
+<p>Once done, you can proceed to next exercise.</p>
diff --git a/src/lessons/welcome/loopfor/LoopFor.java b/src/lessons/welcome/loopfor/LoopFor.java
new file mode 100644
index 0000000..dfb27f0
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopFor.java
@@ -0,0 +1,31 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class LoopFor extends ExerciseTemplated {
+
+	public LoopFor(Lesson lesson) {
+		super(lesson);
+		tabName = "Program";
+		
+		BuggleWorld myWorld = new BuggleWorld("Kitchen",7,7);
+		for (int i=0;i<7;i++) {
+			new Buggle(myWorld, "Hungry"+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
+		    
+		    try {
+				myWorld.newBaggle(i, 6-i);
+			} catch (AlreadyHaveBaggleException e) {
+				e.printStackTrace();
+			}
+		}
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/loopfor/LoopForEntity.java b/src/lessons/welcome/loopfor/LoopForEntity.java
new file mode 100644
index 0000000..74d4ec6
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopForEntity.java
@@ -0,0 +1,34 @@
+package lessons.welcome.loopfor;
+
+import plm.core.model.Game;
+
+public class LoopForEntity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		int cpt = 0;
+		while (!isOverBaggle()) {
+			cpt++;
+			forward();
+		}
+		pickupBaggle();
+		for (int cpt2=0 ; cpt2<cpt ; cpt2++) {
+			backward();
+		}
+		dropBaggle();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopForEntity.py b/src/lessons/welcome/loopfor/LoopForEntity.py
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopForEntity.py
rename to src/lessons/welcome/loopfor/LoopForEntity.py
diff --git a/src/lessons/welcome/loopfor/LoopForEntity.scala b/src/lessons/welcome/loopfor/LoopForEntity.scala
new file mode 100644
index 0000000..1d7b0a8
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopForEntity.scala
@@ -0,0 +1,28 @@
+package lessons.welcome.loopfor;
+
+import plm.universe.bugglequest.SimpleBuggle
+import plm.core.model.Game
+
+class ScalaLoopForEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		var cpt = 0
+		while (!isOverBaggle()) {
+			cpt+=1;
+			forward();
+		}
+		pickupBaggle();
+		for (cpt2 <- 0  to cpt-1) {
+			backward();
+		}
+		dropBaggle();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopStairs-answer0.map b/src/lessons/welcome/loopfor/LoopStairs-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopStairs-answer0.map
rename to src/lessons/welcome/loopfor/LoopStairs-answer0.map
diff --git a/src/lessons/welcome/loop/forloop/LoopStairs.fr.html b/src/lessons/welcome/loopfor/LoopStairs.fr.html
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopStairs.fr.html
rename to src/lessons/welcome/loopfor/LoopStairs.fr.html
diff --git a/src/lessons/welcome/loopfor/LoopStairs.html b/src/lessons/welcome/loopfor/LoopStairs.html
new file mode 100644
index 0000000..cf7a0f5
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopStairs.html
@@ -0,0 +1,13 @@
+<h2>Stairway to Heaven</h2>
+
+<p>Your buggle feels a bit depressed today, but it's currently facing a magic stair: 
+It leads directly to heaven, and each time you walk on it, joyful colors spur all around.</p>
+
+<p>Your goal is to take this stair, one step after the other. 
+First devise the four instructions you have to give you buggle to take one stair step, 
+and then put them in a loop to take the whole stair.</p>
+
+<p>And before that, walk a bit forward to reach that stair, and ensure that you are in 
+the right situation for your loop content to run properly. And once you reach the heaven, 
+take some steps in your new home.</p>
+ 
\ No newline at end of file
diff --git a/src/lessons/welcome/loopfor/LoopStairs.java b/src/lessons/welcome/loopfor/LoopStairs.java
new file mode 100644
index 0000000..5ec4cf4
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopStairs.java
@@ -0,0 +1,25 @@
+package lessons.welcome.loopfor;
+
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class LoopStairs extends ExerciseTemplated{
+	
+		public LoopStairs(Lesson lesson) throws IOException, BrokenWorldFileException {
+			super(lesson);
+			tabName = "Runner";
+					
+			/* Create initial situation */
+			World[] myWorlds = new World[] {
+					BuggleWorld.newFromFile("lessons/welcome/loopfor/LoopStairs")
+			};
+			
+			setup(myWorlds);
+		}
+
+}
diff --git a/src/lessons/welcome/loop/forloop/LoopStairs.map b/src/lessons/welcome/loopfor/LoopStairs.map
similarity index 100%
rename from src/lessons/welcome/loop/forloop/LoopStairs.map
rename to src/lessons/welcome/loopfor/LoopStairs.map
diff --git a/src/lessons/welcome/loopfor/LoopStairsEntity.java b/src/lessons/welcome/loopfor/LoopStairsEntity.java
new file mode 100644
index 0000000..538f02e
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopStairsEntity.java
@@ -0,0 +1,59 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+
+public class LoopStairsEntity extends plm.universe.bugglequest.SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+	Color[] colors = new Color[] {
+			Color.blue,    Color.cyan, Color.green,  Color.yellow,
+			Color.orange,  Color.red,  Color.magenta,Color.pink,};
+	
+	int step = -3;
+	@Override
+	public void forward()  {
+		super.forward();
+		if (step<0 || step%2 == 1 || (step/2)>=colors.length) {
+			if (step < 0)
+				setBrushColor(Color.lightGray);
+			else if ((step/2)>=colors.length)
+				setBrushColor(Color.pink);
+			else
+				setBrushColor(colors[(step/2)%colors.length]);
+			brushDown();
+			brushUp();
+		}
+		step++;
+	}
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		forward();
+		forward();
+		forward();
+		left();
+		for (int i = 0; i<8;i++) { 
+			forward();
+			right();
+			forward();
+			left();
+		}
+		right();
+		forward();
+		forward();
+		forward();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopfor/LoopStairsEntity.py b/src/lessons/welcome/loopfor/LoopStairsEntity.py
new file mode 100644
index 0000000..e668657
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopStairsEntity.py
@@ -0,0 +1,44 @@
+import javax.swing.JOptionPane;
+
+colors = [Color.blue,    Color.cyan, Color.green,  Color.yellow,
+          Color.orange,  Color.red,  Color.magenta,Color.pink]
+
+step = -3
+def forward(i=-1):
+    global step
+    if i==-1:
+      entity.forward()
+      if step<0 or step%2 == 1 or (step/2)>=len(colors):
+          if step < 0:
+              setBrushColor(Color.lightGray)
+          elif (step/2)>=len(colors):
+              setBrushColor(Color.pink)
+          else:
+              setBrushColor(colors[(step/2)%len(colors)])
+          brushDown()
+          brushUp()
+      step += 1
+    else:
+      errorMsg("Sorry Dave, I cannot let you use forward with argument")
+def backward(i=-1):
+    if i==-1:
+      entity.backward()
+    else:
+      errorMsg("Sorry Dave, I cannot let you use backward with argument")
+      
+# BEGIN SOLUTION
+forward()
+forward()
+forward()
+left()
+for i in range(8): 
+    forward()   
+    right()
+    forward()
+    left()
+        
+right()
+forward()
+forward()
+forward()
+# END SOLUTION
diff --git a/src/lessons/welcome/loopfor/LoopStairsEntity.scala b/src/lessons/welcome/loopfor/LoopStairsEntity.scala
new file mode 100644
index 0000000..205cab4
--- /dev/null
+++ b/src/lessons/welcome/loopfor/LoopStairsEntity.scala
@@ -0,0 +1,53 @@
+package lessons.welcome.loopfor;
+
+import java.awt.Color;
+import plm.universe.bugglequest.SimpleBuggle
+import plm.core.model.Game
+
+class ScalaLoopStairsEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	var colors = Array(
+			Color.blue,    Color.cyan, Color.green,  Color.yellow,
+			Color.orange,  Color.red,  Color.magenta,Color.pink)
+	
+	var step = -3
+	override def forward() {
+		super.forward();
+		if (step<0 || step%2 == 1 || (step/2)>=colors.length) {
+			if (step < 0)
+				setBrushColor(Color.lightGray);
+			else if ((step/2)>=colors.length)
+				setBrushColor(Color.pink);
+			else
+				setBrushColor(colors((step/2)%colors.length));
+			brushDown();
+			brushUp();
+		}
+		step += 1; 
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		forward();
+		forward();
+		forward();
+		left();
+		for (i <- 1 to 8) { 
+			forward();
+			right();
+			forward();
+			left();
+		}
+		right();
+		forward();
+		forward();
+		forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeeker-answer0.map b/src/lessons/welcome/loopwhile/BaggleSeeker-answer0.map
similarity index 100%
rename from src/lessons/welcome/baggleseeker/BaggleSeeker-answer0.map
rename to src/lessons/welcome/loopwhile/BaggleSeeker-answer0.map
diff --git a/src/lessons/welcome/loopwhile/BaggleSeeker.fr.html b/src/lessons/welcome/loopwhile/BaggleSeeker.fr.html
new file mode 100644
index 0000000..8c606e9
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/BaggleSeeker.fr.html
@@ -0,0 +1,13 @@
+<h2>Chercheur de baggles</h2>
+<p>Le monde des buggles contient parfois des petits biscuits ronds que les
+buggles peuvent déplacer d'un endroit à un autre. Pour cela, elles peuvent
+utiliser des fonctions spécifiques : <code>estSurBiscuit(), porteBiscuit(),
+prendBiscuit()<code> et <code>poseBiscuit()</code>. Tous les détails se
+trouvent dans la documentation accessible depuis «Aide/À propos de ce
+monde».
+
+<h3>Objectif de cet exercice</h3>
+
+<p>Faites en sorte que chaque buggle trouve son baggle en adaptant le code que
+vous aviez écrit pour l'exercice précédent (vous êtes libre de faire un
+copie/colle de ce que vous aviez fait si vous le souhaitez).
diff --git a/src/lessons/welcome/loopwhile/BaggleSeeker.html b/src/lessons/welcome/loopwhile/BaggleSeeker.html
new file mode 100644
index 0000000..816c63a
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/BaggleSeeker.html
@@ -0,0 +1,11 @@
+<h2>Baggle Seeking</h2>
+<p>The buggle world can sometimes contain some <i>baggles</i>, which are little
+biscuits that buggles can carry from one point to another. For that, they
+have to use specific methods such as <code>isOverBaggle(), isCarryingBaggle(), 
+pickupBaggle()</code> or <code>dropBaggle()</code>. Check their documentation in
+"Help/About this world" for more details.
+
+<h3>Exercise goal</h3>
+
+<p>Let each buggle find its baggle by adapting the code you wrote in previous exercise
+ (copy/paste what you've done before if you want).
diff --git a/src/lessons/welcome/loopwhile/BaggleSeeker.java b/src/lessons/welcome/loopwhile/BaggleSeeker.java
new file mode 100644
index 0000000..148dc81
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/BaggleSeeker.java
@@ -0,0 +1,29 @@
+package lessons.welcome.loopwhile;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class BaggleSeeker extends ExerciseTemplated {
+
+	public BaggleSeeker(Lesson lesson) {
+		super(lesson);
+
+		BuggleWorld myWorld = new BuggleWorld("Kitchen",7,7);
+		for (int i=0;i<7;i++) {
+			new Buggle(myWorld, "Cooker "+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
+
+			try {
+				myWorld.newBaggle(i, 6-i);
+			} catch (AlreadyHaveBaggleException e) {
+				e.printStackTrace();
+			}
+		}
+		setup(myWorld);
+	}
+}
\ No newline at end of file
diff --git a/src/lessons/welcome/loopwhile/BaggleSeekerEntity.java b/src/lessons/welcome/loopwhile/BaggleSeekerEntity.java
new file mode 100644
index 0000000..92bfb41
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/BaggleSeekerEntity.java
@@ -0,0 +1,28 @@
+package lessons.welcome.loopwhile;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class BaggleSeekerEntity extends SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+
+	@Override
+	public void run() { 
+		/* BEGIN TEMPLATE */
+		/* BEGIN SOLUTION */
+		while (!isOverBaggle()) {
+			forward();
+		}
+		/* END SOLUTION */
+		/* END TEMPLATE */
+	}
+}
diff --git a/src/lessons/welcome/baggleseeker/BaggleSeekerEntity.py b/src/lessons/welcome/loopwhile/BaggleSeekerEntity.py
similarity index 100%
rename from src/lessons/welcome/baggleseeker/BaggleSeekerEntity.py
rename to src/lessons/welcome/loopwhile/BaggleSeekerEntity.py
diff --git a/src/lessons/welcome/loopwhile/BaggleSeekerEntity.scala b/src/lessons/welcome/loopwhile/BaggleSeekerEntity.scala
new file mode 100644
index 0000000..b7946d5
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/BaggleSeekerEntity.scala
@@ -0,0 +1,22 @@
+package lessons.welcome.loopwhile;
+
+import plm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game
+
+class ScalaBaggleSeekerEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	override def run() { 
+		/* BEGIN SOLUTION */
+		while (!isOverBaggle()) {
+			forward();
+		}
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhile-answer0.map b/src/lessons/welcome/loopwhile/LoopWhile-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/whileloop/LoopWhile-answer0.map
rename to src/lessons/welcome/loopwhile/LoopWhile-answer0.map
diff --git a/src/lessons/welcome/loopwhile/LoopWhile.fr.html b/src/lessons/welcome/loopwhile/LoopWhile.fr.html
new file mode 100644
index 0000000..4d6cfd6
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/LoopWhile.fr.html
@@ -0,0 +1,42 @@
+<h2>Boucles tant que <tt>(while)</tt></h2>
+		
+<p>En plus des instructions conditionnelles, une autre construction pratique
+est de pouvoir répéter une action tant qu'une condition particulière n'est
+pas arrivée. On utilise pour cela une boucle <tt>while</tt>, dont la syntaxe
+est la suivante :
+ 
+<pre>[!java|scala]while (<b>condition</b>) {
+    <b>action()</b>;
+}[/!][!python]while <b>condition</b>:
+    <b>action()</b>[/!]</pre>
+
+<p>Le bloc est alors exécuté encore et encore, tant que la condition est
+vraie. Plus précisément, la buggle teste la valeur de la condition. Si elle
+est fausse, le bloc est ignoré et l'exécution continue avec la suite. Si la
+condition est vraie, le bloc est exécuté. Ensuite, la buggle réévalue la
+condition. Si elle est devenue fausse (par exemple parce que les
+déplacements du bloc nous ont mis face au mur), le bloc est maintenant
+ignoré et on continue avec la suite. Mais si la condition est toujours
+vraie, on exécute une nouvelle fois le bloc avant de réévaluer une fois de
+plus la condition. Cela continue ainsi tant que la condition reste vraie.</p>
+
+<p>Evidement, si l'action en question ne modifie pas la valeur de la condition,
+la buggle va exécuter l'action à l'infini. C'est dans ce genre de cas que le
+bouton <b>stop</b> de l'interface devient utile. Pour tester cela, vous
+pouvez essayer de taper le code suivant dans l'éditeur :</p>
+
+<pre>[!java|scala]while (true) {
+    gauche();
+}[/!][!python]while True:
+    gauche()[/!]</pre>
+
+<p>La buggle va tourner vers la gauche tant que
+<code>[!java|scala]true[/!][!python]True[/!]</code> est vrai (sans fin donc)
+jusqu'à ce que vous l'arrêtiez manuellement avec le bouton stop.</p>
+
+<h3>Objectif de cet exercice</h3>Il vous faut maintenant écrire le code nécessaire pour que vos buggles
+avancent jusqu'à rencontrer un mur. L'idée est donc de faire :
+<pre>tant que l'on est pas face à un mur, faire :
+  avancer();</pre>
+
+<p>Quand votre programme fonctionne, passez à l'exercice suivant.</p>
diff --git a/src/lessons/welcome/loopwhile/LoopWhile.html b/src/lessons/welcome/loopwhile/LoopWhile.html
new file mode 100644
index 0000000..97ffc2e
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/LoopWhile.html
@@ -0,0 +1,38 @@
+<h2>While loops</h2>
+		
+<p>In addition to conditionals, another handy construction is the ability to
+repeat an action while a specific condition does not appear. A while loop is
+used for that, with the following syntax.
+ 
+<pre>[!java|scala]while (<b>condition</b>) {
+    <b>action()</b>;
+}[/!][!python]while <b>condition</b>:
+    <b>action()</b>[/!]</pre>
+
+<p>The inner bloc is then executed again and again, as long as the condition remains true. 
+More specifically, the buggle tests the value of the condition. If it's false, it ignores the bloc and continue below. 
+If it's true, it executes the bloc.
+After that, it tests the condition. If it's now false 
+(for example because the moves of the block made us facing the wall), it now ignores the bloc and continue.
+If it's still true, it execute the bloc and reevaluate the condition. It does so as long as the condition remains true.</p>
+
+<p>Naturally, if the chosen action does not modify the value of the condition,
+the buggle will do the action endlessly. The <b>stop</b> button of the
+interface becomes then handy. To test this, you can try to type the
+following code in the editor:</p>
+
+<pre>[!java|scala]while (true) {
+    left();
+}[/!][!python]while True:
+    left()[/!]</pre>
+
+<p>This will let the buggle turn left as long as <code>[!java|scala]true[/!][!python]True[/!]</code> remains true (ie, endlessly),
+or until you stop it manually using the stop button.</p>
+
+<h3>Exercise goal</h3>You now have to write some code so that your buggles
+move forward until they encounter a wall. The idea is thus to do something
+like:
+<pre>while we are not facing a wall, do:
+  moveForward()</pre>
+
+<p>When your program works, move forward to the next exercise.</p>
diff --git a/src/lessons/welcome/loopwhile/LoopWhile.java b/src/lessons/welcome/loopwhile/LoopWhile.java
new file mode 100644
index 0000000..b572a74
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/LoopWhile.java
@@ -0,0 +1,28 @@
+package lessons.welcome.loopwhile;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class LoopWhile extends ExerciseTemplated {
+
+	public LoopWhile(Lesson lesson) {
+		super(lesson);
+		tabName = "Program";
+
+		BuggleWorld myWorld = new BuggleWorld("Closed world",7,7);
+		for (int i=0;i<7;i++) {
+			new Buggle(myWorld, "Joker "+(i+1), i, 6, Direction.NORTH, Color.black, Color.lightGray);
+			myWorld.putTopWall (i, 6-i);
+			myWorld.putLeftWall(i, 6-i);
+			myWorld.putLeftWall(0, i  );
+			myWorld.putTopWall (i, 0  );
+		}
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/loopwhile/LoopWhileEntity.java b/src/lessons/welcome/loopwhile/LoopWhileEntity.java
new file mode 100644
index 0000000..b7c3e17
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/LoopWhileEntity.java
@@ -0,0 +1,24 @@
+package lessons.welcome.loopwhile;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class LoopWhileEntity extends SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+	@Override
+	public void run() { 
+		/* BEGIN SOLUTION */
+		while (!isFacingWall())
+			forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/whileloop/LoopWhileEntity.py b/src/lessons/welcome/loopwhile/LoopWhileEntity.py
similarity index 100%
rename from src/lessons/welcome/loop/whileloop/LoopWhileEntity.py
rename to src/lessons/welcome/loopwhile/LoopWhileEntity.py
diff --git a/src/lessons/welcome/loopwhile/LoopWhileEntity.scala b/src/lessons/welcome/loopwhile/LoopWhileEntity.scala
new file mode 100644
index 0000000..419da4e
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/LoopWhileEntity.scala
@@ -0,0 +1,21 @@
+package lessons.welcome.loopwhile;
+
+import plm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game
+
+class ScalaLoopWhileEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument"));
+	}
+
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument"));
+	}
+
+	override def run() { 
+		/* BEGIN SOLUTION */
+		while (!isFacingWall())
+			forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoria-answer0.map b/src/lessons/welcome/loopwhile/WhileMoria-answer0.map
similarity index 100%
rename from src/lessons/welcome/loop/whileloop/WhileMoria-answer0.map
rename to src/lessons/welcome/loopwhile/WhileMoria-answer0.map
diff --git a/src/lessons/welcome/loopwhile/WhileMoria.fr.html b/src/lessons/welcome/loopwhile/WhileMoria.fr.html
new file mode 100644
index 0000000..e6650c5
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoria.fr.html
@@ -0,0 +1,23 @@
+<h2>Perdu dans la Moria</h2>
+		
+<p>Votre buggle est coincée dans une mine ! Des rochers bloquent la sortie, et
+il va falloir dégager le chemin pour passer. Bon, ok, ce ne sont pas
+vraiment des rochers mais juste des biscuits, et votre buggle pourrait
+facilement passer au dessus sans se fatiguer. Mais il est probablement plus
+simple de programmer votre buggle pour qu'elle déplace ces «rochers» plutôt
+que de tenter de la convaincre de passer à la suite sans avoir résolu le
+problème...</p>
+   
+<p>Donc, il vous faut trouver le premier biscuit en travers de votre chemin
+(marchez vers l'est jusqu'à vous trouver au dessus d'un biscuit), le
+ramasser, et retourner à l'autre extrémité du couloir pour le déposer
+(marchez vers l'ouest jusqu'à vous trouver au dessus d'un biscuit puis
+reculez d'un pas). Il faut ensuite faire de même pour tous les biscuits
+jusqu'à trouver la sortie. Une fois ceci fait, marchez vers l'air frais
+comme dans le monde objectif.</p>
+    
+<p>Quand vous serez parvenu à sortir de ce piège, vous pouvez passez à
+l'exercice suivant. Cet exercice est un peu plus difficile que les autres,
+et vous pouvez tout à fait le laisser momentanément de coté pour y revenir
+plus tard si vous n'y parvenez pas pour l'instant.</p>
+
diff --git a/src/lessons/welcome/loopwhile/WhileMoria.html b/src/lessons/welcome/loopwhile/WhileMoria.html
new file mode 100644
index 0000000..f04b84f
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoria.html
@@ -0,0 +1,19 @@
+<h2>Lost in the Moria</h2>
+		
+<p>You buggle got stuck in a mine! Some rocks are blocking the exit, 
+and you will have to clear your way to the exit. Well of course these 
+are only baggles and you could simply walk away, but it will be easier 
+to program your buggle so that it moves those "rocks" than convincing your buggle 
+that it could easily walk away without solving the problem...</p>
+   
+<p>So, you have to find the first baggle blocking the exit (simply walk 
+to the east until you are over a baggle), take it and move it back to the 
+other side of the tunnel (walk to the west while you are not over a baggle, 
+and then move back one step to the east and drop your baggle), and iterate 
+until you find the exit (that is, the wall to the east side). Afterward, 
+move out as in the objective world.</p>
+    
+<p>Once you manage to escape this trap, you can move forward to the next exercise.
+This exercise is a bit more complex, so you can also leave it for now and come 
+back later if you don't get it right now.</p>
+
diff --git a/src/lessons/welcome/loopwhile/WhileMoria.java b/src/lessons/welcome/loopwhile/WhileMoria.java
new file mode 100644
index 0000000..062d1f4
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoria.java
@@ -0,0 +1,26 @@
+package lessons.welcome.loopwhile;
+
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class WhileMoria extends ExerciseTemplated {
+
+	public WhileMoria(Lesson lesson) throws IOException, BrokenWorldFileException {
+		super(lesson);
+		tabName = "Balin";
+		
+		/* Create initial situation */
+		World[] myWorlds = new World[] {
+				BuggleWorld.newFromFile("lessons/welcome/loopwhile/WhileMoria"),
+		};
+		for (World w: myWorlds)
+			w.setDelay(50); // moving a bit faster than usual
+		
+		setup(myWorlds);
+	}
+}
diff --git a/src/lessons/welcome/loop/whileloop/WhileMoria.map b/src/lessons/welcome/loopwhile/WhileMoria.map
similarity index 100%
rename from src/lessons/welcome/loop/whileloop/WhileMoria.map
rename to src/lessons/welcome/loopwhile/WhileMoria.map
diff --git a/src/lessons/welcome/loopwhile/WhileMoriaEntity.java b/src/lessons/welcome/loopwhile/WhileMoriaEntity.java
new file mode 100644
index 0000000..9a4a647
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoriaEntity.java
@@ -0,0 +1,43 @@
+package lessons.welcome.loopwhile;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class WhileMoriaEntity extends SimpleBuggle {
+	@Override
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
+	}
+
+	@Override
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
+	}
+
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() { 
+		/* BEGIN SOLUTION */
+		back();
+		while (!isFacingWall()) {
+			while (!isOverBaggle() && !isFacingWall())
+				forward();
+			if (isOverBaggle()) {
+				pickupBaggle();
+				back();
+				while (!isOverBaggle())
+					forward();
+				backward();
+				dropBaggle();
+				back();
+				forward();
+			}
+		}
+		right();
+		forward();
+		left();
+		forward();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/loopwhile/WhileMoriaEntity.py b/src/lessons/welcome/loopwhile/WhileMoriaEntity.py
new file mode 100644
index 0000000..49be968
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoriaEntity.py
@@ -0,0 +1,19 @@
+# BEGIN SOLUTION
+back()
+while not isFacingWall():
+    while (not isOverBaggle()) and (not isFacingWall()):
+        forward()
+    if isOverBaggle():
+        pickupBaggle()
+        back()
+        while not isOverBaggle():
+            forward()
+        backward()
+        dropBaggle()
+        back()
+        forward()
+right()
+forward()
+left()
+forward()
+# END SOLUTION
diff --git a/src/lessons/welcome/loopwhile/WhileMoriaEntity.scala b/src/lessons/welcome/loopwhile/WhileMoriaEntity.scala
new file mode 100644
index 0000000..73824c2
--- /dev/null
+++ b/src/lessons/welcome/loopwhile/WhileMoriaEntity.scala
@@ -0,0 +1,37 @@
+package lessons.welcome.loopwhile;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaWhileMoriaEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument"));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument"));
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		back();
+		while (!isFacingWall()) {
+			while (!isOverBaggle() && !isFacingWall())
+				forward();
+			if (isOverBaggle()) {
+				pickupBaggle();
+				back();
+				while (!isOverBaggle())
+					forward();
+				backward();
+				dropBaggle();
+				back();
+				forward();
+			}
+		}
+		right();
+		forward();
+		left();
+		forward();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/methods/args/MethodsArgs.fr.html b/src/lessons/welcome/methods/args/MethodsArgs.fr.html
index 8462333..313a884 100644
--- a/src/lessons/welcome/methods/args/MethodsArgs.fr.html
+++ b/src/lessons/welcome/methods/args/MethodsArgs.fr.html
@@ -1,109 +1,83 @@
 <h2>Méthodes avec paramètres</h2>
 
-N'êtes vous pas fatigué d'écrire encore et encore le code qui permet
-d'avancer ou de reculer d'un nombre prédéterminé pas ? Oui, mais écrire les
-méthode <tt>forward2()</tt>, <tt>forward3()</tt>, <tt>forward4()</tt>, et
-<tt>backward2()</tt>, <tt>backward3()</tt>, <tt>backward4()</tt>, et ainsi
-de suite, ça ne constitue pas un réel gain de temps...
+<p>N'êtes vous pas fatigué d'écrire encore et encore le code qui permet
+d'avancer ou de reculer d'un nombre prédéterminé de pas ? Oui, mais écrire
+les méthode <tt>avance2()</tt>, <tt>avance3()</tt>, <tt>avance4()</tt>, et
+<tt>recule2()</tt>, <tt>recule3()</tt>, <tt>recule4()</tt>, et ainsi de
+suite, ça ne constitue pas un réel gain de temps. Et puis, c'est carrément
+moche !</p>
 
 <p>Heureusement, il est possible de donner des <b>paramètres</b> à vos
 méthodes. Il faut marquer leur type et leur nom entre les parenthèses qui
 suivent le nom de la méthode. Ensuite, on peut les utiliser dans le corps de
-la fonction comme s'il s'agissait de variables définies ici.
+la fonction comme s'il s'agissait de variables définies ici.</p>
 
-<pre class="Java">double diviseParDeux(double x) {
-  return x / 2;
-}</pre>
-
-<pre class="Python">def diviseParDeux(x):
-  return x / 2
-</pre>
+<pre>[!java]double [/!]diviseParDeux([!java]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala]{[/!][!python]:[/!]
+     return x / 2[!java];[/!]
+[!scala|java]}[/!]</pre>
 
 <p>À l'usage, il faut indiquer les valeurs qu'elles doivent prendre entre les
-parenthèses de l'appel.
-<pre class="Java">double y = diviseParDeux(3.14);</pre>
-
-<pre class="Python">y = diviseParDeux(3.14);</pre>
-
+parenthèses de l'appel.</p>
+<pre>[!java]double [/!][!scala]val [/!]result = diviseParDeux(3.14)[!java];[/!]</pre>
 
 <p>Si on veut avoir plusieurs paramètres, il faut les séparer par des virgules,
-lors de la déclaration comme lors de l'appel.
-
-<pre class="Java">double divise(double x, double y) {
-  return x / y;
-}</pre>
-<pre class="Java">double y = divise(3.14 , 1.5);</pre>
-
-<pre class="Python">def divise(double x, double y):
-  return x / y
-}</pre>
-<pre class="Python">y = divise(3.14 , 1.5);</pre>
-
-
-<p class="Java">En Java, il est possible d'avoir plusieurs méthodes du même nom, à condition
-qu'elles n'aient pas le même nombre et les mêmes types de paramètres (on dit
-qu'elles n'ont pas la même <b>signature</b>).
-<pre class="Java">int max(int x, int y) {
-  if (x > y) {
-    return x;
-  }
-  return y;
+lors de la déclaration comme lors de l'appel.</p>
+
+<pre>[!java]double divise(double x, double y) {[/!]
+[!scala]def divise(x:Double, y:Double): Double = {[/!]
+[!python]def divise(x, y):[/!]
+     return x / y[!java];[/!]
+[!java|scala]}[/!]</pre>
+<pre>[!java]double res = divise(3.14 , 1.5);[/!]
+[!scala]val res = divise(3.14 , 1.5)[/!]
+[!python]res = divise(3.14 , 1.5)[/!]</pre>
+
+[!java|scala]
+<p>En [!thelang], il est possible d'avoir plusieurs méthodes du même nom, à
+condition qu'elles n'aient pas la même <b>signature</b>, c'est à dire le
+même nombre de paramètres et les mêmes types de paramètres.</p>
+
+<pre>[!java]double max(double x, double y)[/!][!scala]def max(x:Double, int y:Double): Double =[/!] {
+  if (x > y) {
+    return x;
+  }
+  return y;
+}[!java]int max(int x, int y)[/!][!scala]def max(x:Int, int y:Int): Int =[/!] {
+  if (x > y) {
+    return x;
+  }
+  return y;
 }
-int max(int x, int y, int z) {
-  if (x > y && x > z) {
-    return x;
-  }
-  if (y > z) {
-    return y;
-  }
-  return z;
+[!java]int max(int x, int y; int z)[/!][!scala]def max(x:Int, int y:Int, int z:Int): Int =[/!] {
+  if (x > y && x > z) {
+    return x;
+  }
+  if (y > z) {
+    return y;
+  }
+  return z;
 }</pre>
 
-
-
-<!-- introduce default value for parameters in Python language -->
-<p class="Java">Remarquez que nous avons ici laissé de coté les <tt>else</tt> de chaque
+<p>Remarquez que nous avons ici laissé de coté les <tt>else</tt> de chaque
 alternative. Cela fonctionne tout de même car un <tt>return</tt> interrompt
 l'exécution de la méthode. Si on arrive à la dernière ligne de
-<code>max(int,int)</code>, on est donc sur que <code>x<=y</code> car dans
-le cas contraire, le <tt>return</tt> de la deuxième ligne aurait arrêté
-l'exécution de la fonction.</p>
-
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> Il s'agit cette fois d'écrire une méthode
-<code>move(int nbPas, boolean forward)</code> qui avance de
-<code>nbPas</code> si <code>forward</code> est vrai, et recule d'autant de
-pas si le booléen est faux. La buggle s'en servira pour retourner sur la
-ligne du haut. Elle utilisera au passage des méthodes que l'on ne connaît
-pas encore pour deviner sa position et sa direction actuelles afin de
-calculer le sens et le nombre de pas à faire (mais ce n'est pas important
-ici).
-
-<p>Cette fois, il y a un seul monde, et sept buggles. Mais ça ne change pas
-grand chose pour vous, puisque toutes sont ici régies par le même code.</p>
+<code>[!java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>, on est
+donc sûr que <code>x<=y</code> car dans le cas contraire, le
+<tt>return</tt> de la deuxième ligne aurait arrêté l'exécution de la
+fonction.</p>
+<!-- introduce default value for parameters in Python language -->
+[/!]
 
-<p>Le code de la méthode à proprement parler ne devrait pas poser de problème.</p>
 
-<h2>Et ensuite?</h2>
-<p>Vous connaissez maintenant les bases de la programmation. Disons au moins
-que vous avez vu les concepts les plus important et que vous devriez être
-capable de lire et comprendre la plupart des programmes écrits. Pour plus de
-sécurité, vous devriez faire les autres exercices de cette leçon pour
-solidifier vos acquis en les réutilisant dans diverses situations. Après
-cela, vous maîtriserez ce qu'on appelle la "programmation tactique", ce qui
-veut dire que votre maîtrise de la syntaxe vous permettra de vous concentrer
-sur les problèmes à résoudre sans vous battre contre le compilateur à propos
-de la syntaxe. Certains de ces exercices sont même amusants à résoudre ;)
 
-<p>Si vous êtes pressés et voulez plus, vous pouvez sauter ces exercices et
-passer directement à des exercices plus complets et plus intéressants. Par
-exemple, la leçon sur les <i>Labyrinthes</i> vous apprendra à sortir d'un
-labyrinthe. Les algorithmes impliqués ne sont pas ultra complexes, mais vous
-serez amenés à améliorer votre code à plusieurs reprises afin de pouvoir
-sortir de n'importe quel type de labyrinthe. La leçon <i>LightBot</i> est un
-petit jeu de programmation où vous contrôlez un robot voulant éclairer le
-monde. Comme il est programmé graphiquement et non dans un language
-syntaxique, les premiers exercices peuvent être utilisés comme une
-introduction à ce que programmer veut dire pour les débutants. Mais les
-derniers exercices sont plus difficiles et devraient constituer des
-casse-têtes même pour les programmeurs professionnels.</p>   
+<h3>Objectif de cet exercice</h3>
+<p>Cette fois, vous devez écrire une méthode
+<code>[!java]deplace(int nbPas,boolean versLAvant)[/!]
+[!scala]deplace(nbPas: Int,versLAvant: Boolean)[/!]
+[!python]deplace(nbPas,versLAvant)[/!] </code> qui se déplace de
+<code>nbPas</code> pas. Si <code>versLAvant</code> est vrai, il faut avancer
+de ce nombre de pas; dans le cas contraire, il faut reculer.</p>
 
+<p>Cette fois, il y a un seul monde, et sept buggles, qui exécutent toutes le
+code que vous allez écrire.
+Cet exercice ne devrait pas vous poser de problème particulier.</p>
diff --git a/src/lessons/welcome/methods/args/MethodsArgs.html b/src/lessons/welcome/methods/args/MethodsArgs.html
index 7a01bc1..979da04 100644
--- a/src/lessons/welcome/methods/args/MethodsArgs.html
+++ b/src/lessons/welcome/methods/args/MethodsArgs.html
@@ -1,98 +1,79 @@
-<h2>Methods with parameters</h2>
-
-Don't you get tired of writing again and again the code to move by a fixed
-amount of steps? On the other hand, writing <tt>forward2()</tt>,
-<tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>,
-<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help
-
-<p>Luckily, it is possible to pass <b>parameters</b> to your methods. You have
-to specify their type and name between the parenthesis after the method
-name. Then, you can use them in the method body as if it were variables
-defined in there, and which initial value is what the caller specified.
-
-<pre class="Java">double divideByTwo(double x) {
-  return x / 2;
-}</pre>
-
-<pre class="Python">def divideByTwo(x):
-  return x / 2
-</pre>
-
-<p>As caller, you have to specify the initial value of this "variables" between
-the call's parenthesis.
-<pre class="Java">double y = divideByTwo(3.14);</pre>
-
-<pre class="Python">y = divideByTwo(3.14)</pre>
-
-
-<p>If you want several parameters, you need to separate them with comas (,)
-both in the declaration and calls.
-
-<pre class="Java">double divide(double x, double y) {
-  return x / y;
-}</pre>
-<pre class="Java">double y = divide(3.14 , 1.5);</pre>
-
-<pre class="Python">def divide(double x, double y):
-  return x / y
-}</pre>
-<pre class="Python">y = divide(3.14 , 1.5)</pre>
-
-
-<p class="Java">In Java, you can declare several methods of the same name as long as they
-don't have the same parameter types and number (they are said to have
-different <b>signature</b>).
-<pre class="Java">int max(int x, int y) {
-  if (x > y) {
-    return x;
-  }
-  return y;
-}
-int max(int x, int y, int z) {
-  if (x > y && x > z) {
-    return x;
-  }
-  if (y > z) {
-    return y;
-  }
-  return z;
-}</pre>
-
-<!-- introduce default value for parameters in Python language -->
-
-<p class="Java">Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It
-works anyway because a <tt>return</tt> interrupts the method execution. If
-we arrive to the last line of <code>max(int,int)</code>, we know that
-<code>x<=y</code> because on the other case, the <tt>return</tt> of line
-2 would have stopped the execution.</p>
-
-<h3>Exercise goal</h3>This time, you have to write a <code>move(int stepCount,boolean
-forward)</code> method which move forward of <code>stepCount</code> if
-<code>forward</code> is true, and move back of that amount of steps if the
-boolean is false. The buggle will use some methods we did not introduce yet
-to guess its position and orientation in order to determine the amount of
-steps to do and their direction, but it is not relevant here.
-
-<p>This time, there is only one world, and seven buggles. But it does not
-change anything for you, since the same code is used for any buggles.</p>
-
-<p>The code of the method to write should not be really problematic for you.</p>
-
-<h2>What's coming next?</h2>
-<p>You now know the very basics of programming. At least, we introduced all the important 
-concepts, and you should be able to read most code by now. If you want to play safe, you 
-should proceed to the next exercises of this lesson to solidify your knowledge by reusing 
-these concepts in various simple situations. After taking them, you'll master what's called 
-"Tactical programming", meaning that you will master the syntax enough to not have any 
-issue with it, allowing you to focus on the fundamental problems of what you want to solve 
-instead of struggling with syntaxic difficulties. Some of these exercises are even fun to do ;)
-
-<p>If you are in a hurry and want more, you can skip these exercises and proceed directly 
-to more interesting challenges. For example, the <i>Labyrinths</i> lesson will teach you 
-about maze escaping algorithms, which are not rocket science but require several improvements 
-to work for any kind of maze. The <i>Lightbot</i> lesson is a little programming game where 
-you control a little robot wanting to light the world. Since it is not programmed in a language 
-but graphically, the first exercises can be used as an introduction activity to what 
-programming means for real beginners, but the last exercises constitute challenges and 
-brain teaser even to professional programmers.</p>   
-
+<h2>Methods with parameters</h2>
+
+<p>Don't you get tired of writing again and again the code to move by a fixed
+amount of steps? On the other hand, writing <tt>forward2()</tt>,
+<tt>forward3()</tt>, <tt>forward4()</tt>, as well as <tt>backward2()</tt>,
+<tt>backward3()</tt>, <tt>backward4()</tt>, and so on does not really help, 
+to say the less.</p>
+
+<p>Luckily, it is possible to pass <b>parameters</b> to your methods. You have
+to specify their type and name between the parenthesis after the method
+name. Then, you can use them in the method body as if it were variables
+defined in there, and which initial value is what the caller specified.</p>
+
+<pre>[!java]double [/!]divideByTwo([!java]double [/!]x[!scala]: Double[/!])[!scala]: Double =[/!] [!java|scala]{[/!][!python]:[/!]
+     return x / 2[!java];[/!]
+[!scala|java]}[/!]</pre>
+
+<p>As caller, you have to specify the initial value of this "variables" between
+the call's parenthesis.</p>
+<pre>[!java]double [/!][!scala]val [/!]result = divideByTwo(3.14)[!java];[/!]</pre>
+
+<p>If you want several parameters, you need to separate them with comas (,)
+both in the declaration and calls.</p>
+
+<pre>[!java]double divide(double x, double y) {[/!]
+[!scala]def divide(x:Double, y:Double): Double = {[/!]
+[!python]def divide(x, y):[/!]
+     return x / y[!java];[/!]
+[!java|scala]}[/!]</pre>
+<pre>[!java]double res = divide(3.14 , 1.5);[/!]
+[!scala]val res = divide(3.14 , 1.5)[/!]
+[!python]res = divide(3.14 , 1.5)[/!]</pre>
+
+[!java|scala]
+<p>In [!thelang], you can declare several methods of the same name as long as
+they don't have the same <b>signature</b>, that is, the same amount of 
+parameters and the same parameters' types.</p>
+
+<pre>[!java]double max(double x, double y)[/!][!scala]def max(x:Double, int y:Double): Double =[/!] {
+  if (x > y) {
+    return x;
+  }
+  return y;
+}[!java]int max(int x, int y)[/!][!scala]def max(x:Int, int y:Int): Int =[/!] {
+  if (x > y) {
+    return x;
+  }
+  return y;
+}
+[!java]int max(int x, int y; int z)[/!][!scala]def max(x:Int, int y:Int, int z:Int): Int =[/!] {
+  if (x > y && x > z) {
+    return x;
+  }
+  if (y > z) {
+    return y;
+  }
+  return z;
+}</pre>
+
+<p>Observe that we omitted the <tt>else</tt> branches of each <tt>if</tt>. It
+works anyway because a <tt>return</tt> interrupts the method execution. If
+we arrive to the last line of <code>[!java]max(int,int)[/!][!scala]max(Int,Int):Int[/!]</code>,
+we know that <code>x<=y</code> because otherwise, the <tt>return</tt> of line
+2 would have stopped the execution.</p>
+[/!]
+
+<!-- introduce default value for parameters in Python language -->
+
+<h3>Exercise goal</h3>
+<p>This time, you have to write a <code>
+[!java]move(int stepCount,boolean forward)[/!]
+[!scala]move(stepCount: Int,forward: Boolean)[/!]
+[!python]move(stepCount,forward)[/!]
+</code> method which moves forward by <code>stepCount</code> steps if
+<code>forward</code> is true, and moves back of that amount of steps if the
+boolean is false.</p>
+
+<p>This time, there is only one world but seven buggles, all sharing the same code.
+This code should not be really problematic for you to write, actually.</p>
diff --git a/src/lessons/welcome/methods/args/MethodsArgs.java b/src/lessons/welcome/methods/args/MethodsArgs.java
index d88e34b..7e2bbce 100644
--- a/src/lessons/welcome/methods/args/MethodsArgs.java
+++ b/src/lessons/welcome/methods/args/MethodsArgs.java
@@ -2,11 +2,11 @@ package lessons.welcome.methods.args;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class MethodsArgs extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/methods/args/MethodsArgsEntity.java b/src/lessons/welcome/methods/args/MethodsArgsEntity.java
index a787051..dc0ca8a 100644
--- a/src/lessons/welcome/methods/args/MethodsArgsEntity.java
+++ b/src/lessons/welcome/methods/args/MethodsArgsEntity.java
@@ -1,17 +1,17 @@
 package lessons.welcome.methods.args;
 
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.Direction;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class MethodsArgsEntity extends SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
 	}
-
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
 	}
 
 
diff --git a/src/lessons/welcome/methods/args/MethodsArgsEntity.scala b/src/lessons/welcome/methods/args/MethodsArgsEntity.scala
new file mode 100644
index 0000000..de02cae
--- /dev/null
+++ b/src/lessons/welcome/methods/args/MethodsArgsEntity.scala
@@ -0,0 +1,33 @@
+package lessons.welcome.methods.args;
+
+import plm.universe.Direction
+import plm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game
+
+class ScalaMethodsArgsEntity extends SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+
+	override def run() { 
+		move(getY(),getDirection() == Direction.NORTH); 
+	} 
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def move(steps: Int, fwd:Boolean) {
+		if (fwd) {
+			for (i <- 1 to steps) 
+				forward()
+		} else {
+			for (i <- 1 to steps) 
+				backward()
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/basics/Methods.fr.html b/src/lessons/welcome/methods/basics/Methods.fr.html
index 2f28511..d0a22a2 100644
--- a/src/lessons/welcome/methods/basics/Methods.fr.html
+++ b/src/lessons/welcome/methods/basics/Methods.fr.html
@@ -5,105 +5,134 @@ Nous allons maintenant voir comment écrire nos propres méthodes. Il s'agit
 en quelque sorte d'étendre le vocabulaire de la buggle en lui apprenant à
 faire de nouvelles choses. 
 </p>
-<p>Par exemple, nous avons vu à l'exercice précédent comment demander à la
-buggle d'aller chercher la buggle qui se trouve devant elle, et la ramener à
-sa position initiale. S'il y a maintenant plusieurs baggles sur le plateau,
-et que nous voulons tous les ramener sur la ligne du bas, il faut soit
-répéter ce code plusieurs fois, soit l'inclure dans une boucle. Dans les
-deux cas, le code résultant n'est pas très lisible, et il serait mieux que
-la buggle comprenne un ordre de type <code>goAndGet()</code> tout comme elle
-comprend un <code>forward()</code>.</p>
-
-
-<p class="Python">La syntaxe pour écrire une méthode simple nommée <code>goAndGet</code> est
-la suivante:
-<pre class="Python">public void goAndGet() {
-  actions();
-  aFaire();
-}</pre>
-<p class="Java">La syntaxe pour écrire une méthode simple nommée <code>goAndGet</code> est
-la suivante:
-<pre class="Java">public void goAndGet() {
-  actions();
-  aFaire();
-}</pre>
-
-<p class="Java">Le corps de la méthode (entre les accolades) peut contenir autant
-d'instructions que vous le souhaitez, et toutes les constructions vues
-jusque là (for, while, if, etc).</p>
-<p class="Python">Le corps de la méthode (entre les accolades) peut contenir autant
-d'instructions que vous le souhaitez, et toutes les constructions vues
-jusque là (for, while, if, etc).</p>
-
-<p class="Java">Nous reviendrons plus tard sur le sens exact du mot-clé
-<code>public</code>. Disons simplement pour l'instant qu'il indique que tout
-le monde a le droit d'utiliser cette méthode.</p>
-
-<p class="Java"><code>void</code> indique quant à lui que la méthode ne donne pas de
-résultat. Nous avions vu que la méthode <code>isOverBaggle()</code> renvoie
-un booléen, et peut donc être utilisé comme une condition dans un if ou un
-while. Cela signifie qu'elle a été déclarée de la façon suivante :
-<pre class="Java">public boolean isOverBaggle() { ... }</pre>
-
-<p class="Java">Nous verrons dans le prochain exercice comment faire ce genre de chose. Pour
-l'instant, contentons nous d'écrire ce <code>void</code> à cet endroit.</p>
-
-<p class="Java">En Java, il est d'usage de mettre la première lettre du nom d'une méthode en
-minuscules, et de coller tous les mots décrivant la méthode les uns aux
-autres en mettant une majuscule à chacun. Il est interdit de mettre des
-espaces ou des accentués dans le nom d'une méthode. C'est pourquoi nous
-écrivons "go and get" sous la forme "goAndGet".</p>
-
- 
-<p class="Python">
-	 
-	<!--FIXME: add here a word about the variable naming schema. Either caseBased or as_in_C -->
+<p>Par exemple, nous avons vu dans un exercice précédent comment demander à la
+buggle d'aller chercher le biscuit qui se trouve devant elle, et la ramener
+à sa position initiale. S'il y a maintenant plusieurs biscuits sur le
+plateau, et que nous voulons tous les ramener sur la ligne du bas, il faut
+soit répéter ce code plusieurs fois, soit l'inclure dans une boucle. Dans
+les deux cas, il faut que vous évitiez de dupliquer votre code pour qu'il
+reste simple et lisible. Il serait mieux que la buggle comprenne un ordre de
+type <code>vaChercher()</code> tout comme elle comprend un
+<code>avance()</code>.</p>
+
+<h3>Définir des méthodes</h3>
+
+<p>La syntaxe [!thelang] pour écrire une méthode simple nommée
+<code>vaChercher</code> est la suivante:</p>
+<pre>[!java]void vaChercher() {[/!][!python]def vaChercher():[/!][!scala]def vaChercher() {[/!]
+  actions()[!java];[/!]
+  encoreDesActions()[!java];[/!]
+  dautresTrucs()[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>Le corps de la méthode
+[!java|scala](c'est-à-dire le bloc entre accolades)[/!]
+[!python](c'est-à-dire le bloc indenté)[/!]
+sera exécuté à chaque appel de cette méthode (c'est-à-dire à chaque fois que
+nous écrirons <code>vaChercher()</code> quelque part dans notre code).
+Ce corps de boucle peut contenir autant d'instructions que l'on veut, et
+toutes les constructions que nous avions vu jusque là (comme lesboucles et
+les conditionnelles).
+[!java]Le mot-clé <code>void</code> («néant» en anglais) signifie que cette
+méthode ne renvoie pas de résultat. Au contraire, la méthode
+<code>estSurBiscuit()</code> renvoie un résultat booleen indiquant si nous
+nous trouvons oui ou non sur un biscuit. Nous apprendrons bientôt à faire de
+telles méthodes. En attendant, écrivez juste <code>void</code> à cet
+endroit.[/!]
 </p>
 
-
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> L'objectif de cet exercice est donc d'écrire une
-méthode nommée <code>goAndGet()</code> et qui fait la même chose qu'aux
-exercices précédents (avance tant qu'on ne trouve pas de baggle, ramasser le
-baggle, reculer à la case départ, poser le baggle).
-
-<p class="Python">La particularité de cet exercice est que tout votre code doit être écrit
-dans cette fonction, avec rien en dehors. Le code qui appelle votre fonction
-sera automagiquement ajouté quand vous cliquerez sur <b>Start</b>.</p>  
+<h3>Documenter les méthodes</h3>
+
+<p>Vous devez toujours vous efforcer de documenter votre code pour qu'il reste
+lisible. À l'instant où vous l'écrivez, son objectif et ses limitations vous
+semblent clairs, mais la plupart du temps, ça ne dure pas. On oublie vite
+les détails d'une méthode particulier, et quand cela arrive, on est content
+de pouvoir lire sa documentation.
+Dans l'exemple ci-dessous, nous utilisons le formalisme spécifique de
+[!java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], un programme qui
+extrait la documentation du code source pour en faire de belles pages
+web. Le principal avantage de cette approche est que la documentation se
+trouve à coté du code. Donc, quand on change le code, il y a un peu plus de
+chance pour qu'on pense à mettre la documentation à jour.</p>
+
+<p>[!java|scala]Les commentaires [!java]javadoc[/!][!scala]scaladoc[/!]
+commencent avec le marqueur <code>/**</code> (avec deux étoiles). Ces
+commentaires doivent être placés juste avant la méthode qu'ils documentent
+pour que l'outil les trouve[/!]
+[!python]Les commentaire pydoc doivent être placés au début du corps de la
+méthode pour que l'outil les trouve. Ils doivent être placés entre
+<code>"""</code>, qui marquent les chaînes de caractères sur plusieurs
+lignes en python.[/!]
+La première ligne devrait décrire brièvement la méthode tandis que le reste
+de la documentation devrait donner tous les points importants de la méthode.</p>
+
+<pre>[!java|scala]/**
+ *  Avance, récupère le biscuit, et le ramène à la position d'origine
+ *
+ *  Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur.
+ */[/!]
+[!java]void goAndGet() {[/!]
+[!scala]def goAndGet() {[/!]
+[!python]def goAndGet():
+  """Avance, récupère le biscuit, et le ramène à la position d'origine
+
+  Ne vérifie pas la présence de mur; à ne pas l'utiliser en cas de risques de mur."""[/!]
+  actions()[!java];[/!]
+  to()[!java];[/!]
+  do()[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<h3>Conventions de nommage</h3>
+<p>La plupart des langages de programmation interdisent d'utiliser des espaces
+dans les noms de variables et de méthodes. Certains langages (comme le
+[!thelang]) autorisent l'usage des caractères accentués dans ces
+identificateurs, mais cela pose parfois des problèmes de portabilité entre
+les systèmes d'exploitation. C'est pourquoi PLM n'utilise pas d'accents dans
+les identificateurs, même si c'est parfois désagréable en français.</p>
+
+<p>Parmi tous les langages de programmation, il y a deux conventions de nomage
+majeures. La première consiste à concaténer tous les mots en ne laissant que
+la première lettre de chaque mot en majuscule. «va chercher le biscuit»
+devient VaChercherLeBiscuit(). Cette convention est nommée CamelCase en
+anglais, c'est-à-dire casse du chameau, car les identificateurs écrits de
+cette façon font un peu penser au dos d'un chameau. L'autre convention,
+nommée snake_case (casse du serpent), consiste à concaténer tous les mots en
+minuscule en les séparant du caractère souligné (_). «va chercher le
+biscuit» devient va_chercher_le_biscuit().</p>
+
+<p>Le choix de la convention de nommage est le sujet de «discussions» très
+animées entre programmeurs, mais certaines habitudes prédominent pour chaque
+langage. En Python, Ruby, Perl ou en langage C, la casse_du_serpent
+prédomine pour les noms de variables et de méthodes. En Java et en Scala, on
+préfère habituellement la casseDuChameau, en laissant la toute première
+lettre en minuscule.</p> 
+<p>La casseDuChameau est utilisé partout dans PLM car c'est un programme écrit
+en Java à la base, et que nous avons gardé nos habitudes en écrivant le
+support pour d'autres langages. Mais nous considérons le fait Python ne soit
+pas en casse_du_serpent comme un bug, que nous corrigerons dans une version
+future.</p>
+
+<h3>Objectif de cet exercice</h3>
+<p>L'objectif de cet exercice est donc d'écrire une méthode nommée
+<code>goAndGet()</code> (va chercher) et qui fait la même chose que dans un
+exercice précédent (avance tant qu'on ne trouve pas de baggle, ramasser le
+baggle, reculer à la case départ, poser le baggle).</p>
+
+<p>La particularité de cet exercice est que vous n'écrivez pas directement le
+code que votre buggle va exécuter, mais une méthode qui sera appelée quand
+vous appuyez sur <b>Exécuter</b>. Pour votre information, le code appelant a
+la forme suivante:</p>
   
-<p class="Java">La particularité de cet exercice est que vous n'allez donc pas écrire
-directement le code que la buggle va exécuter, mais une méthode qu'elle
-utilisera. En fait, dans tous les exercices précédents, vous avez écrit le
-corps d'une méthode particulière de la buggle nommée <code>run()</code> et
-qui est invoquée par l'environnement quand on clique sur le bouton
-<b>Start</b>.</p> 
-
-<p>N'essayez pas de définir ici cette méthode, puisque la buggle la connaît
-déjà. Cela troublerait le compilateur qui vous donnerait un message d'erreur
-en échange. Pour information, voici le corps de la méthode
-<code>run()</code> de la buggle de cet exercice:
-
-<pre class="Java">public void run() {
-  for (int i=0; i<7; i++) { 
-    goAndGet();
-    turnRight();
-    forward();
-    turnLeft();
-  }
-}</pre>
-<pre class="Pyhton">def run():
-  for i in range(7): 
-    goAndGet()
-    turnRight()
-    forward()
-    turnLeft()
-  
-}</pre>
+<pre>[!java]for (int i=0; i<7; i++) {[/!][!python]for i in range(7):[/!][!scala]for (i <- 1 to 7) {[/!]
+    goAndGet()[!java];[/!]
+    droite()[!java];[/!]
+    avance()[!java];[/!]
+    gauche()[!java];[/!]
+[!java|scala]}[/!]</pre>
 
-
-</p>
 <p>Donc, votre buggle va répéter 7 fois (la taille du monde)  l'opération
 <code>goAndGet()</code> que vous allez écrire, plus les opérations
-nécessaire à se décaler d'une colonne vers la droite (tourner à droite,
+nécessaires pour se décaler d'une colonne vers la droite (tourner à droite,
 avancer, tourner à gauche). Notez que la buggle va donc faire un pas vers la
 droite alors qu'elle sera tout à droite du monde. Cela la ramènera sur le
 bord gauche, car le monde des buggles est torique.</p>
diff --git a/src/lessons/welcome/methods/basics/Methods.html b/src/lessons/welcome/methods/basics/Methods.html
index ae243e8..73ad759 100644
--- a/src/lessons/welcome/methods/basics/Methods.html
+++ b/src/lessons/welcome/methods/basics/Methods.html
@@ -1,106 +1,120 @@
-<h2>Methods</h2>
-
-<p>
-We will now write our own methods. It somehow comes down to extending the
-buggle vocabulary by learning it new tricks. 
-</p>
-<p>For example, we saw in previous exercise how to ask the buggle to go get the
-baggle in front of it, and bring it back. If there is several baggles on the
-board, and if we want to bring all of them on the bottom line, you have to
-repeate this code several times, or include it in a loop. In any case, the
-result may reveal unpleasant to read, and it would be better if the buggle
-could obey an <code>goAndGet()</code> order just like it understands a
-<code>forward()</code> one.</p>
-
-
-<p class="Python">The syntax to write a simple method called <code>goAndGet</code> is the
-following:
-<pre class="Python">def goAndGet():
-  actions();
-  to();
-  do();</pre>
-<p class="Java">The syntax to write a simple method called <code>goAndGet</code> is the
-following:
-<pre class="Java">public void goAndGet() {
-  actions();
-  to();
-  do();
-}</pre>
-
-<p class="Java">The method body (between curly braces) can contain as many instructions as
-you want, and any construction we saw so far (for, while, if, etc).</p>
-<p class="Python">The method body (the code that is indended) can contain as many instructions as
-you want, and any construction we saw so far (for, while, if, etc).</p>
-
-<p class="Java">We will come back later on the exact signification of the
-<code>public</code> keyword. Let's say for now that it means that everybody
-can use this method.</p>
-
-<p class="Java"><code>void</code> means that the method does not return any result. We said
-previously that the <code>isOverBaggle()</code> method returns a boolean and
-can thus be used as a condition in a if or a while. This means that it is
-declared the following way:
-<pre class="Java">public boolean isOverBaggle() { ... }</pre>
-
-<p class="Java">We will introduce in next exercise how to do this kind of tricks. For now,
-let's just write <code>void</code> at this location.</p>
-
-<p class="Java">In Java, the convention is to use lower case for the first letter of a
-method name and concatenate every word describing the method using a upper
-case for each first letter. It is forbidden to use spaces or accentuated
-letters in a method name. That is why we write "go and get" as goAndGet().</p>
-
- 
-<p class="Python">
-	<!--FIXME: add here a word about the variable naming schema. Either caseBased or as_in_C --> 
-	</p>
-
-
-<h3>Exercise goal</h3><a name="Objectives"> The goal of this exercise is to write a method called
-<code>goAndGet()</code> which does the same than in previous exercises (move
-forward until over a baggle, pick it up, move back to initial position, drop
-baggle).
-
-<p class="Python">One particularity of this exercise is that all your code should be written in 
-  this function, with nothing out of it. The code that calls your function will be automagically added 
-  when you click on <b>Start</b>.</p>  
-  
-<p class="Java">One particularity of this exercise is that you shouldn't write directly the
-code that the buggle should execute, but a method it should use. Actually,
-in any previous exercise, you wrote the body of a specific method called
-<code>run()</code> which gets invoked by the environment when you click on
-<b>Start</b>.</p> 
-
-<p>Don't try to define this method here, since the buggle already knows
-it. This would cause trouble to the compiler, which would give you an error
-message in exchange. For your information, here is the <code>run()</code>
-method of this exercise:
-
-<pre class="Java">public void run() {
-  for (int i=0; i<7; i++) { 
-    goAndGet();
-    turnRight();
-    forward();
-    turnLeft();
-  }
-}</pre>
-<pre class="Pyhton">def run():
-  for i in range(7): 
-    goAndGet()
-    turnRight()
-    forward()
-    turnLeft()
-  
-}</pre>
-
-
-</p>
-<p>Your buggle will repeat 7 times (which matches the world's dimension)
-sequence constituted of a call to the <code>goAndGet()</code> method that you should
-write, plus a move to get to the next row (turn right, move
-forward, turn left). As you can see, the buggle will do one step right from
-the right border of the world. It will bring it back to the left side since
-its world is a torus.</p>
-
-<p>You should now write this goAndGet() method.</p>
-
+<h2>Methods</h2>
+
+<p>
+We will now write our own methods. It somehow comes down to extending the
+buggle vocabulary by learning it new tricks. 
+</p>
+<p>For example, we saw in a previous exercise how to ask the buggle to go get the
+baggle in front of it, and bring it back. If there is several baggles on the
+board, and if we want to bring all of them on the bottom line, you have to
+repeat this code several times, or include it in a loop. In any case, you should avoid
+to duplicate your code to keep it pleasant to read and easily understandable.
+It would be better if the buggle could obey an <code>goAndGet()</code> order 
+just like it understands a <code>forward()</code> one.</p>
+
+<h3>Defining methods</h3>
+
+<p>The [!thelang] syntax to write a simple method called <code>goAndGet</code> is the
+following:</p>
+<pre>[!java]void goAndGet() {[/!][!python]def goAndGet():[/!][!scala]def goAndGet() {[/!]
+  actions()[!java];[/!]
+  to()[!java];[/!]
+  do()[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>The method body 
+[!java|scala](between curly braces)[/!][!python](the indented block)[/!] will be
+executed when we call the method later on (that is, when we write
+<code>goAndGet()</code> somewhere in our code). This method body  
+can contain as many instructions as you want, and any construction we saw so far 
+(for, while, if, etc). 
+[!java]The <code>void</code> keyword means that this method does not return any
+result. For example, the <code>isOverBaggle()</code> method does return a result,
+which is a boolean indicating whether or not the buggle is located over a baggle. We
+will soon learn to define such methods too. For now, just write <code>void</code> at
+this location.[/!]
+</p>
+
+<h3>Documenting methods</h3>
+
+<p>You should strive to document your code to keep it readable. When you
+write it, its purpose and limitations are clear to you, but most of the time, this does not
+last for long. You will soon forget about the details of every specific method, and this day
+you will be happy to read its documentation. In the following example, we use the 
+specific formalism of [!java]javadoc[/!][!scala]scaladoc[/!][!python]pydoc[/!], a program 
+that extracts the documentation of [!thelang] source code to produce html pages. The
+main advantage is that it allows to keep the documentation near to the code.  So, when
+you change your code, you have less chances to forget to update the documentation.</p>
+
+<p>[!java|scala][!java]javadoc[/!][!scala]scaladoc[/!] comments begin with the
+<code>/**</code> marker (with two asterisks). They must be placed right before the
+method they document for the tool to find them.[/!]
+[!python]pydoc comments should be placed at the beginning of the method body so that
+the tool finds them. They should be placed between <code>"""</code>, which mark 
+multi-line strings in python.[/!]
+The first line should  be a brief description of what this method does while any subsequent
+lines should provide any important details about the method.</p>
+
+<pre>[!java|scala]/**
+ *  Go, retrieves the baggle in front of the buggle, and brings it back 
+ *
+ *   Does not check for walls, so be careful to not call it when walls are present.
+ */[/!]
+[!java]void goAndGet() {[/!]
+[!scala]def goAndGet() {[/!]
+[!python]def goAndGet():
+  """Go, retrieves the baggle in front of the buggle, and brings it back.
+
+  Does not check for walls, so be careful to not call it when walls are present."""[/!]
+  actions()[!java];[/!]
+  to()[!java];[/!]
+  do()[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<h3>Naming conventions</h3>
+<p>Most programming language forbid the use of spaces in method and variable identifiers (=their names).  
+Accented letters are sometimes allowed (as in [!thelang]), but they can lead to
+portability issues between operating systems and should thus be avoided when possible.</p>
+
+<p>Across all programming languages, there is two main conventions to
+name variables and methods. The first one, consists in concatenating all words with 
+only the first letter of each word in upper case. "go and get" becomes goAndGet(). 
+It is called CamelCase because identifiers written this way graphically remind of a camel
+back. The other convention, called snake_case, is to write every words in lower case,
+separated with underscores symbols (_). "go and get" becomes go_and_get().</p>
+
+<p>Which convention to use is the topic of heated discussion across developers, but
+each programming language has its own habits. In Python, Perl and the C language, the 
+snake_case is often used for methods and variables. Java and Scala prefer the
+lowerCamelCase (the very first letter is lower case) for that.</p> 
+<p>The CamelCase convention is used everywhere in PLM because this program is written
+in Java itself, so we kept our habits when adding new languages. But the fact that the
+Python bindings of PLM use the CamelCase instead of the snake_case is considered as a
+bug that we will fix in further releases.</p>
+
+<h3>Exercise goal</h3>
+<p>The goal of this exercise is to write a method called <code>goAndGet()</code>
+which does the same than in a previous exercises (move forward until over a baggle, 
+pick it up, move back to initial position, drop baggle).</p>
+
+<p>One specificity of this exercise is that you shouldn't write directly the
+code that the buggle should execute, but a method it should use. The code that calls 
+your function will be automagically added when you click on <b>Start</b>. 
+For your information, this calling code will look like this:</p>
+  
+<pre>[!java]for (int i=0; i<7; i++) {[/!][!python]for i in range(7):[/!][!scala]for (i <- 1 to 7) {[/!]
+    goAndGet()[!java];[/!]
+    right()[!java];[/!]
+    forward()[!java];[/!]
+    left()[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>Your buggle will repeat 7 times (which matches the world's dimension)
+the sequence constituted of a call to the <code>goAndGet()</code> method that you
+should write, plus a move to get to the next row (turn right, move
+forward, turn left). As you can see, the buggle will do one step right from
+the right border of the world. It will bring it back to the left side since
+its world is a torus.</p>
+
+<p>You should now write this goAndGet() method.</p>
+
diff --git a/src/lessons/welcome/methods/basics/Methods.java b/src/lessons/welcome/methods/basics/Methods.java
index 794395e..603753a 100644
--- a/src/lessons/welcome/methods/basics/Methods.java
+++ b/src/lessons/welcome/methods/basics/Methods.java
@@ -2,12 +2,12 @@ package lessons.welcome.methods.basics;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
 
 public class Methods extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouse-answer0.map b/src/lessons/welcome/methods/basics/MethodsDogHouse-answer0.map
similarity index 100%
rename from src/lessons/welcome/methods/doghouse/MethodsDogHouse-answer0.map
rename to src/lessons/welcome/methods/basics/MethodsDogHouse-answer0.map
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouse.fr.html b/src/lessons/welcome/methods/basics/MethodsDogHouse.fr.html
new file mode 100644
index 0000000..93a6823
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouse.fr.html
@@ -0,0 +1,49 @@
+<h2>Construire avec méthode</h2>
+
+Nous souhaitons maintenant apprendre à la buggle à se faire une niche.  La
+première approche, la plus simple au premier abord, est d'écrire directement
+le code permettant de le faire, comme ci-dessous (cela marche car la buggle
+de cet exercice laisse une traînée rouge dans son sillage quand elle se
+déplace).
+
+<pre>avance()[!java];[/!]
+avance()[!java];[/!]
+gauche()[!java];[/!]
+avance()[!java];[/!]
+avance()[!java];[/!]
+gauche()[!java];[/!]
+avance()[!java];[/!]
+avance()[!java];[/!]
+gauche()[!java];[/!]
+avance()[!java];[/!]
+avance()[!java];[/!]
+gauche()[!java];[/!]</pre>
+
+<p>Les problèmes commencent quand nous voulons faire faire deux cabanes à la
+buggle : Il faut réécrire le code deux fois, ce qui n'est pas très
+pratique. Quand le code devient un peu long comme dans ce cas, on voit mieux
+pourquoi il faut toujours éviter de dupliquer du code. En effet, si vous
+vous rendez compte que vous vous êtes trompé dans votre code, et que vous
+l'avez recopier à plusieurs endroits, il va falloir le corriger plusieurs
+fois. Et gare si vous oubliez de corriger un exemplaire.</p> 
+
+<p>Ce principe de programmation a même un nom en anglais : DRY/SPOT (qui
+signifie «point sec»). C'est l'acronyme de «Don't Repeat Yourself» (ne vous
+répétez pas) et «Single Point Of Truth» (point unique de vérité). Chaque
+information doit se trouver à un seul endroit de votre programme pour éviter
+que les différentes copies ne se désynchronisent quand vous modifiez votre
+programme.</p>
+
+<p>Nous allons donc appliquer ce beau principe et <b>factoriser le code</b>,
+c'est-à-dire écrire le code une seule fois, par exemple dans une
+méthode. Vous devriez même aller plus loin en factorisant le code de la
+méthode avec une boucle <code>for</code> comme vu précédemment. Si vous vous
+y prenez bien (ce que vous devriez faire), vous n'écrirez qu'un seul appel à
+la méthode <code>gauche()</code> dans votre programme.</p>
+
+<h3>Objectif de cet exercice</h3>
+<p>L'objectif de cet exercice est d'écrire une méthode nommée
+<code>dogHouse()</code> et ayant un comportement identique au code
+ci-dessus. La buggle invoquera plusieurs fois votre œuvre afin de dessiner
+des cabanes un peu partout. </p>
+
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouse.html b/src/lessons/welcome/methods/basics/MethodsDogHouse.html
new file mode 100644
index 0000000..17d457d
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouse.html
@@ -0,0 +1,41 @@
+<h2>Building methodically</h2>
+
+We now would like to learn the buggle to build a doghouse. The naive
+approach consists in directly writing the needed code as follows.  This
+works because the buggle of this exercise leaves a red path as it moves.
+
+<pre>forward()[!java];[/!]
+forward()[!java];[/!]
+left()[!java];[/!]
+forward()[!java];[/!]
+forward()[!java];[/!]
+left()[!java];[/!]
+forward()[!java];[/!]
+forward()[!java];[/!]
+left()[!java];[/!]
+forward()[!java];[/!]
+forward()[!java];[/!]
+left()[!java];[/!]</pre>
+
+<p>It becomes harder when we want to draw two doghouses: we have to rewrite the
+same code twice, which is not really handy. When the code becomes a bit long as this
+one, it becomes easier to see why we insist since a while on the pure evilness that code
+duplication represents. Indeed, if you realize that an error sneaked into a code that you
+copied at several locations, you will have to fix it several times. And mind your back if you forget one of these locations.</p> 
+
+<p>There is even a name to this good principle in programming: DRY/SPOT, which means
+"Don't Repeat Yourself / Single Point Of Truth". The latter part means that each information
+must be written in only one location of your program to avoid the differing locations to get
+out of synch when you modify your code.</p>
+
+<p>So, let's apply this good principle and <b>factorize our code</b>, 
+ie to write it only once, for example in a method. You should even to go further by 
+factorizing the method body with a <code>for</code> loop, as seen previously.
+If you do it correctly (what you should), you can use the method <code>left()</code> only 
+once.</p>
+
+<h3>Exercise goal</h3>
+<p>The goal of this exercise is to write a method called <code>dogHouse</code>
+achieving the same result than the code above, but with a for loop to keep it short. 
+The buggle will call your creation to create several dog houses around its world. </p>
+
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouse.java b/src/lessons/welcome/methods/basics/MethodsDogHouse.java
new file mode 100644
index 0000000..a21b8eb
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouse.java
@@ -0,0 +1,20 @@
+package lessons.welcome.methods.basics;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class MethodsDogHouse extends ExerciseTemplated {
+
+	public MethodsDogHouse(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",7,7);
+		new Buggle(myWorld, "Puppy", 0, 6, Direction.EAST, Color.red, Color.red);
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java
new file mode 100644
index 0000000..5359e36
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.java
@@ -0,0 +1,79 @@
+package lessons.welcome.methods.basics;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class MethodsDogHouseEntity extends SimpleBuggle {
+	@Override
+	public void right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
+	}
+
+	private int line = -1;
+	private boolean studentCode = true;
+	@Override
+	public void left() {
+		if (!studentCode) {
+			super.left();
+			return;
+		}
+		
+		for (StackTraceElement s : Thread.currentThread().getStackTrace()) {
+			if (s.getMethodName().equals("dogHouse")) {
+				if (line != -1 && line != s.getLineNumber()) {
+					int offset = ((Exercise)Game.getInstance().getCurrentLesson().getCurrentExercise()).getSourceFile(Game.JAVA, 0).getOffset();
+				    String msg = Game.i18n.tr("I''m sorry Dave, I''m affraid I cant let you use left() both in lines {0} and {1} in this exercise.",
+					        (line-offset+1),(s.getLineNumber()-offset+1));
+
+					throw new RuntimeException(msg);
+				} else {
+					line = s.getLineNumber();
+					super.left();
+					return;
+				}
+			}
+
+		}
+	}
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	void dogHouse() {
+		for (int i=0;i<4;i++) {
+			forward();
+			forward();
+			left();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+
+	@Override
+	public void run() {
+		studentCode = true;
+		brushDown();
+		dogHouse();
+		brushUp();
+
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+		brushUp();
+
+		forward(2);
+		studentCode = false;left(); studentCode = true;
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+		brushUp();
+
+		forward(2);
+		studentCode = false;left(); studentCode = true;
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+	} 
+}
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.py b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.py
new file mode 100644
index 0000000..da7ab3b
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.py
@@ -0,0 +1,48 @@
+line = -1
+
+def right():
+	raise java.lang.RuntimeException("right() forbidden in this exercise.");
+
+# does not work as Java stacktrace does not contain python function name ;(
+#def left():
+#    global line
+#    errorMsg(str(line))
+#    for s in java.lang.Thread.currentThread().getStackTrace():
+#        if "left" in s.getMethodName():
+#            if line != -1 and line != s.getLineNumber():
+#                errorMsg("Forbidden to use left() more than once in this exercise.")
+#                # throw new RuntimeException("Forbidden to use left() more than once in this exercise.");
+#            else:
+#                line = s.getLineNumber()
+#                entity.left()	
+	
+def dogHouse():
+	raise java.lang.RuntimeException("You must define a dogHouse() method.");
+
+# BEGIN SOLUTION
+def dogHouse():
+    for i in range(4):
+        forward()
+        forward()
+        left()
+
+# END SOLUTION
+
+brushDown()
+dogHouse()
+brushUp()    
+forward(4)
+brushDown()
+dogHouse()		
+brushUp()
+forward(2)
+left()
+forward(4)
+brushDown()
+dogHouse()		
+brushUp()
+forward(2)
+left()
+forward(4)
+brushDown()
+dogHouse()
diff --git a/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.scala b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.scala
new file mode 100644
index 0000000..d33489b
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsDogHouseEntity.scala
@@ -0,0 +1,85 @@
+package lessons.welcome.methods.basics;
+
+import plm.universe.bugglequest.SimpleBuggle
+import plm.core.model.Game
+import scala.collection.JavaConversions
+import plm.core.model.lesson.Exercise
+
+class ScalaMethodsDogHouseEntity extends SimpleBuggle {
+	override def right()  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right."));
+	}
+
+	var savedLine = -1
+	var studentCode = false
+	override def left() {
+	  if (!studentCode) {
+		  super.left()
+		  return
+	  }
+	  var usedLine = 0
+	  for (s <- Thread.currentThread().getStackTrace())
+	    if (s.getMethodName().equals("dogHouse")) {
+	      usedLine = s.getLineNumber()
+	      /*println("left() used in "+s.getFileName()+":"+usedLine+" ("+
+	    		  Thread.currentThread().getStackTrace().apply(2).getClassName()+":"+
+	    		  Thread.currentThread().getStackTrace().apply(2).getMethodName()+")")*/
+	    }
+	  if (usedLine==0) {
+	    //println("Warning, cannot determine the call stack of left(). No check enforced");
+	    super.left()
+	    return
+	  }
+	  if (savedLine == -1) {
+	    savedLine = usedLine
+	  } else if (savedLine != usedLine) {
+	    var offset = Game.getInstance().getCurrentLesson().getCurrentExercise().asInstanceOf[Exercise].getSourceFile(Game.SCALA, 0).getOffset()
+	    var msg = Game.i18n.tr("I'm sorry Dave, I'm affraid I cant let you use left() both in lines {0} and {1}.",
+	        (savedLine-offset),(usedLine-offset));
+		  System.out.println(msg);
+		  throw new RuntimeException(msg);
+	  }
+	  super.left();
+	}
+	/* BEGIN SOLUTION */
+	def dogHouse() {
+		for (i <- 1 to 4) {
+			forward()
+			forward()
+			left()
+		}
+	}
+	/* END SOLUTION */
+
+	override def run() {
+		brushDown();
+		studentCode = true
+		dogHouse();
+		brushUp();
+
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+		brushUp();
+
+		forward(2);
+		studentCode = false
+		left();
+		studentCode = true
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+		brushUp();
+
+		forward(2);
+		studentCode = false
+		left();
+		studentCode = true
+		forward(4);
+
+		brushDown();
+		dogHouse();		
+	} 
+}
diff --git a/src/lessons/welcome/methods/basics/MethodsEntity.java b/src/lessons/welcome/methods/basics/MethodsEntity.java
index 6d48921..c500913 100644
--- a/src/lessons/welcome/methods/basics/MethodsEntity.java
+++ b/src/lessons/welcome/methods/basics/MethodsEntity.java
@@ -1,14 +1,14 @@
 package lessons.welcome.methods.basics;
 
-public class MethodsEntity extends jlm.universe.bugglequest.SimpleBuggle {
+public class MethodsEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise.");
 	}
 
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise.");
 	}
 
 	/* BEGIN TEMPLATE */
@@ -33,9 +33,9 @@ public class MethodsEntity extends jlm.universe.bugglequest.SimpleBuggle {
 	public void run() { 
 		for (int i=0; i<7; i++) {
 			goAndGet();
-			turnRight();
+			right();
 			forward();
-			turnLeft();
+			left();
 		}
 	} 
 }
diff --git a/src/lessons/welcome/methods/basics/MethodsEntity.py b/src/lessons/welcome/methods/basics/MethodsEntity.py
index 3d0ed87..d2d2019 100644
--- a/src/lessons/welcome/methods/basics/MethodsEntity.py
+++ b/src/lessons/welcome/methods/basics/MethodsEntity.py
@@ -24,6 +24,6 @@ def goAndGet():
 
 for i in range(7):
   goAndGet()
-  turnRight()
+  right()
   forward()
-  turnLeft()
+  left()
diff --git a/src/lessons/welcome/methods/basics/MethodsEntity.scala b/src/lessons/welcome/methods/basics/MethodsEntity.scala
new file mode 100644
index 0000000..d59e48d
--- /dev/null
+++ b/src/lessons/welcome/methods/basics/MethodsEntity.scala
@@ -0,0 +1,39 @@
+package lessons.welcome.methods.basics;
+
+import plm.core.model.Game
+
+class ScalaMethodsEntity extends plm.universe.bugglequest.SimpleBuggle {
+  	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	/* BEGIN TEMPLATE */
+	def goAndGet() {
+		/* BEGIN SOLUTION */
+		var i = 0;
+		while (!isOverBaggle()) {
+			i += 1;
+			forward();
+		}
+		pickupBaggle();
+		while (i>0) {
+			backward();
+			i -= 1;
+		}
+		dropBaggle();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+
+	override def run() { 
+		for (i <- 1 to 7) {
+			goAndGet();
+			right();
+			forward();
+			left();
+		}
+	} 
+}
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.fr.html b/src/lessons/welcome/methods/doghouse/MethodsDogHouse.fr.html
deleted file mode 100644
index dd75c58..0000000
--- a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.fr.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<h2>Construire avec méthode</h2>
-
-Nous souhaitons maintenant apprendre à la buggle à se faire une niche.  La
-première approche, la plus simple au premier abord, est d'écrire directement
-le code permettant de le faire, comme ci-dessous (cela marche car la buggle
-de cet exercice laisse une traînée rouge dans son sillage quand elle se
-déplace).
-
-<pre class="Java">
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-</pre>
-
-<pre class="Python">
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-</pre>
-
-<p>Les problèmes commencent quand nous voulons faire faire deux cabanes à la
-buggle : Il faut réécrire le code deux fois, ce qui n'est pas très
-pratique. Pire que ça, une telle duplication de code est en général très mal
-vu. En effet, si vous vous rendez compte que vous vous êtes trompé dans
-votre code, et que vous l'avez recopier à plusieurs endroits, il va falloir
-le corriger plusieurs fois. Et gare si vous oubliez de corriger un
-exemplaire.</p> 
-
-<p>Il est bien préférable de <b>factoriser votre code</b>, c'est-à-dire
-d'écrire le code une seule fois, par exemple dans une méthode. C'est ce que
-vous allez faire maintenant. Il est même possible d'aller plus loin en
-factorisant le code de la méthode avec une boucle <code>for</code> comme vu
-précédemment.
-
-<h3>Objectif de cet exercice</h3><a name="Objectifs"> L'objectif de cet exercice est d'écrire une méthode
-nommée <code>dogHouse()</code> et exécute le code ci-dessus. La buggle
-invoquera plusieurs fois votre oeuvre afin de dessiner des cabanes un peu
-partout. Pensez à factoriser le code de votre méthode avec une boucle for.
-
-<p>À vous de jouer.</p>
-
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.html b/src/lessons/welcome/methods/doghouse/MethodsDogHouse.html
deleted file mode 100644
index 4c74cfb..0000000
--- a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<h2>Building methodically</h2>
-
-We now would like to learn the buggle to build a doghouse. The seamingly
-simpler approach consists in directly writing the needed code as follows (it
-works because the buggle of this exercise leaves a red path as it moves).
-
-<pre class="Java">
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-forward();
-forward();
-turnLeft(); 
-</pre>
-
-<pre class="Python">
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-forward()
-forward()
-turnLeft() 
-</pre>
-
-<p>It becomes harder when we want to draw two doghouses: we have to rewrite the
-same code twice, which is not really handy. Even worse: it's definitively
-not good form to duplicate code this way. Indeed, if you realize that an
-error sneaked into a code that you copied at several locations, you will
-have to fix it several times. And mind your back if you forget one of these
-locations.</p> 
-
-<p>It is good form to <b>factorize your code</b>, ie to write it only once, for
-example in a method. This is what you will do now. It is even possible to go
-further by factorizing the method body with a <code>for</code> loop, as seen
-previously.
-
-<h3>Exercise goal</h3>The goal of this exercise is to write a method called <code>dogHouse</code>
-achieving the same result than the code above. The buggle will call your
-creation to create several dog houses around its world. Remind to factorize
-your method with a for loop.
-
-<p>You're up.</p>
-
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.java b/src/lessons/welcome/methods/doghouse/MethodsDogHouse.java
deleted file mode 100644
index 6e61899..0000000
--- a/src/lessons/welcome/methods/doghouse/MethodsDogHouse.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package lessons.welcome.methods.doghouse;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class MethodsDogHouse extends ExerciseTemplated {
-
-	public MethodsDogHouse(Lesson lesson) {
-		super(lesson);
-		BuggleWorld myWorld =  new BuggleWorld("World",7,7);
-		new Buggle(myWorld, "Puppy", 0, 6, Direction.EAST, Color.red, Color.red);
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.java b/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.java
deleted file mode 100644
index 8fe1f8a..0000000
--- a/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package lessons.welcome.methods.doghouse;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class MethodsDogHouseEntity extends SimpleBuggle {
-
-	private int line = -1;
-
-	@Override
-	public void turnRight() {
-		throw new RuntimeException("turnRight() forbidden in this exercise.");
-	}
-
-	@Override
-	public void turnLeft() {
-		for (StackTraceElement s : Thread.currentThread().getStackTrace()) {
-			if (s.getMethodName().contains("turnLeft")) {
-				if (line != -1 && line != s.getLineNumber()) {
-					System.out.println("Forbiden to use turnLeft() more than once in this exercise.");
-					throw new RuntimeException("Forbiden to use turnLeft() more than once in this exercise.");
-				} else {
-					line = s.getLineNumber();
-					super.turnLeft();
-				}
-			}
-
-		}
-	}
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	void dogHouse() {
-		for (int i=0;i<4;i++) {
-			forward();
-			forward();
-			turnLeft();
-		}
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */
-
-	@Override
-	public void run() {
-		brushDown();
-		dogHouse();
-		brushUp();
-
-		forward(4);
-
-		brushDown();
-		dogHouse();		
-		brushUp();
-
-		forward(2);
-		turnLeft();
-		forward(4);
-
-		brushDown();
-		dogHouse();		
-		brushUp();
-
-		forward(2);
-		turnLeft();
-		forward(4);
-
-		brushDown();
-		dogHouse();		
-	} 
-}
diff --git a/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.py b/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.py
deleted file mode 100644
index cda86d0..0000000
--- a/src/lessons/welcome/methods/doghouse/MethodsDogHouseEntity.py
+++ /dev/null
@@ -1,48 +0,0 @@
-line = -1
-
-def turnRight():
-	raise java.lang.RuntimeException("turnRight() forbidden in this exercise.");
-
-# does not work as Java stacktrace does not contain python function name ;(
-#def turnLeft():
-#    global line
-#    errorMsg(str(line))
-#    for s in java.lang.Thread.currentThread().getStackTrace():
-#        if "turnLeft" in s.getMethodName():
-#            if line != -1 and line != s.getLineNumber():
-#                errorMsg("Forbidden to use turnLeft() more than once in this exercise.")
-#                # throw new RuntimeException("Forbidden to use turnLeft() more than once in this exercise.");
-#            else:
-#                line = s.getLineNumber()
-#                entity.turnLeft()	
-	
-def dogHouse():
-	raise java.lang.RuntimeException("You must define a dogHouse() method.");
-
-# BEGIN SOLUTION
-def dogHouse():
-    for i in range(4):
-        forward()
-        forward()
-        turnLeft()
-
-# END SOLUTION
-
-brushDown()
-dogHouse()
-brushUp()    
-forward(4)
-brushDown()
-dogHouse()		
-brushUp()
-forward(2)
-turnLeft()
-forward(4)
-brushDown()
-dogHouse()		
-brushUp()
-forward(2)
-turnLeft()
-forward(4)
-brushDown()
-dogHouse()
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCase-answer0.map b/src/lessons/welcome/methods/flowerpot/FlowerCase-answer0.map
new file mode 100644
index 0000000..54ff630
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCase-answer0.map
@@ -0,0 +1,287 @@
+BuggleWorld: Flower display case
+Size: 17x17
+Buggle(9,14): east,black,yellow,Jessie
+Buggle(9,14): east,black,yellow,Van Gogh
+Cell(0,1): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,2): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,3): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,4): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,5): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,6): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,7): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,9): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,10): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,11): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,12): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,13): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,14): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,15): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,1): 0/155/0,nobaggle,topwall,leftwall,
+Cell(1,2): red,nobaggle,notopwall,leftwall,
+Cell(1,3): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,4): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,5): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,6): pink,nobaggle,notopwall,leftwall,
+Cell(1,7): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,8): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,9): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,10): red,nobaggle,notopwall,leftwall,
+Cell(1,11): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,12): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,13): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,14): pink,nobaggle,notopwall,leftwall,
+Cell(1,15): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(2,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(2,1): red,nobaggle,topwall,noleftwall,
+Cell(2,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,3): red,nobaggle,notopwall,noleftwall,
+Cell(2,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,5): pink,nobaggle,notopwall,noleftwall,
+Cell(2,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,7): pink,nobaggle,notopwall,noleftwall,
+Cell(2,8): 200/113/55,nobaggle,topwall,leftwall,
+Cell(2,9): red,nobaggle,topwall,noleftwall,
+Cell(2,10): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,11): red,nobaggle,notopwall,noleftwall,
+Cell(2,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,13): pink,nobaggle,notopwall,noleftwall,
+Cell(2,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,15): pink,nobaggle,notopwall,noleftwall,
+Cell(2,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(3,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,2): red,nobaggle,notopwall,noleftwall,
+Cell(3,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,4): orange,nobaggle,notopwall,noleftwall,
+Cell(3,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,6): pink,nobaggle,notopwall,noleftwall,
+Cell(3,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,10): red,nobaggle,notopwall,noleftwall,
+Cell(3,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,12): orange,nobaggle,notopwall,noleftwall,
+Cell(3,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,14): pink,nobaggle,notopwall,noleftwall,
+Cell(3,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(4,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,3): orange,nobaggle,notopwall,noleftwall,
+Cell(4,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(4,5): orange,nobaggle,notopwall,noleftwall,
+Cell(4,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,11): orange,nobaggle,notopwall,noleftwall,
+Cell(4,12): yellow,nobaggle,notopwall,noleftwall,
+Cell(4,13): orange,nobaggle,notopwall,noleftwall,
+Cell(4,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(5,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(5,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,4): orange,nobaggle,notopwall,noleftwall,
+Cell(5,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,6): green,nobaggle,notopwall,noleftwall,
+Cell(5,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,10): cyan,nobaggle,notopwall,noleftwall,
+Cell(5,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,12): orange,nobaggle,notopwall,noleftwall,
+Cell(5,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,14): green,nobaggle,notopwall,noleftwall,
+Cell(5,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(6,1): cyan,nobaggle,topwall,noleftwall,
+Cell(6,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,3): cyan,nobaggle,notopwall,noleftwall,
+Cell(6,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,5): green,nobaggle,notopwall,noleftwall,
+Cell(6,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,7): green,nobaggle,notopwall,noleftwall,
+Cell(6,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,9): cyan,nobaggle,topwall,noleftwall,
+Cell(6,10): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,11): cyan,nobaggle,notopwall,noleftwall,
+Cell(6,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,13): green,nobaggle,notopwall,noleftwall,
+Cell(6,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,15): green,nobaggle,notopwall,noleftwall,
+Cell(6,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(7,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(7,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,4): blue,nobaggle,notopwall,noleftwall,
+Cell(7,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,6): green,nobaggle,notopwall,noleftwall,
+Cell(7,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,10): cyan,nobaggle,notopwall,noleftwall,
+Cell(7,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,12): blue,nobaggle,notopwall,noleftwall,
+Cell(7,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,14): green,nobaggle,notopwall,noleftwall,
+Cell(7,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(8,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,2): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,3): blue,nobaggle,topwall,noleftwall,
+Cell(8,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(8,5): blue,nobaggle,notopwall,noleftwall,
+Cell(8,6): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,7): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,10): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,11): blue,nobaggle,topwall,noleftwall,
+Cell(8,12): yellow,nobaggle,notopwall,noleftwall,
+Cell(8,13): blue,nobaggle,notopwall,noleftwall,
+Cell(8,14): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,15): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(9,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(9,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(9,2): red,nobaggle,notopwall,leftwall,
+Cell(9,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,4): blue,nobaggle,notopwall,noleftwall,
+Cell(9,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,6): pink,nobaggle,notopwall,leftwall,
+Cell(9,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(9,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(9,10): red,nobaggle,notopwall,leftwall,
+Cell(9,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,12): blue,nobaggle,notopwall,noleftwall,
+Cell(9,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,14): pink,nobaggle,notopwall,leftwall,
+Cell(9,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(10,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(10,1): red,nobaggle,topwall,noleftwall,
+Cell(10,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(10,3): red,nobaggle,notopwall,noleftwall,
+Cell(10,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,5): pink,nobaggle,notopwall,noleftwall,
+Cell(10,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(10,7): pink,nobaggle,notopwall,noleftwall,
+Cell(10,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(10,9): red,nobaggle,topwall,noleftwall,
+Cell(10,10): yellow,nobaggle,notopwall,noleftwall,
+Cell(10,11): red,nobaggle,notopwall,noleftwall,
+Cell(10,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,13): pink,nobaggle,notopwall,noleftwall,
+Cell(10,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(10,15): pink,nobaggle,notopwall,noleftwall,
+Cell(10,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(11,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(11,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(11,2): red,nobaggle,notopwall,noleftwall,
+Cell(11,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,4): orange,nobaggle,notopwall,noleftwall,
+Cell(11,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,6): pink,nobaggle,notopwall,noleftwall,
+Cell(11,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(11,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(11,10): red,nobaggle,notopwall,noleftwall,
+Cell(11,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,12): orange,nobaggle,notopwall,noleftwall,
+Cell(11,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,14): pink,nobaggle,notopwall,noleftwall,
+Cell(11,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(12,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(12,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(12,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,3): orange,nobaggle,notopwall,noleftwall,
+Cell(12,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(12,5): orange,nobaggle,notopwall,noleftwall,
+Cell(12,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(12,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(12,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,11): orange,nobaggle,notopwall,noleftwall,
+Cell(12,12): yellow,nobaggle,notopwall,noleftwall,
+Cell(12,13): orange,nobaggle,notopwall,noleftwall,
+Cell(12,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(13,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(13,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(13,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(13,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,4): orange,nobaggle,notopwall,noleftwall,
+Cell(13,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,6): green,nobaggle,notopwall,noleftwall,
+Cell(13,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(13,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(13,10): cyan,nobaggle,notopwall,noleftwall,
+Cell(13,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,12): orange,nobaggle,notopwall,noleftwall,
+Cell(13,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,14): green,nobaggle,notopwall,noleftwall,
+Cell(13,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(14,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(14,1): cyan,nobaggle,topwall,noleftwall,
+Cell(14,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(14,3): cyan,nobaggle,notopwall,noleftwall,
+Cell(14,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,5): green,nobaggle,notopwall,noleftwall,
+Cell(14,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(14,7): green,nobaggle,notopwall,noleftwall,
+Cell(14,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(14,9): cyan,nobaggle,topwall,noleftwall,
+Cell(14,10): yellow,nobaggle,notopwall,noleftwall,
+Cell(14,11): cyan,nobaggle,notopwall,noleftwall,
+Cell(14,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,13): green,nobaggle,notopwall,noleftwall,
+Cell(14,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(14,15): green,nobaggle,notopwall,noleftwall,
+Cell(14,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(15,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(15,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(15,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(15,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,6): green,nobaggle,notopwall,noleftwall,
+Cell(15,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(15,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(15,10): cyan,nobaggle,notopwall,noleftwall,
+Cell(15,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,14): green,nobaggle,notopwall,noleftwall,
+Cell(15,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(16,1): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,2): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,3): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,4): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,5): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,6): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,7): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,9): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,10): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,11): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,12): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,13): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,14): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,15): 200/113/55,nobaggle,notopwall,leftwall,
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCase.fr.html b/src/lessons/welcome/methods/flowerpot/FlowerCase.fr.html
new file mode 100644
index 0000000..40f3d4a
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCase.fr.html
@@ -0,0 +1,7 @@
+<h2>Jardinière de fleurs</h2>
+
+<p>Whaou! Ce n'est plus un petit pot de fleurs, c'est carrément une énorme
+jardinière! Votre buggle est déjà partie la fleurir, et vous devriez aller
+l'aider pour éviter qu'elle ne se cogne à une bordure...</p>
+
+<p>PS: La nouvelle couleur utilisée (pour le bleu) est <code>Color.BLUE</code></p>
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCase.html b/src/lessons/welcome/methods/flowerpot/FlowerCase.html
new file mode 100644
index 0000000..5a1c126
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCase.html
@@ -0,0 +1,7 @@
+<h2>Flower Display Case</h2>
+
+<p>Whao! That's not a little pot anymore! That's a huge large flower display case!
+Your buggle can't help but starts flowering this gorgeous place. You should help 
+it to prevent that it bumps into a wall...</p>
+
+<p>PS: the newly used color is <code>Color.BLUE</code>.</p>
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCase.java b/src/lessons/welcome/methods/flowerpot/FlowerCase.java
new file mode 100644
index 0000000..86bd3cb
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCase.java
@@ -0,0 +1,25 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class FlowerCase extends ExerciseTemplated {
+
+	public FlowerCase(Lesson lesson) throws IOException, BrokenWorldFileException {
+		super(lesson);
+		BuggleWorld[] myWorlds = new BuggleWorld[] {
+				(BuggleWorld) BuggleWorld.newFromFile("lessons/welcome/methods/flowerpot/FlowerCase")
+		};
+
+		new Buggle(myWorlds[0], "Van Gogh", 1, 2, Direction.EAST, Color.black, Color.lightGray);
+		
+		setup(myWorlds);
+	}
+}
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCase.map b/src/lessons/welcome/methods/flowerpot/FlowerCase.map
new file mode 100644
index 0000000..772cd99
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCase.map
@@ -0,0 +1,286 @@
+BuggleWorld: Flower display case
+Size: 17x17
+Buggle(1,2): east,black,black,Jessie
+Cell(0,1): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,2): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,3): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,4): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,5): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,6): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,7): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,9): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,10): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,11): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,12): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,13): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,14): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,15): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,1): 0/155/0,nobaggle,topwall,leftwall,
+Cell(1,2): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,3): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,4): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,5): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,6): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,7): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,8): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,9): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,10): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,11): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,12): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,13): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,14): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,15): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(2,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(2,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(2,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,8): 200/113/55,nobaggle,topwall,leftwall,
+Cell(2,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(2,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(3,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(4,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(5,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(6,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(6,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(6,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(7,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(8,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,2): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,3): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(8,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(8,6): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,7): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,10): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,11): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(8,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(8,14): 200/113/55,nobaggle,topwall,leftwall,
+Cell(8,15): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(8,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(9,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(9,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(9,2): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(9,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,6): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(9,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(9,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(9,10): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(9,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,14): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(9,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(9,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(10,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(10,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(10,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(10,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(10,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(10,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(11,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(11,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(11,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(11,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(11,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(11,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(12,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(12,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(12,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(12,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(12,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(12,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(13,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(13,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(13,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(13,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(13,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(13,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(14,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(14,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(14,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(14,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(14,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(14,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(15,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(15,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(15,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(15,9): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(15,10): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,11): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,12): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,13): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,14): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,15): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(15,16): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(16,1): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,2): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,3): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,4): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,5): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,6): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,7): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,9): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,10): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,11): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,12): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,13): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,14): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(16,15): 200/113/55,nobaggle,notopwall,leftwall,
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.java b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.java
new file mode 100644
index 0000000..3ea2643
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.java
@@ -0,0 +1,74 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+public class FlowerCaseEntity extends SimpleBuggle {
+
+	public void run() {
+		growFlowers();
+	}
+	/* BEGIN SOLUTION */
+
+	void makeFlower(Color c) {
+		setBrushColor(c);
+		brushDown();
+		forward(2);
+		backward();
+		left();
+		forward();
+		backward(2);
+		forward();
+		setBrushColor(Color.YELLOW);
+		brushUp();
+		right();  
+		backward();
+	}
+
+	void line(Color[] colors, boolean returnBack) {
+		boolean first = true;
+		for (Color c:colors) {
+			if (!first)
+				forward(4);
+			makeFlower(c);
+			first = false;
+		}
+
+		if (returnBack)
+			backward(4*(colors.length-1));    
+	}
+	void RLforward(int steps) {
+		right();
+		forward(steps);
+		left();
+	}
+	void LRforward(int steps) {
+		left();
+		forward(steps);
+		right();
+	}
+	void boxes() {
+		line(new Color[]{Color.RED, Color.CYAN},true);        
+		RLforward(4);
+		line(new Color[]{Color.PINK, Color.GREEN},true);
+
+		LRforward(2);
+		forward(2);
+		line(new Color[]{Color.ORANGE,Color.BLUE,Color.ORANGE},false);        
+
+		LRforward(2);
+		backward(2);      
+
+		line(new Color[]{Color.RED, Color.CYAN},true);        
+		RLforward(4);
+		line(new Color[]{Color.PINK, Color.GREEN},true);
+	}
+	void growFlowers() {
+		boxes();
+		LRforward(1);
+		backward(8);
+		RLforward(5);
+		boxes();
+	}
+	/* END SOLUTION */
+}
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.py b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.py
new file mode 100644
index 0000000..42eab40
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.py
@@ -0,0 +1,60 @@
+# BEGIN SOLUTION 
+def makeFlower(c):
+		setBrushColor(c);
+		brushDown();
+		forward(2);
+		backward();
+		left();
+		forward();
+		backward(2);
+		forward();
+		setBrushColor(Color.YELLOW);
+		brushUp();
+		right();  
+		backward();
+
+def line(colors, returnBack):
+		first = True
+		for c in colors:
+			if (not first):
+				forward(4)
+			makeFlower(c);
+			first = False
+
+		if (returnBack):
+			backward(4*(len(colors)-1))    
+def RLforward(steps):
+		right();
+		forward(steps);
+		left();
+def LRforward(steps):
+		left();
+		forward(steps);
+		right();
+	
+def boxes():
+		line( (Color.RED, Color.CYAN),True);        
+		RLforward(4);
+		line( (Color.PINK, Color.GREEN),True);
+
+		LRforward(2);
+		forward(2);
+		line( (Color.ORANGE,Color.BLUE,Color.ORANGE),False);        
+
+		LRforward(2);
+		backward(2);      
+
+		line( (Color.RED, Color.CYAN),True);        
+		RLforward(4);
+		line( (Color.PINK, Color.GREEN),True);
+		
+
+def growFlowers():
+		boxes();
+		LRforward(1);
+		backward(8);
+		RLforward(5);
+		boxes();
+# END SOLUTION 
+
+growFlowers()
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.scala b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.scala
new file mode 100644
index 0000000..eda4a21
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerCaseEntity.scala
@@ -0,0 +1,74 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+class ScalaFlowerCaseEntity extends SimpleBuggle {
+
+	def run() {
+		growFlowers();
+	}
+	/* BEGIN SOLUTION */
+
+	def makeFlower(c:Color) {
+		setBrushColor(c);
+		brushDown();
+		forward(2);
+		backward();
+		left();
+		forward();
+		backward(2);
+		forward();
+		setBrushColor(Color.YELLOW);
+		brushUp();
+		right();  
+		backward();
+	}
+
+	def line(colors:Array[Color], returnBack:Boolean) {
+		var first = true;
+		for (c <- colors) {
+			if (!first)
+				forward(4);
+			makeFlower(c);
+			first = false;
+		}
+
+		if (returnBack)
+			backward(4*(colors.length-1));    
+	}
+	def RLforward(steps: Int) {
+		right();
+		forward(steps);
+		left();
+	}
+	def LRforward(steps: Int) {
+		left();
+		forward(steps);
+		right();
+	}
+	def boxes() {
+		line(Array(Color.RED, Color.CYAN),true);        
+		RLforward(4);
+		line(Array(Color.PINK, Color.GREEN),true);
+
+		LRforward(2);
+		forward(2);
+		line(Array(Color.ORANGE,Color.BLUE,Color.ORANGE),false);        
+
+		LRforward(2);
+		backward(2);      
+
+		line(Array(Color.RED, Color.CYAN),true);        
+		RLforward(4);
+		line(Array(Color.PINK, Color.GREEN),true);
+	}
+	def growFlowers() {
+		boxes();
+		LRforward(1);
+		backward(8);
+		RLforward(5);
+		boxes();
+	}
+	/* END SOLUTION */
+}
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPot-answer0.map b/src/lessons/welcome/methods/flowerpot/FlowerPot-answer0.map
new file mode 100644
index 0000000..c6e85f3
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPot-answer0.map
@@ -0,0 +1,84 @@
+BuggleWorld: Brave new world
+Size: 9x9
+Buggle(1,6): east,black,yellow,Van Gogh
+Cell(0,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,1): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,2): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,3): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,4): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,5): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,6): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,7): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,8): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,1): 0/155/0,nobaggle,topwall,leftwall,
+Cell(1,2): red,nobaggle,notopwall,leftwall,
+Cell(1,3): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,4): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,5): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,6): pink,nobaggle,notopwall,leftwall,
+Cell(1,7): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(2,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(2,1): red,nobaggle,topwall,noleftwall,
+Cell(2,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,3): red,nobaggle,notopwall,noleftwall,
+Cell(2,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,5): pink,nobaggle,notopwall,noleftwall,
+Cell(2,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,7): pink,nobaggle,notopwall,noleftwall,
+Cell(2,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(3,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,2): red,nobaggle,notopwall,noleftwall,
+Cell(3,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,4): orange,nobaggle,notopwall,noleftwall,
+Cell(3,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,6): pink,nobaggle,notopwall,noleftwall,
+Cell(3,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(4,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,3): orange,nobaggle,notopwall,noleftwall,
+Cell(4,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(4,5): orange,nobaggle,notopwall,noleftwall,
+Cell(4,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(5,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(5,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,4): orange,nobaggle,notopwall,noleftwall,
+Cell(5,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,6): green,nobaggle,notopwall,noleftwall,
+Cell(5,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(6,1): cyan,nobaggle,topwall,noleftwall,
+Cell(6,2): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,3): cyan,nobaggle,notopwall,noleftwall,
+Cell(6,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,5): green,nobaggle,notopwall,noleftwall,
+Cell(6,6): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,7): green,nobaggle,notopwall,noleftwall,
+Cell(6,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(7,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,2): cyan,nobaggle,notopwall,noleftwall,
+Cell(7,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,6): green,nobaggle,notopwall,noleftwall,
+Cell(7,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(8,1): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,2): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,3): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,4): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,5): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,6): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,7): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,8): 200/113/55,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPot.fr.html b/src/lessons/welcome/methods/flowerpot/FlowerPot.fr.html
new file mode 100644
index 0000000..c75e4f7
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPot.fr.html
@@ -0,0 +1,25 @@
+<h2>Pot de fleur</h2>
+
+<p>Votre buggle a décidé de fleurir un peu le pot de fleur dans lequel elle
+vit. Vous devez l'aider à reproduire le motif dont elle rêve (vous pouvez le
+voir dans l'onglet «Objectif»).</p>
+
+<p>Pour cela, vous devez écrire une méthode nommée <code>growFlower()</code>
+(«fait pousser les fleurs» en anglais). Cette méthode ne prend aucun
+paramètre et ne renvoie aucun résultat. Comme le motif est un peu complexe,
+il faut que vous le décomposiez en sous-motifs pour que votre code reste
+simple et agréable à lire. Une méthode dessinant une fleur est un bon début,
+même si ce n'est probablement pas assez.</p>
+
+<p>Pour information, ce dessin utilise les cinq couleurs ci-dessous.
+[!java|scala]Le type de données de ces constantes est <code>Color</code>,
+qui décrit naturellement une couleur donnée[/!]</p>
+
+<ul>
+  <li><tt>Color.RED</tt> pour le rouge</li>
+  <li><tt>Color.PINK</tt> pour le rose</li>
+  <li><tt>Color.CYAN</tt> pour le bleu clair</li>
+  <li><tt>Color.ORANGE</tt> pour le orange</li>
+  <li><tt>Color.GREEN</tt> pour le vert</li>
+  <li><tt>Color.YELLOW</tt> pour le jaune</li>
+</ul>
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPot.html b/src/lessons/welcome/methods/flowerpot/FlowerPot.html
new file mode 100644
index 0000000..18e6f1b
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPot.html
@@ -0,0 +1,23 @@
+<h2>Flower Pot</h2>
+
+<p>Your buggle decided to flower a bit the pot it lives in. You have to help it
+reproducing the drawing of its dreams (check the "Objective" tab to see it).</p>
+
+<p>For that, you have to write a <code>growFlowers()</code> method that does not 
+take any parameter and does not return any result. As the pattern is a bit complex, 
+you should try to decompose this drawing in sub-steps so that your code remains 
+short and easy to read. A method to draw one flower of the color passed in 
+parameter sounds like a good start, but it is probably not enough.</p>
+
+<p>For your information, this drawing uses five colors that are listed below. 
+[!java|scala]The data type of these constants is <code>Color</code>, that naturally 
+describes a particular color.[/!]</p>
+
+<ul>
+  <li><tt>Color.RED</tt></li>
+  <li><tt>Color.PINK</tt></li>
+  <li><tt>Color.CYAN</tt></li>
+  <li><tt>Color.ORANGE</tt></li>
+  <li><tt>Color.GREEN</tt></li>
+  <li><tt>Color.YELLOW</tt></li>
+</ul>
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPot.java b/src/lessons/welcome/methods/flowerpot/FlowerPot.java
new file mode 100644
index 0000000..6d6e1b1
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPot.java
@@ -0,0 +1,25 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+import java.io.IOException;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class FlowerPot extends ExerciseTemplated {
+
+	public FlowerPot(Lesson lesson) throws IOException, BrokenWorldFileException {
+		super(lesson);
+		BuggleWorld[] myWorlds = new BuggleWorld[] {
+				(BuggleWorld) BuggleWorld.newFromFile("lessons/welcome/methods/flowerpot/FlowerPot")
+		};
+
+		new Buggle(myWorlds[0], "Van Gogh", 1, 2, Direction.EAST, Color.black, Color.lightGray);
+		
+		setup(myWorlds);
+	}
+}
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPot.map b/src/lessons/welcome/methods/flowerpot/FlowerPot.map
new file mode 100644
index 0000000..4575925
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPot.map
@@ -0,0 +1,83 @@
+BuggleWorld: Brave new world
+Size: 9x9
+Cell(0,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,1): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,2): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,3): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,4): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,5): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,6): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,7): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(0,8): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(1,1): 0/155/0,nobaggle,topwall,leftwall,
+Cell(1,2): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,3): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,4): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,5): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,6): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,7): 0/155/0,nobaggle,notopwall,leftwall,
+Cell(1,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(2,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(2,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(2,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(2,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(3,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(3,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(3,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(3,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(4,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(4,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(4,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(4,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(5,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(5,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(5,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(5,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(6,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(6,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(6,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(6,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(7,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(7,1): 0/155/0,nobaggle,topwall,noleftwall,
+Cell(7,2): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,3): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,4): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,5): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,6): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,7): 0/155/0,nobaggle,notopwall,noleftwall,
+Cell(7,8): 200/113/55,nobaggle,topwall,noleftwall,
+Cell(8,0): 200/113/55,nobaggle,notopwall,noleftwall,
+Cell(8,1): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,2): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,3): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,4): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,5): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,6): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,7): 200/113/55,nobaggle,notopwall,leftwall,
+Cell(8,8): 200/113/55,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.java b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.java
new file mode 100644
index 0000000..095e1bf
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.java
@@ -0,0 +1,51 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+public class FlowerPotEntity extends SimpleBuggle {
+
+	public void run() {
+	    growFlowers();
+	}
+	/* BEGIN SOLUTION */
+	void makeFlower(Color c) {
+	    setBrushColor(c);
+	    brushDown();
+	    forward(2);
+	    backward();
+	    left();
+	    forward();
+	    backward(2);
+	    forward();
+	    setBrushColor(Color.YELLOW);
+	    brushUp();
+	    right();    
+	}
+
+	void line(Color c1, Color c2) {
+	    makeFlower(c1);
+	    forward(3);
+	    makeFlower(c2);
+	    backward(5);    
+	}
+	void halfLine(Color c) {
+	    forward(2);
+	    makeFlower(c);
+	    backward(3);
+	}
+	void growFlowers() {
+	    line(Color.RED, Color.CYAN);
+	    
+	    right();    
+	    forward(2);
+	    left();
+	    halfLine(Color.ORANGE);
+	    right();
+	    forward(2);
+	    left();
+	    
+	    line(Color.PINK, Color.GREEN);
+	}
+	/* END SOLUTION */
+}
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.py b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.py
new file mode 100644
index 0000000..3463086
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.py
@@ -0,0 +1,38 @@
+# BEGIN SOLUTION
+def makeFlower(c):
+	setBrushColor(c)
+	brushDown()
+	forward(2)
+	backward()
+	left()
+	forward()
+	backward(2)
+	forward()
+	setBrushColor(Color.YELLOW)
+	brushUp()
+	right()   
+
+def line(c1, c2):
+	    makeFlower(c1);
+	    forward(3);
+	    makeFlower(c2);
+	    backward(5);    
+def halfLine(c):
+	    forward(2);
+	    makeFlower(c);
+	    backward(3);
+	
+def growFlowers():
+	    line(Color.RED, Color.CYAN);
+	    
+	    right();    
+	    forward(2);
+	    left();
+	    halfLine(Color.ORANGE);
+	    right();
+	    forward(2);
+	    left();
+	    
+	    line(Color.PINK, Color.GREEN);
+# END SOLUTION
+growFlowers()
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.scala b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.scala
new file mode 100644
index 0000000..0a053b0
--- /dev/null
+++ b/src/lessons/welcome/methods/flowerpot/FlowerPotEntity.scala
@@ -0,0 +1,51 @@
+package lessons.welcome.methods.flowerpot;
+
+import java.awt.Color;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaFlowerPotEntity extends SimpleBuggle {
+
+	def run() {
+	    growFlowers();
+	}
+	/* BEGIN SOLUTION */
+	def makeFlower(c: Color) {
+	    setBrushColor(c);
+	    brushDown();
+	    forward(2);
+	    backward();
+	    left();
+	    forward();
+	    backward(2);
+	    forward();
+	    setBrushColor(Color.YELLOW);
+	    brushUp();
+	    right();    
+	}
+
+	def line(c1:Color, c2: Color) {
+	    makeFlower(c1);
+	    forward(3);
+	    makeFlower(c2);
+	    backward(5);    
+	}
+	def halfLine(c:Color) {
+	    forward(2);
+	    makeFlower(c);
+	    backward(3);
+	}
+	def growFlowers() {
+	    line(Color.RED, Color.CYAN);
+	    
+	    right();    
+	    forward(2);
+	    left();
+	    halfLine(Color.ORANGE);
+	    right();
+	    forward(2);
+	    left();
+	    
+	    line(Color.PINK, Color.GREEN);
+	}
+	/* END SOLUTION */
+}
diff --git a/src/lessons/welcome/methods/picture/MethodsPicture-answer0.map b/src/lessons/welcome/methods/picture/MethodsPicture-answer0.map
index 80de987..8d420b4 100644
--- a/src/lessons/welcome/methods/picture/MethodsPicture-answer0.map
+++ b/src/lessons/welcome/methods/picture/MethodsPicture-answer0.map
@@ -1,15 +1,111 @@
 BuggleWorld: World
-Size: 5x5
-Buggle(0,4): east,black,green,Picasso
+Size: 15x15
+Buggle(0,14): east,black,green,Picasso
 Cell(0,1): green,nobaggle,notopwall,noleftwall,
 Cell(0,3): green,nobaggle,notopwall,noleftwall,
+Cell(0,6): green,nobaggle,notopwall,noleftwall,
+Cell(0,8): green,nobaggle,notopwall,noleftwall,
+Cell(0,11): green,nobaggle,notopwall,noleftwall,
+Cell(0,13): green,nobaggle,notopwall,noleftwall,
 Cell(1,0): blue,nobaggle,notopwall,noleftwall,
 Cell(1,2): green,nobaggle,notopwall,noleftwall,
 Cell(1,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(1,5): blue,nobaggle,notopwall,noleftwall,
+Cell(1,7): green,nobaggle,notopwall,noleftwall,
+Cell(1,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(1,10): blue,nobaggle,notopwall,noleftwall,
+Cell(1,12): green,nobaggle,notopwall,noleftwall,
+Cell(1,14): yellow,nobaggle,notopwall,noleftwall,
 Cell(2,1): blue,nobaggle,notopwall,noleftwall,
 Cell(2,3): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,6): blue,nobaggle,notopwall,noleftwall,
+Cell(2,8): yellow,nobaggle,notopwall,noleftwall,
+Cell(2,11): blue,nobaggle,notopwall,noleftwall,
+Cell(2,13): yellow,nobaggle,notopwall,noleftwall,
 Cell(3,0): blue,nobaggle,notopwall,noleftwall,
 Cell(3,2): red,nobaggle,notopwall,noleftwall,
 Cell(3,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(3,5): blue,nobaggle,notopwall,noleftwall,
+Cell(3,7): red,nobaggle,notopwall,noleftwall,
+Cell(3,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(3,10): blue,nobaggle,notopwall,noleftwall,
+Cell(3,12): red,nobaggle,notopwall,noleftwall,
+Cell(3,14): yellow,nobaggle,notopwall,noleftwall,
 Cell(4,1): red,nobaggle,notopwall,noleftwall,
 Cell(4,3): red,nobaggle,notopwall,noleftwall,
+Cell(4,6): red,nobaggle,notopwall,noleftwall,
+Cell(4,8): red,nobaggle,notopwall,noleftwall,
+Cell(4,11): red,nobaggle,notopwall,noleftwall,
+Cell(4,13): red,nobaggle,notopwall,noleftwall,
+Cell(5,1): green,nobaggle,notopwall,noleftwall,
+Cell(5,3): green,nobaggle,notopwall,noleftwall,
+Cell(5,6): green,nobaggle,notopwall,noleftwall,
+Cell(5,8): green,nobaggle,notopwall,noleftwall,
+Cell(5,11): green,nobaggle,notopwall,noleftwall,
+Cell(5,13): green,nobaggle,notopwall,noleftwall,
+Cell(6,0): blue,nobaggle,notopwall,noleftwall,
+Cell(6,2): green,nobaggle,notopwall,noleftwall,
+Cell(6,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,5): blue,nobaggle,notopwall,noleftwall,
+Cell(6,7): green,nobaggle,notopwall,noleftwall,
+Cell(6,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(6,10): blue,nobaggle,notopwall,noleftwall,
+Cell(6,12): green,nobaggle,notopwall,noleftwall,
+Cell(6,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(7,1): blue,nobaggle,notopwall,noleftwall,
+Cell(7,3): yellow,nobaggle,notopwall,noleftwall,
+Cell(7,6): blue,nobaggle,notopwall,noleftwall,
+Cell(7,8): yellow,nobaggle,notopwall,noleftwall,
+Cell(7,11): blue,nobaggle,notopwall,noleftwall,
+Cell(7,13): yellow,nobaggle,notopwall,noleftwall,
+Cell(8,0): blue,nobaggle,notopwall,noleftwall,
+Cell(8,2): red,nobaggle,notopwall,noleftwall,
+Cell(8,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(8,5): blue,nobaggle,notopwall,noleftwall,
+Cell(8,7): red,nobaggle,notopwall,noleftwall,
+Cell(8,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(8,10): blue,nobaggle,notopwall,noleftwall,
+Cell(8,12): red,nobaggle,notopwall,noleftwall,
+Cell(8,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(9,1): red,nobaggle,notopwall,noleftwall,
+Cell(9,3): red,nobaggle,notopwall,noleftwall,
+Cell(9,6): red,nobaggle,notopwall,noleftwall,
+Cell(9,8): red,nobaggle,notopwall,noleftwall,
+Cell(9,11): red,nobaggle,notopwall,noleftwall,
+Cell(9,13): red,nobaggle,notopwall,noleftwall,
+Cell(10,1): green,nobaggle,notopwall,noleftwall,
+Cell(10,3): green,nobaggle,notopwall,noleftwall,
+Cell(10,6): green,nobaggle,notopwall,noleftwall,
+Cell(10,8): green,nobaggle,notopwall,noleftwall,
+Cell(10,11): green,nobaggle,notopwall,noleftwall,
+Cell(10,13): green,nobaggle,notopwall,noleftwall,
+Cell(11,0): blue,nobaggle,notopwall,noleftwall,
+Cell(11,2): green,nobaggle,notopwall,noleftwall,
+Cell(11,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(11,5): blue,nobaggle,notopwall,noleftwall,
+Cell(11,7): green,nobaggle,notopwall,noleftwall,
+Cell(11,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(11,10): blue,nobaggle,notopwall,noleftwall,
+Cell(11,12): green,nobaggle,notopwall,noleftwall,
+Cell(11,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(12,1): blue,nobaggle,notopwall,noleftwall,
+Cell(12,3): yellow,nobaggle,notopwall,noleftwall,
+Cell(12,6): blue,nobaggle,notopwall,noleftwall,
+Cell(12,8): yellow,nobaggle,notopwall,noleftwall,
+Cell(12,11): blue,nobaggle,notopwall,noleftwall,
+Cell(12,13): yellow,nobaggle,notopwall,noleftwall,
+Cell(13,0): blue,nobaggle,notopwall,noleftwall,
+Cell(13,2): red,nobaggle,notopwall,noleftwall,
+Cell(13,4): yellow,nobaggle,notopwall,noleftwall,
+Cell(13,5): blue,nobaggle,notopwall,noleftwall,
+Cell(13,7): red,nobaggle,notopwall,noleftwall,
+Cell(13,9): yellow,nobaggle,notopwall,noleftwall,
+Cell(13,10): blue,nobaggle,notopwall,noleftwall,
+Cell(13,12): red,nobaggle,notopwall,noleftwall,
+Cell(13,14): yellow,nobaggle,notopwall,noleftwall,
+Cell(14,1): red,nobaggle,notopwall,noleftwall,
+Cell(14,3): red,nobaggle,notopwall,noleftwall,
+Cell(14,6): red,nobaggle,notopwall,noleftwall,
+Cell(14,8): red,nobaggle,notopwall,noleftwall,
+Cell(14,11): red,nobaggle,notopwall,noleftwall,
+Cell(14,13): red,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/picture/MethodsPicture.fr.html b/src/lessons/welcome/methods/picture/MethodsPicture.fr.html
index f542d74..94c43b5 100644
--- a/src/lessons/welcome/methods/picture/MethodsPicture.fr.html
+++ b/src/lessons/welcome/methods/picture/MethodsPicture.fr.html
@@ -1,44 +1,44 @@
-<h2>Dessiner avec méthode</h2>
+<h2>Dessins colorés</h2>
 
 Dans cet exercice, nous allons reproduire un dessin géométrique, que vous
-pouvez voir en cliquant sur l'onglet "Objective".
+pouvez voir en cliquant sur l'onglet «Objectif».
 
-<p class="Java">Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire
-une méthode <code>run()</code> la plus simple possible. Pour cela, vous
-veillerez à décomposer le travail à faire en sous-étape, et à faire réaliser
-chaque sous-étape par une méthode particulière.</p>
-
-<p class="Python">Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire
-une méthode principale la plus simple possible. Pour cela, vous veillerez à
-décomposer le travail à faire en sous-étape, et à faire réaliser chaque
-sous-étape par une méthode particulière.</p>
+<p>Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire le
+code le plus simple possible. Pour cela, vous veillerez à décomposer le
+travail à faire en sous-étape, et à faire réaliser chaque sous-étape par une
+méthode particulière.</p>
 
 <p>Si on observe attentivement le modèle à dessiner, on remarque qu'il est
 composé de quatre formes en sorte de V de couleurs différentes, et à des
 positions différentes.  Un découpage possible est d'écrire une fonction
 chargée de faire un V de la couleur indiquée à partir de la position
 courante. Son prototype peut être : 
-<pre class="Java">void makeV(Color c)</pre>
-<pre class="Python">makeV(c)</pre>
+<pre>[!java]void [/!]faireV([!java]Color [/!]c[!scala]: Color[/!])[!python]  <span class="comment"># le paramètre c est de type Color</span>[/!]</pre>
 
 <p>Le type de données <code>Color</code> représente naturellement une couleur
-en particulier.  Votre méthode <code>run()</code> invoquera sans doute
-<code>makeV</code> avec les arguments suivants (une couleur différente à
-chaque appel) :
+en particulier.  Votre code invoquera sans doute <code>faireV</code> avec
+les arguments suivants (une couleur différente à chaque appel) :
 <ul>
-<li>Color.yellow</li>
-<li>Color.red</li>
-<li>Color.blue</li>
-<li>Color.green</li>
+<li>Color.YELLOW (jaune)</li>
+<li>Color.RED (rouge)</li>
+<li>Color.BLUE (bleu)</li>
+<li>Color.GREEN (vert)</li>
 </ul>
 
-<p>Dans la méthode <code>makeV()</code>, il faut utiliser la méthode
-<code>setBrushColor()</code>, qui est prédéfinie dans la buggle, pour
-changer la couleur du pinceau, ainsi que <code>brushUp()</code> et
-<code>brushDown()</code> pour lever et baisser le pinceau.</p>
+<p>Dans la méthode <code>faireV()</code>, il faut utiliser la méthode
+<code>setCouleurBrosse()</code>, qui est prédéfinie dans la buggle, pour
+changer la couleur du pinceau, ainsi que <code>leveBrosse()</code> et
+<code>baisseBrosse()</code> pour lever et baisser le pinceau.</p>
  
-<p>Il faudrait également que la méthode <code>makeV()</code> place la buggle en
-position pour dessiner le prochain V directement.</p>
+<p>Il faudrait également que la méthode <code>faireV()</code> place la buggle
+en position pour dessiner le prochain V directement.</p>
  
-<p>À vous de jouer. La méthode <code>run()</code> ne devrait pas prendre plus
-de quatre lignes...</p>
+[!java|scala]
+<p>À vous de jouer. Je suis sûr que vous parviendrez à trouver d'autres
+méthodes à ajouter pour décomposer ce problème et faire en sorte que votre
+code reste simple et agréable à lire. Complétez la méthode
+<code>run()</code> qui sera appelée automatiquement une fois.
+[!java]Le mot-clé <code>public</code> signifie plus ou moins que tout le
+monde a le droit d'invoquer cette méthode. Ça tombe bien, l'infrastructure
+de la PLM va l'invoquer directement.[/!] </p>
+[/!]
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/picture/MethodsPicture.html b/src/lessons/welcome/methods/picture/MethodsPicture.html
index 673aece..0e6d8b6 100644
--- a/src/lessons/welcome/methods/picture/MethodsPicture.html
+++ b/src/lessons/welcome/methods/picture/MethodsPicture.html
@@ -1,41 +1,39 @@
-<h2>Methodically drawing</h2>
-
-In this exercise, we will reproduce the geometric drawing that you can see
-in the "Objective" tab.
-
-<p class="Java">Your goal (here and in any well written program) is to write the simplest
-possible <code>run()</code>. For that, you have to decompose your work in
-sub-steps, and write a specific method for each sub-step.</p>
-
-<p class="Python">Your goal (here and in any well written program) is to write the simplest
-possible main code. For that, you have to decompose your work in
-sub-steps, and write a specific method for each sub-step.</p>
-
-<p>If you observe carefully the picture to draw, it is constituted of four
-parts depicting a sort of V using a different color. A possible
-decomposition is to write a method in charge of drawing a V of the specified
-color from the current position. Its prototype can be: 
-<pre class="Java">void makeV(Color c)</pre>
-<pre class="Python">makeV(c)</pre>
-
-<p>The <code>Color</code> data type naturally describes a particular
-color. Your <code>run()</code> method should probably call
-<code>makeV</code> with the following arguments (a different color for each
-call):
-<ul>
-<li>Color.yellow</li>
-<li>Color.red</li>
-<li>Color.blue</li>
-<li>Color.green</li>
-</ul>
-
-<p>In <code>makeV()</code>, you should use the <code>setBrushColor()</code>
-method (predefined in the buggle) to change the color of the buggle's brush,
-as well as <code>brushUp()</code> and <code>brushDown()</code> to change the
-brush position.</p>
- 
-<p>It may be wise to write the <code>makeV()</code> so that it places directly
-the buggle in position for the next V.</p>
- 
-<p>Your turn. The <code>run()</code> method should not be longer than 4
-lines...</p>
+<h2>Colorful drawing</h2>
+
+In this exercise, we will reproduce the geometric drawing that you can see
+in the "Objective" tab.
+
+<p>Your goal (here and in any well written program) is to write the simplest
+possible code. For that, you have to decompose your work in
+sub-steps, and write a specific method for each sub-step.</p>
+
+<p>If you observe carefully the picture to draw, it is constituted of four
+parts depicting a sort of V using a different color. A possible
+decomposition is to write a method in charge of drawing a V of the specified
+color from the current position. Its prototype can be: 
+<pre>[!java]void [/!]makeV([!java]Color [/!]c[!scala]: Color[/!])[!python]  <span class="comment"># parameter c is of type Color</span>[/!]</pre>
+
+<p>The <code>Color</code> data type naturally describes a particular
+color. Your code should probably call <code>makeV</code> with the following arguments 
+(a different color for each call):
+<ul>
+<li>Color.YELLOW</li>
+<li>Color.RED</li>
+<li>Color.BLUE</li>
+<li>Color.GREEN</li>
+</ul>
+
+<p>In <code>makeV()</code>, you should use the <code>setBrushColor()</code>
+method (predefined in the buggle) to change the color of the buggle's brush,
+as well as <code>brushUp()</code> and <code>brushDown()</code> to change the
+brush position.</p>
+ 
+<p>It may be wise to write the <code>makeV()</code> so that it places directly
+the buggle in position for the next V.</p>
+ 
+[!java|scala]
+<p>Your turn now. I'm sure you can imagine the other methods you need to keep your code simple and pleasant to read. 
+Complete the run which prototype is already given. It will be called automatically (once). 
+[!java]the public keyword means more or less that anybody can call this method, which is good because the PLM 
+infrastructure calls it directly.[/!] </p>
+[/!]
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/picture/MethodsPicture.java b/src/lessons/welcome/methods/picture/MethodsPicture.java
index b40da3f..9da8799 100644
--- a/src/lessons/welcome/methods/picture/MethodsPicture.java
+++ b/src/lessons/welcome/methods/picture/MethodsPicture.java
@@ -2,19 +2,20 @@ package lessons.welcome.methods.picture;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class MethodsPicture extends ExerciseTemplated {
 
 	public MethodsPicture(Lesson lesson) {
 		super(lesson);
-		BuggleWorld myWorld =  new BuggleWorld("World",5,5);
-		new Buggle(myWorld, "Picasso", 0, 4, Direction.EAST, Color.black, Color.lightGray);
-		
+		BuggleWorld myWorld =  new BuggleWorld("World",15,15);
+		myWorld.setDelay(20);
+		new Buggle(myWorld, "Picasso", 0, 14, Direction.EAST, Color.black, Color.lightGray);
+
 		setup(myWorld);
 	}
 }
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureEntity.java b/src/lessons/welcome/methods/picture/MethodsPictureEntity.java
index 2b03eab..445a4e7 100644
--- a/src/lessons/welcome/methods/picture/MethodsPictureEntity.java
+++ b/src/lessons/welcome/methods/picture/MethodsPictureEntity.java
@@ -2,13 +2,16 @@ package lessons.welcome.methods.picture;
 
 import java.awt.Color;
 
-import jlm.universe.bugglequest.SimpleBuggle;
-/* The suppress warning is sometimes mandatory for student code to compile cleanly */
- at SuppressWarnings("unused")
-public class MethodsPictureEntity extends SimpleBuggle {
+public class MethodsPictureEntity extends plm.universe.bugglequest.SimpleBuggle {
 
 	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
+	public void run() {
+		/* BEGIN SOLUTION */
+		for (int i=0; i<3;i++) {
+			makeLine(3);
+			nextLine();
+		}
+	}
 	void mark() {
 		brushDown();
 		brushUp();
@@ -20,27 +23,38 @@ public class MethodsPictureEntity extends SimpleBuggle {
 		mark();
 
 		forward();
-		turnLeft();
+		left();
 		forward();
 		mark();
 
 		backward();
-		turnRight();
+		right();
 		forward();
 		mark();
 
 		forward();
-		turnLeft();
+		left();
 	}
 
-
-
-	public void run() {
+	void makePattern() {
 		makeV(Color.YELLOW);
 		makeV(Color.RED);
 		makeV(Color.BLUE);
 		makeV(Color.GREEN);
+		forward(5);
+	}
+
+	void makeLine(int count){
+		for (int i=0; i<count;i++)
+			makePattern();
+		backward(count*5);
+	}
+
+	void nextLine() {
+		left();
+		forward(5);
+		right();	
+		/* END SOLUTION */
 	}
-	/* END SOLUTION */
 	/* END TEMPLATE */
 }
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureEntity.py b/src/lessons/welcome/methods/picture/MethodsPictureEntity.py
index 4e6b0f3..7563422 100644
--- a/src/lessons/welcome/methods/picture/MethodsPictureEntity.py
+++ b/src/lessons/welcome/methods/picture/MethodsPictureEntity.py
@@ -10,19 +10,34 @@ def makeV(c):
    forward()
    mark()
    forward()
-   turnLeft()
+   left()
    forward()
    mark()
    backward()
-   turnRight()
+   right()
    forward()
    mark()   
    forward()
-   turnLeft()
+   left()
 
+def makePattern():
+   makeV(Color.yellow)
+   makeV(Color.red)
+   makeV(Color.blue)
+   makeV(Color.green)
+   forward(5)
 
-makeV(Color.yellow)
-makeV(Color.red)
-makeV(Color.blue)
-makeV(Color.green)
+def makeLine(count):
+   for i in range(count):
+      makePattern()
+   backward(count*5)
+
+def nextLine():
+   left()
+   forward(5)
+   right()
+
+for i in range(3):
+   makeLine(3)
+   nextLine()
 # END SOLUTION
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureEntity.scala b/src/lessons/welcome/methods/picture/MethodsPictureEntity.scala
new file mode 100644
index 0000000..5c374ce
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureEntity.scala
@@ -0,0 +1,61 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+import plm.universe.bugglequest.SimpleBuggle
+
+class ScalaMethodsPictureEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 3) {
+			makeLine(3);
+			nextLine();
+		}
+	}
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def makeV(c:Color) {
+		setBrushColor(c);
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	def makePattern() {
+		makeV(Color.YELLOW);
+		makeV(Color.RED);
+		makeV(Color.BLUE);
+		makeV(Color.GREEN);
+		forward(5);
+	}
+
+	def makeLine(count: Int){
+		for (i <- 1 to count)
+			makePattern();
+		backward(count*5);
+	}
+
+	def nextLine() {
+		left();
+		forward(5);
+		right();	
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3-answer0.map b/src/lessons/welcome/methods/picture/MethodsPictureLarge-answer0.map
similarity index 100%
rename from src/lessons/welcome/methods/picture3/MethodsPicture3-answer0.map
rename to src/lessons/welcome/methods/picture/MethodsPictureLarge-answer0.map
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLarge.fr.html b/src/lessons/welcome/methods/picture/MethodsPictureLarge.fr.html
new file mode 100644
index 0000000..d2a4c92
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLarge.fr.html
@@ -0,0 +1,12 @@
+<h2>Grand dessin coloré</h2>
+
+Vous vous en doutez, il vous faut encore une fois reproduire un dessin
+géométrique dont le modèle se trouve dans l'onglet «Objectif». Comme vous le
+voyez, il est encore plus grand que le précédent.
+
+<p>Il va donc falloir définir encore plus de méthodes afin de tirer partie des
+répétitions du motif pour factoriser votre code. Ou alors, il va falloir
+<i>paramétrer</i> vos fonctions pour réutiliser ce que vous aviez écrit en
+changant les tailles.  
+
+<p>À vous de jouer...</p>
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLarge.html b/src/lessons/welcome/methods/picture/MethodsPictureLarge.html
new file mode 100644
index 0000000..47ee2d5
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLarge.html
@@ -0,0 +1,11 @@
+<h2>Larger colorful drawing</h2>
+
+As you can imagine, you have to reproduce the geometric drawing depicted in
+the "Objectives" tab. As you can see, it is even bigger than the previous
+one.
+
+<p>You thus have to declare even more methods to use the repetitions of the
+pattern and factorize your code. Another solution is to <i>parametrize</i>
+your functions to reuse the code you wrote previously by changing the size.  
+
+<p>Your turn...</p>
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLarge.java b/src/lessons/welcome/methods/picture/MethodsPictureLarge.java
new file mode 100644
index 0000000..2b5c276
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLarge.java
@@ -0,0 +1,21 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class MethodsPictureLarge extends ExerciseTemplated {
+
+	public MethodsPictureLarge(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",45,45);
+		myWorld.setDelay(5);
+		new Buggle(myWorld, "Picasso", 0, 44, Direction.EAST, Color.black, Color.lightGray);
+				
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.java b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.java
new file mode 100644
index 0000000..1f59fa5
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.java
@@ -0,0 +1,62 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class MethodsPictureLargeEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		for (int i=0; i<9; i++) {
+			makeLine(9);
+			nextLine();
+		}
+	}
+	void mark() {
+		brushDown();
+		brushUp();
+	}
+
+	void makeV(Color c) {
+		setBrushColor(c);
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	void makePattern() {
+		makeV(Color.YELLOW);
+		makeV(Color.RED);
+		makeV(Color.BLUE);
+		makeV(Color.GREEN);
+		forward(5);
+	}
+
+	void makeLine(int count){
+		for (int i=0; i<count;i++)
+			makePattern();
+		backward(count*5);
+	}
+
+	void nextLine() {
+		left();
+		forward(5);
+		right();	
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.py b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.py
new file mode 100644
index 0000000..088499c
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.py
@@ -0,0 +1,43 @@
+import java.awt.Color as Color
+
+# BEGIN SOLUTION
+def mark():
+   brushDown()
+   brushUp()
+
+def makeV(c):
+   setBrushColor(c)
+   forward()
+   mark()
+   forward()
+   left()
+   forward()
+   mark()
+   backward()
+   right()
+   forward()
+   mark()   
+   forward()
+   left()
+
+def makePattern():
+   makeV(Color.yellow)
+   makeV(Color.red)
+   makeV(Color.blue)
+   makeV(Color.green)
+   forward(5)
+
+def makeLine(count):
+   for i in range(count):
+      makePattern()
+   backward(count*5)
+
+def nextLine():
+   left()
+   forward(5)
+   right()
+
+for i in range(9):
+   makeLine(9)
+   nextLine()
+# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.scala b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.scala
new file mode 100644
index 0000000..14ae811
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/MethodsPictureLargeEntity.scala
@@ -0,0 +1,62 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaMethodsPictureLargeEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		for (i <- 1 to 9) {
+			makeLine(9);
+			nextLine();
+		}
+	}
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def makeV(c:Color) {
+		setBrushColor(c);
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	def makePattern() {
+		makeV(Color.YELLOW);
+		makeV(Color.RED);
+		makeV(Color.BLUE);
+		makeV(Color.GREEN);
+		forward(5);
+	}
+
+	def makeLine(count: Int){
+		for (i<- 1 to count)
+			makePattern();
+		backward(count*5);
+	}
+
+	def nextLine() {
+		left();
+		forward(5);
+		right();	
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4-answer0.map b/src/lessons/welcome/methods/picture/PatternPicture-answer0.map
similarity index 100%
rename from src/lessons/welcome/methods/picture4/MethodsPicture4-answer0.map
rename to src/lessons/welcome/methods/picture/PatternPicture-answer0.map
diff --git a/src/lessons/welcome/methods/picture/PatternPicture.fr.html b/src/lessons/welcome/methods/picture/PatternPicture.fr.html
new file mode 100644
index 0000000..9cc1d2c
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPicture.fr.html
@@ -0,0 +1,10 @@
+<h2>Autre motif coloré</h2>
+
+Voici de nouveau un exercice où il faut reproduire un motif donné dans
+l'onglet «Objectif».
+
+<p>Celui-ci est un peu plus difficile que ceux vus précédement. Cherchez les
+motifs qui se répètent, même si la couleur change, et faites une méthode
+dessinant chacun d'entre eux.</p>
+ 
+<p>Bon courage !</p>
diff --git a/src/lessons/welcome/methods/picture/PatternPicture.html b/src/lessons/welcome/methods/picture/PatternPicture.html
new file mode 100644
index 0000000..d643ef9
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPicture.html
@@ -0,0 +1,10 @@
+<h2>Another Colorful Pattern</h2>
+
+Here is yet another exercise where you have to reproduce the pattern
+provided in the "Objective" tab.
+
+<p>This one is a bit more difficult than the one seen previously. Look for
+repeating patterns, even if the color changes, and write a method drawing
+each of them.</p>
+ 
+<p>Good luck!</p>
diff --git a/src/lessons/welcome/methods/picture/PatternPicture.java b/src/lessons/welcome/methods/picture/PatternPicture.java
new file mode 100644
index 0000000..a75e46f
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPicture.java
@@ -0,0 +1,26 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class PatternPicture extends ExerciseTemplated {
+
+	public PatternPicture(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",8,8);
+		
+		for (int i=0;i<8;i++) {
+			myWorld.putTopWall (i, 0);
+			myWorld.putLeftWall(0, i);
+		}
+		
+		new Buggle(myWorld, "Picasso", 0, 7, Direction.EAST, Color.black, Color.lightGray);
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/picture/PatternPictureEntity.java b/src/lessons/welcome/methods/picture/PatternPictureEntity.java
new file mode 100644
index 0000000..1ba1bb3
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPictureEntity.java
@@ -0,0 +1,85 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class PatternPictureEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		bigSquare();
+		forward(4);
+		bigSquare();
+
+		backward(4);
+		left();
+		forward(4);
+		right();
+
+		bigSquare(); 
+		forward(4);
+		bigSquare();
+	}
+	void mark() {
+		brushDown();
+		brushUp();
+	}
+
+	void squareA(Color c) {
+		setBrushColor(c);
+
+		forward();
+		mark();
+
+		left();
+		forward();
+
+		left();
+		forward();
+		mark();
+
+		left();
+		forward();
+		left();
+	}
+
+	void squareB(Color c) {
+		setBrushColor(c);
+		mark();
+
+		forward();
+
+		left();
+		forward();
+		mark();
+
+		left();
+		forward();
+
+		left();
+		forward();
+		left();
+	}
+
+	void bigSquare() {
+		squareA(Color.RED); 
+		forward(2);
+		squareB(Color.BLUE);
+		backward(2);
+		left();
+		forward(2);
+		right();
+		squareB(Color.YELLOW);
+		forward(2);
+		squareA(Color.GREEN);
+
+		backward(2);
+		left();
+		backward(2);
+		right();
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PatternPictureEntity.py b/src/lessons/welcome/methods/picture/PatternPictureEntity.py
new file mode 100644
index 0000000..e0103ee
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPictureEntity.py
@@ -0,0 +1,63 @@
+import java.awt.Color as Color
+
+# BEGIN SOLUTION
+def mark():
+   brushDown()
+   brushUp()
+
+def squareA(c):
+   setBrushColor(c)
+   forward()
+   mark()
+   left()
+   forward()
+   left()
+   forward()
+   mark()
+   left()
+   forward()
+   left()
+   
+def squareB(c):
+   setBrushColor(c)
+   mark()
+   forward()
+   left()
+   forward()
+   mark()
+   left()
+   forward()
+   left()
+   forward()
+   left()
+
+def bigSquare():
+   squareA(Color.red)
+   forward(2)
+   squareB(Color.blue)
+   backward(2)
+   left()
+   forward(2)
+   right()
+   squareB(Color.yellow)
+   forward(2)
+   squareA(Color.green)
+   backward(2)
+   left()
+   backward(2)
+   right()
+	
+bigSquare()
+forward(4)
+bigSquare()
+		
+backward(4)
+left()
+forward(4)
+right()
+		
+bigSquare() 
+forward(4)
+bigSquare()
+# END SOLUTION
+
diff --git a/src/lessons/welcome/methods/picture/PatternPictureEntity.scala b/src/lessons/welcome/methods/picture/PatternPictureEntity.scala
new file mode 100644
index 0000000..cdc2355
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PatternPictureEntity.scala
@@ -0,0 +1,85 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaPatternPictureEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		bigSquare();
+		forward(4);
+		bigSquare();
+
+		backward(4);
+		left();
+		forward(4);
+		right();
+
+		bigSquare(); 
+		forward(4);
+		bigSquare();
+	}
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def squareA(c:Color) {
+		setBrushColor(c);
+
+		forward();
+		mark();
+
+		left();
+		forward();
+
+		left();
+		forward();
+		mark();
+
+		left();
+		forward();
+		left();
+	}
+
+	def squareB(c: Color) {
+		setBrushColor(c);
+		mark();
+
+		forward();
+
+		left();
+		forward();
+		mark();
+
+		left();
+		forward();
+
+		left();
+		forward();
+		left();
+	}
+
+	def bigSquare() {
+		squareA(Color.RED); 
+		forward(2);
+		squareB(Color.BLUE);
+		backward(2);
+		left();
+		forward(2);
+		right();
+		squareB(Color.YELLOW);
+		forward(2);
+		squareA(Color.GREEN);
+
+		backward(2);
+		left();
+		backward(2);
+		right();
+	/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono-answer0.map b/src/lessons/welcome/methods/picture/PictureMono-answer0.map
new file mode 100644
index 0000000..2b91b08
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono-answer0.map
@@ -0,0 +1,15 @@
+BuggleWorld: World
+Size: 5x5
+Buggle(0,4): east,black,lightGray,Picasso
+Cell(0,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,3): lightGray,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/picture/PictureMono.fr.html b/src/lessons/welcome/methods/picture/PictureMono.fr.html
new file mode 100644
index 0000000..c1d89e8
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono.fr.html
@@ -0,0 +1,24 @@
+<h2>Dessiner avec méthode</h2>
+
+Dans cet exercice, nous allons reproduire un dessin géométrique, que vous
+pouvez voir en cliquant sur l'onglet «Objectif».
+
+<p>Votre objectif (ici, et dans tous les programmes bien faits) est d'écrire le
+code le plus simple possible. Pour cela, vous veillerez à décomposer le
+travail à faire en sous-étape, et à faire réaliser chaque sous-étape par une
+méthode particulière.</p>
+
+<p>Si on observe attentivement le modèle à dessiner, on remarque qu'il est
+composé de quatre formes en sorte de V à des positions différentes.  Un
+découpage possible est d'écrire une fonction chargée de faire un V à partir
+de la position courante. Son prototype peut être : <code>[!java]void
+[/!]faireV()</code></p>
+
+<p>Dans cette méthode, vous devez utiliser les méthodes
+<code>baisseBrosse()</code> et <code>leveBrosse()</code> pour marquer le
+sol. Peut-être que marquer le sol devrait faire l'objet d'une méthode
+séparée? Il faudrait également que  méthode <code>faireV()</code> place
+directement la buggle en position pour dessiner le prochain V.</p>
+ 
+<p>À vous de jouer. Votre code ne devrait pas prendre plus de quatre lignes
+(sans compter <code>faireV</code>)...</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono.html b/src/lessons/welcome/methods/picture/PictureMono.html
new file mode 100644
index 0000000..9b603a9
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono.html
@@ -0,0 +1,21 @@
+<h2>Methodically drawing</h2>
+
+In this exercise, we will reproduce the geometric drawing that you can see
+in the "Objective" tab.
+
+<p>Your goal (here and in any well written program) is to write the simplest
+possible code. For that, you have to decompose your work in
+sub-steps, and write a specific method for each sub-step.</p>
+
+<p>If you observe carefully the picture to draw, it is constituted of four
+parts depicting a sort of V. A possible decomposition is to write a method 
+in charge of drawing a V from the current position. Its prototype can be: 
+<code>[!java]void [/!]makeV()</code></p>
+
+<p>In this method, you should use the methods <code>brushUp()</code> and
+<code>brushDown()</code> to mark the ground (you may want to factorize this in another
+method). It may be wise to write the <code>makeV()</code> so that it places directly 
+the buggle in position for the next V.</p>
+ 
+<p>Your turn. Your code of should not be longer than 4 lines (not counting 
+<code>makeV</code>)...</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono.java b/src/lessons/welcome/methods/picture/PictureMono.java
new file mode 100644
index 0000000..d93d0c4
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono.java
@@ -0,0 +1,20 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class PictureMono extends ExerciseTemplated {
+
+	public PictureMono(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",5,5);
+		new Buggle(myWorld, "Picasso", 0, 4, Direction.EAST, Color.black, Color.lightGray);
+		
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono2-answer0.map b/src/lessons/welcome/methods/picture/PictureMono2-answer0.map
new file mode 100644
index 0000000..e265217
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2-answer0.map
@@ -0,0 +1,111 @@
+BuggleWorld: World
+Size: 15x15
+Buggle(0,14): east,black,lightGray,Picasso
+Cell(0,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,13): lightGray,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/picture/PictureMono2.fr.html b/src/lessons/welcome/methods/picture/PictureMono2.fr.html
new file mode 100644
index 0000000..59c2a4c
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2.fr.html
@@ -0,0 +1,18 @@
+<h2>Dessiner avec méthode (en plus grand)</h2>
+
+Nous allons maintenant reproduire un dessin géométrique plus grand. Encore
+une fois, vous pouvez voir le modèle en cliquant sur l'onglet «Objectif».
+
+<p>Vous pouvez bien entendu réutiliser tout le code que vous aviez tapé à
+l'exercice précédent (sélectionnez l'autre exercice, allez dans le code,
+sélectionner tout, faites Ctrl-C, revenez dans le code de l'exercice
+courant, faites Ctrl-V).</p>
+
+<p>Mais pour que votre méthode principale reste aussi simple que possible, il
+faudra définir de nouvelles méthodes afin de gérer simplement les répétions
+du motif. Par exemple, une méthode <code>faireMotif()</code> réalisant le
+motif de l'exercice précédent semble être un bon départ (mais ce n'est sans
+doute pas suffisant).</p> 
+
+<p>À vous de jouer. Le code principal ne devrait pas prendre plus de 2 lignes (
+incluses dans une boucle for).</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono2.html b/src/lessons/welcome/methods/picture/PictureMono2.html
new file mode 100644
index 0000000..56c4c74
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2.html
@@ -0,0 +1,16 @@
+<h2>Methodically drawing (only bigger)</h2>
+
+We will now reproduce an even bigger geometrical drawing. Once again, you
+can see the model by clicking on the "Objective" tab.
+
+<p>You can naturally reuse all the code you typed in previous exercise (select
+the other exercise, do Ctrl-C, come back to the code of this exercise, do
+Ctrl-V).</p>
+
+<p>But you want to keep your code as simple as possible. For that, define new 
+methods to deal simply with the repetitions in the pattern. For example, a method
+<code>makePattern()</code> achieving the pattern of previous example seems to 
+be a good idea (but this may not be enough).</p> 
+
+<p>Why don't you give it a shot? The main code method shouldn't take
+more than 2 lines (included in a for loop)</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono2.java b/src/lessons/welcome/methods/picture/PictureMono2.java
new file mode 100644
index 0000000..12b33ec
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2.java
@@ -0,0 +1,21 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class PictureMono2 extends ExerciseTemplated {
+
+	public PictureMono2(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",15,15);
+		myWorld.setDelay(20);
+		new Buggle(myWorld, "Picasso", 0, 14, Direction.EAST, Color.black, Color.lightGray);
+
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono2Entity.java b/src/lessons/welcome/methods/picture/PictureMono2Entity.java
new file mode 100644
index 0000000..68a303d
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2Entity.java
@@ -0,0 +1,59 @@
+package lessons.welcome.methods.picture;
+
+
+public class PictureMono2Entity extends plm.universe.bugglequest.SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	void mark() {
+		brushDown();
+		brushUp();
+	}
+
+	void makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	void makePattern() {
+		makeV();
+		makeV();
+		makeV();
+		makeV();
+		forward(5);
+	}
+
+	void makeLine(int count){
+		for (int i=0; i<count;i++)
+			makePattern();
+		backward(count*5);
+	}
+
+	void nextLine() {
+		left();
+		forward(5);
+		right();	
+	}
+
+	public void run() {
+		for (int i=0; i<3;i++) {
+			makeLine(3);
+			nextLine();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono2Entity.py b/src/lessons/welcome/methods/picture/PictureMono2Entity.py
new file mode 100644
index 0000000..13b18a6
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2Entity.py
@@ -0,0 +1,38 @@
+# BEGIN SOLUTION
+def mark():
+   brushDown()
+   brushUp()
+
+def makeV():
+   forward()
+   mark()
+   forward()
+   left()
+   forward()
+   mark()
+   backward()
+   right()
+   forward()
+   mark()   
+   forward()
+   left()
+
+def makePattern():
+    for i in range(4):
+        makeV()
+    forward(5)
+
+def makeLine(count):
+   for i in range(count):
+      makePattern()
+   backward(count*5)
+
+def nextLine():
+   left()
+   forward(5)
+   right()
+
+for i in range(3):
+   makeLine(3)
+   nextLine()
+# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture/PictureMono2Entity.scala b/src/lessons/welcome/methods/picture/PictureMono2Entity.scala
new file mode 100644
index 0000000..ccefab0
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono2Entity.scala
@@ -0,0 +1,58 @@
+package lessons.welcome.methods.picture;
+
+
+class ScalaPictureMono2Entity extends plm.universe.bugglequest.SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	def makePattern() {
+	  for (i <- 1 to 4) {
+		  makeV();
+	  }
+	  forward(5);
+	}
+
+	def makeLine(count: Int){
+		for (i <- 1 to count)
+			makePattern();
+		backward(count*5);
+	}
+
+	def nextLine() {
+		left();
+		forward(5);
+		right();	
+	}
+
+	override def run() {
+		for (i <- 1 to 3) {
+			makeLine(3);
+			nextLine();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono3-answer0.map b/src/lessons/welcome/methods/picture/PictureMono3-answer0.map
new file mode 100644
index 0000000..fabc668
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3-answer0.map
@@ -0,0 +1,975 @@
+BuggleWorld: World
+Size: 45x45
+Buggle(0,44): east,black,lightGray,Picasso
+Cell(0,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(0,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(1,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(2,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(3,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(4,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(5,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(6,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(7,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(8,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(9,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(10,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(11,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(12,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(13,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(14,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(15,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(16,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(17,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(18,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(19,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(20,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(21,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(22,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(23,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(24,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(25,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(26,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(27,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(28,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(29,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(30,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(31,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(32,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(33,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(34,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(35,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(36,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(37,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(38,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(39,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(40,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(41,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(42,43): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,0): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,2): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,4): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,5): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,7): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,9): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,10): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,12): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,14): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,15): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,17): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,19): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,20): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,22): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,24): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,25): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,27): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,29): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,30): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,32): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,34): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,35): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,37): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,39): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,40): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,42): lightGray,nobaggle,notopwall,noleftwall,
+Cell(43,44): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,1): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,3): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,6): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,8): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,11): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,13): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,16): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,18): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,21): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,23): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,26): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,28): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,31): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,33): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,36): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,38): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,41): lightGray,nobaggle,notopwall,noleftwall,
+Cell(44,43): lightGray,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/picture/PictureMono3.fr.html b/src/lessons/welcome/methods/picture/PictureMono3.fr.html
new file mode 100644
index 0000000..c398d8f
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3.fr.html
@@ -0,0 +1,8 @@
+<h2>Dessiner de plus en plus grand</h2>
+
+Vous vous en doutez, il vous faut encore une fois reproduire un dessin
+géométrique dont le modèle se trouve dans l'onglet «Objectif». Comme vous le
+voyez, il est encore plus grand que le précédent.
+
+<p>Il va donc falloir définir encore plus de méthodes afin de tirer partie des
+répétitions du motif pour factoriser votre code. À vous de jouer...</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono3.html b/src/lessons/welcome/methods/picture/PictureMono3.html
new file mode 100644
index 0000000..0100e5c
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3.html
@@ -0,0 +1,8 @@
+<h2>Drawing bigger and bigger</h2>
+
+As you can imagine, you have to reproduce the geometric drawing depicted in
+the "Objectives" tab. As you can see, it is even bigger than the previous
+one.
+
+<p>You thus have to declare even more methods to use the repetitions of the
+pattern and factorize your code.  Your turn...</p>
diff --git a/src/lessons/welcome/methods/picture/PictureMono3.java b/src/lessons/welcome/methods/picture/PictureMono3.java
new file mode 100644
index 0000000..52b491d
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3.java
@@ -0,0 +1,21 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class PictureMono3 extends ExerciseTemplated {
+
+	public PictureMono3(Lesson lesson) {
+		super(lesson);
+		BuggleWorld myWorld =  new BuggleWorld("World",45,45);
+		myWorld.setDelay(5);
+		new Buggle(myWorld, "Picasso", 0, 44, Direction.EAST, Color.black, Color.lightGray);
+				
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono3Entity.java b/src/lessons/welcome/methods/picture/PictureMono3Entity.java
new file mode 100644
index 0000000..9761e7a
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3Entity.java
@@ -0,0 +1,60 @@
+package lessons.welcome.methods.picture;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class PictureMono3Entity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	void mark() {
+		brushDown();
+		brushUp();
+	}
+
+	void makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	void makePattern() {
+		makeV();
+		makeV();
+		makeV();
+		makeV();
+		forward(5);
+	}
+
+	void makeLine(int count){
+		for (int i=0; i<count;i++)
+			makePattern();
+		backward(count*5);
+	}
+
+	void nextLine() {
+		left();
+		forward(5);
+		right();	
+	}
+
+	public void run() {
+		for (int i=0; i<9; i++) {
+			makeLine(9);
+			nextLine();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMono3Entity.py b/src/lessons/welcome/methods/picture/PictureMono3Entity.py
new file mode 100644
index 0000000..e1ed066
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3Entity.py
@@ -0,0 +1,38 @@
+# BEGIN SOLUTION
+def mark():
+   brushDown()
+   brushUp()
+
+def makeV():
+   forward()
+   mark()
+   forward()
+   left()
+   forward()
+   mark()
+   backward()
+   right()
+   forward()
+   mark()   
+   forward()
+   left()
+
+def makePattern():
+    for i in range(4):
+        makeV()
+    forward(5)
+
+def makeLine(count):
+   for i in range(count):
+      makePattern()
+   backward(count*5)
+
+def nextLine():
+   left()
+   forward(5)
+   right()
+
+for i in range(9):
+   makeLine(9)
+   nextLine()
+# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture/PictureMono3Entity.scala b/src/lessons/welcome/methods/picture/PictureMono3Entity.scala
new file mode 100644
index 0000000..a15eec7
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMono3Entity.scala
@@ -0,0 +1,60 @@
+package lessons.welcome.methods.picture;
+
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaPictureMono3Entity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+	def makePattern() {
+		makeV();
+		makeV();
+		makeV();
+		makeV();
+		forward(5);
+	}
+
+	def makeLine(count: Int){
+		for (i <- 1 to count)
+			makePattern();
+		backward(count*5);
+	}
+
+	def nextLine() {
+		left();
+		forward(5);
+		right();	
+	}
+
+	def run() {
+		for (i <- 1 to 9) {
+			makeLine(9);
+			nextLine();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMonoEntity.java b/src/lessons/welcome/methods/picture/PictureMonoEntity.java
new file mode 100644
index 0000000..1da824e
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMonoEntity.java
@@ -0,0 +1,39 @@
+package lessons.welcome.methods.picture;
+
+import plm.universe.bugglequest.SimpleBuggle;
+public class PictureMonoEntity extends SimpleBuggle {
+
+	/* BEGIN SOLUTION */
+	void mark() {
+		brushDown();
+		brushUp();
+	}
+
+	void makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+
+
+	public void run() {
+		makeV();
+		makeV();
+		makeV();
+		makeV();
+	}
+	/* END SOLUTION */
+}
diff --git a/src/lessons/welcome/methods/picture/PictureMonoEntity.py b/src/lessons/welcome/methods/picture/PictureMonoEntity.py
new file mode 100644
index 0000000..7e74a14
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMonoEntity.py
@@ -0,0 +1,23 @@
+# BEGIN SOLUTION
+def mark():
+   brushDown()
+   brushUp()
+
+def makeV():
+   forward()
+   mark()
+   forward()
+   left()
+   forward()
+   mark()
+   backward()
+   right()
+   forward()
+   mark()   
+   forward()
+   left()
+
+
+for i in range(4):
+    makeV()
+# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture/PictureMonoEntity.scala b/src/lessons/welcome/methods/picture/PictureMonoEntity.scala
new file mode 100644
index 0000000..e753f96
--- /dev/null
+++ b/src/lessons/welcome/methods/picture/PictureMonoEntity.scala
@@ -0,0 +1,42 @@
+package lessons.welcome.methods.picture;
+
+import java.awt.Color;
+
+import plm.universe.bugglequest.SimpleBuggle;
+class ScalaPictureMonoEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	def mark() {
+		brushDown();
+		brushUp();
+	}
+
+	def makeV() {
+		forward();
+		mark();
+
+		forward();
+		left();
+		forward();
+		mark();
+
+		backward();
+		right();
+		forward();
+		mark();
+
+		forward();
+		left();
+	}
+
+
+
+	override def run() {
+		for (i <- 1 to 4) {
+			makeV();
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2-answer0.map b/src/lessons/welcome/methods/picture2/MethodsPicture2-answer0.map
deleted file mode 100644
index 8d420b4..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2-answer0.map
+++ /dev/null
@@ -1,111 +0,0 @@
-BuggleWorld: World
-Size: 15x15
-Buggle(0,14): east,black,green,Picasso
-Cell(0,1): green,nobaggle,notopwall,noleftwall,
-Cell(0,3): green,nobaggle,notopwall,noleftwall,
-Cell(0,6): green,nobaggle,notopwall,noleftwall,
-Cell(0,8): green,nobaggle,notopwall,noleftwall,
-Cell(0,11): green,nobaggle,notopwall,noleftwall,
-Cell(0,13): green,nobaggle,notopwall,noleftwall,
-Cell(1,0): blue,nobaggle,notopwall,noleftwall,
-Cell(1,2): green,nobaggle,notopwall,noleftwall,
-Cell(1,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(1,5): blue,nobaggle,notopwall,noleftwall,
-Cell(1,7): green,nobaggle,notopwall,noleftwall,
-Cell(1,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(1,10): blue,nobaggle,notopwall,noleftwall,
-Cell(1,12): green,nobaggle,notopwall,noleftwall,
-Cell(1,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(2,1): blue,nobaggle,notopwall,noleftwall,
-Cell(2,3): yellow,nobaggle,notopwall,noleftwall,
-Cell(2,6): blue,nobaggle,notopwall,noleftwall,
-Cell(2,8): yellow,nobaggle,notopwall,noleftwall,
-Cell(2,11): blue,nobaggle,notopwall,noleftwall,
-Cell(2,13): yellow,nobaggle,notopwall,noleftwall,
-Cell(3,0): blue,nobaggle,notopwall,noleftwall,
-Cell(3,2): red,nobaggle,notopwall,noleftwall,
-Cell(3,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(3,5): blue,nobaggle,notopwall,noleftwall,
-Cell(3,7): red,nobaggle,notopwall,noleftwall,
-Cell(3,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(3,10): blue,nobaggle,notopwall,noleftwall,
-Cell(3,12): red,nobaggle,notopwall,noleftwall,
-Cell(3,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(4,1): red,nobaggle,notopwall,noleftwall,
-Cell(4,3): red,nobaggle,notopwall,noleftwall,
-Cell(4,6): red,nobaggle,notopwall,noleftwall,
-Cell(4,8): red,nobaggle,notopwall,noleftwall,
-Cell(4,11): red,nobaggle,notopwall,noleftwall,
-Cell(4,13): red,nobaggle,notopwall,noleftwall,
-Cell(5,1): green,nobaggle,notopwall,noleftwall,
-Cell(5,3): green,nobaggle,notopwall,noleftwall,
-Cell(5,6): green,nobaggle,notopwall,noleftwall,
-Cell(5,8): green,nobaggle,notopwall,noleftwall,
-Cell(5,11): green,nobaggle,notopwall,noleftwall,
-Cell(5,13): green,nobaggle,notopwall,noleftwall,
-Cell(6,0): blue,nobaggle,notopwall,noleftwall,
-Cell(6,2): green,nobaggle,notopwall,noleftwall,
-Cell(6,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(6,5): blue,nobaggle,notopwall,noleftwall,
-Cell(6,7): green,nobaggle,notopwall,noleftwall,
-Cell(6,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(6,10): blue,nobaggle,notopwall,noleftwall,
-Cell(6,12): green,nobaggle,notopwall,noleftwall,
-Cell(6,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(7,1): blue,nobaggle,notopwall,noleftwall,
-Cell(7,3): yellow,nobaggle,notopwall,noleftwall,
-Cell(7,6): blue,nobaggle,notopwall,noleftwall,
-Cell(7,8): yellow,nobaggle,notopwall,noleftwall,
-Cell(7,11): blue,nobaggle,notopwall,noleftwall,
-Cell(7,13): yellow,nobaggle,notopwall,noleftwall,
-Cell(8,0): blue,nobaggle,notopwall,noleftwall,
-Cell(8,2): red,nobaggle,notopwall,noleftwall,
-Cell(8,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(8,5): blue,nobaggle,notopwall,noleftwall,
-Cell(8,7): red,nobaggle,notopwall,noleftwall,
-Cell(8,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(8,10): blue,nobaggle,notopwall,noleftwall,
-Cell(8,12): red,nobaggle,notopwall,noleftwall,
-Cell(8,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(9,1): red,nobaggle,notopwall,noleftwall,
-Cell(9,3): red,nobaggle,notopwall,noleftwall,
-Cell(9,6): red,nobaggle,notopwall,noleftwall,
-Cell(9,8): red,nobaggle,notopwall,noleftwall,
-Cell(9,11): red,nobaggle,notopwall,noleftwall,
-Cell(9,13): red,nobaggle,notopwall,noleftwall,
-Cell(10,1): green,nobaggle,notopwall,noleftwall,
-Cell(10,3): green,nobaggle,notopwall,noleftwall,
-Cell(10,6): green,nobaggle,notopwall,noleftwall,
-Cell(10,8): green,nobaggle,notopwall,noleftwall,
-Cell(10,11): green,nobaggle,notopwall,noleftwall,
-Cell(10,13): green,nobaggle,notopwall,noleftwall,
-Cell(11,0): blue,nobaggle,notopwall,noleftwall,
-Cell(11,2): green,nobaggle,notopwall,noleftwall,
-Cell(11,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(11,5): blue,nobaggle,notopwall,noleftwall,
-Cell(11,7): green,nobaggle,notopwall,noleftwall,
-Cell(11,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(11,10): blue,nobaggle,notopwall,noleftwall,
-Cell(11,12): green,nobaggle,notopwall,noleftwall,
-Cell(11,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(12,1): blue,nobaggle,notopwall,noleftwall,
-Cell(12,3): yellow,nobaggle,notopwall,noleftwall,
-Cell(12,6): blue,nobaggle,notopwall,noleftwall,
-Cell(12,8): yellow,nobaggle,notopwall,noleftwall,
-Cell(12,11): blue,nobaggle,notopwall,noleftwall,
-Cell(12,13): yellow,nobaggle,notopwall,noleftwall,
-Cell(13,0): blue,nobaggle,notopwall,noleftwall,
-Cell(13,2): red,nobaggle,notopwall,noleftwall,
-Cell(13,4): yellow,nobaggle,notopwall,noleftwall,
-Cell(13,5): blue,nobaggle,notopwall,noleftwall,
-Cell(13,7): red,nobaggle,notopwall,noleftwall,
-Cell(13,9): yellow,nobaggle,notopwall,noleftwall,
-Cell(13,10): blue,nobaggle,notopwall,noleftwall,
-Cell(13,12): red,nobaggle,notopwall,noleftwall,
-Cell(13,14): yellow,nobaggle,notopwall,noleftwall,
-Cell(14,1): red,nobaggle,notopwall,noleftwall,
-Cell(14,3): red,nobaggle,notopwall,noleftwall,
-Cell(14,6): red,nobaggle,notopwall,noleftwall,
-Cell(14,8): red,nobaggle,notopwall,noleftwall,
-Cell(14,11): red,nobaggle,notopwall,noleftwall,
-Cell(14,13): red,nobaggle,notopwall,noleftwall,
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2.fr.html b/src/lessons/welcome/methods/picture2/MethodsPicture2.fr.html
deleted file mode 100644
index 3f33f8e..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2.fr.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<h2>Dessiner avec méthode (en plus grand)</h2>
-
-Nous allons maintenant reproduire un dessin géométrique plus grand. Encore
-une fois, vous pouvez voir le modèle en cliquant sur l'onglet "Objective".
-
-<p>Vous pouvez bien entendu réutiliser tout le code que vous aviez tapé à
-l'exercice précédent (sélectionnez l'autre exercice, allez dans le code,
-sélectionner tout, faites Ctrl-C, revenez dans le code de l'exercice
-courant, faites Ctrl-V).</p>
-
-<p class="Java">Mais pour que votre méthode principale <code>run()</code> reste aussi simple
-que possible, il faudra définir de nouvelles méthodes afin de gérer
-simplement les répétions du motif. Par exemple, une méthode
-<code>makePattern()</code> réalisant le motif de l'exercice précédent semble
-être un bon départ (mais ce n'est sans doute pas suffisant).</p> 
-
-<p class="Python">Mais pour que votre méthode principale reste aussi simple que possible, il
-faudra définir de nouvelles méthodes afin de gérer simplement les répétions
-du motif. Par exemple, une méthode <code>makePattern()</code> réalisant le
-motif de l'exercice précédent semble être un bon départ (mais ce n'est sans
-doute pas suffisant).</p> 
-
-<p class="Java">À vous de jouer. La méthode <code>run()</code> ne devrait pas prendre plus
-de 2 lignes, incluses dans une boucle for...</p>
-
-<p class="Python">À vous de jouer. Le code de la méthode principale ne devrait pas prendre
-plus de 2 lignes ( incluses dans une boucle for)</p>
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2.html b/src/lessons/welcome/methods/picture2/MethodsPicture2.html
deleted file mode 100644
index effc5c5..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<h2>Methodically drawing (only bigger)</h2>
-
-We will now reproduce an even bigger geometrical drawing. Once again, you
-can see the model by clicking on the "Objective" tab.
-
-<p>You can naturally reuse all the code you typed in previous exercise (select
-the other exercise, do Ctrl-C, come back to the code of this exercise, do
-Ctrl-V).</p>
-
-<p class="Java">But you want to keep your main<code>run()</code> as simple as possible. For
-that, define new methods to deal simply with the repetitions in the
-pattern. For example, a method <code>makePattern()</code> achieving the
-pattern of previous example seems to be a good idea (but this may not be
-enough).</p> 
-
-<p class="Python">But you want to keep your main code  as simple as possible. For
-that, define new methods to deal simply with the repetitions in the
-pattern. For example, a method <code>makePattern()</code> achieving the
-pattern of previous example seems to be a good idea (but this may not be
-enough).</p> 
-
-<p class="Java">Why don't you give it a shot? The <code>run()</code> method shouldn't take
-more than 2 lines (included in a for loop)</p>
-
-<p class="Python">Why don't you give it a shot? The main code method shouldn't take
-more than 2 lines (included in a for loop)</p>
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2.java b/src/lessons/welcome/methods/picture2/MethodsPicture2.java
deleted file mode 100644
index 16ad216..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package lessons.welcome.methods.picture2;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class MethodsPicture2 extends ExerciseTemplated {
-
-	public MethodsPicture2(Lesson lesson) {
-		super(lesson);
-		BuggleWorld myWorld =  new BuggleWorld("World",15,15);
-		myWorld.setDelay(20);
-		new Buggle(myWorld, "Picasso", 0, 14, Direction.EAST, Color.black, Color.lightGray);
-
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.java b/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.java
deleted file mode 100644
index 8d56930..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package lessons.welcome.methods.picture2;
-
-import java.awt.Color;
-
-/* The suppress warning is sometimes mandatory for student code to compile cleanly */
- at SuppressWarnings("unused")
-public class MethodsPicture2Entity extends jlm.universe.bugglequest.SimpleBuggle {
-
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	void mark() {
-		brushDown();
-		brushUp();
-	}
-
-	void makeV(Color c) {
-		setBrushColor(c);
-		forward();
-		mark();
-
-		forward();
-		turnLeft();
-		forward();
-		mark();
-
-		backward();
-		turnRight();
-		forward();
-		mark();
-
-		forward();
-		turnLeft();
-	}
-
-	void makePattern() {
-		makeV(Color.YELLOW);
-		makeV(Color.RED);
-		makeV(Color.BLUE);
-		makeV(Color.GREEN);
-		forward(5);
-	}
-
-	void makeLine(int count){
-		for (int i=0; i<count;i++)
-			makePattern();
-		backward(count*5);
-	}
-
-	void nextLine() {
-		turnLeft();
-		forward(5);
-		turnRight();	
-	}
-
-	public void run() {
-		for (int i=0; i<3;i++) {
-			makeLine(3);
-			nextLine();
-		}
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.py b/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.py
deleted file mode 100644
index beb99ec..0000000
--- a/src/lessons/welcome/methods/picture2/MethodsPicture2Entity.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN SOLUTION
-def mark():
-   brushDown()
-   brushUp()
-
-def makeV(c):
-   setBrushColor(c)
-   forward()
-   mark()
-   forward()
-   turnLeft()
-   forward()
-   mark()
-   backward()
-   turnRight()
-   forward()
-   mark()   
-   forward()
-   turnLeft()
-
-def makePattern():
-   makeV(Color.yellow)
-   makeV(Color.red)
-   makeV(Color.blue)
-   makeV(Color.green)
-   forward(5)
-
-def makeLine(count):
-   for i in range(count):
-      makePattern()
-   backward(count*5)
-
-def nextLine():
-   turnLeft()
-   forward(5)
-   turnRight()
-
-for i in range(3):
-   makeLine(3)
-   nextLine()
-# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3.fr.html b/src/lessons/welcome/methods/picture3/MethodsPicture3.fr.html
deleted file mode 100644
index d20c146..0000000
--- a/src/lessons/welcome/methods/picture3/MethodsPicture3.fr.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<h2>Dessiner de plus en plus grand</h2>
-
-Vous vous en doutez, il vous faut encore une fois reproduire un dessin
-géométrique dont le modèle se trouve dans l'onglet "Objective". Comme vous
-le voyez, il est encore plus grand que le précédent.
-
-<p>Il va donc falloir définir encore plus de méthodes afin de tirer partie des
-répétitions du motif pour factoriser votre code. Ou alors, il va falloir
-<i>paramétrer</i> vos fonctions pour réutiliser ce que vous aviez écrit en
-changant les tailles.  
-
-<p>À vous de jouer...</p>
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3.html b/src/lessons/welcome/methods/picture3/MethodsPicture3.html
deleted file mode 100644
index 57e976b..0000000
--- a/src/lessons/welcome/methods/picture3/MethodsPicture3.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h2>Drawing bigger and bigger</h2>
-
-As you can imagine, you have to reproduce the geometric drawing depicted in
-the "Objectives" tab. As you can see, it is even bigger than the previous
-one.
-
-<p>You thus have to declare even more methods to use the repetitions of the
-pattern and factorize your code. Another solution is to <i>parametrize</i>
-your functions to reuse the code you wrote previously by changing the size.  
-
-<p>Your turn...</p>
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3.java b/src/lessons/welcome/methods/picture3/MethodsPicture3.java
deleted file mode 100644
index c8aad69..0000000
--- a/src/lessons/welcome/methods/picture3/MethodsPicture3.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package lessons.welcome.methods.picture3;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class MethodsPicture3 extends ExerciseTemplated {
-
-	public MethodsPicture3(Lesson lesson) {
-		super(lesson);
-		BuggleWorld myWorld =  new BuggleWorld("World",45,45);
-		myWorld.setDelay(5);
-		new Buggle(myWorld, "Picasso", 0, 44, Direction.EAST, Color.black, Color.lightGray);
-				
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.java b/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.java
deleted file mode 100644
index f1259be..0000000
--- a/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package lessons.welcome.methods.picture3;
-
-import java.awt.Color;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-/* The suppress warning is sometimes mandatory for student code to compile cleanly */
- at SuppressWarnings("unused")
-public class MethodsPicture3Entity extends SimpleBuggle {
-
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	void mark() {
-		brushDown();
-		brushUp();
-	}
-
-	void makeV(Color c) {
-		setBrushColor(c);
-		forward();
-		mark();
-
-		forward();
-		turnLeft();
-		forward();
-		mark();
-
-		backward();
-		turnRight();
-		forward();
-		mark();
-
-		forward();
-		turnLeft();
-	}
-
-	void makePattern() {
-		makeV(Color.YELLOW);
-		makeV(Color.RED);
-		makeV(Color.BLUE);
-		makeV(Color.GREEN);
-		forward(5);
-	}
-
-	void makeLine(int count){
-		for (int i=0; i<count;i++)
-			makePattern();
-		backward(count*5);
-	}
-
-	void nextLine() {
-		turnLeft();
-		forward(5);
-		turnRight();	
-	}
-
-	public void run() {
-		for (int i=0; i<9; i++) {
-			makeLine(9);
-			nextLine();
-		}
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.py b/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.py
deleted file mode 100644
index bd76f7c..0000000
--- a/src/lessons/welcome/methods/picture3/MethodsPicture3Entity.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN SOLUTION
-def mark():
-   brushDown()
-   brushUp()
-
-def makeV(c):
-   setBrushColor(c)
-   forward()
-   mark()
-   forward()
-   turnLeft()
-   forward()
-   mark()
-   backward()
-   turnRight()
-   forward()
-   mark()   
-   forward()
-   turnLeft()
-
-def makePattern():
-   makeV(Color.yellow)
-   makeV(Color.red)
-   makeV(Color.blue)
-   makeV(Color.green)
-   forward(5)
-
-def makeLine(count):
-   for i in range(count):
-      makePattern()
-   backward(count*5)
-
-def nextLine():
-   turnLeft()
-   forward(5)
-   turnRight()
-
-for i in range(9):
-   makeLine(9)
-   nextLine()
-# END SOLUTION
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4.fr.html b/src/lessons/welcome/methods/picture4/MethodsPicture4.fr.html
deleted file mode 100644
index 5b2444d..0000000
--- a/src/lessons/welcome/methods/picture4/MethodsPicture4.fr.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h2>Encore des motifs à dessiner</h2>
-<h3>(et des méthodes à écrire)</h3>
-
-Voici de nouveau un exercice où il faut reproduire un motif donné dans
-l'onglet "Objective".
-
-<p>Celui-ci est un peu plus difficile que ceux vus précédement. Cherchez les
-motifs qui se répètent, même si la couleur change, et faites une méthode
-dessinant chacun d'entre eux.</p>
- 
-<p>Bon courage !</p>
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4.html b/src/lessons/welcome/methods/picture4/MethodsPicture4.html
deleted file mode 100644
index adba255..0000000
--- a/src/lessons/welcome/methods/picture4/MethodsPicture4.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<h2>Even more pattern to draw</h2>
-<h3>(and methods to write)</h3>
-
-Here is yet another exercise where you have to reproduce the pattern
-provided in the "Objective" tab.
-
-<p>This one is a bit more difficult than the one seen previously. Look for
-repeating patterns, even if the color changes, and write a method drawing
-each of them.</p>
- 
-<p>Good luck!</p>
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4.java b/src/lessons/welcome/methods/picture4/MethodsPicture4.java
deleted file mode 100644
index f832b82..0000000
--- a/src/lessons/welcome/methods/picture4/MethodsPicture4.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package lessons.welcome.methods.picture4;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class MethodsPicture4 extends ExerciseTemplated {
-
-	public MethodsPicture4(Lesson lesson) {
-		super(lesson);
-		BuggleWorld myWorld =  new BuggleWorld("World",8,8);
-		
-		for (int i=0;i<8;i++) {
-			myWorld.putTopWall (i, 0);
-			myWorld.putLeftWall(0, i);
-		}
-		
-		new Buggle(myWorld, "Picasso", 0, 7, Direction.EAST, Color.black, Color.lightGray);
-		
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.java b/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.java
deleted file mode 100644
index 4692fcb..0000000
--- a/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package lessons.welcome.methods.picture4;
-
-import java.awt.Color;
-
-import jlm.universe.bugglequest.SimpleBuggle;
-
-/* The suppress warning is sometimes mandatory for student code to compile cleanly */
- at SuppressWarnings("unused")
-public class MethodsPicture4Entity extends SimpleBuggle {
-
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	void mark() {
-		brushDown();
-		brushUp();
-	}
-
-	void squareA(Color c) {
-		setBrushColor(c);
-
-		forward();
-		mark();
-
-		turnLeft();
-		forward();
-
-		turnLeft();
-		forward();
-		mark();
-
-		turnLeft();
-		forward();
-		turnLeft();
-	}
-
-	void squareB(Color c) {
-		setBrushColor(c);
-		mark();
-
-		forward();
-
-		turnLeft();
-		forward();
-		mark();
-
-		turnLeft();
-		forward();
-
-		turnLeft();
-		forward();
-		turnLeft();
-	}
-
-	void bigSquare() {
-		squareA(Color.RED); 
-		forward(2);
-		squareB(Color.BLUE);
-		backward(2);
-		turnLeft();
-		forward(2);
-		turnRight();
-		squareB(Color.YELLOW);
-		forward(2);
-		squareA(Color.GREEN);
-
-		backward(2);
-		turnLeft();
-		backward(2);
-		turnRight();
-	}
-
-	public void run() {
-		bigSquare();
-		forward(4);
-		bigSquare();
-
-		backward(4);
-		turnLeft();
-		forward(4);
-		turnRight();
-
-		bigSquare(); 
-		forward(4);
-		bigSquare();
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */
-}
diff --git a/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.py b/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.py
deleted file mode 100644
index b9fc3f4..0000000
--- a/src/lessons/welcome/methods/picture4/MethodsPicture4Entity.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN SOLUTION
-def mark():
-   brushDown()
-   brushUp()
-
-def squareA(c):
-   setBrushColor(c)
-   forward()
-   mark()
-   turnLeft()
-   forward()
-   turnLeft()
-   forward()
-   mark()
-   turnLeft()
-   forward()
-   turnLeft()
-   
-def squareB(c):
-   setBrushColor(c)
-   mark()
-   forward()
-   turnLeft()
-   forward()
-   mark()
-   turnLeft()
-   forward()
-   turnLeft()
-   forward()
-   turnLeft()
-
-def bigSquare():
-   squareA(Color.red)
-   forward(2)
-   squareB(Color.blue)
-   backward(2)
-   turnLeft()
-   forward(2)
-   turnRight()
-   squareB(Color.yellow)
-   forward(2)
-   squareA(Color.green)
-   backward(2)
-   turnLeft()
-   backward(2)
-   turnRight()
-	
-bigSquare()
-forward(4)
-bigSquare()
-		
-backward(4)
-turnLeft()
-forward(4)
-turnRight()
-		
-bigSquare() 
-forward(4)
-bigSquare()
-# END SOLUTION
-
diff --git a/src/lessons/welcome/methods/returning/MethodsReturning.fr.html b/src/lessons/welcome/methods/returning/MethodsReturning.fr.html
index 43cca8a..cde598d 100644
--- a/src/lessons/welcome/methods/returning/MethodsReturning.fr.html
+++ b/src/lessons/welcome/methods/returning/MethodsReturning.fr.html
@@ -1,31 +1,33 @@
 <h2>Méthodes retournant un résultat</h2>
 
-Écrire des méthodes retournant un résultat n'est pas bien plus compliqué
-qu'écrire une méthode n'en renvoyant pas. <span class="Java"> Vous devez
-simplement indiquer le type du résultat attendu avant le nom de la
-méthode</span>. Il faut écrire dans le corps de la méthode une instruction
-<code>return</code> qui précise la valeur à renvoyer.
+<p>Écrire une méthode retournant un résultat n'est pas tellement plus dur que
+pour les méthodes sans résultat.
+[!java]Il suffit d'écrire le type de données renvoyées par votre méthode
+avant son nom (là où nous écrivions <code>void</code> avant).[/!]
+[!scala]Il suffit d'ajouter deux points (:), le type de données renvoyées
+par votre méthode et le signe égal (=) entre  les parenthèses de la
+déclaration et l'accolade du bloc. Cette syntaxe est assez proche de la
+définition d'une variable (avec son type) dont la valeur serait une
+fonction.[/!]
+Vous pouvez utiliser l'instruction <code>return</code> n'importe ou dans le
+corps de votre méthode pour spécifier que le calcul est fini (la suite de la
+méthode n'est pas exécutée) et donner la valeur à donner à l'appelant après
+le mot-clé <code>return</code>.</p>
 
-<pre class="Java">double pi() {
-    return 3.14159;
-}
-boolean deuxEstIlPair() {
-    return true;
-}
-</pre>
-<pre class="Python">def pi():
-    return 3.14159
+<pre>[!java]double pi() {[/!][!scala]def pi(): Double = {[/!][!python]def pi():[/!]
+    return 3.14159[!java];[/!]
+[!java|scala]}[/!]</pre>
 
-def deuxEstIlPair():
-    return True
-</pre>
+<p>En fait, vous pouvez également utiliser le mot-clé <code>return</code> dans
+les méthodes ne renvoyant pas de résultat, pour interrompre leur
+exécution. Dans ce cas, il ne faut bien entendu pas donner de valeur à
+droite du <code>return</code>.</p>
 
 <p>Il est possible d'avoir plusieurs instructions <code>return</code> dans
 différentes branches de <code>if</code>. Ce qui est interdit, c'est d'avoir
 une branche du code qui n'est pas terminée par un <code>return</code>, ou
-d'écrire du code après le <code>return</code>.</p>
-
-<p>En effet, si la machine arrive à la fin de la méthode sans avoir rencontré
+d'écrire du code après le <code>return</code>.
+En effet, si la machine arrive à la fin de la méthode sans avoir rencontré
 de <tt>return</tt>, elle ne peut pas savoir quelle valeur communiquer à
 celui qui a appelé la méthode. De plus, le <tt>return</tt> interrompt
 immédiatement l'exécution de la méthode (pourquoi continuer à chercher quand
@@ -33,44 +35,41 @@ on a déjà trouvé le résultat de la méthode?). Donc, s'il y a du code après
 un <tt>return</tt>, c'est sans doute une erreur, et le compilateur vous
 l'indique.</p>
 
-<pre class="Java">boolean negation(boolean cond) {
-    if (cond == true) {
-        return true;
-        <span class="comment">/* interdit d'écrire du code ici */</span>
-    } else {
-        return false;
-        <span class="comment">/* ici aussi */</span>
-    }
-    <span class="comment">/* même ici */</span>
-}</pre>
-<pre class="Python">def negation(cond):
-    if cond == True:
-        return True
-        <span class="comment"># interdit d'écrire du code ici</span>
-    else:
-        return False
-        <span class="comment"># ici aussi</span>
-    
-    <span class="comment"># même ici</span>
-</pre>
+<pre>[!java|scala][!java]boolean [/!][!scala]def [/!]estDevantLibre()[!scala]:Boolean =[/!] {
+    if (estFaceMur() == true) {
+        return false;
+        <span class="comment">/* interdit d'écrire du code ici */</span>
+    } else {
+        return true;
+        <span class="comment">/* pareil ici */</span>
+    }
+    <span class="comment">/* même ici, oubliez */</span>
+}[/!][!python]def estDevantLibre():
+    if estFaceMur() == True:
+        return False
+        <span class="comment"># interdit d'écrire du code ici</span>
+    else
+        return True
+        <span class="comment"># pareil ici</span>
+<span class="comment"># même ici, oubliez</span>[/!]</pre>
 
 <h3>Objectif de cet exercice</h3><a name="Objectifs"> Vous allez encore une fois écrire une méthode qui sera
 utilisée par la buggle. Son nom doit être <code>haveBaggle</code>, et elle
 doit renvoyer un booléen indiquant si la colonne face à la buggle contient
-un baggle ou non. Votre buggle va s'en servir pour chercher la première
-colonne contenant un baggle et s'y arrêter.
+un biscuit ou non. Votre buggle va s'en servir pour chercher la première
+colonne contenant un biscuit et s'y arrêter.
 
 <p>Le plus simple pour écrire cette méthode est peut être d'utiliser une
-variable booléenne <code>vuBaggle</code> indiquant si on a vu un baggle
+variable booléenne <code>vuBiscuit</code> indiquant si on a vu un biscuit
 jusque là. Initialement, elle contient faux.</p>
 
 <p>Ensuite, on avance de 6 cases (le monde contient 7 cases, et on est déjà sur
-l'une d'entre elles). Pour chaque case, si elle contient un baggle, on range
-la valeur vrai dans <tt>vuBaggle</tt> (et on ne fait rien d'autre qu'avancer
-si non).</p>
+l'une d'entre elles). Pour chaque case, si elle contient un biscuit, on
+range la valeur vrai dans <tt>vuBiscuit</tt> (et on ne fait rien d'autre
+qu'avancer si non).</p>
 
 <p>Quand on est arrivé à la fin, on recule de 6 cases, et on retourne le
-contenu de <tt>vuBaggle</tt> à l'appelant.</p>
+contenu de <tt>vuBiscuit</tt> à l'appelant.</p>
 
 
 <p>Cet exercice est un peu particulier, puisqu'il a deux mondes initiaux,
diff --git a/src/lessons/welcome/methods/returning/MethodsReturning.html b/src/lessons/welcome/methods/returning/MethodsReturning.html
index b3a08b7..67154ea 100644
--- a/src/lessons/welcome/methods/returning/MethodsReturning.html
+++ b/src/lessons/welcome/methods/returning/MethodsReturning.html
@@ -1,79 +1,71 @@
-<h2>Methods returning a result</h2>
-
-Writing a method returning a result is not really more work than writing a
-method without any result. <span class="Java">You simply have to specify the data type of
-expected results before the method name</span>. And, then write a
-<code>return</code> instruction in your method body to specify the actual
-value to return.
-
-<pre class="Java">double pi() {
-    return 3.14159;
-}
-boolean isNumberTwoEven() {
-    return true;
-}
-</pre>
-<pre class="Python">def pi():
-    return 3.14159
-
-def isNumberTwoEven():
-    return True
-</pre>
-
-<p>It is possible to have several <code>return</code> instructions in several
-branches of a conditional. It is even forbidden to have one execution path of
-your body without any <code>return</code>, or to write some code after the
-<code>return</code> instruction.</p>
-
-<p>Indeed, if the machine reaches the end of the method without finding any
-<code>return</code>, it cannot know what actual value to give back to the
-method caller. Moreover, <code>return</code> interrupts immediately the
-method execution (why bother looking further when you know the method
-result?). So, if there is some code after a <code>return</code>, it must be
-an error and the compiler warns you.</p>
-
-<pre class="Java">boolean negation(boolean cond) {
-    if (cond == true) {
-        return true;
-        <span class="comment">/* no code allowed here */</span>
-    } else {
-        return false;
-        <span class="comment">/* here neither */</span>
-    }
-    <span class="comment">/* even here, forget it */</span>
-}</pre>
-<pre class="Python">def negation(cond):
-    if cond == True:
-        return True
-        <span class="comment"># no code allowed here</span>
-    else:
-        return False
-        <span class="comment"># here neither</span>
-    
-    <span class="comment"># even here, forget it</span>
-</pre>
-
-<h3>Exercise goal</h3>You will once again write a method that the buggle will use. Its name must
-be <code>haveBaggle</code>, and it returns a boolean value indicating
-whether the row in front of the buggle contains a baggle or not. The buggle
-will use it to search the first row containing a baggle, and stop here.
-
-<p>The easier for this method is to use a boolean variable called
-<code>seenBaggle</code> indicating whether or not we saw a baggle so far. It
-initial value is 'false'.</p>
-
-<p>Then, move 6 steps forward (the world contains 7 cells and we already are
-one one of them). For each cell, if it contains a baggle, we store true in
-<code>sawBaggle</code> (and we don't do anything but moving forward if not).</p>
-
-<p>At the end, we move back by 6 steps, and we return the value of
-<code>seenBaggle</code> to the caller.</p>
-
-
-<p>This exercise is a bit different since there is two initial worlds, each
-with a specific objective. Your code must work for each of them. Observe
-that the world selection scrolling menu (right below the speed slider)
-allows to switch the observed world. </p>
-
-<p>When your method <code>haveBaggle</code> works, proceed to next exercise.</p>
-
+<h2>Methods returning a result</h2>
+
+<p>Writing a method returning a result is not really more work than writing a
+method without any result. 
+[!java]You simply have to specify the data type of expected results before the method name (where we previously had <code>void</code>).[/!]
+[!scala]You simply have to add a column (:) after the parenthesis and write the type of data that your method will return, and add an equal sign (=). This syntax is actually rather
+close to defining a variable, with its type, that is actually a function.[/!]
+You can use the <code>return</code> instruction anywhere in your method body to 
+specify that the computation is done (the method is not further executed), and that 
+the result is the the value following the <code>return</code> keyword.</p>
+
+<pre>[!java]double pi() {[/!][!scala]def pi(): Double = {[/!][!python]def pi():[/!]
+    return 3.14159[!java];[/!]
+[!java|scala]}[/!]</pre>
+
+<p>Actually, you can also use that <code>return</code> keyword in methods that do not return any result, to interupt the computation. Of course, you should not provide any
+value to return in that case.</p>
+
+<p>It is possible to have several <code>return</code> instructions in several
+branches of a conditional. In fac, it is forbidden to have any execution path of
+your body without any <code>return</code>, or to write some code after the
+<code>return</code> instruction. Indeed, if the machine reaches the end of the 
+method without finding any <code>return</code>, it cannot know what actual 
+value to give back to the method caller. 
+Moreover, <code>return</code> interrupts immediately the method execution 
+(why bother looking further when you know the method result?). So, if there is 
+some code after a <code>return</code>, it must be an error and the compiler 
+warns you.</p>
+
+<pre>[!java|scala][!java]boolean [/!][!scala]def [/!]isFrontFree()[!scala]:Boolean =[/!] {
+    if (isFacingWall() == true) {
+        return false;
+        <span class="comment">/* no code allowed here */</span>
+    } else {
+        return true;
+        <span class="comment">/* here neither */</span>
+    }
+    <span class="comment">/* even here, forget it */</span>
+}[/!][!python]def isFrontFree():
+    if isFacingWall() == True:
+        return False
+        <span class="comment"># no code allowed here</span>
+    else
+        return True
+        <span class="comment"># here neither</span>
+<span class="comment"># even here, forget it</span>[/!]</pre>
+
+<h3>Exercise goal</h3>You will once again write a method that the buggle will use. Its name must
+be <code>haveBaggle</code>, and it returns a boolean value indicating
+whether the row in front of the buggle contains a baggle or not. The buggle
+will use it to search the first row containing a baggle, and stop here.
+
+<p>The easier for this method is to use a boolean variable called
+<code>seenBaggle</code> indicating whether or not we saw a baggle so far. It
+initial value is 'false'.</p>
+
+<p>Then, move 6 steps forward (the world contains 7 cells and we already are
+one one of them). For each cell, if it contains a baggle, we store true in
+<code>sawBaggle</code> (and we don't do anything but moving forward if not).</p>
+
+<p>At the end, we move back by 6 steps, and we return the value of
+<code>seenBaggle</code> to the caller.</p>
+
+
+<p>This exercise is a bit different since there is two initial worlds, each
+with a specific objective. Your code must work for each of them. Observe
+that the world selection scrolling menu (right below the speed slider)
+allows to switch the observed world. </p>
+
+<p>When your method <code>haveBaggle</code> works, proceed to next exercise.</p>
+
diff --git a/src/lessons/welcome/methods/returning/MethodsReturning.java b/src/lessons/welcome/methods/returning/MethodsReturning.java
index f2a1567..969eedf 100644
--- a/src/lessons/welcome/methods/returning/MethodsReturning.java
+++ b/src/lessons/welcome/methods/returning/MethodsReturning.java
@@ -2,12 +2,12 @@ package lessons.welcome.methods.returning;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
 
 public class MethodsReturning extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/methods/returning/MethodsReturningEntity.java b/src/lessons/welcome/methods/returning/MethodsReturningEntity.java
index cbbdde8..8e9b49e 100644
--- a/src/lessons/welcome/methods/returning/MethodsReturningEntity.java
+++ b/src/lessons/welcome/methods/returning/MethodsReturningEntity.java
@@ -1,30 +1,31 @@
 package lessons.welcome.methods.returning;
 
+import plm.core.model.Game;
 
-public class MethodsReturningEntity extends jlm.universe.bugglequest.SimpleBuggle {
+
+public class MethodsReturningEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
 	}
 
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
 	}
 
-
 	@Override
 	public void run() { 
 		for (int i=0; i<7; i++) {
 			if (haveBaggle()) 
 				return;
-			turnRight();
+			right();
 			forward();
-			turnLeft();
+			left();
 		}
 	}
 	/* BEGIN TEMPLATE */
-	public boolean haveBaggle() {
+	boolean haveBaggle() {
 		/* BEGIN SOLUTION */
 		boolean res = false;
 		for (int i=0; i<6; i++) {
diff --git a/src/lessons/welcome/methods/returning/MethodsReturningEntity.py b/src/lessons/welcome/methods/returning/MethodsReturningEntity.py
index 3b9bfef..bebd5ef 100644
--- a/src/lessons/welcome/methods/returning/MethodsReturningEntity.py
+++ b/src/lessons/welcome/methods/returning/MethodsReturningEntity.py
@@ -28,7 +28,7 @@ def haveBaggle():
 for i in range(7):
     if haveBaggle():
         break
-    turnRight()
+    right()
     forward()
-    turnLeft()
+    left()
 
diff --git a/src/lessons/welcome/methods/returning/MethodsReturningEntity.scala b/src/lessons/welcome/methods/returning/MethodsReturningEntity.scala
new file mode 100644
index 0000000..168f9e4
--- /dev/null
+++ b/src/lessons/welcome/methods/returning/MethodsReturningEntity.scala
@@ -0,0 +1,40 @@
+package lessons.welcome.methods.returning;
+
+import com.sun.org.apache.xpath.internal.operations.Bool
+import plm.core.model.Game
+
+
+class ScalaMethodsReturningEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	override def run() { 
+		for (i <- 1 to 7) {
+			if (haveBaggle()) 
+				return;
+			right();
+			forward();
+			left();
+		}
+	}
+	/* BEGIN TEMPLATE */
+	def haveBaggle():Boolean = {
+		/* BEGIN SOLUTION */
+		var res = false
+		for (i <- 1 to 6) {
+			if (isOverBaggle()) 
+				res = true;
+			forward();
+		}
+		for (i <- 1 to 6) 
+			backward();
+		return res;
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */
+}
diff --git a/src/lessons/welcome/slug/SlugHunting-answer0.map b/src/lessons/welcome/methods/slug/SlugHunting-answer0.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugHunting-answer0.map
rename to src/lessons/welcome/methods/slug/SlugHunting-answer0.map
diff --git a/src/lessons/welcome/slug/SlugHunting-answer1.map b/src/lessons/welcome/methods/slug/SlugHunting-answer1.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugHunting-answer1.map
rename to src/lessons/welcome/methods/slug/SlugHunting-answer1.map
diff --git a/src/lessons/welcome/methods/slug/SlugHunting.fr.html b/src/lessons/welcome/methods/slug/SlugHunting.fr.html
new file mode 100644
index 0000000..7d13962
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugHunting.fr.html
@@ -0,0 +1,24 @@
+<h2>Chasse à la limace</h2>
+
+<p>Maintenant que votre méthode <code>isFacingTrail()</code> fonctionne, il est
+temps d'écrire le code de la chasse à proprement parler. Copie/collez le
+code que vous aviez fait pour l'exercice précédent, et complétez la méthode
+<code>hunt()</code> (<i>hunt</i> signifie <i>chasse</i> en anglais).</p>
+
+<p>Suivre une piste n'est pas très difficile : avancez tant que vous êtes face
+à la piste. Si la piste n'est plus devant vous, cherchez si elle se trouve à
+gauche ou à droite, et suivez-la encore.</p>
+
+<p>Pour ne pas confondre la partie de la trace à suivre avec celle que votre
+buggle a déjà suivie, il est conseillé d'effacer la piste derrière
+vous. Pour cela, utilisez la méthode <code>baisseBrosse()</code> pour
+baisser votre brosse, et <code>leveBrosse()</code> pour la relever.</p>
+
+<p>Enfin, n'oubliez de capturer votre proie une fois que vous l'aurez débusquée
+(avec <code>prendBiscuit()</code>).</p>
+
+
+<h3>Objectif de cet exercice</h3>
+<a name="Objectifs"> Complétez la méthode <code>hunt()</code>. Vous voulez
+probablement copier votre méthode <code>isFacingTrail()</code> de l'exercice
+précédent.
diff --git a/src/lessons/welcome/slug/SlugHunting.html b/src/lessons/welcome/methods/slug/SlugHunting.html
similarity index 100%
rename from src/lessons/welcome/slug/SlugHunting.html
rename to src/lessons/welcome/methods/slug/SlugHunting.html
diff --git a/src/lessons/welcome/methods/slug/SlugHunting.java b/src/lessons/welcome/methods/slug/SlugHunting.java
new file mode 100644
index 0000000..ab32b4d
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugHunting.java
@@ -0,0 +1,71 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class SlugHunting extends ExerciseTemplated {
+
+	public SlugHunting(Lesson lesson) {
+		super(lesson);
+
+		BuggleWorld[] myWorlds = new BuggleWorld[2];
+
+		BuggleWorld myWorld = new BuggleWorld("Forrest", 8, 7);
+		for (int i = 5; i >= 2; i--)
+			myWorld.setColor(6, i,Color.green);
+		myWorld.setColor(5, 2,Color.green);
+		for (int i = 2; i <= 4; i++)
+			myWorld.setColor(4, i,Color.green);
+		myWorld.setColor(3, 4,Color.green);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.green);
+		myWorld.setColor(1, 1,Color.green);
+		myWorld.setColor(0, 1,Color.green);
+		try {
+			myWorld.newBaggle(0, 1);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[0] = myWorld;
+
+		myWorld = new BuggleWorld("Desert", 8, 7);
+		for (int i = 5; i >= 2; i--)
+		    myWorld.setColor(6, i,Color.green);
+		myWorld.putTopWall(6, 2);
+		myWorld.putLeftWall(6, 3);
+		myWorld.putLeftWall(7, 2);
+		myWorld.setColor(5, 2,Color.green);
+		myWorld.setColor(5, 1,Color.green);
+		myWorld.setColor(5, 0,Color.green);
+		myWorld.setColor(4, 0,Color.green);
+		myWorld.setColor(3, 0,Color.green);
+		myWorld.setColor(2, 0,Color.green);
+				       
+		myWorld.setColor(3, 4,Color.green);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.green);
+		myWorld.setColor(4, 4,Color.green);
+
+		try {
+			myWorld.newBaggle(3, 4);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[1] = myWorld;
+
+		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		setup(myWorlds);
+	}
+
+}
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/slug/SlugHuntingEntity.java b/src/lessons/welcome/methods/slug/SlugHuntingEntity.java
new file mode 100644
index 0000000..f2ae8cd
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugHuntingEntity.java
@@ -0,0 +1,45 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+
+public class SlugHuntingEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	@Override
+	public void run() {
+		hunt(); 
+	}
+
+	/* BEGIN TEMPLATE */
+	public void hunt() {
+		// Write your code here
+		/* BEGIN SOLUTION */
+		while (! isOverBaggle()) {
+			if (isFacingTrail()) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+		/* END SOLUTION */
+	}
+
+	/* BEGIN HIDDEN */
+	boolean isFacingTrail() {
+		if (isFacingWall())
+			return false;
+
+		forward();
+		boolean res = getGroundColor().equals(Color.green);
+		backward();
+		return res;
+
+	}		
+	/* END HIDDEN */
+	/* END TEMPLATE */
+
+
+}
diff --git a/src/lessons/welcome/methods/slug/SlugHuntingEntity.py b/src/lessons/welcome/methods/slug/SlugHuntingEntity.py
new file mode 100644
index 0000000..476174e
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugHuntingEntity.py
@@ -0,0 +1,30 @@
+import java.awt.Color as Color
+
+# BEGIN TEMPLATE
+# BEGIN HIDDEN
+def isFacingTrail():
+   if isFacingWall():
+      return False
+   else:
+	  forward()
+	  res = getGroundColor().toString() == Color.green.toString()
+	  backward()
+	  return res
+# END HIDDEN
+
+def hunt():
+   # write your code here
+   # BEGIN SOLUTION
+   while not isOverBaggle():
+      brushUp()
+      if isFacingTrail():
+         brushDown()
+         forward()
+         brushUp()
+      else:
+	     left()
+   pickupBaggle()
+   # END SOLUTION
+# END TEMPLATE
+
+hunt()
diff --git a/src/lessons/welcome/methods/slug/SlugHuntingEntity.scala b/src/lessons/welcome/methods/slug/SlugHuntingEntity.scala
new file mode 100644
index 0000000..accde82
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugHuntingEntity.scala
@@ -0,0 +1,44 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+class ScalaSlugHuntingEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	override def run() {
+		hunt(); 
+	}
+
+	/* BEGIN TEMPLATE */
+	def hunt() {
+		// Write your code here
+		/* BEGIN SOLUTION */
+	  while (! isOverBaggle()) {
+			if (isFacingTrail()) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+		/* END SOLUTION */
+	}
+	
+	// Copy your isFacingTrail() here
+	/* END TEMPLATE */
+
+	/* BEGIN HIDDEN */
+	def isFacingTrail():Boolean = {
+		if (isFacingWall())
+			return false;
+
+		forward();
+		var res = getGroundColor() == Color.green;
+		backward();
+		return res;
+
+	}		
+	/* END HIDDEN */
+
+}
diff --git a/src/lessons/welcome/slug/SlugSnail-answer0.map b/src/lessons/welcome/methods/slug/SlugSnail-answer0.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugSnail-answer0.map
rename to src/lessons/welcome/methods/slug/SlugSnail-answer0.map
diff --git a/src/lessons/welcome/slug/SlugSnail-answer1.map b/src/lessons/welcome/methods/slug/SlugSnail-answer1.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugSnail-answer1.map
rename to src/lessons/welcome/methods/slug/SlugSnail-answer1.map
diff --git a/src/lessons/welcome/slug/SlugSnail.fr.html b/src/lessons/welcome/methods/slug/SlugSnail.fr.html
similarity index 100%
rename from src/lessons/welcome/slug/SlugSnail.fr.html
rename to src/lessons/welcome/methods/slug/SlugSnail.fr.html
diff --git a/src/lessons/welcome/slug/SlugSnail.html b/src/lessons/welcome/methods/slug/SlugSnail.html
similarity index 100%
rename from src/lessons/welcome/slug/SlugSnail.html
rename to src/lessons/welcome/methods/slug/SlugSnail.html
diff --git a/src/lessons/welcome/methods/slug/SlugSnail.java b/src/lessons/welcome/methods/slug/SlugSnail.java
new file mode 100644
index 0000000..3a3df9f
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugSnail.java
@@ -0,0 +1,74 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class SlugSnail extends ExerciseTemplated {
+
+	public SlugSnail(Lesson lesson) {
+		super(lesson);
+
+		BuggleWorld[] myWorlds = new BuggleWorld[2];
+
+		BuggleWorld myWorld = new BuggleWorld("Kitty", 8, 7);
+		for (int i = 5; i >= 2; i--)
+			myWorld.setColor(6, i,Color.pink);
+		myWorld.setColor(5, 2,Color.pink);
+		for (int i = 2; i <= 4; i++)
+			myWorld.setColor(4, i,Color.pink);
+		myWorld.setColor(3, 4,Color.pink);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.pink);
+		myWorld.setColor(1, 1,Color.pink);
+		myWorld.setColor(0, 1,Color.pink);
+		myWorld.setParameter(new Object[] {Color.pink});
+		
+		try {
+			myWorld.newBaggle(0, 1);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[0] = myWorld;
+
+		myWorld = new BuggleWorld("Snail", 8, 7);
+		for (int i = 5; i >= 2; i--)
+		    myWorld.setColor(6, i,Color.orange);
+		myWorld.putTopWall(6, 2);
+		myWorld.putLeftWall(6, 3);
+		myWorld.putLeftWall(7, 2);
+		myWorld.setColor(5, 2,Color.orange);
+		myWorld.setColor(5, 1,Color.orange);
+		myWorld.setColor(5, 0,Color.orange);
+		myWorld.setColor(4, 0,Color.orange);
+		myWorld.setColor(3, 0,Color.orange);
+		myWorld.setColor(2, 0,Color.orange);
+				       
+		myWorld.setColor(3, 4,Color.orange);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.orange);
+		myWorld.setColor(4, 4,Color.orange);
+		myWorld.setParameter(new Object[] {Color.orange});
+
+		try {
+			myWorld.newBaggle(3, 4);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[1] = myWorld;
+
+		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		setup(myWorlds);
+	}
+
+}
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/slug/SlugSnailEntity.java b/src/lessons/welcome/methods/slug/SlugSnailEntity.java
new file mode 100644
index 0000000..87b124b
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugSnailEntity.java
@@ -0,0 +1,47 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+
+public class SlugSnailEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	@Override
+	public void run() {
+		hunt((Color) getParam(0)); 
+	}
+
+	/* BEGIN TEMPLATE */
+	public void hunt(Color c) {
+		// Write your code here
+		/* BEGIN SOLUTION */
+		while (! isOverBaggle()) {
+			if (isFacingTrail(c)) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+		/* END SOLUTION */
+	}
+   
+	// here comes your isFacingTrail method   
+
+	/* BEGIN HIDDEN */
+	boolean isFacingTrail(Color c) {
+		if (isFacingWall())
+			return false;
+
+		forward();
+		boolean res = getGroundColor().equals(c);
+		backward();
+		return res;
+
+	}		
+	/* END HIDDEN */
+	/* END TEMPLATE */
+
+
+}
diff --git a/src/lessons/welcome/methods/slug/SlugSnailEntity.py b/src/lessons/welcome/methods/slug/SlugSnailEntity.py
new file mode 100644
index 0000000..4bbcc2f
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugSnailEntity.py
@@ -0,0 +1,31 @@
+import java.awt.Color as Color
+
+# BEGIN TEMPLATE
+def isFacingTrail(color):
+   # write your code here
+   # BEGIN SOLUTION
+   if isFacingWall():
+      return False
+   else:
+	  forward()
+	  res = (getGroundColor() == color)
+	  backward()
+	  return res
+   # END SOLUTION
+
+def hunt(color):
+   # BEGIN HIDDEN
+   while not isOverBaggle():
+      brushUp()
+      if isFacingTrail(color):
+         brushDown()
+         forward()
+         brushUp()
+      else:
+	     left()
+   pickupBaggle()
+   # END HIDDEN
+# END TEMPLATE
+
+hunt(getParam(0))
+
diff --git a/src/lessons/welcome/methods/slug/SlugSnailEntity.scala b/src/lessons/welcome/methods/slug/SlugSnailEntity.scala
new file mode 100644
index 0000000..68f1e44
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugSnailEntity.scala
@@ -0,0 +1,45 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+
+class ScalaSlugSnailEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	override def run() {
+		hunt(getParam(0).asInstanceOf[Color]); 
+	}
+
+	/* BEGIN TEMPLATE */
+	def hunt(c:Color) {
+		// Write your code here
+		/* BEGIN SOLUTION */
+		while (! isOverBaggle()) {
+			if (isFacingTrail(c)) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+		/* END SOLUTION */
+	}
+   
+	// here comes your isFacingTrail method   
+
+	/* BEGIN HIDDEN */
+	def isFacingTrail(c:Color):Boolean = {
+		if (isFacingWall())
+			return false;
+
+		forward();
+		val res = (getGroundColor() == c);
+		backward();
+		return res;
+	}		
+	/* END HIDDEN */
+	/* END TEMPLATE */
+
+
+}
diff --git a/src/lessons/welcome/slug/SlugTracking-answer0.map b/src/lessons/welcome/methods/slug/SlugTracking-answer0.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugTracking-answer0.map
rename to src/lessons/welcome/methods/slug/SlugTracking-answer0.map
diff --git a/src/lessons/welcome/slug/SlugTracking-answer1.map b/src/lessons/welcome/methods/slug/SlugTracking-answer1.map
similarity index 100%
rename from src/lessons/welcome/slug/SlugTracking-answer1.map
rename to src/lessons/welcome/methods/slug/SlugTracking-answer1.map
diff --git a/src/lessons/welcome/methods/slug/SlugTracking.fr.html b/src/lessons/welcome/methods/slug/SlugTracking.fr.html
new file mode 100644
index 0000000..3450660
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTracking.fr.html
@@ -0,0 +1,28 @@
+<h2>Pistage de la limace</h2>
+<p>
+Votre buggle est super contente ! Elle vient de trouver une grosse traînée
+baveuse sur le sol, certainement laissée par une grosse limace. Au bout de
+cette piste, la buggle est sûre de se régaler d'un bon jus de limace
+(représentée par un baggle). 
+</p>
+
+<p>Pour arriver au résultat, vous devez écrire la méthode booléenne
+<code>isFacingTrail()</code>, qui permet de savoir si on est face à une case
+verte ou non. Bien sûr, si on est face à un mur, elle doit répondre faux
+sans se cogner. Il faudrait de plus que cette méthode soit <b>sans effet de
+bord</b>, c'est-à-dire qu'elle ne modifie ni la buggle qui l'appelle, ni le
+monde environnant.</p>
+
+<p>Votre outil pour cela est la méthode <code>getCouleurSol()</code> qui
+retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut
+vous rendre dans la case à tester avant d'appeler cette méthode.
+[!java]Vous ne pouvez pas simplement utiliser <code>==</code> pour tester si
+la couleur retournée est le vert, mais vous devez plutôt écrire quelque
+chose comme <code>getCouleurSol().equals(Color.green)</code>. C'est parce
+que les couleurs sont des <i>objets</i> en Java, et que
+<code>.equals()</code> est la marche à suivre pour tester l'égalité d'objets
+Java.[/!]</p>   
+
+<h3>Objectif de cet exercice</h3>
+<p>Complétez la méthode <code>isFacingTrail()</code> qui sera appelée
+automatiquement comme il faut.</p>
diff --git a/src/lessons/welcome/methods/slug/SlugTracking.html b/src/lessons/welcome/methods/slug/SlugTracking.html
new file mode 100644
index 0000000..f94b9bb
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTracking.html
@@ -0,0 +1,20 @@
+<h2>Slug Tracking</h2>
+<p>
+Your buggle is super happy! It just found the green dribbling trail, certainly left by a big yummy slug. 
+At its end, the buggle is certain to entertain itself with this appetizing slug (represented as a baggle). 
+</p>
+
+<p>To reach that goal, you had to write a boolean method <tt>isFacingTrail</tt>, which determines whether 
+we are facing a green cell or not. Of course, if we are facing a wall, it should return
+false without bumping into it. You should make sure that this method has no <b>side effect</b>, i.e. that
+it does not change the state of the calling buggle nor of its world.</p>
+
+<p>Your tool to that end is the <code>getGroundColor()</code> that returns the color of
+the current cell. Just go to the cell you want to test and run that function. 
+[!java]You cannot test whether this color is equal to <code>Color.green</code> with an
+<code>==</code> sign but instead you have to write something like
+<code>getGroundColor().equals(Color.green)</code>. This is because green is an 
+<i>object</i> in Java, and <code>.equals()</code> is the way to go to test equality between Java objects.[/!]</p>   
+
+<h3>Exercise goal</h3>
+<p>Complete the <code>isFacingTrail()</code> method (which gets called automatically).</p>
diff --git a/src/lessons/welcome/methods/slug/SlugTracking.java b/src/lessons/welcome/methods/slug/SlugTracking.java
new file mode 100644
index 0000000..323e4a2
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTracking.java
@@ -0,0 +1,71 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class SlugTracking extends ExerciseTemplated {
+
+	public SlugTracking(Lesson lesson) {
+		super(lesson);
+
+		BuggleWorld[] myWorlds = new BuggleWorld[2];
+
+		BuggleWorld myWorld = new BuggleWorld("Forrest", 8, 7);
+		for (int i = 5; i >= 2; i--)
+			myWorld.setColor(6, i,Color.green);
+		myWorld.setColor(5, 2,Color.green);
+		for (int i = 2; i <= 4; i++)
+			myWorld.setColor(4, i,Color.green);
+		myWorld.setColor(3, 4,Color.green);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.green);
+		myWorld.setColor(1, 1,Color.green);
+		myWorld.setColor(0, 1,Color.green);
+		try {
+			myWorld.newBaggle(0, 1);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[0] = myWorld;
+
+		myWorld = new BuggleWorld("Desert", 8, 7);
+		for (int i = 5; i >= 2; i--)
+		    myWorld.setColor(6, i,Color.green);
+		myWorld.putTopWall(6, 2);
+		myWorld.putLeftWall(6, 3);
+		myWorld.putLeftWall(7, 2);
+		myWorld.setColor(5, 2,Color.green);
+		myWorld.setColor(5, 1,Color.green);
+		myWorld.setColor(5, 0,Color.green);
+		myWorld.setColor(4, 0,Color.green);
+		myWorld.setColor(3, 0,Color.green);
+		myWorld.setColor(2, 0,Color.green);
+				       
+		myWorld.setColor(3, 4,Color.green);
+		for (int i = 4; i >= 1; i--)
+			myWorld.setColor(2, i,Color.green);
+		myWorld.setColor(4, 4,Color.green);
+
+		try {
+			myWorld.newBaggle(3, 4);
+		} catch (AlreadyHaveBaggleException e) {
+			e.printStackTrace();
+		}
+		myWorlds[1] = myWorld;
+
+		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
+		hunter.brushDown();
+
+		setup(myWorlds);
+	}
+
+}
\ No newline at end of file
diff --git a/src/lessons/welcome/methods/slug/SlugTrackingEntity.java b/src/lessons/welcome/methods/slug/SlugTrackingEntity.java
new file mode 100644
index 0000000..4cf1335
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTrackingEntity.java
@@ -0,0 +1,40 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+
+public class SlugTrackingEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	@Override
+	public void run() {
+		hunt(); 
+	}
+
+	public void hunt() {
+		while (! isOverBaggle()) {
+			if (isFacingTrail()) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+	}
+
+	/* BEGIN TEMPLATE */
+	boolean isFacingTrail() {
+		// Write your code here
+		/* BEGIN SOLUTION */
+		if (isFacingWall())
+			return false;
+		forward();
+		boolean res = getGroundColor().equals(Color.green); 
+		backward();
+		return res;
+		/* END SOLUTION */
+	}		
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/welcome/methods/slug/SlugTrackingEntity.py b/src/lessons/welcome/methods/slug/SlugTrackingEntity.py
new file mode 100644
index 0000000..73b134d
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTrackingEntity.py
@@ -0,0 +1,29 @@
+import java.awt.Color as Color
+
+# BEGIN TEMPLATE
+def isFacingTrail():
+   # write your code here
+   # BEGIN SOLUTION
+   if isFacingWall():
+      return False
+   else:
+	  forward()
+	  res = (getGroundColor() == Color.green)
+	  backward()
+	  return res
+   # END SOLUTION
+# END TEMPLATE
+
+def hunt():
+   while not isOverBaggle():
+      brushUp()
+      if isFacingTrail():
+         brushDown()
+         forward()
+         brushUp()
+      else:
+	     left()
+   pickupBaggle()
+
+hunt()
+
diff --git a/src/lessons/welcome/methods/slug/SlugTrackingEntity.scala b/src/lessons/welcome/methods/slug/SlugTrackingEntity.scala
new file mode 100644
index 0000000..3f3d1c3
--- /dev/null
+++ b/src/lessons/welcome/methods/slug/SlugTrackingEntity.scala
@@ -0,0 +1,39 @@
+package lessons.welcome.methods.slug;
+
+import java.awt.Color;
+
+
+class ScalaSlugTrackingEntity extends plm.universe.bugglequest.SimpleBuggle {
+
+	override def run() {
+		hunt(); 
+	}
+
+	def hunt() {
+		while (! isOverBaggle()) {
+			if (isFacingTrail()) {
+				brushDown();
+				forward();
+				brushUp();
+			} else {
+				left();
+			}
+		}
+		pickupBaggle();
+	}
+
+	/* BEGIN TEMPLATE */
+	def isFacingTrail():Boolean = {
+		// Write your code here
+		/* BEGIN SOLUTION */
+		if (isFacingWall())
+			return false;
+		forward();
+		val res = (getGroundColor() == Color.green); 
+		backward();
+		return res;
+		/* END SOLUTION */
+	}		
+	/* END TEMPLATE */
+
+}
diff --git a/src/lessons/welcome/slug/SlugHunting.fr.html b/src/lessons/welcome/slug/SlugHunting.fr.html
deleted file mode 100644
index f25ab92..0000000
--- a/src/lessons/welcome/slug/SlugHunting.fr.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<h2>Chasse à la limace</h2>
-
-<p>Maintenant que votre méthode <code>isFacingTrail()</code> fonctionne, il est
-temps d'écrire le code de la chasse à proprement parler. Copie/collez le
-code que vous aviez fait pour l'exercice précédent, et complétez la méthode
-<code>hunt()</code> (<i>hunt</i> signifie <i>chasse</i> en anglais).</p>
-
-<p>Suivre une piste n'est pas très difficile : avancez tant que vous êtes face
-à la piste. Si la piste n'est plus devant vous, cherchez si elle se trouve à
-gauche ou à droite, et suivez-la encore.</p>
-
-<p>Pour ne pas confondre la partie de la trace à suivre avec celle que votre
-buggle a déjà suivie, il est conseillé d'effacer la piste derrière
-vous. Pour cela, utilisez la méthode <code>brushDown()</code> pour baisser
-votre crayon, et <code>brushUp()</code> pour le relever.</p>
-
-<p>Enfin, n'oubliez de capturer votre proie une fois que vous l'aurez débusquée
-(avec <code>pickupBaggle()</code>).</p>
-
-
-<h3>Objectif de cet exercice</h3>
-<a name="Objectifs"> Complétez la méthode <code>hunt()</code>. Vous voulez
-probablement copier votre méthode <code>isFacingTrail()</code> de l'exercice
-précédent.
diff --git a/src/lessons/welcome/slug/SlugHunting.java b/src/lessons/welcome/slug/SlugHunting.java
deleted file mode 100644
index 7b36be1..0000000
--- a/src/lessons/welcome/slug/SlugHunting.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-public class SlugHunting extends ExerciseTemplated {
-
-	public SlugHunting(Lesson lesson) {
-		super(lesson);
-
-		BuggleWorld[] myWorlds = new BuggleWorld[2];
-
-		BuggleWorld myWorld = new BuggleWorld("Forrest", 8, 7);
-		for (int i = 5; i >= 2; i--)
-			myWorld.setColor(6, i,Color.green);
-		myWorld.setColor(5, 2,Color.green);
-		for (int i = 2; i <= 4; i++)
-			myWorld.setColor(4, i,Color.green);
-		myWorld.setColor(3, 4,Color.green);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.green);
-		myWorld.setColor(1, 1,Color.green);
-		myWorld.setColor(0, 1,Color.green);
-		try {
-			myWorld.newBaggle(0, 1);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[0] = myWorld;
-
-		myWorld = new BuggleWorld("Desert", 8, 7);
-		for (int i = 5; i >= 2; i--)
-		    myWorld.setColor(6, i,Color.green);
-		myWorld.putTopWall(6, 2);
-		myWorld.putLeftWall(6, 3);
-		myWorld.putLeftWall(7, 2);
-		myWorld.setColor(5, 2,Color.green);
-		myWorld.setColor(5, 1,Color.green);
-		myWorld.setColor(5, 0,Color.green);
-		myWorld.setColor(4, 0,Color.green);
-		myWorld.setColor(3, 0,Color.green);
-		myWorld.setColor(2, 0,Color.green);
-				       
-		myWorld.setColor(3, 4,Color.green);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.green);
-		myWorld.setColor(4, 4,Color.green);
-
-		try {
-			myWorld.newBaggle(3, 4);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[1] = myWorld;
-
-		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		setup(myWorlds);
-	}
-
-}
\ No newline at end of file
diff --git a/src/lessons/welcome/slug/SlugHuntingEntity.java b/src/lessons/welcome/slug/SlugHuntingEntity.java
deleted file mode 100644
index 141fe38..0000000
--- a/src/lessons/welcome/slug/SlugHuntingEntity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-
-public class SlugHuntingEntity extends jlm.universe.bugglequest.SimpleBuggle {
-
-	@Override
-	public void run() {
-		hunt(); 
-	}
-
-	/* BEGIN TEMPLATE */
-	public void hunt() {
-		// Write your code here
-		/* BEGIN SOLUTION */
-		while (! isOverBaggle()) {
-			if (isFacingTrail()) {
-				brushDown();
-				forward();
-				brushUp();
-			} else {
-				turnLeft();
-			}
-		}
-		pickupBaggle();
-		/* END SOLUTION */
-	}
-
-	/* BEGIN HIDDEN */
-	boolean isFacingTrail() {
-		if (isFacingWall())
-			return false;
-
-		forward();
-		boolean res = getGroundColor().equals(Color.green);
-		backward();
-		return res;
-
-	}		
-	/* END HIDDEN */
-	/* END TEMPLATE */
-
-
-}
diff --git a/src/lessons/welcome/slug/SlugHuntingEntity.py b/src/lessons/welcome/slug/SlugHuntingEntity.py
deleted file mode 100644
index 2dbf55a..0000000
--- a/src/lessons/welcome/slug/SlugHuntingEntity.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN TEMPLATE
-# BEGIN HIDDEN
-def isFacingTrail():
-   if isFacingWall():
-      return False
-   else:
-	  forward()
-	  res = getGroundColor().toString() == Color.green.toString()
-	  backward()
-	  return res
-# END HIDDEN
-
-def hunt():
-   # write your code here
-   # BEGIN SOLUTION
-   while not isOverBaggle():
-      brushUp()
-      if isFacingTrail():
-         brushDown()
-         forward()
-         brushUp()
-      else:
-	     turnLeft()
-   pickupBaggle()
-   # END SOLUTION
-# END TEMPLATE
-
-hunt()
diff --git a/src/lessons/welcome/slug/SlugSnail.java b/src/lessons/welcome/slug/SlugSnail.java
deleted file mode 100644
index 266cc2d..0000000
--- a/src/lessons/welcome/slug/SlugSnail.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-public class SlugSnail extends ExerciseTemplated {
-
-	public SlugSnail(Lesson lesson) {
-		super(lesson);
-
-		BuggleWorld[] myWorlds = new BuggleWorld[2];
-
-		BuggleWorld myWorld = new BuggleWorld("Kitty", 8, 7);
-		for (int i = 5; i >= 2; i--)
-			myWorld.setColor(6, i,Color.pink);
-		myWorld.setColor(5, 2,Color.pink);
-		for (int i = 2; i <= 4; i++)
-			myWorld.setColor(4, i,Color.pink);
-		myWorld.setColor(3, 4,Color.pink);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.pink);
-		myWorld.setColor(1, 1,Color.pink);
-		myWorld.setColor(0, 1,Color.pink);
-		myWorld.setParameter(new Object[] {Color.pink});
-		
-		try {
-			myWorld.newBaggle(0, 1);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[0] = myWorld;
-
-		myWorld = new BuggleWorld("Snail", 8, 7);
-		for (int i = 5; i >= 2; i--)
-		    myWorld.setColor(6, i,Color.orange);
-		myWorld.putTopWall(6, 2);
-		myWorld.putLeftWall(6, 3);
-		myWorld.putLeftWall(7, 2);
-		myWorld.setColor(5, 2,Color.orange);
-		myWorld.setColor(5, 1,Color.orange);
-		myWorld.setColor(5, 0,Color.orange);
-		myWorld.setColor(4, 0,Color.orange);
-		myWorld.setColor(3, 0,Color.orange);
-		myWorld.setColor(2, 0,Color.orange);
-				       
-		myWorld.setColor(3, 4,Color.orange);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.orange);
-		myWorld.setColor(4, 4,Color.orange);
-		myWorld.setParameter(new Object[] {Color.orange});
-
-		try {
-			myWorld.newBaggle(3, 4);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[1] = myWorld;
-
-		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		setup(myWorlds);
-	}
-
-}
\ No newline at end of file
diff --git a/src/lessons/welcome/slug/SlugSnailEntity.java b/src/lessons/welcome/slug/SlugSnailEntity.java
deleted file mode 100644
index c8dc0a4..0000000
--- a/src/lessons/welcome/slug/SlugSnailEntity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-
-public class SlugSnailEntity extends jlm.universe.bugglequest.SimpleBuggle {
-
-	@Override
-	public void run() {
-		hunt((Color) getParam(0)); 
-	}
-
-	/* BEGIN TEMPLATE */
-	public void hunt(Color c) {
-		// Write your code here
-		/* BEGIN SOLUTION */
-		while (! isOverBaggle()) {
-			if (isFacingTrail(c)) {
-				brushDown();
-				forward();
-				brushUp();
-			} else {
-				turnLeft();
-			}
-		}
-		pickupBaggle();
-		/* END SOLUTION */
-	}
-   
-	// here comes your isFacingTrail method   
-
-	/* BEGIN HIDDEN */
-	boolean isFacingTrail(Color c) {
-		if (isFacingWall())
-			return false;
-
-		forward();
-		boolean res = getGroundColor().equals(c);
-		backward();
-		return res;
-
-	}		
-	/* END HIDDEN */
-	/* END TEMPLATE */
-
-
-}
diff --git a/src/lessons/welcome/slug/SlugSnailEntity.py b/src/lessons/welcome/slug/SlugSnailEntity.py
deleted file mode 100644
index 101a4e4..0000000
--- a/src/lessons/welcome/slug/SlugSnailEntity.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN TEMPLATE
-def isFacingTrail(color):
-   # write your code here
-   # BEGIN SOLUTION
-   if isFacingWall():
-      return False
-   else:
-	  forward()
-	  res = (getGroundColor() == color)
-	  backward()
-	  return res
-   # END SOLUTION
-
-def hunt(color):
-   # BEGIN HIDDEN
-   while not isOverBaggle():
-      brushUp()
-      if isFacingTrail(color):
-         brushDown()
-         forward()
-         brushUp()
-      else:
-	     turnLeft()
-   pickupBaggle()
-   # END HIDDEN
-# END TEMPLATE
-
-hunt(getParam(0))
-
diff --git a/src/lessons/welcome/slug/SlugTracking.fr.html b/src/lessons/welcome/slug/SlugTracking.fr.html
deleted file mode 100644
index d82dec1..0000000
--- a/src/lessons/welcome/slug/SlugTracking.fr.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<h2>Pistage de la limace</h2>
-<p>
-Votre buggle est super contente ! Elle vient de trouver une grosse traînée
-baveuse sur le sol, certainement laissée par une grosse limace. Au bout de
-cette piste, la buggle est sûre de se régaler d'un bon jus de limace
-(représentée par un baggle). 
-</p>
-
-<p>Pour arriver au résultat, vous devez écrire la méthode booléenne
-<code>isFacingTrail()</code>, qui permet de savoir si on est face à une case
-verte ou non. Bien sûr, si on est face à un mur, elle doit répondre faux
-sans se cogner. Il faudrait de plus que cette méthode soit <b>sans effet de
-bord</b>, c'est-à-dire qu'elle ne modifie  ni la buggle qui l'appelle, ni le
-monde environnant.</p>
-
-<p class="Java">Votre outil pour cela est la méthode <code>getGroundColor()</code> qui
-retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut
-vous rendre dans la case à tester avant d'appeler cette méthode. Vous ne
-pouvez pas simplement utiliser <code>==</code> pour tester si la couleur
-retournée est le vert, mais vous devez plutôt écrire quelque chose comme
-<code>getGroundColor().equals(Color.green)</code>. C'est parce que les
-couleurs sont des <i>objets</i> en Java, et que <code>.equals()</code> est
-la marche à suivre pour tester l'égalité d'objets Java.</p>   
-
-<p class="python">Votre outil pour cela est la méthode <code>getGroundColor()</code> qui
-retourne la couleur du sol dans la case où se trouve la buggle. Il vous faut
-vous rendre dans la case à tester avant d'appeler cette méthode.</p>
-
-<h3>Objectif de cet exercice</h3>
-<p>Complétez la méthode <code>isFacingTrail()</code> qui sera appelée
-automatiquement comme il faut.</p>
diff --git a/src/lessons/welcome/slug/SlugTracking.html b/src/lessons/welcome/slug/SlugTracking.html
deleted file mode 100644
index 10b23fb..0000000
--- a/src/lessons/welcome/slug/SlugTracking.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<h2>Slug Tracking</h2>
-<p>
-Your buggle is super happy! It just found the green dribbling trail, certainly left by a big yummy slug. 
-At its end, the buggle is certain to entertain itself with this appetizing slug (represented as a baggle). 
-</p>
-
-<p>To reach that goal, you had to write a boolean method <tt>isFacingTrail</tt>, which determines whether 
-we are facing a green cell or not. Of course, if we are facing a wall, it should return
-false without bumping into it. You should make sure that this method has no <b>side effect</b>, i.e. that
-it does not change the state of the calling buggle nor of its world.</p>
-
-<p class="Java">Your tool to that end is the <code>getGroundColor()</code> that returns the color of the 
-current cell. Just go to the cell you want to test and run that function. You cannot test whether this 
-color is equal to <code>Color.green</code> with an <code>==</code> sign but instead you have to write 
-something like <code>getGroundColor().equals(Color.green)</code>. This is because green is an 
-<i>object</i> in Java, and <code>.equals()</code> is the way to go to test equality between Java objects.</p>   
-
-<p class="python">Your tool to that end is the <code>getGroundColor()</code> that returns the color of the 
-current cell. Just go to the cell you want to test and run that function.</p>
-
-<h3>Exercise goal</h3>
-<p>Complete the <code>isFacingTrail()</code> method (which gets called automatically).</p>
diff --git a/src/lessons/welcome/slug/SlugTracking.java b/src/lessons/welcome/slug/SlugTracking.java
deleted file mode 100644
index da85960..0000000
--- a/src/lessons/welcome/slug/SlugTracking.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
-
-public class SlugTracking extends ExerciseTemplated {
-
-	public SlugTracking(Lesson lesson) {
-		super(lesson);
-
-		BuggleWorld[] myWorlds = new BuggleWorld[2];
-
-		BuggleWorld myWorld = new BuggleWorld("Forrest", 8, 7);
-		for (int i = 5; i >= 2; i--)
-			myWorld.setColor(6, i,Color.green);
-		myWorld.setColor(5, 2,Color.green);
-		for (int i = 2; i <= 4; i++)
-			myWorld.setColor(4, i,Color.green);
-		myWorld.setColor(3, 4,Color.green);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.green);
-		myWorld.setColor(1, 1,Color.green);
-		myWorld.setColor(0, 1,Color.green);
-		try {
-			myWorld.newBaggle(0, 1);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[0] = myWorld;
-
-		myWorld = new BuggleWorld("Desert", 8, 7);
-		for (int i = 5; i >= 2; i--)
-		    myWorld.setColor(6, i,Color.green);
-		myWorld.putTopWall(6, 2);
-		myWorld.putLeftWall(6, 3);
-		myWorld.putLeftWall(7, 2);
-		myWorld.setColor(5, 2,Color.green);
-		myWorld.setColor(5, 1,Color.green);
-		myWorld.setColor(5, 0,Color.green);
-		myWorld.setColor(4, 0,Color.green);
-		myWorld.setColor(3, 0,Color.green);
-		myWorld.setColor(2, 0,Color.green);
-				       
-		myWorld.setColor(3, 4,Color.green);
-		for (int i = 4; i >= 1; i--)
-			myWorld.setColor(2, i,Color.green);
-		myWorld.setColor(4, 4,Color.green);
-
-		try {
-			myWorld.newBaggle(3, 4);
-		} catch (AlreadyHaveBaggleException e) {
-			e.printStackTrace();
-		}
-		myWorlds[1] = myWorld;
-
-		Buggle hunter = new Buggle(myWorlds[0], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		hunter = new Buggle(myWorlds[1], "Hunter", 6, 6, Direction.NORTH, Color.black, Color.lightGray);
-		hunter.brushDown();
-
-		setup(myWorlds);
-	}
-
-}
\ No newline at end of file
diff --git a/src/lessons/welcome/slug/SlugTrackingEntity.java b/src/lessons/welcome/slug/SlugTrackingEntity.java
deleted file mode 100644
index 0498f4d..0000000
--- a/src/lessons/welcome/slug/SlugTrackingEntity.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package lessons.welcome.slug;
-
-import java.awt.Color;
-
-
-public class SlugTrackingEntity extends jlm.universe.bugglequest.SimpleBuggle {
-
-	@Override
-	public void run() {
-		hunt(); 
-	}
-
-	public void hunt() {
-		while (! isOverBaggle()) {
-			if (isFacingTrail()) {
-				brushDown();
-				forward();
-				brushUp();
-			} else {
-				turnLeft();
-			}
-		}
-		pickupBaggle();
-	}
-
-	/* BEGIN TEMPLATE */
-	boolean isFacingTrail() {
-		// Write your code here
-		/* BEGIN SOLUTION */
-		if (isFacingWall())
-			return false;
-		forward();
-		boolean res = getGroundColor().equals(Color.green); 
-		backward();
-		return res;
-		/* END SOLUTION */
-	}		
-	/* END TEMPLATE */
-
-}
diff --git a/src/lessons/welcome/slug/SlugTrackingEntity.py b/src/lessons/welcome/slug/SlugTrackingEntity.py
deleted file mode 100644
index ab90016..0000000
--- a/src/lessons/welcome/slug/SlugTrackingEntity.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import java.awt.Color as Color
-
-# BEGIN TEMPLATE
-def isFacingTrail():
-   # write your code here
-   # BEGIN SOLUTION
-   if isFacingWall():
-      return False
-   else:
-	  forward()
-	  res = (getGroundColor() == Color.green)
-	  backward()
-	  return res
-   # END SOLUTION
-# END TEMPLATE
-
-def hunt():
-   while not isOverBaggle():
-      brushUp()
-      if isFacingTrail():
-         brushDown()
-         forward()
-         brushUp()
-      else:
-	     turnLeft()
-   pickupBaggle()
-
-hunt()
-
diff --git a/src/lessons/welcome/snake/Snake.fr.html b/src/lessons/welcome/snake/Snake.fr.html
deleted file mode 100644
index 585def1..0000000
--- a/src/lessons/welcome/snake/Snake.fr.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<h2>Monde de serpents</h2>
-
-<p>Nous allons maintenant apprendre à la buggle à explorer son monde. Sa
-position de départ est en bas à gauche, et elle doit visiter toutes les
-cases juqu'en haut (en coloriant le sol sur son passage).  La boucle
-principale de la méthode <code>run()</code> (que vous devez écrire)  est de
-la forme :</p>
-<pre>
- baisser le crayon
- tant que l'on est pas à la position finale
-   avancer comme un serpent
-</pre>
-
-<p>Le prototype de cette méthode (sa première ligne) doit être :</p>
-<pre>public void run()</pre>
-<p>(nous verrons plus tard ce que ce <code>public</code> signifie).  Il faut
-donc écrire deux méthodes en plus de <code>run()</code>. L'une renvoit un
-booléen et indique si l'on se trouve à une position finale, tandis que
-l'autre ne renvoit pas de résultat et avance d'un pas.</p>
-
-<p>On se trouve sur une position finale si et seulement si les deux conditions
-suivantes sont vraies.:</p>
-<ul>
-  <li>On est face à un mur</li>
-  <li>Il y a un mur au nord de la buggle. Donc, si la buggle regarde à l'est, il
-faut vérifier s'il y a un mur à gauche, et si la buggle regarde à l'ouest,
-il faut vérifier s'il y a un mur à droite.<br/>
-      On obtient la direction actuelle de la buggle avec la méthode
-<code>getDirection()</code>, et on sait si elle regarde à l'est avec le test
-<code>getDirection() == Direction.EAST</code> (WEST pour ouest).<br/>
-      Pour la vérification elle-même, rien de magique : il faut se tourner et
-regarder si on est face à un mur une fois tourné.</li>
-</ul>
-
-<p>Ensuite un pas de serpent se fait en avancant d'un pas si l'on est pas face
-à un mur, et en montant à la ligne du dessus sinon (càd, si on regarde à
-l'ouest face à un mur, il faut tourner à droite, avancer, tourner à droite).</p>
-
-<p>Indication: la boucle principale de la méthode <code>run()</code> doit
-continuer tant que la fonction adéquate renvoie faux. On peut l'écrire de
-deux façons:</p>
-<pre class="Java">while (fonctionTest() == false)</pre>
-<pre class="python">while fonctionTest() == false:</pre>
-<p>ou bien</p>
-<pre class="Java">while (! fonctionTest())</pre>
-<pre class="Python">while not fonctionTest():</pre>
-<p class="Java">Cela fonctionne car le point d'exclamation en java indique une négation
-booléenne.</p>
-
-<p>À vous de jouer...</p>
-
diff --git a/src/lessons/welcome/snake/Snake.html b/src/lessons/welcome/snake/Snake.html
deleted file mode 100644
index c3c6d12..0000000
--- a/src/lessons/welcome/snake/Snake.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<h2>Snake World</h2>
-
-<p>We will now teach the buggle to explore its world. Its initial position is
-the bottom left corner, and it should visit any cells up to the top
-(coloring the ground on its path. The main loop of the <code>run()</code>
-method (that you should write) is something like:</p>
-<pre>
- move brush down
- while we did not reach the final position
-   move like a snake
-</pre>
-
-<p>The prototype of this method (its first line) must be:</p>
-<pre>public void run()</pre>
-<p>(we will come back later on the meaning of <code>public</code>). We thus
-have to write two methods in addition to <code>run()</code>. The former
-returns a boolean indicating whether we are on a final position while the
-latter does not return any result and move one snake step forward.</p>
-
-<p>We reached the final position if and only if both conditions are true:</p>
-<ul>
-  <li>We are facing a wall</li>
-  <li>There is a wall on the north of the buggle. So, if the buggle is facing
-east, you should check whether there is a wall on the left, and if the
-buggle is facing west, you should check on the right side.<br/>
-      We can get the current heading of the buggle using the
-<code>getDirection()</code>, and we know whether it looks east using
-<code>getDirection() == Direction.EAST</code> (WEST for west).<br/>
-      For the checking itself, nothing magical: you have to turn the buggle and
-check whether it is facing a wall afterward.</li>
-</ul>
-
-<p>Then, a snake step can be achieved by moving one step forward if we are not
-facing a wall, and moving to the upper line else (ie, if you look to the
-west facing a wall, you have to turn right, forward and turn right).</p>
-
-<p>Hint: the main loop of the <code>run()</code> method must continue while the
-testing function returns false. Their is thus two way of writing it:</p>
-<pre class="Java">while (testingFunction() == false)</pre>
-<pre class="python">while testingFunction() == False:</pre>
-<p>or</p>
-<pre class="Java">while (! testingFunction())</pre>
-<pre class="Python">while not testingFunction():</pre>
-<p class="Java">It works because the exclamation mark (!) means in Java a boolean negation.</p>
-
-<p>Your turn...</p>
-
diff --git a/src/lessons/welcome/snake/Snake.java b/src/lessons/welcome/snake/Snake.java
deleted file mode 100644
index 1a20b20..0000000
--- a/src/lessons/welcome/snake/Snake.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package lessons.welcome.snake;
-
-import java.awt.Color;
-
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-
-public class Snake extends ExerciseTemplated {
-
-	public Snake(Lesson lesson) {
-		super(lesson);
-		tabName = "SnakeBuggle";
-
-		BuggleWorld myWorld = new BuggleWorld("Desert",7,7);
-		for (int i=0; i<7;i++) {
-			myWorld.putTopWall(i, 0);
-			myWorld.putLeftWall(0, i);
-		}
-		
-		new Buggle(myWorld, "Snake", 0, 6, Direction.EAST, Color.red, Color.red);
-
-		setup(myWorld);
-	}
-}
diff --git a/src/lessons/welcome/snake/SnakeEntity.java b/src/lessons/welcome/snake/SnakeEntity.java
deleted file mode 100644
index 6eb1377..0000000
--- a/src/lessons/welcome/snake/SnakeEntity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package lessons.welcome.snake;
-
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.SimpleBuggle;
-
-public class SnakeEntity extends SimpleBuggle {
-	/* BEGIN TEMPLATE */
-	/* BEGIN SOLUTION */
-	boolean endingPosition() {
-		if (! isFacingWall()) 
-			return false;
-
-		boolean res = false;
-		turnLeft();
-		if (isFacingWall()) 
-			res = true;
-		turnRight();		
-		return res;
-	}
-
-	void snakeStep() {
-		if (isFacingWall()) {
-			if (getDirection() == Direction.EAST) {
-				turnLeft();
-				forward();
-				turnLeft();
-			} else {
-				turnRight();
-				forward();
-				turnRight();
-			}
-		} else {
-			forward();
-		}
-
-	}
-
-	@Override
-	public void run() {
-		brushDown();
-		while (!endingPosition()) {
-			snakeStep();
-		}
-	}
-	/* END SOLUTION */
-	/* END TEMPLATE */	
-}
diff --git a/src/lessons/welcome/snake/SnakeEntity.py b/src/lessons/welcome/snake/SnakeEntity.py
deleted file mode 100644
index 34c53db..0000000
--- a/src/lessons/welcome/snake/SnakeEntity.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# BEGIN SOLUTION
-def endingPosition():
-	if not isFacingWall():
-		return False
-	else:
-		res = False
-		turnLeft()
-		if isFacingWall():
-			res = True
-		turnRight()
-		return res
-
-def snakeStep():
-	if isFacingWall():
-		if getDirection().toString() == "EAST":
-			turnLeft()
-			forward()
-			turnLeft()
-		else:
-			turnRight()
-			forward()
-			turnRight()
-	else:
-		forward()
-
-brushDown()
-while not endingPosition():
-	snakeStep()
-# END SOLUTION
diff --git a/src/lessons/welcome/snake/Snake-answer0.map b/src/lessons/welcome/traversal/Snake-answer0.map
similarity index 100%
rename from src/lessons/welcome/snake/Snake-answer0.map
rename to src/lessons/welcome/traversal/Snake-answer0.map
diff --git a/src/lessons/welcome/traversal/Snake.fr.html b/src/lessons/welcome/traversal/Snake.fr.html
new file mode 100644
index 0000000..810eba0
--- /dev/null
+++ b/src/lessons/welcome/traversal/Snake.fr.html
@@ -0,0 +1,44 @@
+<h2>Monde de serpents</h2>
+
+<p>Nous allons maintenant apprendre à la buggle à explorer son monde. Sa
+position de départ est en bas à gauche, et elle doit visiter toutes les
+cases juqu'en haut (en coloriant le sol sur son passage).  La boucle
+principale de votre code doit être de la forme :</p>
+<pre>
+ baisser le crayon
+ tant que l'on est pas à la position finale
+   avancer comme un serpent
+</pre>
+
+<p>Il faut donc écrire deux méthodes spécifiques. L'une renvoie un booléen
+indiquant si l'on se trouve à la position finale, tandis que l'autre avance
+d'un pas de serpent.</p>
+
+<p>On se trouve sur une position finale si et seulement si les deux conditions
+suivantes sont vraies.:</p>
+<ul>
+  <li>On est face à un mur</li>
+  <li>Il y a un mur au nord de la buggle. Donc, si la buggle regarde à l'est, il
+faut vérifier s'il y a un mur à gauche, et si la buggle regarde à l'ouest,
+il faut vérifier s'il y a un mur à droite.<br/>
+      On obtient la direction actuelle de la buggle avec la méthode
+<code>getDirection()</code>, et on sait si elle regarde à l'est avec le test
+<code>getDirection() == Direction.EAST</code> (WEST pour ouest).<br/>
+      Pour la vérification elle-même, rien de magique : il faut se tourner et
+regarder si on est face à un mur une fois tourné.</li>
+</ul>
+
+<p>Ensuite un pas de serpent se fait en avancant d'un pas si l'on est pas face
+à un mur, et en montant à la ligne du dessus sinon (càd, si on regarde à
+l'ouest face à un mur, il faut tourner à droite, avancer, tourner à droite).</p>
+
+<p>Indication: la boucle principale de votre code doit continuer tant que la
+fonction adéquate renvoie faux. On peut l'écrire de deux façons:</p>
+<pre>while (fonctionTest() == [!java|scala]false) {[/!][!python]False):[/!]</pre>
+<p>[!python]Vous pouvez préférer l'écrire ainsi:[/!]
+[!java|scala]Comme le point d'exclamation (!) dénote la négation booléenne
+en [!thelang], vous pouvez aussi l'écrire:[/!]</p>
+<pre>while ([!java|scala]![/!][!python]not [/!]fonctionTest())[!java|scala] {[/!][!python]:[/!]</pre>
+
+<p>À vous de jouer...</p>
+
diff --git a/src/lessons/welcome/traversal/Snake.html b/src/lessons/welcome/traversal/Snake.html
new file mode 100644
index 0000000..ebd1aba
--- /dev/null
+++ b/src/lessons/welcome/traversal/Snake.html
@@ -0,0 +1,40 @@
+<h2>Snake World</h2>
+
+<p>We will now teach the buggle to explore its world. Its initial position is
+the bottom left corner, and it should visit any cells up to the top
+(coloring the ground on its path. The main loop of your code is something like:</p>
+<pre>
+ move brush down
+ while we did not reach the final position
+   move like a snake
+</pre>
+
+<p>We thus have to write two specific methods: The first one
+returns a boolean indicating whether we are on a final position while the
+second moves one snake step forward.</p>
+
+<p>We reached the final position if and only if both conditions are true:</p>
+<ul>
+  <li>We are facing a wall</li>
+  <li>There is a wall on the north of the buggle. So, if the buggle is facing
+east, you should check whether there is a wall on the left, and if the
+buggle is facing west, you should check on the right side.<br/>
+      We can get the current heading of the buggle using the
+<code>getDirection()</code>, and we know whether it looks east using
+<code>getDirection() == Direction.EAST</code> (WEST for west).<br/>
+      To check, nothing magical: you have to turn the buggle and check whether it is facing a wall afterward.</li>
+</ul>
+
+<p>Then, a snake step can be achieved by moving one step forward if we are not
+facing a wall, and moving to the upper line else (i.e., if you look to the
+west facing a wall, you have to turn right, forward and turn right).</p>
+
+<p>Hint: the main loop of your code must continue while the
+testing function returns false. Their is thus two way of writing it:</p>
+<pre>while (testingFunction() == [!java|scala]false) {[/!][!python]False):[/!]</pre>
+<p>[!python]You may prefer to write it as:[/!]
+[!java|scala]Since the exclamation mark (!) denotes the boolean negation in [!thelang], you may write it as:[/!]</p>
+<pre>while ([!java|scala]![/!][!python]not [/!]testingFunction())[!java|scala] {[/!][!python]:[/!]</pre>
+
+<p>Your turn...</p>
+
diff --git a/src/lessons/welcome/traversal/Snake.java b/src/lessons/welcome/traversal/Snake.java
new file mode 100644
index 0000000..34f8d3e
--- /dev/null
+++ b/src/lessons/welcome/traversal/Snake.java
@@ -0,0 +1,27 @@
+package lessons.welcome.traversal;
+
+import java.awt.Color;
+
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Snake extends ExerciseTemplated {
+
+	public Snake(Lesson lesson) {
+		super(lesson);
+		tabName = "SnakeBuggle";
+
+		BuggleWorld myWorld = new BuggleWorld("Desert",7,7);
+		for (int i=0; i<7;i++) {
+			myWorld.putTopWall(i, 0);
+			myWorld.putLeftWall(0, i);
+		}
+		
+		new Buggle(myWorld, "Snake", 0, 6, Direction.EAST, Color.red, Color.red);
+
+		setup(myWorld);
+	}
+}
diff --git a/src/lessons/welcome/traversal/SnakeEntity.java b/src/lessons/welcome/traversal/SnakeEntity.java
new file mode 100644
index 0000000..230bf90
--- /dev/null
+++ b/src/lessons/welcome/traversal/SnakeEntity.java
@@ -0,0 +1,46 @@
+package lessons.welcome.traversal;
+
+import plm.universe.Direction;
+import plm.universe.bugglequest.SimpleBuggle;
+
+public class SnakeEntity extends SimpleBuggle {
+	@Override
+	/* BEGIN TEMPLATE */
+	public void run() {
+		/* BEGIN SOLUTION */
+		brushDown();
+		while (!endingPosition()) {
+			snakeStep();
+		}
+	}
+	boolean endingPosition() {
+		if (! isFacingWall()) 
+			return false;
+
+		boolean res = false;
+		left();
+		if (isFacingWall()) 
+			res = true;
+		right();		
+		return res;
+	}
+
+	void snakeStep() {
+		if (isFacingWall()) {
+			if (getDirection() == Direction.EAST) {
+				left();
+				forward();
+				left();
+			} else {
+				right();
+				forward();
+				right();
+			}
+		} else {
+			forward();
+		}
+
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */	
+}
diff --git a/src/lessons/welcome/traversal/SnakeEntity.py b/src/lessons/welcome/traversal/SnakeEntity.py
new file mode 100644
index 0000000..f32ea3a
--- /dev/null
+++ b/src/lessons/welcome/traversal/SnakeEntity.py
@@ -0,0 +1,29 @@
+# BEGIN SOLUTION
+def endingPosition():
+	if not isFacingWall():
+		return False
+	else:
+		res = False
+		left()
+		if isFacingWall():
+			res = True
+		right()
+		return res
+
+def snakeStep():
+	if isFacingWall():
+		if getDirection().toString() == "EAST":
+			left()
+			forward()
+			left()
+		else:
+			right()
+			forward()
+			right()
+	else:
+		forward()
+
+brushDown()
+while not endingPosition():
+	snakeStep()
+# END SOLUTION
diff --git a/src/lessons/welcome/traversal/SnakeEntity.scala b/src/lessons/welcome/traversal/SnakeEntity.scala
new file mode 100644
index 0000000..a46db1b
--- /dev/null
+++ b/src/lessons/welcome/traversal/SnakeEntity.scala
@@ -0,0 +1,46 @@
+package lessons.welcome.traversal;
+
+import plm.universe.Direction;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaSnakeEntity extends SimpleBuggle {
+
+	/* BEGIN TEMPLATE */
+	def run() {
+		/* BEGIN SOLUTION */
+		brushDown();
+		while (!endingPosition()) {
+			snakeStep();
+		}
+	}
+	def endingPosition():Boolean = {
+		if (! isFacingWall()) 
+			return false;
+
+		var res = false;
+		left();
+		if (isFacingWall()) 
+			res = true;
+		right();		
+		return res;
+	}
+
+	def snakeStep() {
+		if (isFacingWall()) {
+			if (getDirection() == Direction.EAST) {
+				left();
+				forward();
+				left();
+			} else {
+				right();
+				forward();
+				right();
+			}
+		} else {
+			forward();
+		}
+
+		/* END SOLUTION */
+	}
+	/* END TEMPLATE */	
+}
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumn.fr.html b/src/lessons/welcome/traversal/column/TraversalByColumn.fr.html
index 6dc6d51..d74cfcf 100644
--- a/src/lessons/welcome/traversal/column/TraversalByColumn.fr.html
+++ b/src/lessons/welcome/traversal/column/TraversalByColumn.fr.html
@@ -1,31 +1,29 @@
 <h2>Parcours en colonne</h2>
 
-L'objectif de cette série d'exercices est de faire parcourir le monde à la
+<p>L'objectif de cette série d'exercices est de faire parcourir le monde à la
 buggle.  Elle doit de plus numéroter les différentes cases rencontrées pour
-montrer son ordre de parcours. 
+montrer son ordre de parcours.</p>
 
-<p div="Java">La boucle principale de la méthode <code>run()</code> (que vous devez
-écrire)  est de la forme :<p>
-<p div="python">La boucle principale du code que vous devez écrire est de la forme :<p>
-<p><pre>
+<p>La boucle principale du code que vous devez écrire est de la forme :</p>
+<pre>
  tant que l'on n'est pas à la position finale
    aller à la prochaine position
    marquer le numéro de case au sol 
-</pre></p>
+</pre>
 
 <p>À la différence des exercices vus jusque là, nous n'allons pas utiliser les
-méthodes <code>forward()</code>, <code>backward()</code> et autres, mais
-nous allons calculer les coordonnées de la prochaine position de la buggle,
-et utiliser la méthode <code>setPos(x, y)</code> pour <i>téléporter</i> la
+méthodes <code>avance()</code>, <code>recule()</code> et autres, mais nous
+allons calculer les coordonnées de la prochaine position de la buggle, et
+utiliser la méthode <code>setPos(x, y)</code> pour <i>téléporter</i> la
 buggle directement à cette position. Par exemple, <code>setPos(3, 5)</code>
 téléporte la buggle sur la case où x=3 et y=5.</p>
 
 <p>Le premier objectif est donc d'écrire une fonction booléenne indiquant si la
 buggle a atteint la position finale ou non, càd si elle est arrivée en bas à
 droite du monde.  Vous utiliserez pour cela les méthodes
-<code>getWorldWidth()</code> et <code>getWorldHeight()</code> qui retournent
-respectivement la largeur et la hauteur du monde.  Votre test est de
-comparer les coordonnées actuelles de votre buggle (que vous pouvez
+<code>getMondeHauteur()</code> et <code>getMondeLargueur()</code> qui
+retournent respectivement la hauteur et la largeur du monde.  Votre test est
+de comparer les coordonnées actuelles de votre buggle (que vous pouvez
 retrouver avec les méthodes <code>getX()</code> et <code>getY()</code>) aux
 dimensions du monde.<br/>
 Attention, la première ligne et la première colonne sont numérotées 0 et non
@@ -42,17 +40,14 @@ faut. Pensez à utiliser le bouton <b>stop</b> pour arrêter l'exécution si
 votre programme ne se termine pas correctement.</p>
 
 <p>Il est temps d'écrire au sol les numéros de case. Pour cela, vous aurez
-besoin d'un compteur initialisé à zéro au début de votre méthode
-<code>run()</code>, et incrémenté de un à chaque pas (par exemple avec
-<code>cpt += 1;</code>). Ensuite, il faut écrire la valeur de ce compteur au
-sol à chaque pas, par exemple avec <code>writeMessage(cpt);</code>.
-
-<p div="Java">Il est sans doute nécessaire d'écrire la valeur de la première ou dernière
-case en dehors de la boucle principale, selon que vous utilisez un
-<code>while {}</code> ou un <code>do {} while</code>...</p>
-
-<p div="python">Si vous le souhaitez, vous pouvez écrire la première valeur en dehors de la
-boucle <code>while ....:</code>.</p>
+besoin d'un compteur initialisé à zéro au début de votre code, et incrémenté
+à chaque pas (par exemple avec <code>cpt += 1;</code>). Ensuite, il faut
+écrire cette valeur au sol (avec <code>ecritMessage()</code>).
+
+<p>Il est sans doute nécessaire d'écrire la valeur de la première[!java|scala]
+ou dernière[/!] case en dehors de la boucle principale[!java|scala], selon
+que vous utilisez une boucle <code>while</code> ou
+<code>do/while</code>[/!].</p>
 
 <p>À vous de jouer...</p>
 
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumn.html b/src/lessons/welcome/traversal/column/TraversalByColumn.html
index e90b40b..72d2782 100644
--- a/src/lessons/welcome/traversal/column/TraversalByColumn.html
+++ b/src/lessons/welcome/traversal/column/TraversalByColumn.html
@@ -1,53 +1,47 @@
-<h2>Traversal by column</h2>
-
-The goal of this serie of exercises is to let the buggle traverse its
-world. It must number the cells it walks on to show its traversal order. 
-
-<p div="Java">The main loop of the <code>run()</code> method (that you must write) is
-something like:<p>
-<p div="python">The main loop of your code should be something like:<p>
-<p><pre>
- while we are not on the final position
-   go to the next position
-   label the cell with its number
-</pre></p>
-
-<p>In contrary to the exercises we saw so far, we won't use the
-<code>forward()</code>, <code>backward()</code> and similar
-methods. Instead, we will compute the coordinate of the next buggle position
-and use the <code>setPos(x, y)</code> method to <i>teleport</i> the
-buggle directly to this position. For example, <code>setPos(3, 5)</code>
-teleports the buggle to the cell where x=3 and y=5.</p>
-
-<p>Your first task is thus to write a boolean function indicating whether the
-buggle the final position or not, ie if it reached the bottom right corner
-of the world. For this, you can use <code>getWorldWidth()</code> and
-<code>getWorldHeight()</code> which return respectively the world's width
-and height. Your test is about comparing the buggle's current position (that
-you can access with <code>getX()</code> and <code>getY()</code>) to the
-world dimensions.<br/>
-Beware, the first line and column are numbered 0 and not 1...</p>  
-
-<p>Then, you have to write the code to reach the next position. In this
-exercise, you have to traverse the world row after row. So, if you are at
-the bottom of a row, you have to move to the top of next row, and you have
-to move to the cell below else.</p>
-
-<p>At this point, you can launch your program to check that the buggle
-correctly traverse the world in the expected order, and that it stops when
-it has to. Use the <b>stop</b> button if the buggle does not stop correctly.</p>
-
-<p>It is now time to write done the cell numbers. For that, you will need a
-counter initialiser to zero at the begining of your <code>run()</code>
-method, and incremented by one at each step (for example with
-<code>counter += 1;</code>). Then, you have to write the value on the ground,
-for example with <code>writeMessage(counter);</code>.
-
-<p div="Java">You probably need to write the first or last value out of the main loop,
-depending on whether you prefer to use a <code>while {}</code> or a <code>do
-{} while</code>...</p>
-
-<p div="python">You may want to write the first value out of the main <code>while ...:</code> loop.</p>
-
-<p>Your turn...</p>
-
+<h2>Traversal by column</h2>
+
+<p>The goal of this serie of exercises is to let the buggle traverse its
+world. It must number the cells it walks on to show its traversal order.</p>
+
+<p>The main loop of your code should be something like:</p>
+<pre>
+ while we are not on the final position
+   go to the next position
+   label the cell with its number
+</pre>
+
+<p>In contrary to the exercises we saw so far, we won't use the
+<code>forward()</code>, <code>backward()</code> and similar
+methods. Instead, we will compute the coordinate of the next buggle position
+and use the <code>setPos(x, y)</code> method to <i>teleport</i> the
+buggle directly to this position. For example, <code>setPos(3, 5)</code>
+teleports the buggle to the cell where x=3 and y=5.</p>
+
+<p>Your first task is thus to write a boolean function indicating whether the
+buggle reached the final position or not, ie if it reached the bottom right corner
+of the world. For this, you can use <code>getWorldWidth()</code> and
+<code>getWorldHeight()</code> which return respectively the world's width
+and height. Your test is about comparing the buggle's current position (that
+you can access with <code>getX()</code> and <code>getY()</code>) to the
+world dimensions.<br/>
+Beware, the first line and column are numbered 0 and not 1...</p>  
+
+<p>Then, you have to write the code to reach the next position. In this
+exercise, you have to traverse the world row after row. So, if you are at
+the bottom of a row, you have to move to the top of next row, and you have
+to move to the cell below else.</p>
+
+<p>At this point, you can launch your program to check that the buggle
+correctly traverse the world in the expected order, and that it stops when
+it has to. Use the <b>stop</b> button if the buggle does not stop correctly.</p>
+
+<p>It is now time to write down the cell numbers. For that, you will need a
+counter initialiser to zero at the begining of your code, and incremented by 
+one at each step (for example with <code>counter += 1;</code>). 
+Then, you have to use <code>writeMessage()</code> to write the value on the ground.
+
+<p>You probably need to write the first [!java|scala]or last [/!]value out of the main loop
+[!java|scala], depending on whether you prefer to use a <code>while</code> or a <code>do/while</code> one[/!].</p>
+
+<p>Your turn...</p>
+
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumn.java b/src/lessons/welcome/traversal/column/TraversalByColumn.java
index 73db61d..c08774e 100644
--- a/src/lessons/welcome/traversal/column/TraversalByColumn.java
+++ b/src/lessons/welcome/traversal/column/TraversalByColumn.java
@@ -2,11 +2,11 @@ package lessons.welcome.traversal.column;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class TraversalByColumn extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumnEntity.java b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.java
index ecb51c6..a21f3cc 100644
--- a/src/lessons/welcome/traversal/column/TraversalByColumnEntity.java
+++ b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.java
@@ -1,6 +1,7 @@
 package lessons.welcome.traversal.column;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class TraversalByColumnEntity extends SimpleBuggle {
 	/* BEGIN TEMPLATE */
@@ -39,53 +40,41 @@ public class TraversalByColumnEntity extends SimpleBuggle {
 	}
 	/* END SOLUTION */
 	/* END TEMPLATE */	
-
 	@Override
-	public void forward()  {
-		if (isInited())
-			throw new RuntimeException("forward() forbidden in this exercise");
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void forward(int step)  {
+	public void forward()  {
 		if (isInited())
-			throw new RuntimeException("forward(int step) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void backward()  {
-		if (isInited())
-			throw new RuntimeException("backward() forbidden in this exercise");
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void backward(int step)  {
-		if (isInited())
-			throw new RuntimeException("backward(int step) forbidden in this exercise");
+	public void backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void turnLeft()  {
-		if (isInited())
-			throw new RuntimeException("turnLeft() forbidden in this exercise");
+	public void left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
 	}
 	@Override
-	public void turnRight()  {
-		if (isInited())
-			throw new RuntimeException("turnRight() forbidden in this exercise");
+	public void right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
 	}
 	@Override
-	public void turnBack()  {
-		if (isInited())
-			throw new RuntimeException("turnBack() forbidden in this exercise");
+	public void back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
 	}
 	@Override
-	public boolean isFacingWall()  {
-		if (isInited())
-			throw new RuntimeException("isFacingWall() forbidden in this exercise");
-		return false;
+	public boolean isFacingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
 	}
 	@Override
-	public boolean isBackingWall()  {
-		if (isInited())
-			throw new RuntimeException("isBackingWall() forbidden in this exercise");
-		return false;
-	}    
-
+	public boolean isBackingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
+	}
 }
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumnEntity.py b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.py
index 9064400..bc4317f 100644
--- a/src/lessons/welcome/traversal/column/TraversalByColumnEntity.py
+++ b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.py
@@ -4,14 +4,14 @@ def forward(i):
 def backward(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use backward() in this exercise.")
 
-def turnRight(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnRight() in this exercise.")
+def right(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use right() in this exercise.")
 
-def turnLeft(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnLeft() in this exercise.")
+def left(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use left() in this exercise.")
 
-def turnBack(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnBack() in this exercise.")
+def back(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use back() in this exercise.")
 
 def isFacingWall(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use isFacingWall() in this exercise.")
diff --git a/src/lessons/welcome/traversal/column/TraversalByColumnEntity.scala b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.scala
new file mode 100644
index 0000000..ed2c088
--- /dev/null
+++ b/src/lessons/welcome/traversal/column/TraversalByColumnEntity.scala
@@ -0,0 +1,70 @@
+package lessons.welcome.traversal.column;
+
+import plm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game
+
+class ScalaTraversalByColumnEntity extends SimpleBuggle {
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */	
+	def nextStep() {	
+		var x=getX();
+		var y=getY();
+
+		if (y < getWorldHeight()-1) {
+			y+=1;
+		} else {
+			y = 0;
+			if (x < getWorldWidth()-1) {
+				x+=1;
+			} else {
+				x = 0; 
+			}
+		}
+		setPos(x,y);
+	}
+
+	def endingPosition(): Boolean = {
+		return (getX() == getWorldWidth() -1) && (getY() == getWorldHeight()-1);
+	}
+
+
+	def run() {
+		var cpt=0;
+		writeMessage(cpt);
+		while (!endingPosition()) {
+			nextStep();
+			cpt+=1;
+			writeMessage(cpt);
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */	
+
+	override def forward(i:Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def forward()  {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def backward(i:Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
+	}
+	override def right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
+	}
+	override def back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
+	}
+	override def isFacingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
+	}
+	override def isBackingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
+	}
+}
diff --git a/src/lessons/welcome/traversal/diagonal/TraversalDiagonal.java b/src/lessons/welcome/traversal/diagonal/TraversalDiagonal.java
index 2c3d680..3a2efb8 100644
--- a/src/lessons/welcome/traversal/diagonal/TraversalDiagonal.java
+++ b/src/lessons/welcome/traversal/diagonal/TraversalDiagonal.java
@@ -2,11 +2,11 @@ package lessons.welcome.traversal.diagonal;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class TraversalDiagonal extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java
index a7a848b..0c255d2 100644
--- a/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java
+++ b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.java
@@ -1,6 +1,7 @@
 package lessons.welcome.traversal.diagonal;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class TraversalDiagonalEntity extends SimpleBuggle {
 	/* BEGIN TEMPLATE */
@@ -45,50 +46,40 @@ public class TraversalDiagonalEntity extends SimpleBuggle {
 	/* END TEMPLATE */
 
 	@Override
-	public void forward()  {
-		if (isInited())
-			throw new RuntimeException("forward() forbidden in this exercise");
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void forward(int step)  {
+	public void forward()  {
 		if (isInited())
-			throw new RuntimeException("forward(int step) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void backward()  {
-		if (isInited())
-			throw new RuntimeException("backward() forbidden in this exercise");
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void backward(int step)  {
-		if (isInited())
-			throw new RuntimeException("backward(int step) forbidden in this exercise");
+	public void backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void turnLeft()  {
-		if (isInited())
-			throw new RuntimeException("turnLeft() forbidden in this exercise");
+	public void left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
 	}
 	@Override
-	public void turnRight()  {
-		if (isInited())
-			throw new RuntimeException("turnRight() forbidden in this exercise");
+	public void right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
 	}
 	@Override
-	public void turnBack()  {
-		if (isInited())
-			throw new RuntimeException("turnBack() forbidden in this exercise");
+	public void back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
 	}
 	@Override
-	public boolean isFacingWall()  {
-		if (isInited())
-			throw new RuntimeException("isFacingWall() forbidden in this exercise");
-		return false;
+	public boolean isFacingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
 	}
 	@Override
-	public boolean isBackingWall()  {
-		if (isInited())
-			throw new RuntimeException("isBackingWall() forbidden in this exercise");
-		return false;
+	public boolean isBackingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
 	}
 }
diff --git a/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.py b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.py
index c256974..e40faf7 100644
--- a/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.py
+++ b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.py
@@ -4,14 +4,14 @@ def forward(i):
 def backward(i):
 	errorMsg("Sorry Dave, I cannot let you use backward() in this exercise")
 
-def turnRight(i):
-	errorMsg("Sorry Dave, I cannot let you use turnRight() in this exercise")
+def right(i):
+	errorMsg("Sorry Dave, I cannot let you use right() in this exercise")
 
-def turnLeft(i):
-	errorMsg("Sorry Dave, I cannot let you use turnLeft() in this exercise")
+def left(i):
+	errorMsg("Sorry Dave, I cannot let you use left() in this exercise")
 
-def turnBack(i):
-	errorMsg("Sorry Dave, I cannot let you use turnBack() in this exercise")
+def back(i):
+	errorMsg("Sorry Dave, I cannot let you use back() in this exercise")
 
 def isFacingWall(i):
 	errorMsg("Sorry Dave, I cannot let you use isFacingWall() in this exercise")
diff --git a/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.scala b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.scala
new file mode 100644
index 0000000..8512084
--- /dev/null
+++ b/src/lessons/welcome/traversal/diagonal/TraversalDiagonalEntity.scala
@@ -0,0 +1,75 @@
+package lessons.welcome.traversal.diagonal;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaTraversalDiagonalEntity extends SimpleBuggle {
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+	var diag = 0;
+
+	def nextStep() {
+		var x = getX();
+		var y = getY();
+
+		if ((x + 1 < getWorldWidth()) && (y > 0)) {
+			x+=1;
+			y-=1;
+		} else if (diag + 1 < getWorldHeight()) {
+			diag+=1;
+			y = diag;
+			x = 0;
+		} else {
+			diag+=1;
+			x = diag - (getWorldWidth() - 1);
+			y = diag - x;
+		}
+
+		setPos(x, y);
+	}
+
+	def endingPosition():Boolean = {
+		return (getX() == getWorldWidth() - 1) && (getY() == getWorldHeight() - 1);
+	}
+
+	def run() {
+		var cpt = 0;
+		writeMessage(cpt);
+		while (!endingPosition()) {
+			nextStep();
+			cpt+=1;
+			writeMessage(cpt);
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */
+
+
+	override def forward(i:Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def forward()  {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def backward(i:Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
+	}
+	override def right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
+	}
+	override def back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
+	}
+	override def isFacingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
+	}
+	override def isBackingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
+	}
+}
diff --git a/src/lessons/welcome/traversal/line/TraversalByLine.java b/src/lessons/welcome/traversal/line/TraversalByLine.java
index 4c100ff..688ad2d 100644
--- a/src/lessons/welcome/traversal/line/TraversalByLine.java
+++ b/src/lessons/welcome/traversal/line/TraversalByLine.java
@@ -2,11 +2,11 @@ package lessons.welcome.traversal.line;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class TraversalByLine extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/traversal/line/TraversalByLineEntity.java b/src/lessons/welcome/traversal/line/TraversalByLineEntity.java
index 7bd1025..c6fb85d 100644
--- a/src/lessons/welcome/traversal/line/TraversalByLineEntity.java
+++ b/src/lessons/welcome/traversal/line/TraversalByLineEntity.java
@@ -1,6 +1,7 @@
 package lessons.welcome.traversal.line;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class TraversalByLineEntity extends SimpleBuggle {
 	/* BEGIN TEMPLATE */
@@ -41,50 +42,40 @@ public class TraversalByLineEntity extends SimpleBuggle {
 	/* END TEMPLATE */	
 
 	@Override
-	public void forward()  {
-		if (isInited())
-			throw new RuntimeException("forward() forbidden in this exercise");
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void forward(int step)  {
+	public void forward()  {
 		if (isInited())
-			throw new RuntimeException("forward(int step) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void backward()  {
-		if (isInited())
-			throw new RuntimeException("backward() forbidden in this exercise");
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void backward(int step)  {
-		if (isInited())
-			throw new RuntimeException("backward(int step) forbidden in this exercise");
+	public void backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void turnLeft()  {
-		if (isInited())
-			throw new RuntimeException("turnLeft() forbidden in this exercise");
+	public void left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
 	}
 	@Override
-	public void turnRight()  {
-		if (isInited())
-			throw new RuntimeException("turnRight() forbidden in this exercise");
+	public void right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
 	}
 	@Override
-	public void turnBack()  {
-		if (isInited())
-			throw new RuntimeException("turnBack() forbidden in this exercise");
+	public void back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
 	}
 	@Override
-	public boolean isFacingWall()  {
-		if (isInited())
-			throw new RuntimeException("isFacingWall() forbidden in this exercise");
-		return false;
+	public boolean isFacingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
 	}
 	@Override
-	public boolean isBackingWall()  {
-		if (isInited())
-			throw new RuntimeException("isBackingWall() forbidden in this exercise");
-		return false;
+	public boolean isBackingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
 	}
 }
diff --git a/src/lessons/welcome/traversal/line/TraversalByLineEntity.py b/src/lessons/welcome/traversal/line/TraversalByLineEntity.py
index 51216da..f182076 100644
--- a/src/lessons/welcome/traversal/line/TraversalByLineEntity.py
+++ b/src/lessons/welcome/traversal/line/TraversalByLineEntity.py
@@ -4,14 +4,14 @@ def forward(i):
 def backward(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use backward() in this exercise.")
 
-def turnRight(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnRight() in this exercise.")
+def right(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use right() in this exercise.")
 
-def turnLeft(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnLeft() in this exercise.")
+def left(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use left() in this exercise.")
 
-def turnBack(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnBack() in this exercise.")
+def back(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use back() in this exercise.")
 
 def isFacingWall(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use isFacingWall() in this exercise.")
diff --git a/src/lessons/welcome/traversal/line/TraversalByLineEntity.scala b/src/lessons/welcome/traversal/line/TraversalByLineEntity.scala
new file mode 100644
index 0000000..bcb714f
--- /dev/null
+++ b/src/lessons/welcome/traversal/line/TraversalByLineEntity.scala
@@ -0,0 +1,71 @@
+package lessons.welcome.traversal.line;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaTraversalByLineEntity extends SimpleBuggle {
+	/* BEGIN TEMPLATE */
+	/* BEGIN SOLUTION */
+
+	def nextStep() {
+		var x=getX();
+		var y=getY();
+		if (x < getWorldWidth()-1) {
+			x+=1;
+		} else {
+			x = 0; 
+			if (y < getWorldHeight()-1) {
+				y+=1; 
+			} else {
+				y = 0;
+			}
+		}
+		setPos(x,y);
+	}
+
+	def endingPosition():Boolean = {
+		return (getX() == getWorldWidth()-1) && (getY() == getWorldHeight()-1);
+	}
+
+
+	def run() {
+		var cpt=0;
+		do {
+			writeMessage(cpt);
+			nextStep();
+			cpt+=1;
+		} while (!endingPosition());
+		writeMessage(cpt);
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */	
+
+
+	override def forward(i:Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def forward()  {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def backward(i:Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
+	}
+	override def right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
+	}
+	override def back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
+	}
+	override def isFacingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
+	}
+	override def isBackingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
+	}
+}
diff --git a/src/lessons/welcome/traversal/zigzag/TraversalZigZag.java b/src/lessons/welcome/traversal/zigzag/TraversalZigZag.java
index b2ef57c..66b6624 100644
--- a/src/lessons/welcome/traversal/zigzag/TraversalZigZag.java
+++ b/src/lessons/welcome/traversal/zigzag/TraversalZigZag.java
@@ -2,11 +2,11 @@ package lessons.welcome.traversal.zigzag;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class TraversalZigZag extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java
index 12b5d48..911cd91 100644
--- a/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java
+++ b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.java
@@ -1,6 +1,7 @@
 package lessons.welcome.traversal.zigzag;
 
-import jlm.universe.bugglequest.SimpleBuggle;
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
 
 public class TraversalZigZagEntity extends SimpleBuggle {
 	/* BEGIN TEMPLATE */		
@@ -45,50 +46,40 @@ public class TraversalZigZagEntity extends SimpleBuggle {
 	/* END TEMPLATE */	
 
 	@Override
-	public void forward()  {
-		if (isInited())
-			throw new RuntimeException("forward() forbidden in this exercise");
+	public void forward(int i)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void forward(int step)  {
+	public void forward()  {
 		if (isInited())
-			throw new RuntimeException("forward(int step) forbidden in this exercise");
+			throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
 	}
 	@Override
-	public void backward()  {
-		if (isInited())
-			throw new RuntimeException("backward() forbidden in this exercise");
+	public void backward(int i) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void backward(int step)  {
-		if (isInited())
-			throw new RuntimeException("backward(int step) forbidden in this exercise");
+	public void backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
 	}
 	@Override
-	public void turnLeft()  {
-		if (isInited())
-			throw new RuntimeException("turnLeft() forbidden in this exercise");
+	public void left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
 	}
 	@Override
-	public void turnRight()  {
-		if (isInited())
-			throw new RuntimeException("turnRight() forbidden in this exercise");
+	public void right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
 	}
 	@Override
-	public void turnBack()  {
-		if (isInited())
-			throw new RuntimeException("turnBack() forbidden in this exercise");
+	public void back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
 	}
 	@Override
-	public boolean isFacingWall()  {
-		if (isInited())
-			throw new RuntimeException("isFacingWall() forbidden in this exercise");
-		return false;
+	public boolean isFacingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
 	}
 	@Override
-	public boolean isBackingWall()  {
-		if (isInited())
-			throw new RuntimeException("isBackingWall() forbidden in this exercise");
-		return false;
+	public boolean isBackingWall() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
 	}
 }
diff --git a/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.py b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.py
index c183a23..2b10aba 100644
--- a/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.py
+++ b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.py
@@ -4,14 +4,14 @@ def forward(i):
 def backward(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use backward() in this exercise.")
 
-def turnRight(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnRight() in this exercise.")
+def right(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use right() in this exercise.")
 
-def turnLeft(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnLeft() in this exercise.")
+def left(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use left() in this exercise.")
 
-def turnBack(i):
-	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use turnBack() in this exercise.")
+def back(i):
+	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use back() in this exercise.")
 
 def isFacingWall(i):
 	errorMsg("I'm sorry Dave, I'm afraid I cannot let you use isFacingWall() in this exercise.")
diff --git a/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.scala b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.scala
new file mode 100644
index 0000000..b9b83ef
--- /dev/null
+++ b/src/lessons/welcome/traversal/zigzag/TraversalZigZagEntity.scala
@@ -0,0 +1,75 @@
+package lessons.welcome.traversal.zigzag;
+
+import plm.core.model.Game;
+import plm.universe.bugglequest.SimpleBuggle;
+
+class ScalaTraversalZigZagEntity extends SimpleBuggle {
+	/* BEGIN TEMPLATE */		
+	/* BEGIN SOLUTION */
+
+	def nextStep() {        
+		var x=getX();
+		var y=getY();
+
+		if (y % 2 == 0) {
+			if (x < getWorldWidth()-1) {
+				x+=1;
+			} else if (y < getWorldHeight()-1) {
+				y+=1; 
+			}
+		} else {
+			if (0 < x) {
+				x-=1;
+			} else if (y < getWorldHeight()-1) {
+				y+=1; 
+			}
+		}
+
+		setPos(x,y);
+	}
+
+	def endingPosition():Boolean = {
+		return (getX() == getWorldWidth() -1) && (getY() == getWorldHeight()-1);
+	}
+
+	def run() {
+		var cpt=0;
+		writeMessage(cpt);
+		while (!endingPosition()) {
+			nextStep();
+			cpt+=1;
+			writeMessage(cpt);
+		}
+	}
+	/* END SOLUTION */
+	/* END TEMPLATE */	
+
+
+	override def forward(i:Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def forward()  {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward() in this exercise."));
+	}
+	override def backward(i:Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def backward() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward() in this exercise."));
+	}
+	override def left() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use left() in this exercise."));
+	}
+	override def right() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use right() in this exercise."));
+	}
+	override def back() {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use back() in this exercise."));
+	}
+	override def isFacingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isFacingWall() in this exercise."));
+	}
+	override def isBackingWall():Boolean = {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use isBackingWall() in this exercise."));
+	}
+}
diff --git a/src/lessons/welcome/variables/RunFour.fr.html b/src/lessons/welcome/variables/RunFour.fr.html
index e94af18..63c753b 100644
--- a/src/lessons/welcome/variables/RunFour.fr.html
+++ b/src/lessons/welcome/variables/RunFour.fr.html
@@ -4,7 +4,7 @@
 commencé. C'est une compétition traditionnelle par laquelle les jeunes
 buggles prouvent leur valeur à la tribu. C'est à la fois une épreuve de
 force et d'intelligence puisqu'il faut courir le plus vite possible, mais
-s'arrêter dès que vous avez rejoint votre quatrième baggle. Il faut que vous
-aidiez les buggles à avancer tout en comptant les baggles pour déterminer
-quand s'arrêter.</p> 
+s'arrêter dès que vous avez rejoint votre quatrième biscuit. Il faut que
+vous aidiez les buggles à avancer tout en comptant les biscuits pour
+déterminer quand s'arrêter.</p> 
 
diff --git a/src/lessons/welcome/variables/RunFour.java b/src/lessons/welcome/variables/RunFour.java
index 78c93a6..86aa1c3 100644
--- a/src/lessons/welcome/variables/RunFour.java
+++ b/src/lessons/welcome/variables/RunFour.java
@@ -2,11 +2,11 @@ package lessons.welcome.variables;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class RunFour extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/variables/RunFourEntity.java b/src/lessons/welcome/variables/RunFourEntity.java
index 651b7ac..6a839ed 100644
--- a/src/lessons/welcome/variables/RunFourEntity.java
+++ b/src/lessons/welcome/variables/RunFourEntity.java
@@ -1,14 +1,15 @@
 package lessons.welcome.variables;
 
-public class RunFourEntity extends jlm.universe.bugglequest.SimpleBuggle {
+import plm.core.model.Game;
+
+public class RunFourEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
 	}
-
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
 	}
 
 
diff --git a/src/lessons/welcome/variables/RunFourEntity.scala b/src/lessons/welcome/variables/RunFourEntity.scala
new file mode 100644
index 0000000..ed89239
--- /dev/null
+++ b/src/lessons/welcome/variables/RunFourEntity.scala
@@ -0,0 +1,23 @@
+package lessons.welcome.variables;
+
+import plm.core.model.Game
+
+class ScalaRunFourEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		var cpt = 0;
+		while (cpt != 4) {
+			forward();
+			if (isOverBaggle())
+				cpt += 1
+		}
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/variables/RunHalf.fr.html b/src/lessons/welcome/variables/RunHalf.fr.html
index aeea074..896caa7 100644
--- a/src/lessons/welcome/variables/RunHalf.fr.html
+++ b/src/lessons/welcome/variables/RunHalf.fr.html
@@ -3,9 +3,9 @@
 <p>C'est le second jour de la Grande Course des Buggles. Comme d'habitude, il
 faut courir jusqu'à trouver la case où vous devez vous arrêter. Mais cette
 fois, vous devez vous arrêter quand vous aurez compté deux fois plus de
-baggles que de cases oranges plus une. En d'autres termes, la condition
-d'arrêt est la suivante : <code>2 * baggles = caseOrange + 1</code>.</p>
+biscuits que de cases oranges plus une. En d'autres termes, la condition
+d'arrêt est la suivante : <code>2 * biscuits = caseOrange + 1</code>.</p>
 
 <p>Vous pouvez déterminer si vous vous trouvez sur une case orange avec la
-méthode <code>isOverOrange()</code>.</p> 
+méthode <code>estSurOrange()</code>.</p> 
 
diff --git a/src/lessons/welcome/variables/RunHalf.java b/src/lessons/welcome/variables/RunHalf.java
index affe2c1..89e1917 100644
--- a/src/lessons/welcome/variables/RunHalf.java
+++ b/src/lessons/welcome/variables/RunHalf.java
@@ -2,11 +2,11 @@ package lessons.welcome.variables;
 
 import java.io.IOException;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.BrokenWorldFileException;
-import jlm.universe.World;
-import jlm.universe.bugglequest.BuggleWorld;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
 
 public class RunHalf extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/variables/RunHalfEntity.java b/src/lessons/welcome/variables/RunHalfEntity.java
index 06a1d6b..7ae1b0d 100644
--- a/src/lessons/welcome/variables/RunHalfEntity.java
+++ b/src/lessons/welcome/variables/RunHalfEntity.java
@@ -2,20 +2,23 @@ package lessons.welcome.variables;
 
 import java.awt.Color;
 
-public class RunHalfEntity extends jlm.universe.bugglequest.SimpleBuggle {
+import plm.core.model.Game;
+
+public class RunHalfEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
 	}
-
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
 	}
 	public boolean isOverOrange() {
 		return getGroundColor().equals(Color.orange);
 	}
-
+	/* BINDINGS TRANSLATION */
+	public boolean estSurOrange() { return isOverOrange(); }
+	
 	@Override
 	/* BEGIN TEMPLATE */
 	public void run() { 
diff --git a/src/lessons/welcome/variables/RunHalfEntity.py b/src/lessons/welcome/variables/RunHalfEntity.py
index 0b1cf07..707c9bf 100644
--- a/src/lessons/welcome/variables/RunHalfEntity.py
+++ b/src/lessons/welcome/variables/RunHalfEntity.py
@@ -9,6 +9,9 @@ def backward(i=1):
 def isOverOrange():
     return getGroundColor() == Color.orange
 
+def estSurOrange(): # BINDINGS TRANSLATION
+    return isOverOrange()
+
 # BEGIN SOLUTION
 baggle = 0
 orange = 0
diff --git a/src/lessons/welcome/variables/RunHalfEntity.scala b/src/lessons/welcome/variables/RunHalfEntity.scala
new file mode 100644
index 0000000..ebdfb88
--- /dev/null
+++ b/src/lessons/welcome/variables/RunHalfEntity.scala
@@ -0,0 +1,34 @@
+package lessons.welcome.variables;
+
+import java.awt.Color;
+import plm.core.model.Game
+
+class ScalaRunHalfEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument."));
+	}
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument."));
+	}
+	def isOverOrange():Boolean = {
+		return getGroundColor().equals(Color.orange);
+	}
+	/* BINDINGS TRANSLATION */
+	def estSurOrange():Boolean = { return isOverOrange(); }
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		var baggle:Int = 0;
+		var orange:Int = 0;
+		while (2 * baggle != orange + 1) {
+			//if (getName().equals("buggle2")) 
+			//	System.out.println("baggle: "+baggle+"; orange: "+orange+"; sum:"+(2*baggle-orange-1));
+			forward();
+			if (isOverBaggle())
+				baggle += 1
+			if (isOverOrange())
+				orange += 1
+		}
+		/* END SOLUTION */
+	}
+}
diff --git a/src/lessons/welcome/variables/Variables.fr.html b/src/lessons/welcome/variables/Variables.fr.html
index 9cd0ea3..8ad20c4 100644
--- a/src/lessons/welcome/variables/Variables.fr.html
+++ b/src/lessons/welcome/variables/Variables.fr.html
@@ -6,111 +6,170 @@ des buggles, les principales données sont cachées derrière la représentation
 graphique, mais ce n'est pas une raison pour ne jamais manipuler
 explicitement des données. 
 
-  <h3 class="Java">Les données en Java</h3>
-  <h3 class="Python">Les données en Python</h3>
-  Dans un programme, on peut utiliser différents <i>types</i> de données, tels
+  <h3>Les données en [!thelang]</h3>
+<p>Dans un programme, on peut utiliser différents <i>types</i> de données, tels
 que les entiers, les nombres à virgules ou les chaînes de caractères. Si on
 veut utiliser une donnée plusieurs fois, il faut la stocker dans une
-<i>variable</i>, qui est une sorte de case contenant une valeur. Ce n'est
-pas très différent d'une étagère contenant un livre: vous rangez votre
-donnée (disons '5') dans la variable (disons 'longueur'), et vous pouvez la
-retrouver plus tard quand vous en avez besoin.
-
-  <p class="Java">Java est un langage <i>typé</i>, ce qui veut dire que l'on ne peut stocker
-une valeur que dans une variable du bon type. Pas question de stocker votre
-nom dans une variable entière.</p>
-  <p class="Python">Le langage Python est dit <i>non typé</i>, ce qui signifie qu'une variable
-donnée peutcontenir n'importe quel type de donnée. D'autres langages (comme
-Java) rendent obligatoire que chaque variable  ne puisse contenir que des
-données d'un certain type, mais il n'y a pas de telles difficultés ici.</p>
+<i>variable</i>, qui est une sorte de case contenant une valeur: vous rangez
+votre donnée (disons '5') dans la variable (disons «longueur»), et vous
+pouvez la retrouver plus tard quand vous en avez besoin. C'est exactement
+comme prendre une boîte avec une étiquette (disons «cadeau») et d'y ranger
+quelque chose dedans (disons, un flacon de Channel Numéro 5).  
+
+<h3>Déclaration de Variables</h3>  
+
+<p>Il est très simple de <b>déclarer</b> (c'est-à-dire, créer) une variable en
+[!thelang]. Il suffit d'écrire
+[!java]son type, une espace et le nom de la variable.[/!]
+[!scala]le mot-clé <code>var</code>, le nom de la variable, deux points (:)
+et le type de la variable.[/!]
+[!python]le nom de la variable, un signe égal (=) et sa valeur initiale.[/!]
+
+Le nom de la variable est un label pour la retrouver plus tard[!python].[/!]
+
+[!java|scala] tandis que son type est le genre de données qu'on va pouvoir
+stoker dans cette variable.[/!]
+Il est interdit de mettre des espaces et des accents dans les noms de
+variable.
+Ainsi, on peut nommer une variable <code>dejaFait</code>, mais ni <code>deja
+fait</code> ni <code>déjaFait</code> ne sont des identificateurs de
+variables valides.
+  </p>
+
+[!java|scala]
+  <p>Ainsi, pour créer une variable nommée <b>x</b> contenant des entiers, on
+écrira :</p> 
+  <pre>[!java]int x;[/!][!scala]var x: Int[/!]</pre>
+[/!]
+
+<p>[!java|scala]Si vous le souhaitez, vous pouvez spécifier une valeur initiale
+en faisant suivre la déclaration d'un symbole égal (=) suivi de la valeur à
+utiliser.[/!]
+[!scala]Si vous spécifiez une valeur, il n'est alors plus indispensable de
+spécifier le type de la variable, puisque Scala parvient à le deviner tout
+seul. Vous êtes libre de le spécifier quand même si vous le désirez (ou si
+le compilateur se trompe, comme cela arrive parfois par exemple entre les
+différents types de nombres), mais c'est optionnel.[/!]
+Donc, si vous voulez utiliser 5 comme valeur initiale, il faut écrire: </p>
+<pre>[!java]int x=5;[/!][!python]x = 5[/!][!scala]var x: Int =  5 <span class="comment">// je peux quand même donner le type si je veux</span>
+var y = 10       <span class="comment">// ou bien je peux l'omettre</span>[/!]</pre>
+  
+[!java|scala]
+<p>Comme vous pouvez le voir, les variables sont <b>typées</b>
+en[!thelang]. Cela veut dire qu'elles sont en quelque sorte spécialisées:
+une variable donnée ne peut stocker qu'un type de données
+spécifique. N'essayez même pas de rancher des nombres dans une variable
+faite pour recevoir des lettres !
+D'autres langages (comme le python) sont moins regardants, et on peut ranger
+n'importe quel type de données dans n'importe quelle variable sans
+restriction. À première vue, cela semble plus simple, mais ce genre de
+restriction permet au compilateur de détecter plus d'erreurs de logiques
+pour vous, ce qui n'est pas dommage. En quelque sorte, il est plus facile
+d'écrire du python, mais le typage empêche certaines erreurs de se glisser
+dans vos programmes.
+Voici quelque uns des types de données existants en [!thelang] :</p>
+<ul>
+  <li><b>[!java]int[/!][!scala]Int[/!]</b>, pour les entiers;</li>
+  <li><b>[!java]double[/!][!scala]Double[/!]</b>, pour les nombres à virgule;</li> 
+  <li><b>[!java]boolean[/!][!scala]Boolean[/!]</b>, pour les booléens,
+c'est-à-dire les variables dont la valeur est soit "vrai" soit "faux";</li>
+  <li><b>String</b>, pour les chaînes de caractères.</li>
+</ul>
+[/!] [!python]
+<p>Comme vous pouvez le voir, les variables ne sont pas <b>typées</b> en
+Python, ce qui veut dire qu'elles ne sont pas spécialisées sur un type de
+données particulier. Il est tout à fait envisageable de stocker des nombres
+dans une variable, puis d'y mettre des lettres un peu plus tard.
+D'autres langages (comme le Java ou le Scala) sont plus restrictifs et
+imposent de spécialiser chaque variable pour un type donné. Cela semble bien
+plus contraignant à première vue, mais ce genre de restriction permet au
+compilateur de détecter plus d'erreurs de logique pour vous. D'une certaine
+manière, il est plus facile d'écrire du Python, mais le typage de ces
+langages empêche certaines erreurs de se glisser dans les programmes.</p>
+[/!]
   
-<p class="Java">Pour <i>déclarer</i> (i.e. créer) une variable, il suffit d'écrire son type,
-un espace et le nom de la variable. Notez qu'il n'est pas possible
-d'utiliser d'accents dans les noms de variables, malheureusement. Parmi les
-types existants, on trouve: <b>int</b> pour les entiers, <b>double</b> pour
-les nombres à virgule, <b>boolean</b> pour les booléens (i.e. les variables
-qui peuvent être soit vraies soit fausses) et <b>String</b> pour les chaînes
-de caractères.  Si l'on veut, on peut faire suivre la déclaration du signe =
-suivi de la valeur initiale à donner à la valeur. </p>
-<p class="Java">Ainsi, pour créer une variable nommée <b>x</b> contenant des entiers, on
-écrira : <pre class="Java">int x;</pre></p>
-<p class="Java">Si on veut que sa valeur initiale soit 5, on écrira : <pre class="Java">int x = 5;</pre></p>	
-<p class="Java">Plus tard dans le programme, si l'on souhaite <i>affecter</i> une nouvelle
-valeur à la variable, c'est très simple : <pre class="Java">x = 3;</pre>
-<p class="Java">La syntaxe pour créer une variable entière <code>x</code> de valeur initiale
-4 est la suivante : 
-  <pre class="Java">int x = 4;</pre></p>
-<p class="Java">C'est la même histoire pour les chaînes, nombres à virgule flottante et les
+
+<p class="scala">Si vous savez que votre «variable» ne va jamais changer de valeur (par
+exemple parce qu'il s'agit de la taille de l'écran ou une autre constante du
+genre), alors vous devriez en faire une <b>valeur</b> plutôt qu'une
+variable.
+Utilisez simplement le mot-clé <code>val</code> au lieu de
+<code>var</code>.
+Le compilateur pourra alors faire plus de vérifications pour aider les
+étourdis cherchant à modifier les constantes. Plus intéressant, le
+compilateur parvient également à produire du code plus rapide dans certains
+cas.</p>
+
+<p>C'est la même histoire pour les chaînes, nombres à virgule flottante et les
 booléens.</p>
-  <pre class="Java">String nom = "Martin Quinson";
+
+<pre class="java">String nom = "Martin Quinson";
 double taille=1.77; <span class="comment">// en mètres</span>
-boolean marie=true;</pre>
-
-<p class="Python"><i>Déclarer</i> (ie créer) une variable en Python est extrèmement simple:
-vous avez juste besoin de lui donner une valeur initiale en écrivant son
-nom, le signe égal et la valeur.</p>  
-<p class="Python">Ainsi, pour créer une variable nommée <b>x</b> dont la valeur initiale sera
-5, on écrira : <pre class="Python">x = 5;</pre></p>
-<p class="Python">Plus tard dans le programme, si l'on souhaite <i>affecter</i> une nouvelle
-valeur à la variable, c'est très simple : <pre class="Python">x = 3;</pre>
-<p class="Python">C'est la même histoire pour les chaînes, nombres à virgule flottante et les
-booléens.</p>
-<pre class="Python">prenom = "Martin"
+boolean marie=true; <span class="comment">// Signifie vrai; le contraire (faux) s'écrirait "false"</span></pre>
+
+<pre class="scala">val nom:String = "Martin Quinson"; <span class="comment">// impossible de le modifier (c'est une valeur)</span>
+var taille: Double = 1.77; <span class="comment">// en metre</span>
+var marie = true; <span class="comment">// Signifie vrai; le contraire (faux) s'écrirait "false"</span>
+<span class="comment">// Scala sait que 'true' est une valeur de type Boolean, pas besoin de le répéter</span></pre>
+
+<pre class="python">prenom = "Martin"
 nom = 'Quinson' <span class="comment"># les simples et les doubles quotes fonctionnent ici</span>
 devise = "Je ne finis jam' (mais je continue d'essayer)" <span class="comment"># avoir des quotes simples dans des doubles quotes fonctionne</span> 
 taille=1.77 <span class="comment"># en mètre</span>
-marie=True <span class="comment"># le contraire serait marqué False</span></pre>
+marie=True <span class="comment"># Signifie 'vrai'; le contraire (faux) serait marqué 'False'</span></pre>
 
-      
-<p>À droite du signe égal, on peut mettre une expression quelconque, qui peut
-contenir des constantes, des variables et des opérations : 
+<h3>Affectations</h3>
 
-<pre class="Java">x = 3 + 2;
-x = 3 * x;
-hello = "Salut "+nom;
-</pre> 
-<pre class="Python">x = 3 + 2
-x = 3 * x
-hello = "Salut "+nom
-</pre> 
+<p>Une fois que votre variable est déclarée, vous pouvez y <i>affecter</i> une
+nouvelle valeur plus tard dans votre programme. C'est vraiment très simple :</p> 
+<pre>x = 3[!java];[/!]</pre>
 
+<p>À droite du signe égal, on peut mettre une expression quelconque, qui peut
+contenir des constantes, des variables et des opérations :</p>
+
+<pre>x = 3 + 2[!java];[/!]
+x = 3 * x[!java];[/!]
+greeting = "Hello "+name[!java];[/!] <span class="comment">[!python]#[/!][!scala|java]//[/!] + est (également) l'opérateur pour concaténer les chaînes (càd pour les fusionner</span></pre> 
 
 <h3>Objectif de cet exercice</h3>
 Il est temps de faire un exercice un peu plus dur, n'est ce pas ? L'objectif
-cette fois est d'avancer jusqu'au baggle qui se trouve devant la buggle, le
-ramasser, revenir à la position initiale, puis de poser le baggle.
+cette fois est d'avancer jusqu'au biscuit qui se trouve devant la buggle, le
+ramasser, revenir à la position initiale, puis de poser le biscuit.
 
 <h3>Comment faire ?</h3> 
 <p>Pour résoudre ce problème, il faut le décomposer en parties que vous savez
 résoudre. Par exemple, on peut vouloir faire les étapes suivantes :
 <ol>
-  <li>Avancer jusqu'à se trouver sur un baggle</li>
-  <li>Ramasser le baggel au sol</li>
+  <li>Avancer jusqu'à se trouver sur un biscuit</li>
+  <li>Ramasser le biscuit au sol</li>
   <li>Reculer du même nombre de cases que ce qu'on a avancé</li>
-  <li>Reposer le baggel au sol</li>
+  <li>Reposer le biscuit au sol</li>
 </ol></p>
 
 <p>Bien entendu, il est impossible de reculer du bon nombre de case à l'étape 3
 si l'on a pas compté le nombre de pas faits à la première étape. On va pour
 cela utiliser une variable, que l'on peut nommer <code>nbPas</code>.</p>
 
-<p class="Java">On crée cette variable (de type <code>int</code>) avant l'étape 1, on
-l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1
-(<code>nbPas = nbPas + 1;</code> ou <code>nbPas++;</code>, les deux
-écritures sont équivalentes).</p>
-<p class="Python">On crée cette variable (de type <code>int</code>) avant l'étape 1, on
+<p>On crée cette variable (de type <code>int</code>) avant l'étape 1, on
 l'initialise à 0, et chaque fois qu'on avance d'un pas, on l'incrémente de 1
-(<code>nbPas = nbPas + 1;</code> ou <code>nbPas++;</code>, les deux
-écritures sont équivalentes).</p>
+(<code>nbPas = nbPas + 1;</code>[!java] ou <code>nbPas++;</code>, les deux
+écritures sont équivalentes[/!]).</p>
+  
+[!python|scala]
+<p>Si vous connaissez le Java ou d'autres langages du genre, vous serez
+probablement tenté d'utiliser l'opérateur <code>++</code> pour incrémenter
+la variable. Malheureusement, cet opérateur n'existe pas en
+[!thelang]. C'est parce qu'il serait difficile de savoir quoi faire quand on
+l'applique à un nombre complexe ou à une chaîne de caractères. Le problème
+ne se pose pas en Java, où ++ est défini pour le type <code>int</code> qui
+n'est pas un type d'objet mais un type primitif (si vous ne connaissez pas
+l'opérateur ++, ignorez simplement ce paragraphe : cela n'existe pas en
+[!thelang]).</p>
+[/!]
 
 <p>Ensuite, l'étape 3 consiste simplement à créer une nouvelle variable entière
 <code>dejaFait</code> initialisée à zéro, et reculer d'un pas tant que
 <code>dejaFait</code> n'est pas égal à <code>nbPas</code>, en incrémentant
 <code>dejaFait</code> à chaque fois.</p>
 
-<p>Attention, il est interdit d'utiliser des caractères accentués ou des
-espaces dans les noms de variables Java. Vous pouvez donc nommer votre
-variable <code>dejaFait</code>, mais ni <code>déjaFait</code> ni <code>deja
-Fait</code> ne sont des noms valides.</p>
-
 <p>À vous de jouer !</p>
diff --git a/src/lessons/welcome/variables/Variables.html b/src/lessons/welcome/variables/Variables.html
index 860eec0..452ce8b 100644
--- a/src/lessons/welcome/variables/Variables.html
+++ b/src/lessons/welcome/variables/Variables.html
@@ -5,69 +5,94 @@
    the graphical representation, but that's no reason to never manipulate some 
    data explicitly. 
 
-  <h3 class="Java">Data in Java</h3>
-  <h3 class="Python">Data in Python</h3>
-  In a program, you can use several <i>types</i> of data, such as integers or strings
+  <h3>Data in [!thelang]</h3>
+<p>In a program, you can use several <i>types</i> of data, such as integers or strings
 of chars. If you want to use a data several times, you need to store it
-within a <i>variable</i>, which is a memory cell containing a value. It's not very 
-different from a shelve containing a book: you put your data (say '5') in the 
-variable (say 'length'), and you can retrieve it latter when you need it.
-
-  <p class="Java">Java is said to be a <i>typed</i> language, which means that it is
-	only possible to store a value in a variable of the right type. Don't think
-	about storing the letters of your name into an integer variable. In other languages (such as Python) 
-	allow you to store any kind of data in any variable without such restriction, but not in Java.</p>
-  <p class="Python">The Python language is said to <i>not typed</i>, which means you can 
-  store any type of data into a given variable. Other languages (such as Java) mandate 
-  that each variable store only data of a given type, but there is no such 
-  difficulties here.</p>
+within a <i>variable</i>, which is a memory cell containing a value:
+you put your data (say the value '5') in the variable (say 'length'), and you can retrieve it 
+latter when you need it. That's very similar to a box of label 'gift' in which you would put 
+some stuff, like a bottle of perfume "Channel N°5".  
+
+<h3>Variable declarations</h3>  
+
+<p><b>Declaring</b> (ie, creating) a variable in [!thelang], is very simple. You just need to write
+  [!java]its type, a space, and the variable name.[/!]
+  [!scala]the <code>var</code> keyword, the variable name, a column (:) and the variable type.[/!]
+  [!python]the variable name, an equal sign (=) and an initial value.[/!]
+  The variable name is the label to retrieve it afterward[!python].[/!]
+  [!java|scala] while the type is the kind of data that this variable accepts to store.[/!]
+  It is forbidden to use spaces in variable names. So you can name a variable <code>stepAmount</code> if you want, 
+  but <code>step amount</code> is not a valid name.
+  </p>
+
+[!java|scala]
+  <p>So, to create a variable named <b>x</b> intended to contain integers, one should write:</p> 
+  <pre>[!java]int x;[/!][!scala]var x: Int[/!]</pre>
+[/!]
+
+<p>[!java|scala]If you want, you can specify the initial value of the variable by adding a equal sign (=) followed by the value after the declaration.[/!] 
+   [!scala]If you specify a value, you don't have to specify the type of the variable, since Scala manages to guess it alone in most cases.
+   You are still free to specify the type if you prefer (or if the compiler fail to determine the type for some reason), but it's optional.[/!] 
+   So you want that the variable contains 5 as initial value, you should type: </p>
+<pre>[!java]int x=5;[/!][!python]x = 5[/!][!scala]var x: Int =  5 <span class="comment">// I can define the type if I want to</span>
+var y =  10      <span class="comment">// or I can omit the type if I prefer</span>[/!]</pre>
   
-<p class="Java">To <i>declare</i> (ie, create) a variable, you just need to write its type,
-  a space, and the variable name. From the existing types, we can speak of
-  <b>int</b> (for integers), <b>double</b> for dot numbers, <b>boolean</b> for
-  booleans (ie, values being either true or false) and <b>String</b> for char
-  strings. If you want, you can specify the initial value of the variable by
-  adding a equal sign (=) followed by the value after the declaration. </p>
-<p class="Java">So, to create a variable named <b>x</b> intended to contain integers, one
-  can write: <pre class="Java">int x;</pre></p>
-<p class="Java">If you want that the variable contains 5 as initial value, you should type: <pre class="Java">int x = 5;</pre></p>	
-<p class="Java">Later in the program, if you want to <i>affect</i> a new value to the
-  variable, that's really easy: <pre class="Java">x = 3;</pre>
-<p class="Java">The syntax to create an integer variable <code>x</code> with 4 as initial
-  value is the following: 
-  <pre class="Java">int x = 4;</pre></p>
-<p class="Java">This quite the same story for strings, floating point
-numbers and boolean values.</p>
-  <pre class="Java">String name = "Martin Quinson";
+[!java|scala]
+<p>As you can see, the variables are <b>typed</b> in [!thelang], which means that they are somehow specialized: 
+  A given variable can only store data of a given type; Don't even think of storing numbers in a variable that is tailored for letters!  
+  Other languages (such as Python) are less picky and allow you to store any kind of data in any variable without restriction.
+  This seems easier at the first glance, but this kind of restriction allows the compiler to catch 
+  more logic errors for you, which is also good. In some sense, Python is easier to write but errors can sneak in more easily than in [!thelang]. 
+  Here are some of the existing types:</p>
+<ul>
+  <li><b>[!java]int[/!][!scala]Int[/!]</b>, for integers;</li>
+  <li><b>[!java]double[/!][!scala]Double[/!]</b>, for dot numbers;</li> 
+  <li><b>[!java]boolean[/!][!scala]Boolean[/!]</b>, for booleans that are values being either true or false;</li>
+  <li><b>String</b>, for char strings.</li>
+</ul>
+[/!]
+
+[!python]
+<p>As you can see, the variables are not <b>typed</b> in Python, which means that they are not specialized in any type of data.
+  A given variable store any type of data of a given type: you can store a number in a variable and latter on store a number in the same variable.  
+  Other languages (such as Java or Scala) are much more picky and prevent you to mix data types in a given variable.
+  This seems annoying at the first glance, but this kind of restriction allows the compiler to catch 
+  more logic errors for you, which is also good. In some sense, Python is easier to write but errors can sneak in more easily.</p>
+[/!]
+  
+
+<p class="scala">If you know that the value of your "variable" will never change (eg because it contains the screen 
+size or some other constant value), then you should make it a <b>value</b> instead of a variable. Simply change the 
+<code>var</code> keyword with the <code>val</code> one. The compiler can then perform more verifications and catch when 
+you inadvertently modify the value. More interestingly, the compiler can produce faster code in some cases.</p>
+
+<p>Variables work very similarly for strings, floating point numbers and boolean values.</p>
+
+<pre class="java">String name = "Martin Quinson";
 double height=1.77; <span class="comment">// in meters</span>
-boolean married=true;</pre>
-
-<p class="Python"><i>Declaring</i> (ie, creating) a variable in Python is 
-  dead simple: you just need to give it an initial value by writing its name, the equal sign and the value.</p>  
-<p class="Python">So, to create a variable named <b>x</b> which initial value should be 5, you should type: <pre class="Python">x = 5</pre></p>
-<p class="Python">Later in the program, if you want to <i>affect</i> a new value to the
-  variable, that's really easy: <pre class="Python">x = 3</pre>
-<p class="Python">This quite the same story for strings, floating
-point numbers and boolean values.</p>
-<pre class="Python">firstName = "Martin"
+boolean married=true;<span class="comment">// the contrary would be written "false"</span></pre>
+
+<pre class="scala">val name:String = "Martin Quinson"; <span class="comment">// this cannot be modified (it's a value)</span>
+var height: Double = 1.77; <span class="comment">// in meters</span>
+var married = true; <span class="comment">// the contrary would be written "false"</span>
+<span class="comment">// Scala knows that 'true' is a Boolean value, no need to repeat it here</span></pre>
+
+<pre class="python">firstName = "Martin"
 lastName = 'Quinson' <span class="comment"># both single and double quote work here</span>
 motto = "I never finish anyth' (but I keep trying)" <span class="comment"># having single quote within double quote is fine</span> 
 height=1.77 <span class="comment"># in meters</span>
-married=True <span class="comment"># the contrary would be written False</span></pre>
+married=True <span class="comment"># the contrary would be written "False"</span></pre>
 
-      
-<p>To the right of the equal symbol, you can put an expression containing constants, 
-variables and operations: 
+<h3>Affectations</h3>
 
-<pre class="Java">x = 3 + 2;
-x = 3 * x;
-greeting = "Hello "+name;
-</pre> 
-<pre class="Python">x = 3 + 2
-x = 3 * x
-greeting = "Hello "+name
-</pre> 
+<p>Once your variable is declared, you can <b>affect</b> a new value to it later in the program. That's really easy:</p> 
+<pre>x = 3[!java];[/!]</pre>
 
+<p>To the right of the equal symbol, you can put an arithmetic expression containing constants, variables and operations.</p>
+
+<pre>x = 3 + 2[!java];[/!]
+x = 3 * x[!java];[/!]
+greeting = "Hello "+name[!java];[/!] <span class="comment">[!python]#[/!][!scala|java]//[/!] + is (also) the operation to concatenate (ie, to join) strings</span></pre> 
 
 <h3>Exercise goal</h3>
 It is now time to do more challenging exercises, don't you think? 
@@ -89,21 +114,24 @@ example, you may want to do the following steps:
 3 if you didn't count the amount of steps done in the first phase. You can
 use a variable for that, which can be named <code>stepAmount</code>.</p>
 
-<p class="Java">Create a variable (of type <code>int</code>) before phase 1, initialize it
-  to 0, and each time you move one step forward, increment its value by one
-  (<code>stepAmount = stepAmount + 1;</code> or <code>stepAmount++;</code>,
-  both syntaxes being equivalent).</p>
-<p class="Python">Create a variable before phase 1, initialize it
-  to 0, and each time you move one step forward, increment its value by one
-  (<code>stepAmount = stepAmount + 1</code>).</p>
+<p>Create an integer variable before phase 1, initialize it to 0,
+  and each time you move one step forward, increment its value by one
+  (<code>stepAmount = stepAmount + 1;</code>[!java] or <code>stepAmount++;</code>,
+  both syntaxes being equivalent[/!]).
+  Such variable which takes every values of a given range is often called a <b>stepper</b>.</p>
+  
+[!python|scala]
+<p>If you know Java or other languages, you will probably try to use the <code>++</code> 
+  operator to increment the variable, but it's not allowed in [!thelang]. 
+  This is because it would be difficult to define this operator for every data types. 
+  For example, what should ++ do when applied to a Complex value or to a String? 
+  The problem does not occur in Java as <code>int</code> is not an object but a primitive type. 
+  (if you don't know the <code>++</code>, just ignore this paragraph: it does not exist in [!thelang])</p>
+[/!]
 
 <p>Then, phase 3 consists in simply creating a new integer variable
 <code>doneSteps</code> initialized to 0, and do one step backward until
 <code>doneSteps</code> equals <code>stepAmount</code>, incrementing
 <code>doneSteps</code> each time.</p>
 
-<p>Please note that it is forbidden to use spaces in variable names. So
-you can name you variable <code>stepAmount</code>, but <code>step
-Amount</code> is not a valid name.</p>
-
 <p>It's your turn now!</p>
diff --git a/src/lessons/welcome/variables/Variables.java b/src/lessons/welcome/variables/Variables.java
index 1b84865..3edd5ac 100644
--- a/src/lessons/welcome/variables/Variables.java
+++ b/src/lessons/welcome/variables/Variables.java
@@ -2,12 +2,12 @@ package lessons.welcome.variables;
 
 import java.awt.Color;
 
-import jlm.core.model.lesson.ExerciseTemplated;
-import jlm.core.model.lesson.Lesson;
-import jlm.universe.Direction;
-import jlm.universe.bugglequest.Buggle;
-import jlm.universe.bugglequest.BuggleWorld;
-import jlm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.Direction;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
 
 public class Variables extends ExerciseTemplated {
 
diff --git a/src/lessons/welcome/variables/VariablesEntity.java b/src/lessons/welcome/variables/VariablesEntity.java
index 14ede69..d97788d 100644
--- a/src/lessons/welcome/variables/VariablesEntity.java
+++ b/src/lessons/welcome/variables/VariablesEntity.java
@@ -1,14 +1,16 @@
 package lessons.welcome.variables;
 
-public class VariablesEntity extends jlm.universe.bugglequest.SimpleBuggle {
+import plm.core.model.Game;
+
+public class VariablesEntity extends plm.universe.bugglequest.SimpleBuggle {
 	@Override
 	public void forward(int i)  { 
-		throw new RuntimeException("forward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument in this exercise."));
 	}
 
 	@Override
 	public void backward(int i) {
-		throw new RuntimeException("backward(int) forbidden in this exercise");
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument in this exercise."));
 	}
 
 
diff --git a/src/lessons/welcome/variables/VariablesEntity.scala b/src/lessons/welcome/variables/VariablesEntity.scala
new file mode 100644
index 0000000..3f4dd9f
--- /dev/null
+++ b/src/lessons/welcome/variables/VariablesEntity.scala
@@ -0,0 +1,30 @@
+package lessons.welcome.variables;
+
+import plm.core.model.Game
+
+class ScalaVariablesEntity extends plm.universe.bugglequest.SimpleBuggle {
+	override def forward(i: Int)  { 
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use forward with an argument"));
+	}
+
+	override def backward(i: Int) {
+		throw new RuntimeException(Game.i18n.tr("I'm sorry Dave, I'm affraid I can't let you use backward with an argument"));
+	}
+
+
+	override def run() {
+		/* BEGIN SOLUTION */
+		var stepper = 0;
+		while (!isOverBaggle()) {
+			stepper += 1
+			forward()
+		}
+		pickupBaggle();
+		while (stepper>0) {
+			backward()
+			stepper -= 1
+		}
+		dropBaggle();
+		/* END SOLUTION */
+	}
+}
diff --git a/src/plm/core/CompilerJava.java b/src/plm/core/CompilerJava.java
new file mode 100644
index 0000000..e637dbc
--- /dev/null
+++ b/src/plm/core/CompilerJava.java
@@ -0,0 +1,657 @@
+package plm.core;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import plm.core.model.Game;
+
+
+/**
+ * This class provides an adapted interface to the javax.tools compiler.
+ * 
+ * Its main method is compile(), of prototype: 
+ *  INPUT:  Map<String, String>  : a list of named sourcefiles
+ *  OUTPUT: Map<String, Class<Object>> : a list of named compiled class 
+ * 
+ * It is used in {@link plm.core.model.lesson.Exercise}, where the student code gets compiled.
+ * 
+ * See also "Create dynamic applications with javax.tools", David J. Biesack.
+ * http://www.ibm.com/developerworks/java/library/j-jcomp/index.html?ca=dgr-lnxw82jvaxtools&S_TACT=105AGX59&S_CMP=GR
+ */
+
+public class CompilerJava {
+	// Compiler requires source files with a ".java" extension:
+	static final String JAVA_EXTENSION = ".java";
+
+	private final ClassLoaderImpl classLoader;
+
+	// The compiler instance that this facade uses.
+	private JavaCompiler compiler;
+
+	// The compiler options (such as "-target" "1.6").
+	private final List<String> options;
+
+	// collect compiler diagnostics in this instance.
+	private DiagnosticCollector<JavaFileObject> diagnostics;
+
+	// The FileManager which will store source and class "files".
+	private final FileManagerImpl javaFileManager;
+
+	/**
+	 * Construct a new instance which delegates to the named class loader.
+	 * 
+	 * @param options
+	 *            The compiler options (such as "-target" "1.5"). See the usage
+	 *            for javac
+	 * @throws IllegalStateException
+	 *             if the Java compiler cannot be loaded.
+	 */
+	public CompilerJava(Iterable<String> options) {
+		final ClassLoader loader = getClass().getClassLoader();
+		
+		compiler = ToolProvider.getSystemJavaCompiler();
+		if (compiler == null) {
+			try {
+				compiler = (JavaCompiler) Class.forName("com.sun.tools.javac.api.JavacTool").newInstance();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		if (compiler == null) {
+			throw new IllegalStateException("Cannot find the system Java compiler. "
+					+ "Please use a java SDK instead of a java runtime or check the class path.");
+		}
+
+		classLoader = (ClassLoaderImpl) AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+			public ClassLoader run() {
+				return new ClassLoaderImpl(loader);
+			}
+		});
+
+		diagnostics = new DiagnosticCollector<JavaFileObject>();
+		final JavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
+		javaFileManager = new FileManagerImpl(fileManager, classLoader);
+
+		this.options = new ArrayList<String>();
+		if (options != null) {
+			for (String option : options) {
+				this.options.add(option);
+			}
+		}
+
+		// piece of code dedicated to webstart (jnlp) support
+		// (might be improved one day...)
+		List<URL> classpath = new ArrayList<URL>();
+
+		if (loader instanceof URLClassLoader) {
+			for (URL url : ((URLClassLoader) loader).getURLs()) {
+				if (url.toString().startsWith("http:")) {
+					try {
+						String jarFilename = url.getFile();
+						jarFilename = jarFilename.substring(jarFilename.lastIndexOf('/'));
+						File tempFile = new File(System.getProperty("java.io.tmpdir"), jarFilename);
+						// if the compiler was a singleton, we could have used
+						// File.createTempFile("cached-",".jar");
+						if (!tempFile.exists()) {
+							// we have to re-download .jar since
+							// JarURLConnection is not properly working
+							download(url, tempFile);
+							tempFile.deleteOnExit();
+						}
+						URL jarLocation = new URL("file:" + tempFile.getAbsolutePath());
+						classpath.add(jarLocation);
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+				} else {
+					classpath.add(url);
+				}
+			}
+		}
+		String classPath = System.getProperty("java.class.path");
+		for (String path : classPath.split(File.pathSeparator)) {
+			try {
+				classpath.add(new URL("file:" + path));
+			} catch (MalformedURLException e) {
+				e.printStackTrace();
+			}
+		}
+
+		StringBuffer sb = new StringBuffer();
+		for (URL jar : classpath) {
+			sb.append(jar.getPath());
+			sb.append(File.pathSeparatorChar);
+		}
+		this.options.add("-cp");
+		this.options.add(sb.toString());
+	}
+
+	private static void download(URL url, File localFileName) {
+		OutputStream out = null;
+		InputStream in = null;
+		try {
+			out = new BufferedOutputStream(new FileOutputStream(localFileName));
+			URLConnection conn = url.openConnection();
+			in = conn.getInputStream();
+			byte[] buffer = new byte[1024 * 512];
+			int numRead;
+			while ((numRead = in.read(buffer)) != -1) {
+				out.write(buffer, 0, numRead);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (in != null)
+					in.close();
+				if (out != null)
+					out.close();
+			} catch (IOException ioe) {
+				// ioe.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * Compile Java source in <var>javaSource</var> and return the resulting
+	 * class.
+	 * <p>
+	 * Thread safety: this method is thread safe if the <var>javaSource</var>
+	 * and <var>diagnosticsList</var> are isolated to this thread.
+	 * 
+	 * @param qualifiedClassName
+	 *            The fully qualified class name.
+	 * @param javaSource
+	 *            Complete java source, including a package statement and a
+	 *            class, interface, or annotation declaration.
+	 * @param diagnosticsList
+	 *            Any diagnostics generated by compiling the source are added to
+	 *            this collector.
+	 * @param types
+	 *            zero or more Class objects representing classes or interfaces
+	 *            that the resulting class must be assignable (castable) to.
+	 * @return a Class which is generated by compiling the source
+	 * @throws CharSequenceCompilerException
+	 *             if the source cannot be compiled - for example, if it
+	 *             contains syntax or semantic errors or if dependent classes
+	 *             cannot be found.
+	 * @throws ClassCastException
+	 *             if the generated class is not assignable to all the optional
+	 *             <var>types</var>.
+	 */
+	public synchronized Class<Object> compile(final String qualifiedClassName, final String javaSource,
+			final DiagnosticCollector<JavaFileObject> diagnosticsList, final Class<?>... types)
+			throws PLMCompilerException, ClassCastException {
+		if (diagnosticsList != null)
+			diagnostics = diagnosticsList;
+		else
+			diagnostics = new DiagnosticCollector<JavaFileObject>();
+		Map<String, String> classes = new HashMap<String, String>(1);
+		classes.put(qualifiedClassName, javaSource);
+		Map<String, Class<Object>> compiled = compile(classes, diagnosticsList);
+		Class<Object> newClass = compiled.get(qualifiedClassName);
+		return castable(newClass, types);
+	}
+
+	/**
+	 * Compile multiple Java source strings and return a Map containing the
+	 * resulting classes.
+	 * <p>
+	 * Thread safety: this method is thread safe if the <var>classes</var> and
+	 * <var>diagnosticsList</var> are isolated to this thread.
+	 * 
+	 * @param classes
+	 *            A Map whose keys are qualified class names and whose values
+	 *            are the Java source strings containing the definition of the
+	 *            class. A map value may be null, indicating that compiled class
+	 *            is expected, although no source exists for it (it may be a
+	 *            non-public class contained in one of the other strings.)
+	 * @param diagnosticsList
+	 *            Any diagnostics generated by compiling the source are added to
+	 *            this list.
+	 * @return A mapping of qualified class names to their corresponding
+	 *         classes. The map has the same keys as the input
+	 *         <var>classes</var>; the values are the corresponding Class
+	 *         objects.
+	 * @throws CharSequenceCompilerException
+	 *             if the source cannot be compiled
+	 */
+	public synchronized Map<String, Class<Object>> compile(final Map<String, String> classes,
+			final DiagnosticCollector<JavaFileObject> diagnosticsList) throws PLMCompilerException {
+
+		if (diagnosticsList != null)
+			diagnostics = diagnosticsList;
+		else
+			diagnostics = new DiagnosticCollector<JavaFileObject>();
+
+		List<JavaFileObject> sources = new ArrayList<JavaFileObject>();
+		for (Entry<String, String> entry : classes.entrySet()) {
+			String qualifiedClassName = entry.getKey();
+			String javaSource = entry.getValue();
+			if (javaSource != null) {
+				final int dotPos = qualifiedClassName.lastIndexOf('.');
+				final String className = dotPos == -1 ? qualifiedClassName : qualifiedClassName.substring(dotPos + 1);
+				final String packageName = dotPos == -1 ? "" : qualifiedClassName.substring(0, dotPos);
+				final JavaFileObjectImpl source = new JavaFileObjectImpl(className, javaSource);
+				sources.add(source);
+				// Store the source file in the FileManager via package/class
+				// name.
+				// For source files, we add a .java extension
+				javaFileManager.putFileForInput(StandardLocation.SOURCE_PATH, packageName, className + JAVA_EXTENSION,
+						source);
+			}
+		}
+		// Get a CompliationTask from the compiler and compile the sources
+		final CompilationTask task = compiler.getTask(null, javaFileManager, diagnostics, options, null, sources);
+		final Boolean result = task.call();
+		if (result == null || !result.booleanValue()) {
+			/*
+			 * FIXME: provide a way to debug
+			 * when templates are broken
+			 */
+			 //for (String n:classes.keySet()) 
+			 // System.out.println("File "+n+":\n"+classes.get(n));
+			 
+			throw new PLMCompilerException(Game.i18n.tr("Compilation failed."), classes.keySet(), diagnostics);
+		}
+		try {
+			// For each class name in the input map, get its compiled
+			// class and put it in the output map
+			Map<String, Class<Object>> compiled = new HashMap<String, Class<Object>>();
+			for (String qualifiedClassName : classes.keySet()) {
+				final Class<Object> newClass = loadClass(qualifiedClassName);
+				compiled.put(qualifiedClassName, newClass);
+			}
+			return compiled;
+		} catch (ClassNotFoundException e) {
+			throw new PLMCompilerException(classes.keySet(), e, diagnostics);
+		} catch (IllegalArgumentException e) {
+			throw new PLMCompilerException(classes.keySet(), e, diagnostics);
+		} catch (SecurityException e) {
+			throw new PLMCompilerException(classes.keySet(), e, diagnostics);
+		}
+	}
+
+	/**
+	 * Load a class that was generated by this instance or accessible from its
+	 * parent class loader. Use this method if you need access to additional
+	 * classes compiled by
+	 * {@link #compile(String, CharSequence, DiagnosticCollector, Class...)
+	 * compile()}, for example if the primary class contained nested classes or
+	 * additional non-public classes.
+	 * 
+	 * @param qualifiedClassName
+	 *            the name of the compiled class you wish to load
+	 * @return a Class instance named by <var>qualifiedClassName</var>
+	 * @throws ClassNotFoundException
+	 *             if no such class is found.
+	 */
+	@SuppressWarnings("unchecked")
+	public Class<Object> loadClass(final String qualifiedClassName) throws ClassNotFoundException {
+		return (Class<Object>) classLoader.loadClass(qualifiedClassName);
+	}
+
+	/**
+	 * Check that the <var>newClass</var> is a subtype of all the type
+	 * parameters and throw a ClassCastException if not.
+	 * 
+	 * @param types
+	 *            zero of more classes or interfaces that the
+	 *            <var>newClass</var> must be castable to.
+	 * @return <var>newClass</var> if it is castable to all the types
+	 * @throws ClassCastException
+	 *             if <var>newClass</var> is not castable to all the types.
+	 */
+	private Class<Object> castable(Class<Object> newClass, Class<?>... types) throws ClassCastException {
+		for (Class<?> type : types)
+			if (!type.isAssignableFrom(newClass)) {
+				throw new ClassCastException(type.getName());
+			}
+		return newClass;
+	}
+
+	/**
+	 * Converts a String to a URI.
+	 * 
+	 * @param name
+	 *            a file name
+	 * @return a URI
+	 */
+	static URI toURI(String name) {
+		try {
+			return new URI(name);
+		} catch (URISyntaxException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
+
+/**
+ * A JavaFileManager which manages Java source and classes. This FileManager
+ * delegates to the JavaFileManager and the ClassLoaderImpl provided in the
+ * constructor. The sources are all in memory CharSequence instances and the
+ * classes are all in memory byte arrays.
+ */
+final class FileManagerImpl extends ForwardingJavaFileManager<JavaFileManager> {
+	// the delegating class loader (passed to the constructor)
+	private final ClassLoaderImpl classLoader;
+
+	// Internal map of filename URIs to JavaFileObjects.
+	private final Map<URI, JavaFileObject> fileObjects = new HashMap<URI, JavaFileObject>();
+
+	/**
+	 * Construct a new FileManager which forwards to the <var>fileManager</var>
+	 * for source and to the <var>classLoader</var> for classes
+	 * 
+	 * @param fileManager
+	 *            another FileManager that this instance delegates to for
+	 *            additional source.
+	 * @param classLoader
+	 *            a ClassLoader which contains dependent classes that the
+	 *            compiled classes will require when compiling them.
+	 */
+	public FileManagerImpl(JavaFileManager fileManager, ClassLoaderImpl classLoader) {
+		super(fileManager);
+		this.classLoader = classLoader;
+	}
+
+	/**
+	 * @return the class loader which this file manager delegates to
+	 */
+	public ClassLoader getClassLoader() {
+		return classLoader;
+	}
+
+	/**
+	 * For a given file <var>location</var>, return a FileObject from which the
+	 * compiler can obtain source or byte code.
+	 * 
+	 * @param location
+	 *            an abstract file location
+	 * @param packageName
+	 *            the package name for the file
+	 * @param relativeName
+	 *            the file's relative name
+	 * @return a FileObject from this or the delegated FileManager
+	 * @see javax.tools.ForwardingJavaFileManager#getFileForInput(javax.tools.JavaFileManager.Location,
+	 *      java.lang.String, java.lang.String)
+	 */
+	@Override
+	public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
+		FileObject o = fileObjects.get(uri(location, packageName, relativeName));
+		if (o != null)
+			return o;
+		return super.getFileForInput(location, packageName, relativeName);
+	}
+
+	/**
+	 * Store a file that may be retrieved later with
+	 * {@link #getFileForInput(javax.tools.JavaFileManager.Location, String, String)}
+	 * 
+	 * @param location
+	 *            the file location
+	 * @param packageName
+	 *            the Java class' package name
+	 * @param relativeName
+	 *            the relative name
+	 * @param file
+	 *            the file object to store for later retrieval
+	 */
+	public void putFileForInput(StandardLocation location, String packageName, String relativeName, JavaFileObject file) {
+		fileObjects.put(uri(location, packageName, relativeName), file);
+	}
+
+	/**
+	 * Convert a location and class name to a URI
+	 */
+	private URI uri(Location location, String packageName, String relativeName) {
+		return CompilerJava.toURI(location.getName() + '/' + packageName + '/' + relativeName);
+	}
+
+	/**
+	 * Create a JavaFileImpl for an output class file and store it in the
+	 * classloader.
+	 * 
+	 * @see javax.tools.ForwardingJavaFileManager#getJavaFileForOutput(javax.tools.JavaFileManager.Location,
+	 *      java.lang.String, javax.tools.JavaFileObject.Kind,
+	 *      javax.tools.FileObject)
+	 */
+	@Override
+	public JavaFileObject getJavaFileForOutput(Location location, String qualifiedName, Kind kind, FileObject outputFile)
+			throws IOException {
+		JavaFileObject file = new JavaFileObjectImpl(qualifiedName, kind);
+		classLoader.add(qualifiedName, file);
+		return file;
+	}
+
+	@Override
+	public ClassLoader getClassLoader(JavaFileManager.Location location) {
+		return classLoader;
+	}
+
+	@Override
+	public String inferBinaryName(Location loc, JavaFileObject file) {
+		String result;
+		// For our JavaFileImpl instances, return the file's name, else
+		// simply run the default implementation
+		if (file instanceof JavaFileObjectImpl)
+			result = file.getName();
+		else
+			result = super.inferBinaryName(loc, file);
+		return result;
+	}
+
+	@Override
+	public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse)
+			throws IOException {
+		Iterable<JavaFileObject> result = super.list(location, packageName, kinds, recurse);
+
+		ArrayList<JavaFileObject> files = new ArrayList<JavaFileObject>();
+		if (location == StandardLocation.CLASS_PATH && kinds.contains(JavaFileObject.Kind.CLASS)) {
+			for (JavaFileObject file : fileObjects.values()) {
+				if (file.getKind() == Kind.CLASS && file.getName().startsWith(packageName))
+					files.add(file);
+			}
+			files.addAll(classLoader.files());
+		} else if (location == StandardLocation.SOURCE_PATH && kinds.contains(JavaFileObject.Kind.SOURCE)) {
+			for (JavaFileObject file : fileObjects.values()) {
+				if (file.getKind() == Kind.SOURCE && file.getName().startsWith(packageName))
+					files.add(file);
+			}
+		}
+		for (JavaFileObject file : result) {
+			files.add(file);
+		}
+
+		return files;
+	}
+}
+
+/**
+ * A JavaFileObject which contains either the source text or the compiler
+ * generated class. This class is used in two cases.
+ * <ol>
+ * <li>This instance uses it to store the source which is passed to the
+ * compiler. This uses the
+ * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, CharSequence)}
+ * constructor.
+ * <li>The Java compiler also creates instances (indirectly through the
+ * FileManagerImplFileManager) when it wants to create a JavaFileObject for the
+ * .class output. This uses the
+ * {@link JavaFileObjectImpl#JavaFileObjectImpl(String, JavaFileObject.Kind)}
+ * constructor.
+ * </ol>
+ * This class does not attempt to reuse instances (there does not seem to be a
+ * need, as it would require adding a Map for the purpose, and this would also
+ * prevent garbage collection of class byte code.)
+ */
+final class JavaFileObjectImpl extends SimpleJavaFileObject {
+	// If kind == CLASS, this stores byte code from openOutputStream
+	private ByteArrayOutputStream byteCode;
+
+	// if kind == SOURCE, this contains the source text
+	private final CharSequence source;
+
+	/**
+	 * Construct a new instance which stores source
+	 * 
+	 * @param baseName
+	 *            the base name
+	 * @param source
+	 *            the source code
+	 */
+	JavaFileObjectImpl(final String baseName, final String source) {
+		super(CompilerJava.toURI(baseName + CompilerJava.JAVA_EXTENSION), Kind.SOURCE);
+		this.source = source;
+	}
+
+	/**
+	 * Construct a new instance
+	 * 
+	 * @param name
+	 *            the file name
+	 * @param kind
+	 *            the kind of file
+	 */
+	JavaFileObjectImpl(final String name, final Kind kind) {
+		super(CompilerJava.toURI(name), kind);
+		source = null;
+	}
+
+	/**
+	 * Return the source code content
+	 * 
+	 * @see javax.tools.SimpleJavaFileObject#getCharContent(boolean)
+	 */
+	@Override
+	public CharSequence getCharContent(final boolean ignoreEncodingErrors) throws UnsupportedOperationException {
+		if (source == null)
+			throw new UnsupportedOperationException("getCharContent()");
+		return source;
+	}
+
+	/**
+	 * Return an input stream for reading the byte code
+	 * 
+	 * @see javax.tools.SimpleJavaFileObject#openInputStream()
+	 */
+	@Override
+	public InputStream openInputStream() {
+		return new ByteArrayInputStream(getByteCode());
+	}
+
+	/**
+	 * Return an output stream for writing the bytecode
+	 * 
+	 * @see javax.tools.SimpleJavaFileObject#openOutputStream()
+	 */
+	@Override
+	public OutputStream openOutputStream() {
+		byteCode = new ByteArrayOutputStream();
+		return byteCode;
+	}
+
+	/**
+	 * @return the byte code generated by the compiler
+	 */
+	byte[] getByteCode() {
+		return byteCode.toByteArray();
+	}
+}
+
+/**
+ * A custom ClassLoader which maps class names to JavaFileObjectImpl instances.
+ */
+final class ClassLoaderImpl extends ClassLoader {
+	private final Map<String, JavaFileObject> classes = new HashMap<String, JavaFileObject>();
+
+	ClassLoaderImpl(final ClassLoader parentClassLoader) {
+		super(parentClassLoader);
+	}
+
+	/**
+	 * @return An collection of JavaFileObject instances for the classes in the
+	 *         class loader.
+	 */
+	Collection<JavaFileObject> files() {
+		return Collections.unmodifiableCollection(classes.values());
+	}
+
+	@Override
+	protected Class<?> findClass(final String qualifiedClassName) throws ClassNotFoundException {
+		JavaFileObject file = classes.get(qualifiedClassName);
+		if (file != null) {
+			byte[] bytes = ((JavaFileObjectImpl) file).getByteCode();
+			return defineClass(qualifiedClassName, bytes, 0, bytes.length);
+		}
+		// Workaround for "feature" in Java 6
+		// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6434149
+		try {
+			Class<?> c = Class.forName(qualifiedClassName);
+			return c;
+		} catch (ClassNotFoundException nf) {
+			// Ignore and fall through
+			nf.printStackTrace();
+		}
+		return super.findClass(qualifiedClassName);
+	}
+
+	/**
+	 * Add a class name/JavaFileObject mapping
+	 * 
+	 * @param qualifiedClassName
+	 *            the name
+	 * @param javaFile
+	 *            the file associated with the name
+	 */
+	void add(final String qualifiedClassName, final JavaFileObject javaFile) {
+		classes.put(qualifiedClassName, javaFile);
+	}
+
+	@Override
+	public InputStream getResourceAsStream(final String name) {
+		if (name.endsWith(".class")) {
+			String qualifiedClassName = name.substring(0, name.length() - ".class".length()).replace('/', '.');
+			JavaFileObjectImpl file = (JavaFileObjectImpl) classes.get(qualifiedClassName);
+			if (file != null) {
+				return new ByteArrayInputStream(file.getByteCode());
+			}
+		}
+		return super.getResourceAsStream(name);
+	}
+
+}
diff --git a/src/plm/core/CompilerScala.java b/src/plm/core/CompilerScala.java
new file mode 100644
index 0000000..79017f6
--- /dev/null
+++ b/src/plm/core/CompilerScala.java
@@ -0,0 +1,173 @@
+/** In memory compiler of scala code. This is highly inspired of https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala */
+
+package plm.core;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import plm.core.model.Game;
+import scala.Option;
+import scala.collection.JavaConverters;
+import scala.reflect.internal.util.BatchSourceFile;
+import scala.reflect.internal.util.Position;
+import scala.reflect.internal.util.SourceFile;
+import scala.reflect.io.VirtualDirectory;
+import scala.reflect.io.VirtualFile;
+import scala.tools.nsc.Global;
+import scala.tools.nsc.Global.Run;
+import scala.tools.nsc.Settings;
+import scala.tools.nsc.interpreter.AbstractFileClassLoader;
+import scala.tools.nsc.reporters.AbstractReporter;
+
+public class CompilerScala {
+	
+	static private CompilerScala instance;
+	public static CompilerScala getInstance() {
+		if (instance == null)
+			instance = new CompilerScala();
+		return instance;
+	}
+	
+	private PLMReporter reporter;
+	private Settings settings;
+	private Map<String, Class<?>> cache = new HashMap<String, Class<?>>();
+	private Global global;
+	private VirtualDirectory target;
+	private ClassLoader classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
+	
+	private CompilerScala() {
+		super();
+		settings = new Settings();
+		settings.nowarnings().tryToSetFromPropertyValue("true"); // warnings seem to be exceptions, and we don't want them to mess with us
+
+		Option<VirtualDirectory> noAncestor = scala.Option$.MODULE$.apply(null);
+		target = new VirtualDirectory("(memory)", noAncestor);
+		settings.outputDirs().setSingleOutput(target);
+		
+		settings.usejavacp().tryToSetFromPropertyValue("true");
+		//settings.usemanifestcp().tryToSetFromPropertyValue("true");
+		reporter = new PLMReporter(settings);
+		global = new Global(settings,reporter);
+	}
+
+	public void reset() {
+		reporter.reset();
+		reporter.setOffset(0);
+		target.clear();
+		cache = new HashMap<String, Class<?>>();
+		classLoader = new AbstractFileClassLoader(target, this.getClass().getClassLoader());
+	}
+
+	public void compile(String name,String content,int offset) throws PLMCompilerException {
+		
+		Run compiler = global.new Run();
+		List<SourceFile> sources = new LinkedList<SourceFile>();
+		
+		sources.add(new BatchSourceFile(new VirtualFile(name) , content.toCharArray()));
+		reporter.setOffset(offset);
+		
+		compiler.compileSources(JavaConverters.asScalaBufferConverter(sources).asScala().toList());
+		
+		if (Game.getInstance().isDebugEnabled() && reporter.hasErrors())
+			System.out.println("Here is the scala source code of "+name+" (offset:"+offset+"): "+content);
+		reporter.throwExceptionOnNeed();
+	}
+	public Class<?> findClass(String className) {
+		synchronized (this) {
+			if (!cache.containsKey(className)) {
+				Class<?> res;
+				try {
+					res = classLoader.loadClass(className);
+				} catch (ClassNotFoundException e) {
+					res = null;
+				}
+				cache.put(className, res);
+			}
+
+			return cache.get(className);			
+		}
+	}
+	
+	class PLMReporter extends AbstractReporter {
+		final static int INFO = 0;
+		final static int WARNING = 1;
+		final static int ERROR = 2;
+		int offset=0;
+		Vector<String> messages = new Vector<String>();
+		Settings settings;
+
+		public PLMReporter(Settings s) {
+			settings = s;
+		}
+		public void setOffset(int _offset) {
+			this.offset = _offset;
+		}
+		@Override
+		public Settings settings() {
+			return settings;
+		}
+		@Override
+		public void displayPrompt() { 
+			/* Don't do that, pal. */ 
+		}
+		@Override
+		public void display(Position pos, String message, Severity _severity) {
+			String severityName = _severity.toString(); 
+			String label = "";
+			int severity = -1;
+			if (severityName.equals("INFO") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 0"))
+				severity = INFO;
+			if (severityName.equals("WARNING") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 1")) {
+				severity = WARNING;
+				label= "warning: ";
+			}
+			if (severityName.equals("ERROR") || severityName.equals("scala.tools.nsc.reporters.Reporter$Severity at 2")) {
+				severity = ERROR;
+				label = "error: ";
+			}
+			if (severity == -1)
+				throw new RuntimeException("Got an unknown severity: "+severityName+". Please adapt the PLM to this new version of scala (or whatever).");
+			if (severity == INFO && !Game.getInstance().isDebugEnabled()) 
+				return;
+
+			int lineNum = -1;
+			try {
+				lineNum = pos.line() - offset;
+			} catch (Throwable t) {
+				// That's fine if the line number is not defined.
+			}
+
+			String name = pos.source().path();
+			int lastDot = name.lastIndexOf('.');
+			if (lastDot != -1)
+				name = name.substring(lastDot+1);
+			String msg = name+(lineNum == -1? "": ":"+lineNum) +": "+label+message;
+
+			// Append the line content and a position marker, if possible
+			if (pos != null && pos.isDefined()) {
+				msg += "\n"+pos.inUltimateSource(pos.source()).lineContent()+"\n";
+				for (int i=0;i<pos.column()-1;i++)
+					msg += " ";
+				msg += "^";
+			}
+
+			messages.add(msg);
+		}
+		public void throwExceptionOnNeed() throws PLMCompilerException {
+			if (hasErrors()) {
+				StringBuffer sb = new StringBuffer();
+				for (String s : messages)
+					sb.append(s);
+				throw new PLMCompilerException(sb.toString(), null, null);
+			}
+		}
+		@Override
+		public void reset() {
+			super.reset();
+			messages.removeAllElements();
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/plm/core/ExoTest.java b/src/plm/core/ExoTest.java
new file mode 100644
index 0000000..63de7d3
--- /dev/null
+++ b/src/plm/core/ExoTest.java
@@ -0,0 +1,168 @@
+package plm.core;
+
+import static org.junit.Assert.fail;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+import plm.core.model.lesson.Exercise.StudentOrCorrection;
+import plm.core.model.lesson.Exercise.WorldKind;
+import plm.core.utils.FileUtils;
+import plm.universe.Entity;
+import plm.universe.World;
+import plm.universe.bat.BatExercise;
+import plm.universe.bat.BatTest;
+import plm.universe.bat.BatWorld;
+
+ at RunWith(Parameterized.class)
+public class ExoTest {
+	static private String[] lessons = new String[] { 
+		"lessons.welcome", "lessons.turmites", "lessons.maze", "lessons.turtleart",
+		"lessons.sort", "lessons.sort.baseball", "lessons.sort.pancake",  
+		"lessons.recursion", "lessons.recursion.hanoi",
+		// "lessons.lightbot", // Well, testing this requires testing the swing directly I guess
+		"lessons.bat.string1",
+		};
+
+	@BeforeClass
+	static public void setUpClass() {
+	}
+	
+	/* Generate the list of parameters we want to run our test on */
+	@Parameters
+	static public Collection<Object[]> data() {
+		LinkedList<Object[]> result = new LinkedList<Object[]>();
+		
+		FileUtils.setLocale(new Locale("en"));
+		Game g = Game.getInstance();
+
+		/* Compute the answers with the java entities */
+		Game.getInstance().setProgramingLanguage(Game.JAVA);
+		Set<Lecture> allExercises = new HashSet<Lecture>();  
+		for (String lessonName : lessons) { 
+			g.switchLesson(lessonName,true);
+			System.out.println("Lesson "+lessonName+" loaded ("+g.getCurrentLesson().getExerciseCount()+" exercises)");
+			if (g.getCurrentLesson().getExerciseCount() == 0) {
+				System.err.println("Cannot find any exercise in "+lessonName+". Something's wrong here");
+				System.exit(1);
+			}
+			for (Lecture l : g.getCurrentLesson().exercises()) 
+				if (l instanceof Exercise) {
+					result.add(new Object[] {Game.getInstance().getCurrentLesson(), l});
+					if (allExercises.contains(l)) {
+						System.err.println("Warning, I tried to add the exercise "+l.getName()+" twice. Something's wrong here");
+						System.exit(1);
+					}
+					allExercises.add(l);
+				}
+		}
+		System.out.println("There is currently "+result.size()+" exercises in our database. Yes sir.");
+		g.switchDebug();
+		g.removeSessionKit();
+		
+		g.setLocale(new Locale("en"));
+		return result;
+	}
+
+	
+	private Exercise exo;
+	public ExoTest(Lesson l, Exercise e) {
+		this.exo = e;
+
+		Game.getInstance().setCurrentLesson(l);
+		Game.getInstance().setCurrentExercise(exo);
+		for (int worldRank=0; worldRank<exo.getWorldCount(); worldRank++) 
+			exo.getWorlds(WorldKind.INITIAL).get(worldRank).setDelay(0);
+	}
+	
+	/** Resets current world, populate it with the correction entity, and rerun it */
+	private void testCorrectionEntity() {
+		ProgrammingLanguage lang = Game.getProgrammingLanguage();
+		Game.getInstance().setCurrentExercise(exo);
+		Game.getInstance().setProgramingLanguage(lang); // This stupid Game.setCurrentExercise tries to be cleaver if the current progLang is not avail in the requested exercise
+		
+		System.out.flush();
+		System.err.println("XXXXXXX "+exo.getName()+" in "+lang.getLang()+" XXXXXXX");
+		exo.lastResult = new ExecutionProgress();
+		
+		try {
+			exo.compileAll(null,StudentOrCorrection.CORRECTION);
+			if (exo.lastResult.compilationError != null)
+				fail(exo.getId()+": compilation error: "+exo.lastResult.compilationError);
+
+			exo.reset();
+			// For compiled languages, we mutate to the compiled entity. 
+			// For script languages, we mutate to the correction entity.
+			StudentOrCorrection what = StudentOrCorrection.CORRECTION;
+			if (lang == Game.JAVA || lang == Game.SCALA)
+				what = StudentOrCorrection.STUDENT;
+			exo.mutateEntities(WorldKind.CURRENT, what);
+			
+			if (exo instanceof BatExercise)
+				for (BatTest t : ((BatWorld)exo.getWorld(0)).tests) 
+					t.objectiveTest = false; // we want to set the result for real, not the expected
+			
+			for (World w : exo.getWorlds(WorldKind.CURRENT)) 
+				for (Entity ent: w.getEntities())  
+					ent.runIt(exo.lastResult);
+			
+			exo.check();
+		} catch (PLMCompilerException e) {
+			// compileAll already setup the error message; we just needed to not run the entity in that case
+		}
+		
+		if (exo.lastResult.compilationError != null) 
+				fail(exo.getId()+": compilation error: "+exo.lastResult.compilationError+". Compiled file:\n"+
+						((exo.getSourceFileCount(lang)>0) ? (exo.getSourceFile(lang, 0).getCompilableContent(StudentOrCorrection.CORRECTION))
+							                              : "none"));
+		
+		
+		if (exo.lastResult.totalTests == 0 
+				|| exo.lastResult.totalTests != exo.lastResult.passedTests 
+				|| !exo.lastResult.details.equals("")) {
+			System.out.println(""+exo.getId()+" failed in "+Game.getProgrammingLanguage()+": "+exo.lastResult.details);
+			fail(exo.getId()+": failed exercise ("+
+				exo.lastResult.passedTests+"/"+exo.lastResult.totalTests+" passed): '"+exo.lastResult.details+"'");
+		}
+		System.out.println(""+exo.getId()+" passed in "+Game.getProgrammingLanguage());
+
+	}
+	
+	@Test(timeout=10000)
+	public void testJavaEntity() {
+		Game.getInstance().setProgramingLanguage(Game.JAVA);
+		testCorrectionEntity();
+	}
+	@Test(timeout=30000) // The compiler sometimes takes time to kick in 
+	public void testScalaEntity() {
+		if (!exo.getProgLanguages().contains(Game.SCALA)) 
+			fail("Exercise "+exo.getId()+" does not support scala");
+		
+		Game.getInstance().setProgramingLanguage(Game.SCALA);
+		testCorrectionEntity();
+	}
+	
+	@Test(timeout=30000) // the well known python's "performance"...
+	public void testPythonEntity() {
+		if (!exo.getProgLanguages().contains(Game.PYTHON)) 
+			fail("Exercise "+exo.getId()+" does not support python");
+	
+		Game.getInstance().setProgramingLanguage(Game.PYTHON);
+		testCorrectionEntity();
+	}
+}
diff --git a/src/plm/core/GameListener.java b/src/plm/core/GameListener.java
new file mode 100644
index 0000000..8812047
--- /dev/null
+++ b/src/plm/core/GameListener.java
@@ -0,0 +1,22 @@
+package plm.core;
+
+import plm.core.model.lesson.Lecture;
+import plm.universe.World;
+
+public interface GameListener {
+
+	// when a lesson becomes current lesson of the game
+	public void currentLessonHasChanged() ;
+	
+	// when an exercise becomes current exercise of the game
+	public void currentExerciseHasChanged(Lecture lect) ;
+	
+	// when a world is selected as the current world
+	public void selectedWorldHasChanged(World newWorld); 
+	
+	// when an entity is selected as the current entity in a world
+	public void selectedEntityHasChanged();
+
+	// when entities are replaced in the current 
+	public void selectedWorldWasUpdated();
+}
\ No newline at end of file
diff --git a/src/plm/core/GameStateListener.java b/src/plm/core/GameStateListener.java
new file mode 100644
index 0000000..ece74f2
--- /dev/null
+++ b/src/plm/core/GameStateListener.java
@@ -0,0 +1,9 @@
+package plm.core;
+
+import plm.core.model.Game;
+
+public interface GameStateListener {
+
+	public void stateChanged(Game.GameState type) ;
+	
+}
diff --git a/src/plm/core/HumanLangChangesListener.java b/src/plm/core/HumanLangChangesListener.java
new file mode 100644
index 0000000..b6e219f
--- /dev/null
+++ b/src/plm/core/HumanLangChangesListener.java
@@ -0,0 +1,9 @@
+package plm.core;
+
+import java.util.Locale;
+
+public interface HumanLangChangesListener {
+    // when the used human language (English, French, etc) has changed
+	public void currentHumanLanguageHasChanged(Locale newLang);
+
+}
diff --git a/src/plm/core/PLMCompilerException.java b/src/plm/core/PLMCompilerException.java
new file mode 100644
index 0000000..547c3d2
--- /dev/null
+++ b/src/plm/core/PLMCompilerException.java
@@ -0,0 +1,76 @@
+package plm.core;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/**
+ * An exception thrown when trying to compile Java programs from strings
+ * containing source.
+ * 
+ * @author <a href="mailto:David.Biesack at sas.com">David J. Biesack</a>
+ */
+public class PLMCompilerException extends Exception {
+	   private static final long serialVersionUID = 1L;
+	   /**
+	    * The fully qualified name of the class that was being compiled.
+	    */
+	   private Set<String> classNames;
+	   // Unfortunately, Diagnostic and Collector are not Serializable, so we can't
+	   // serialize the collector.
+	   transient private DiagnosticCollector<JavaFileObject> diagnostics;
+
+	   public PLMCompilerException(String message,
+	         Set<String> qualifiedClassNames, Throwable cause,
+	         DiagnosticCollector<JavaFileObject> diagnostics) {
+	      super(message, cause);
+	      setClassNames(qualifiedClassNames);
+	      setDiagnostics(diagnostics);
+	   }
+
+	   public PLMCompilerException(String message,
+	         Set<String> qualifiedClassNames,
+	         DiagnosticCollector<JavaFileObject> diagnostics) {
+	      super(message);
+	      setClassNames(qualifiedClassNames);
+	      setDiagnostics(diagnostics);
+	   }
+
+	   public PLMCompilerException(Set<String> qualifiedClassNames,
+	         Throwable cause, DiagnosticCollector<JavaFileObject> diagnostics) {
+	      super(cause);
+	      setClassNames(qualifiedClassNames);
+	      setDiagnostics(diagnostics);
+	   }
+
+	   private void setClassNames(Set<String> qualifiedClassNames) {
+	      // Creates a new HashSet because the set passed in may not be Serializable.
+	      // For example, Map.keySet() returns a non-Serializable set.
+		   if (qualifiedClassNames != null)
+			   classNames = new HashSet<String>(qualifiedClassNames);
+	   }
+
+	   private void setDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
+	      this.diagnostics = diagnostics;
+	   }
+
+	   /**
+	    * Gets the diagnostics collected by this exception.
+	    * 
+	    * @return this exception's diagnostics
+	    */
+	   public DiagnosticCollector<JavaFileObject> getDiagnostics() {
+	      return diagnostics;
+	   }
+	   
+	   /**
+	    * @return The name of the classes whose compilation caused the compile
+	    *         exception
+	    */
+	   public Collection<String> getClassNames() {
+	      return Collections.unmodifiableSet(classNames);
+	   }
+}
diff --git a/src/plm/core/PLMException.java b/src/plm/core/PLMException.java
new file mode 100644
index 0000000..76432d2
--- /dev/null
+++ b/src/plm/core/PLMException.java
@@ -0,0 +1,11 @@
+package plm.core;
+
+public class PLMException extends RuntimeException {
+
+	private static final long serialVersionUID = 5763400564033977767L;
+
+	public PLMException(String msg) {
+		super(msg);
+	}
+	
+}
diff --git a/src/plm/core/ProgLangChangesListener.java b/src/plm/core/ProgLangChangesListener.java
new file mode 100644
index 0000000..ca70002
--- /dev/null
+++ b/src/plm/core/ProgLangChangesListener.java
@@ -0,0 +1,9 @@
+package plm.core;
+
+import plm.core.model.ProgrammingLanguage;
+
+public interface ProgLangChangesListener {
+    // when the used programming language has changed
+	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang);
+
+}
diff --git a/src/plm/core/PythonExceptionDecipher.java b/src/plm/core/PythonExceptionDecipher.java
new file mode 100644
index 0000000..3d0879c
--- /dev/null
+++ b/src/plm/core/PythonExceptionDecipher.java
@@ -0,0 +1,84 @@
+package plm.core;
+
+import javax.script.ScriptException;
+
+import org.python.core.PyException;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.universe.Entity;
+
+public class PythonExceptionDecipher {
+
+	public static boolean isPythonException(ScriptException e) {
+		return (e.getCause() instanceof PyException);
+	}
+	
+	public static void handlePythonException (ScriptException e,Entity ent,ExecutionProgress progress) {
+		if (e.getCause() instanceof org.python.core.PyException) { // This seem to be all exceptions raised by python
+			org.python.core.PyException cause = (org.python.core.PyException) e.getCause();
+
+			StringBuffer msg = new StringBuffer();
+
+			if (cause.type.toString().equals("<type 'exceptions.SyntaxError'>")) {
+				msg.append(Game.i18n.tr("Syntax error at line {0}: {1}\n" +
+						"In doubt, check your indentation, and that you don't mix tabs and spaces\n",
+						((cause.value.__findattr__("lineno").asInt())-ent.getScriptOffset(Game.PYTHON)),
+						cause.value.__findattr__("msg")));
+
+			} else { /* It makes sense to display a backtrace for any errors but syntax ones */
+
+				if (cause.type.toString().equals("<type 'exceptions.NameError'>")) {
+					msg.append(Game.i18n.tr("NameError raised: You seem to use a non-existent identifier; Please check for typos\n"));
+					msg.append(cause.value+"\n");
+				} else if (cause.type.toString().equals("<type 'exceptions.TypeError'>")) {
+					msg.append(Game.i18n.tr("TypeError raised: you are probably misusing a function or something.\n"));
+					msg.append(cause.value+"\n");
+				} else if (cause.type.toString().equals("<type 'exceptions.UnboundLocalError'>")) {
+					msg.append(Game.i18n.tr("UnboundLocalError raised: you are probably using a global variable that is not declared as such.\n"));
+					msg.append(cause.value+"\n");
+
+
+					/* FIXME: how could we factorize the world's error? */ 
+				} else if (cause.type.toString().equals("<type 'plm.universe.bugglequest.exception.NoBaggleUnderBuggleException'>")) {
+					msg.append(Game.i18n.tr("Error: there is no baggle to pickup under the buggle"));
+				} else if (cause.type.toString().equals("<type 'plm.universe.bugglequest.exception.AlreadyHaveBaggleException'>")) {
+					msg.append(Game.i18n.tr("Error: a buggle cannot carry more than one baggle at the same time"));
+				} else if (cause.type.toString().equals("<type 'plm.universe.bugglequest.exception.BuggleInOuterSpaceException'>")) {
+					msg.append(Game.i18n.tr("Error: your buggle just teleported to the outer space..."));
+				} else if (cause.type.toString().equals("<type 'plm.universe.bugglequest.exception.BuggleWallException'>")) {
+					msg.append(Game.i18n.tr("Error: your buggle just hit a wall. That hurts."));
+
+				} else {
+					msg.append(Game.i18n.tr("Unknown error (please report): {0}\nIts value is: {1}",
+							cause.type.toString(),cause.value+"\n"));
+
+				}
+
+
+				/* The following is very inspired from <jython>/src/org/python/core/PyTraceback.java, 
+				 * even if we cannot reuse directly this implementation since we want to change all linenos on the fly. 
+				 */
+				org.python.core.PyTraceback tb = cause.traceback;
+				while (tb != null) {
+					tb.tb_lineno-= ent.getScriptOffset(Game.PYTHON);
+					if (tb.tb_frame == null || tb.tb_frame.f_code == null) {
+						msg.append(String.format("  (no code object) at line %s\n", tb.tb_lineno));
+					} else {
+						msg.append(String.format("  File \"%.500s\", line %d, in %.500s\n",
+								tb.tb_frame.f_code.co_filename, tb.tb_lineno, tb.tb_frame.f_code.co_name));
+					}
+					tb = (org.python.core.PyTraceback) tb.tb_next;
+				}
+			}				
+
+			if (Game.getInstance().isDebugEnabled()) {
+				System.err.println("CAUSE: "+cause.value.toString());
+				System.err.println("MSG: "+e.getMessage());
+				System.err.println("BT: "+msg);
+			}
+
+			progress.setCompilationError(msg.toString());
+		}
+	}
+}
diff --git a/src/plm/core/StatusStateListener.java b/src/plm/core/StatusStateListener.java
new file mode 100644
index 0000000..e144951
--- /dev/null
+++ b/src/plm/core/StatusStateListener.java
@@ -0,0 +1,8 @@
+package plm.core;
+
+
+public interface StatusStateListener {
+
+	public void stateChanged(String txt) ;
+	
+}
diff --git a/src/plm/core/model/Course.java b/src/plm/core/model/Course.java
new file mode 100644
index 0000000..092450f
--- /dev/null
+++ b/src/plm/core/model/Course.java
@@ -0,0 +1,281 @@
+package plm.core.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+
+/**
+ * Class to manage course data online
+ * It has an id and allows to save/retrieve users results by course
+ * It contains lists of students names sorted by criteria :
+ * * students needing help (pressed the help button)
+ * * good students (>=90% of good answers)
+ * * bad students (<=5% of good answers
+ * * layabout students (didn't try any exercises)
+ */
+public abstract class Course {
+
+    protected String courseId;
+    protected String password;
+    protected String teacherPassword;
+    protected Map<String, ServerUserData> serverData;
+    protected ArrayList<String> needingHelpStudents;
+    protected ArrayList<String> goodStudents;
+    protected ArrayList<String> badStudents;
+    protected ArrayList<String> layaboutStudents;
+
+    public Course() {
+        this(null);
+    }
+
+    public Course(String id) {
+        courseId = id;
+        password = "";
+        teacherPassword = "";
+    }
+
+    public Course(String id, String password) {
+        courseId = id;
+        this.password = password;
+        teacherPassword = "";
+    }
+
+    /**
+     * Create a new course on the server
+     * For example "top_quinson"
+     * A user password is set to push data, a teacher password to administrate course
+     */
+    public ServerAnswer create() {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("action", "new");
+        jsonObject.put("course", courseId);
+        jsonObject.put("password", password);
+        jsonObject.put("teacher_password", teacherPassword);
+
+        String response;
+
+        try {
+            response = sendTeacherRequest(jsonObject.toString());
+        } catch (IOException e) {
+            return null;
+        }
+
+        return ServerAnswer.values()[Integer.parseInt(response)];
+    }
+
+    /**
+     * Download updated data from server It loads a list of results by student
+     * and by exercise
+     */
+    public String refresh() {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("action", "refresh");
+        jsonObject.put("course", courseId);
+        jsonObject.put("teacher_password", teacherPassword);
+
+        String answer = null;
+        try {
+            answer = sendTeacherRequest(jsonObject.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+        // test if the answer was a status code or course data
+        try {
+            Integer.parseInt(answer);
+        } catch (NumberFormatException nfe) {
+            serverData = ServerUserData.parse(answer);
+        }
+        return answer;
+    }
+
+    /**
+     * Delete the course on the server All student and exercises results will be
+     * removed
+     */
+    public String delete() {
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("action", "remove");
+        jsonObject.put("course", courseId);
+        jsonObject.put("teacher_password", teacherPassword);
+
+        try {
+            return sendTeacherRequest(jsonObject.toString());
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Get all courses identifiers from the server It allows to display it in
+     * form, to select the current course
+     *
+     * @return list of all courses on the server
+     */
+    public ArrayList<String> getAllCoursesId() {
+        String response = "";
+        ArrayList<String> coursesId = new ArrayList<String>();
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("action", "allids");
+
+        try {
+            response = sendCourseRequest(jsonObject.toString());
+        } catch (IOException e) {
+            return null;
+        }
+
+        if (response != null && !response.isEmpty()) {
+            JSONArray arrayResult = (JSONArray) JSONValue.parse(response);
+            for (Object anArrayResult : arrayResult) {
+                coursesId.add((String) anArrayResult);
+            }
+        }
+
+        return coursesId;
+    }
+
+    /**
+     * Refresh all the students filter lists from the server
+     */
+    public void refreshStudentsLists(){
+        refreshStudentsNeedingHelp();
+        refreshLayaboutStudents();
+        refreshBadStudents();
+        refreshGoodStudents();
+    }
+
+    /**
+     * Generic method that constructs a request to get a list of students, depending on a filter
+     * @param filter filter to apply in the request
+     * @return the list of students
+     */
+    public ArrayList<String> refreshStudentsFromFilter(String filter) {
+        String answer = "";
+        ArrayList<String> students = new ArrayList<String>();
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("action", filter);
+        jsonObject.put("course", courseId);
+        jsonObject.put("teacher_password", teacherPassword);
+
+        try {
+            answer = sendTeacherRequest(jsonObject.toString());
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+        try {
+            if (!answer.isEmpty()) {
+                JSONArray arrayResult = (JSONArray) JSONValue.parse(answer);
+                for (Object result : arrayResult)
+                    students.add((String) result);
+            }
+        } catch (ClassCastException cce) {
+            // the answer is a status number, it can't be casted into a list...
+            return null;
+        }
+
+        return students;
+    }
+
+    public void refreshStudentsNeedingHelp() {
+        needingHelpStudents = refreshStudentsFromFilter("needinghelp");
+    }
+
+    public void refreshLayaboutStudents() {
+        layaboutStudents = refreshStudentsFromFilter("ugly");
+    }
+
+    public void refreshBadStudents() {
+        badStudents = refreshStudentsFromFilter("bad");
+    }
+
+    public void refreshGoodStudents() {
+        goodStudents = refreshStudentsFromFilter("good");
+    }
+
+    /**
+     * Method to implement to indicate how/where to send data
+     *
+     * @param request request in json to send to the server
+     */
+    public abstract String sendTeacherRequest(String request) throws IOException;
+
+    public abstract String sendCourseRequest(String request) throws IOException;
+
+    /*
+      * Getters and setters...
+      */
+
+    public String getCourseId() {
+        if (courseId == null)
+            return "";
+        return courseId;
+    }
+
+    public void setCourseId(String courseId) {
+        this.courseId = courseId;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getTeacherPassword() {
+        return teacherPassword;
+    }
+
+    public void setTeacherPassword(String teacherPassword) {
+        this.teacherPassword = teacherPassword;
+    }
+
+    public Map<String, ServerUserData> getServerData() {
+        return serverData;
+    }
+
+    public void setServerData(Map<String, ServerUserData> serverData) {
+        this.serverData = serverData;
+    }
+
+    public ArrayList<String> getNeedingHelpStudents() {
+        return needingHelpStudents;
+    }
+
+    public void setNeedingHelpStudents(ArrayList<String> needingHelpStudents) {
+        this.needingHelpStudents = needingHelpStudents;
+    }
+
+    public ArrayList<String> getGoodStudents() {
+        return goodStudents;
+    }
+
+    public void setGoodStudents(ArrayList<String> goodStudents) {
+        this.goodStudents = goodStudents;
+    }
+
+    public ArrayList<String> getBadStudents() {
+        return badStudents;
+    }
+
+    public void setBadStudents(ArrayList<String> badStudents) {
+        this.badStudents = badStudents;
+    }
+
+    public ArrayList<String> getLayaboutStudents() {
+        return layaboutStudents;
+    }
+
+    public void setLayaboutStudents(ArrayList<String> layaboutStudents) {
+        this.layaboutStudents = layaboutStudents;
+    }
+}
diff --git a/src/plm/core/model/CourseAppEngine.java b/src/plm/core/model/CourseAppEngine.java
new file mode 100644
index 0000000..26ef8ef
--- /dev/null
+++ b/src/plm/core/model/CourseAppEngine.java
@@ -0,0 +1,79 @@
+package plm.core.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * Implementation of Course which works with GAE
+ * It overrides Course methods to send requests constructed by it
+ */
+public class CourseAppEngine extends Course {
+
+    private static URL teacherServer;
+    private static URL courseServer;
+
+    public CourseAppEngine() {
+        this(null);
+    }
+
+    public CourseAppEngine(String id) {
+        super(id);
+        try {
+            teacherServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/teacher");
+            courseServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/course");
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public CourseAppEngine(String id, String password) {
+        super(id, password);
+        try {
+            teacherServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/teacher");
+            courseServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/course");
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public String sendTeacherRequest(String request) throws IOException{
+        return sendRequest(request, teacherServer);
+    }
+
+    @Override
+    public String sendCourseRequest(String request) throws IOException{
+       return sendRequest(request, courseServer);
+    }
+
+    public String sendRequest(String request, URL server) throws IOException{
+        String response = "";
+        try {
+
+            // Send data
+            URLConnection conn = server.openConnection();
+            conn.setDoOutput(true);
+            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
+            wr.write(request);
+            wr.flush();
+
+            // Get response data and print it
+            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = br.readLine()) != null)
+            	response += line;
+
+            wr.close();
+            br.close();
+        } catch (IOException e) {
+            System.out.println("Unable to contact PLMServer to send request " + request);
+            throw new IOException(e);
+        }
+        return response;
+    }
+}
diff --git a/src/plm/core/model/DemoRunner.java b/src/plm/core/model/DemoRunner.java
new file mode 100644
index 0000000..166347f
--- /dev/null
+++ b/src/plm/core/model/DemoRunner.java
@@ -0,0 +1,65 @@
+package plm.core.model;
+
+import java.util.Iterator;
+import java.util.List;
+
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+
+/** 
+ * This class runs the demo of the current exercise in a separated thread 
+ * when the Demo button is clicked. The run and demo buttons are disabled until the demo ends.
+ * 
+ * Activated by {@link Game#startExerciseDemoExecution()}.
+ */
+public class DemoRunner extends Thread {
+
+	private Game game;
+	private List<Thread> runners = null; // threads who run entities from lesson
+
+	public DemoRunner(Game game, List<Thread> list) {
+		super();
+		this.game = game;
+		this.runners = list;
+		this.runners.add(this);
+	}
+
+	@Override
+	public void run() {
+		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
+		if (! (lect instanceof Exercise))
+			return;
+		Exercise exo = (Exercise) lect;
+		
+		boolean stepModeWasActivated = this.game.stepModeEnabled();
+
+		try {
+			game.setState(Game.GameState.DEMO_STARTED);
+			
+			this.game.disableStepMode();
+			
+			exo.runDemo(runners);
+
+			Iterator<Thread> it = runners.iterator();
+			while (it.hasNext()) {
+				Thread t = it.next();
+				if (!t.equals(this)) { /* do not wait for myself */
+					t.join();
+					it.remove();
+				}
+			}
+		} catch (InterruptedException e) {
+			game.getOutputWriter().log(e);
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			if (stepModeWasActivated) {
+				this.game.enableStepMode();
+			}
+			game.setState(Game.GameState.DEMO_ENDED);			
+		}
+
+		runners.remove(this);
+	}
+
+}
diff --git a/src/plm/core/model/Game.java b/src/plm/core/model/Game.java
new file mode 100644
index 0000000..758e238
--- /dev/null
+++ b/src/plm/core/model/Game.java
@@ -0,0 +1,1080 @@
+package plm.core.model;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.InvalidPropertiesFormatException;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.swing.JOptionPane;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.GameListener;
+import plm.core.GameStateListener;
+import plm.core.HumanLangChangesListener;
+import plm.core.ProgLangChangesListener;
+import plm.core.StatusStateListener;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Exercise.WorldKind;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+import plm.core.model.session.ISessionKit;
+import plm.core.model.session.SessionDB;
+import plm.core.model.session.ZipSessionKit;
+import plm.core.model.tracking.HeartBeatSpy;
+import plm.core.model.tracking.LocalFileSpy;
+import plm.core.model.tracking.ProgressSpyListener;
+import plm.core.model.tracking.ServerSpyAppEngine;
+import plm.core.model.tracking.TwitterSpy;
+import plm.core.ui.MainFrame;
+import plm.core.ui.ResourcesCache;
+import plm.core.utils.FileUtils;
+import plm.universe.Entity;
+import plm.universe.IWorldView;
+import plm.universe.World;
+
+/*
+ *  core model which contains all known exercises.
+ */
+public class Game implements IWorldView {
+	/** Current state of the engine: whether we are running the student code, a demo, saving to files, or whatever. 
+	 *  Helps deciding which interface buttons are enabled/disabled for example.
+	 */
+	public enum GameState {
+		IDLE, 
+		SAVING, SAVING_DONE,
+		LOADING, LOADING_DONE,
+		COMPILATION_STARTED, COMPILATION_ENDED, 
+		EXECUTION_STARTED, EXECUTION_ENDED,
+		DEMO_STARTED, DEMO_ENDED,
+	}
+
+	private GameState state = GameState.IDLE;
+
+	private final static String LOCAL_PROPERTIES_FILENAME = "plm.properties";
+
+	private static Properties defaultGameProperties = new Properties();
+	private static Properties localGameProperties = new Properties();
+	private static File localGamePropertiesLoadedFile;
+
+	private static Game instance = null;
+	private Map<String, Lesson> lessons = new HashMap<String, Lesson>();
+	private Lesson currentLesson;
+	private Course currentCourse;
+
+	public static final String [][] humanLangs = { {"Francais","fr"}, {"English","en"}};
+	
+	public static final ProgrammingLanguage JAVA =       new ProgrammingLanguage("Java","java",ResourcesCache.getIcon("img/lang_java.png"));
+	public static final ProgrammingLanguage PYTHON =     new ProgrammingLanguage("Python","py",ResourcesCache.getIcon("img/lang_python.png"));
+	public static final ProgrammingLanguage SCALA =      new ProgrammingLanguage("Scala","scala",ResourcesCache.getIcon("img/lang_scala.png"));
+	//public static final ProgrammingLanguage JAVASCRIPT = new ProgrammingLanguage("JavaScript","js",ResourcesCache.getIcon("img/lang_javascript.png"));
+	public static final ProgrammingLanguage RUBY =       new ProgrammingLanguage("Ruby","rb",ResourcesCache.getIcon("img/lang_ruby.png"));
+	public static final ProgrammingLanguage LIGHTBOT =   new ProgrammingLanguage("lightbot","ignored",ResourcesCache.getIcon("img/lightbot_light.png"));
+	public static final ProgrammingLanguage[] programmingLanguages = new ProgrammingLanguage[] {
+		JAVA, PYTHON, SCALA, RUBY, LIGHTBOT // TODO: re-add JAVASCRIPT to this list once it works at least a bit
+	}; 
+	private ProgrammingLanguage programmingLanguage = JAVA;
+
+	/* TODO: document these values elsewhere */
+	public static final String PROP_OUTPUT_CAPTURE = "output.capture"; // Whether to redirect stdout and stderr to the graphical console. Defaults to true
+	public static final String PROP_ANSWER_CACHE = "answers.cache"; // Whether to use the cache of answers worlds on disk, defaults to true. 
+	                                                                // Turning to false will slow down the startup process, but avoid out of date files
+	
+	public static final String PROP_PROGRESS_TWITTER = "plm.progress.twitter";     //  
+	public static final String PROP_PROGRESS_APPENGINE = "plm.progress.appengine"; // Whether the progresses should be posted to the appengine (default: false)
+	public static final String PROP_APPENGINE_URL = "plm.appengine.url"; // Where to find the appengine. This is related to the teacher console, that should be rewritten at some point.
+	
+	public static final String PROP_PROGRAMING_LANGUAGE = "plm.programingLanguage";
+
+	public static final String PROP_FONT_SIZE = "plm.display.fontsize"; // the CSS property of the font size
+
+	private List<GameListener> listeners = new ArrayList<GameListener>();
+	private World selectedWorld;
+	private World answerOfSelectedWorld;
+	private World initialOfSelectedWorld;
+	private Entity selectedEntity;
+	private List<Thread> demoRunners = new ArrayList<Thread>();
+	private static List<Thread> initRunners = new ArrayList<Thread>();
+
+    private HeartBeatSpy heartBeatSpy;
+
+	private ArrayList<GameStateListener> gameStateListeners = new ArrayList<GameStateListener>();
+
+	private LogWriter outputWriter;
+
+	public SessionDB studentWork = new SessionDB();
+	private ISessionKit sessionKit = new ZipSessionKit(this);
+
+	private static boolean ongoingInitialization = false;
+	private static String lessonChooser = "lessons.chooser";
+	public  static I18n i18n;
+
+	public static Game getInstance() {
+		if (Game.instance == null) {
+			if (ongoingInitialization)
+				throw new RuntimeException("Loop in initialization process. This is a PLM bug.");
+			ongoingInitialization = true;
+			Game.instance = new Game();
+			ongoingInitialization = false;
+			Game.instance.loadSession();
+		}
+		return Game.instance;
+	}
+
+	private Game() {
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
+		loadProperties();
+
+		if (checkScala())
+			System.err.println(i18n.tr("Scala is usable on your machine. Congratulations."));
+		else
+			System.err.println(i18n.tr("Please install Scala version 2.10 or higher to use it in PLM."));
+		if (checkPython())
+			System.err.println(i18n.tr("Jython is usable on your machine. Congratulations."));
+		else
+			System.err.println(i18n.tr("Please install jython to use the python programming language in PLM."));
+		
+		String defaultProgrammingLanguage = Game.getProperty(PROP_PROGRAMING_LANGUAGE,"Java",true);
+		if (!defaultProgrammingLanguage.equalsIgnoreCase(Game.JAVA.getLang()) &&
+			!defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang()) &&
+			!defaultProgrammingLanguage.equalsIgnoreCase(Game.SCALA.getLang())) 
+			System.err.println(i18n.tr("Warning, the default programming language is neither ''Java'' nor ''python'' or ''Scala'' but {0}.\n"+
+					"   This language will be used to setup the worlds, possibly leading to severe issues for the exercises that don''t expect it.\n" +
+					"   It is safer to change the current language, and restart PLM before proceeding.\n"+
+					"   Alternatively, the property {1} can be changed in your configuration file ($HOME/.plm/plm.properties)",defaultProgrammingLanguage,PROP_PROGRAMING_LANGUAGE));
+		
+		if (defaultProgrammingLanguage.equalsIgnoreCase(Game.SCALA.getLang()) && !canScala) {
+			System.err.println(i18n.tr("The default programming language is Scala, but your scala installation is not usable. Switching to Java instead.\n"));
+			setProgramingLanguage(JAVA);
+		} else if (defaultProgrammingLanguage.equalsIgnoreCase(Game.PYTHON.getLang()) && !canPython) {
+			System.err.println(i18n.tr("The default programming language is python, but your python installation is not usable. Switching to Java instead.\n"));
+			setProgramingLanguage(JAVA);
+		} else {
+			for (ProgrammingLanguage pl : Game.getProgrammingLanguages()) 
+				if (pl.getLang().equals(defaultProgrammingLanguage)) {
+					setProgramingLanguage(pl);
+					break;
+				}
+		}
+				
+		addProgressSpyListener(new LocalFileSpy(SAVE_DIR));
+		
+		if (getProperty(PROP_PROGRESS_TWITTER, "true",true).equalsIgnoreCase("true")) {
+			System.err.println(i18n.tr("Your progress will be posted to https://twitter.com/jlmlovers This can be turned off through the property {0}",Game.PROP_PROGRESS_TWITTER));
+			addProgressSpyListener(new TwitterSpy());
+		} else {
+			System.err.println(i18n.tr("Your progress will NOT be posted to twitter, as requested by the property {0}",Game.PROP_PROGRESS_TWITTER));			
+		}
+		if (getProperty(PROP_PROGRESS_APPENGINE, "false",true).equalsIgnoreCase("true"))
+			addProgressSpyListener(new ServerSpyAppEngine());
+
+        currentCourse = new CourseAppEngine();
+	}
+	
+	boolean canScala = false;
+	String scalaError = "";
+	
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private boolean checkScala() {
+		String[] resources = new String[] {"/scala/tools/nsc/Interpreter", "/scala/ScalaObject", "/scala/reflect/io/AbstractFile"};
+		String[] hints     = new String[] {"scala-compiler.jar",           "scala-library.jar",  "scala-reflect.jar"};
+		for (int i=0;i<resources.length;i++) {
+			scalaError = canResolve(resources[i],hints[i]);
+			if (!scalaError.isEmpty()) {
+				System.err.println(scalaError);
+				return canScala;
+			}
+		}
+
+		String version = null;
+		try {
+			Class props = Class.forName("scala.util.Properties");
+			Method meth = props.getMethod("versionString", new Class[] {});
+			version = (String) meth.invoke(props);
+		} catch (Exception e) {
+			scalaError = i18n.tr("Error {0} while retrieving the Scala version: {1}", e.getClass().getName() ,e.getLocalizedMessage());
+			System.err.println( scalaError );
+			return canScala;
+		}
+
+		if (version.contains("version 2.10") || version.contains("version 2.11")) {
+			canScala = true;
+			return canScala;
+		} else {
+			scalaError = i18n.tr("Scala is too ancient. Found {0} while I need 2.10 or higher.",version);
+			System.err.println(scalaError);
+			return canScala;
+		}
+	}
+	
+	public boolean canPython = false;
+	String pythonError = "";
+	private boolean checkPython() {
+		String[] resources = new String[] {
+				"/org/python/jsr223/PyScriptEngineFactory", "/org/jruby/ext/posix/util/Platform","/org/antlr/runtime/CharStream",
+				"/org/objectweb/asm/Opcodes"
+				};
+		String[] hints     = new String[] {"jython.jar", "jruby.jar","antlr3-runtime.jar",
+				"asm3.jar"};
+		for (int i=0;i<resources.length;i++) {
+			pythonError = canResolve(resources[i],hints[i]);
+			if (!pythonError.isEmpty()) {
+				System.err.println(pythonError);
+				return canPython;
+			}
+		}
+		
+		ScriptEngineManager manager = new ScriptEngineManager();       
+		if (manager.getEngineByName("python") == null) {
+			pythonError = i18n.tr("Cannot retrieve the python ScriptEngine. Are jython.jar and its dependencies in the classpath?");
+		}
+
+		canPython = true;
+		return true;
+	}
+
+	private String canResolve(String resource, String hint) {
+		try {
+			URL path = getClass().getResource(resource+".class");
+			if (path != null)
+				return ""; // Cool, found it.
+				
+			path = ClassLoader.getSystemResource(resource+".class");
+			if (path != null)
+				return ""; // Cool, found it.
+			
+			resource = resource.replaceAll("/", ".");
+			resource = resource.substring(1);
+			Class.forName(resource).newInstance();
+			return ""; // That's cool if I manage to create one such object
+			
+		} catch (ClassNotFoundException ce) {
+			return i18n.tr("Resource {0} not found in the classpath.\nIs {1} in your classpath?",resource,hint);
+		} catch (Exception e) {
+			return i18n.tr("{0} received while searching for resource {1}: {2}",e.getClass().getName(),resource,e.getLocalizedMessage());
+		}
+	}
+		
+	
+	/**
+	 * Load the chooser, stored in plm.core.ui.chooser
+	 */
+	public void loadChooser() {
+		Game.instance.switchLesson(lessonChooser,false);
+	}
+	
+	
+	/** Change the current lesson.
+	 * 
+	 * Also, initialize the newly used lesson on need. It must already be in the classpath 
+	 * (use @loadLesson() if you want to load a lesson located in an external jar file)
+	 *  
+	 * @param lessonName package name of the lesson to load 
+	 */
+	
+	public Lesson switchLesson(String lessonName, boolean failOnError) {
+		if (stepModeEnabled())
+			disableStepMode();
+		
+		this.setState(GameState.LOADING);
+		// Try caching the lesson to avoid the possibly long loading time during which we compute the solution of each exercise  
+		Lesson lesson = lessons.get(lessonName);
+		statusArgAdd(lessonName);
+		
+		if (lesson == null) { // we have to load it 
+			try {
+				// This is where we assume here that each lesson contains a Main object, instantiating the Lesson class.
+				// We manually build a call to the constructor of this object, and fire it
+				// This creates such an object, which is in charge of creating the whole lesson (including exercises) from its constructor
+				lesson = (Lesson) Class.forName(lessonName + ".Main").newInstance();
+				
+				lessons.put(lessonName, lesson); // cache the newly created object
+			} catch (InstantiationException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			} catch (ClassNotFoundException e) {
+				if (failOnError)
+					throw new RuntimeException(Game.i18n.tr("Cannot switch to lesson {0}: class Main not found.",lessonName));
+				System.err.println(Game.i18n.tr("Cannot switch to lesson {0}: class Main not found.",lessonName));
+				statusArgRemove(Game.i18n.tr("Load lesson {0}",lessonName));				
+				return getCurrentLesson();
+			}
+		}
+		// Prevent an error message telling us that the PLM couldn't load our code for the chooser -- kinda obvious
+		if ( !lessonName.equals(lessonChooser) && sessionKit != null)
+			sessionKit.loadLesson(SAVE_DIR, lesson);
+		try {
+			waitInitThreads();
+		} catch (InterruptedException e) {
+			System.err.println("Interrupted while loading the lesson "+lesson.getName());
+			e.printStackTrace();
+		}
+		setCurrentLesson(lesson);
+		
+		this.setState(GameState.LOADING_DONE);
+
+		return lesson;
+	}
+	private Set<String> usedJARs = new HashSet<String>(); // cache used in loadLessonFromJAR()
+	/** Load a new lesson from an external JAR file.
+	 *  
+	 * This will only work if the system classloader is an URLClassLoader. 
+	 * If your JVM gave you something else (and if you failed to change it from the command line or whatever), this will fail with an exception. 
+	 * 
+	 * @param path Path to the JAR file
+	 * @throws LessonLoadingException if the JAR file is inexistent or invalid (or if the system classloader does not accept URLs)
+	 */
+	public void loadLessonFromJAR(File jar) throws LessonLoadingException {
+		
+		if (!jar.exists())
+			throw new LessonLoadingException("File "+jar.getName()+" does not exist");
+		
+		
+		// Check if the JAR has already been added. If not, load it in the classloader.
+		if (!usedJARs.contains(jar.getAbsolutePath())) {	
+			URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
+			Class<URLClassLoader> sysclass = URLClassLoader.class;
+			
+			URL urlOfJar;
+			try {
+				urlOfJar = jar.toURI().toURL();
+			} catch (IOException e1) {
+				throw new LessonLoadingException("Error while reading the jarfile "+jar.getName(),e1);
+			}
+	        
+	        try {
+	        	// Hell yeah. That method is usually private, but I can change it that easily.
+	        	// Some people even call this bullshit "security"...
+	        	
+	            Method method = sysclass.getDeclaredMethod("addURL",new Class[]{URL.class});
+	            method.setAccessible(true);
+	            method.invoke(sysloader,new Object[]{ urlOfJar });
+	        } catch (Throwable t) {
+	        	throw new LessonLoadingException("Internal Error: The system classloader refused to load the URL of this lesson file. You may want to change the JVM classloader from the command line.",t);
+	        }
+	        
+	        usedJARs.add(jar.getAbsolutePath());
+		}
+        
+		// Load the JAR manifest file to retrieve the lesson's package name in it
+		Manifest manifest;
+		try {
+			manifest = new JarFile(jar).getManifest();
+		} catch (Exception e) {
+			throw new LessonLoadingException("Invalid lesson file (Manifest not found): "+jar.getName(), e);
+		}
+		
+		String lessonPackage = manifest.getMainAttributes().getValue("LessonPackage");
+		if (lessonPackage == null)
+			throw new LessonLoadingException("Invalid lesson file (Attribute 'LessonPackage' not found in Manifest): "+jar.getName());
+		
+		// We are ready to launch this lesson
+		Game.getInstance().switchLesson("lessons." + lessonPackage,false);
+    }//end method
+
+	
+
+	public static void addInitThread(Thread t) {
+		initRunners.add(t);
+	}
+	public static void waitInitThreads() throws InterruptedException {
+		for (Thread t:initRunners) 
+			t.join();
+	}
+
+	public Collection<Lesson> getLessons() {
+		return this.lessons.values();
+	}
+
+	public Lesson getCurrentLesson() {
+		if (this.currentLesson == null && this.lessons.size() > 0) {
+			setCurrentLesson(this.lessons.get(0));
+		}
+		return this.currentLesson;
+	}
+
+	public void setCurrentLesson(Lesson lesson) {
+		try {
+			saveSession(); // don't loose user changes 
+			
+			this.currentLesson = lesson;
+			fireCurrentLessonChanged();
+			setCurrentExercise(this.currentLesson.getCurrentExercise());
+			
+		} catch (UserAbortException e) { 
+			System.out.println(i18n.tr("Operation cancelled by the user"));
+		}
+	}
+
+	// only to avoid that exercise views register as listener of a lesson
+	public void setCurrentExercise(Lecture lect) {
+		try {
+			saveSession(); // don't loose user changes 
+
+			this.currentLesson.setCurrentExercise(lect);
+			fireCurrentExerciseChanged(lect);
+			if (lect instanceof Exercise) {
+				Exercise exo = (Exercise) lect;
+				exo.reset();
+				setSelectedWorld(exo.getWorld(0));
+
+				ProgrammingLanguage fallback = null;
+				for (ProgrammingLanguage l:exo.getProgLanguages()) {
+					if (l.equals(programmingLanguage))
+						return; /* The exo accepts the language we currently have */
+					if (fallback == null)
+						fallback = l;
+				}
+				/* Use the first (programming) language advertised by the exercise java as a fallback */
+				System.out.println( 
+						Game.i18n.tr("Exercise {0} does not support language {1}. Fallback to {2} instead. "
+								+ "Please consider contributing to this project by adapting this exercise to this language.",
+								lect.getName(),getProgrammingLanguage(),fallback.getLang()));
+				setProgramingLanguage(fallback);
+				
+			}
+			MainFrame.getInstance().currentExerciseHasChanged(lect); // make sure that the right language is selected -- yeah that's a ugly way of doing it
+
+		} catch (UserAbortException e) { 
+			System.out.println(i18n.tr("Operation cancelled by the user"));
+		}
+	}
+
+	public World getSelectedWorld() {
+		Lecture lecture = this.currentLesson.getCurrentExercise();
+		if (lecture instanceof Exercise) {
+			if (this.selectedWorld == null) {
+				setSelectedWorld(((Exercise) lecture).getWorld(0));
+			}
+			return this.selectedWorld;
+		} else {
+			return null;
+		}
+	}
+	public World[] getSelectedWorlds() {
+		World[] res = new World[3];
+		res[0] = selectedWorld;
+		res[1] = answerOfSelectedWorld;
+		res[2] = initialOfSelectedWorld;
+		return res;
+	}
+
+	public void setSelectedWorld(World world) {
+		Lecture lect = getCurrentLesson().getCurrentExercise();
+		if (lect instanceof Exercise) {
+			Exercise exo = (Exercise) lect;
+			if (this.selectedWorld != null)
+				this.selectedWorld.removeEntityUpdateListener(this);
+			this.selectedWorld = world;
+			this.selectedWorld.addEntityUpdateListener(this);
+
+			int index = exo.indexOfWorld(this.selectedWorld);
+			this.answerOfSelectedWorld = exo.getAnswerOfWorld(index);
+			this.initialOfSelectedWorld = exo.getWorlds(WorldKind.INITIAL).get(index);
+			if (this.selectedWorld.getEntityCount()>0) {
+				this.selectedEntity = this.selectedWorld.getEntity(0);
+			}
+			fireSelectedWorldHasChanged(world);
+		} else {
+			throw new RuntimeException(Game.i18n.tr("The lecture {0} has no world that I can select",lect));
+		}
+	}
+
+	public World getAnswerOfSelectedWorld() {
+		return this.answerOfSelectedWorld;
+	}
+
+	public void setSelectedEntity(Entity b) {
+		this.selectedEntity = b;
+		fireSelectedEntityHasChanged();
+	}
+
+	public Entity getSelectedEntity() {
+		return this.selectedEntity;
+	}
+
+	/* Actions of the toolbar buttons */
+	private boolean stepMode = false;
+	private LessonRunner runner;
+	public void startExerciseExecution() {
+		runner = new LessonRunner(Game.getInstance());
+		runner.start();
+	}
+	public void stopExerciseExecution() {
+		if (stepModeEnabled()) 
+			disableStepMode();
+
+		if (runner != null)
+			runner.stopAll();
+		
+		Lecture lecture = this.currentLesson.getCurrentExercise();
+		if (lecture instanceof Exercise)
+			for (World w : ((Exercise) lecture).getWorlds(WorldKind.ANSWER))
+				w.doneDelay();
+
+		setState(GameState.EXECUTION_ENDED);
+	}
+	public void startExerciseDemoExecution() {
+		DemoRunner runner = new DemoRunner(Game.getInstance(), this.demoRunners);
+		runner.start();
+	}
+	public void startExerciseStepExecution() {
+		stepMode = true;
+		startExerciseExecution();
+	}
+
+	public void enableStepMode() {
+		this.stepMode = true;
+	}
+	public void disableStepMode() {
+		this.stepMode = false;
+	}
+
+	public boolean stepModeEnabled() {
+		return this.stepMode;
+	}
+
+	public void allowOneStep() {
+		Lecture lecture = this.currentLesson.getCurrentExercise();
+		if (lecture instanceof Exercise)
+			for (World w: ((Exercise) lecture).getWorlds(WorldKind.CURRENT))
+				for (Entity e : w.getEntities())
+					e.allowOneStep();
+	}
+
+	/**  Reset the current exercise (see {@link Exercise.reset()} */
+	public void reset() {
+		Lecture lecture = this.currentLesson.getCurrentExercise();
+		if (lecture instanceof Exercise) {
+			((Exercise) lecture).reset();
+			fireCurrentExerciseChanged(lecture);
+		}
+	}
+
+	public void setState(GameState status) {
+		this.state = status;
+		fireStateChanged(status);
+	}
+
+	public GameState getState() {
+		return this.state;
+	}
+
+	public void setOutputWriter(LogWriter writer) {
+		this.outputWriter = writer;
+		if (getProperty(PROP_OUTPUT_CAPTURE, "true",true).equals("true")) {
+			Logger l = new Logger(outputWriter);
+			System.setOut(l);
+			System.setErr(l);
+		}
+	}
+
+	public LogWriter getOutputWriter() {
+		return this.outputWriter;
+	}
+
+	public void quit() {
+		try {
+			// FIXME: this method is not called when pressing APPLE+Q on OSX
+
+            // report user leave on the server
+            for(ProgressSpyListener spyListener: progressSpyListeners){
+                spyListener.leave();
+            }
+            // stop the heartbeat report to PLMServer
+            if(heartBeatSpy != null)
+                heartBeatSpy.die();
+
+			saveSession();
+			storeProperties();
+			System.exit(0);
+		} catch (UserAbortException e) {
+			// Ok, user decided to not quit (to get a chance to export the session)
+			System.out.println("Exit aborted");
+		}
+	}
+
+	public void clearSession() {
+		if (sessionKit == null)
+			return;
+		this.sessionKit.cleanAll(SAVE_DIR);
+		for (Lesson l : this.lessons.values())
+			for (Lecture lect : l.exercises())
+				if (lect instanceof Exercise)
+					for (ProgrammingLanguage lang:((Exercise) lect).getProgLanguages()) 
+						Game.getInstance().studentWork.setPassed(lect, lang, false);
+
+		fireCurrentExerciseChanged(currentLesson.getCurrentExercise());
+	}
+
+	public void loadSession() {
+		if (sessionKit == null)
+			return;
+		this.setState(GameState.LOADING);
+		this.sessionKit.loadAll(SAVE_DIR);
+		this.setState(GameState.LOADING_DONE);
+	}
+
+	public void saveSession() throws UserAbortException {
+		if (sessionKit == null)
+			return;
+		this.setState(GameState.SAVING);
+		this.sessionKit.storeAll(SAVE_DIR);
+		this.setState(GameState.SAVING_DONE);
+	}
+
+	public ISessionKit getSessionKit() {
+		return this.sessionKit;
+	}
+	public void removeSessionKit() {
+		sessionKit = null;
+		System.out.println("Disabling the session kit on disk.");
+	}
+	
+	public static void loadProperties() {
+		InputStream is = null;
+		try {
+			is = Game.class.getClassLoader().getResourceAsStream("resources/plm.configuration.properties");
+			if (is==null) // try to find the file in the Debian package
+				is = Game.class.getClassLoader().getResourceAsStream("/etc/plm.configuration.properties");
+			Game.defaultGameProperties.load(is);
+		} catch (InvalidPropertiesFormatException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (NullPointerException e) {
+			// resources/plm.configuration.properties not found. Try plm.configuration.properties afterward
+		} finally {
+			if (is != null)
+				try {
+					is.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+		}
+
+		File localPropertiesFile = new File(SAVE_DIR + File.separator + Game.LOCAL_PROPERTIES_FILENAME);
+		if (localPropertiesFile.exists()) {
+			FileInputStream fi = null;
+			try {
+				fi = new FileInputStream(localPropertiesFile);
+				Game.localGameProperties.load(fi);
+				Game.localGamePropertiesLoadedFile = localPropertiesFile;
+			} catch (InvalidPropertiesFormatException e) {
+				e.printStackTrace();
+			} catch (FileNotFoundException e) {
+				e.printStackTrace();
+			} catch (IOException e) {
+				e.printStackTrace();
+			} finally {
+				if (fi != null)
+					try {
+						fi.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+			}
+			System.out.println(String.format("Loading properties [%s]", localPropertiesFile));
+		}
+	}
+
+	public static void storeProperties() {
+		Game.localGamePropertiesLoadedFile = new File(SAVE_DIR + File.separator + Game.LOCAL_PROPERTIES_FILENAME);
+		FileOutputStream fo;
+		try {
+			fo = new FileOutputStream(Game.localGamePropertiesLoadedFile);
+			Game.localGameProperties.store(fo, "Java Learning Machine properties");
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	public static void setProperty(String key, String value) {
+		Game.localGameProperties.setProperty(key, value);
+	}
+
+	public static String getProperty(String key) {
+		return Game.getProperty(key, "", false);
+	}
+
+	/** 
+	 * Gets the value from either the local properties set (in ~/.plm) or the global one (in the jar file).
+	 * If the value is not defined in either of them, use the default value. If so and if the save parameter is true, this is saved back to the local properties file. 
+	 */
+	public static String getProperty(String key, String defaultValue, boolean save) {
+		if (Game.localGameProperties.containsKey(key)) {
+			return Game.localGameProperties.getProperty(key);
+		} else {
+			String res = Game.defaultGameProperties.getProperty(key, defaultValue);
+			if (save)
+				setProperty(key, res);
+			return res;
+		}
+	}
+
+	public void addGameListener(GameListener l) {
+		this.listeners.add(l);
+	}
+
+	public void removeGameListener(GameListener l) {
+		this.listeners.remove(l);
+	}
+
+	protected void fireCurrentLessonChanged() {
+		for (GameListener v : this.listeners) {
+			v.currentLessonHasChanged();
+		}
+	}
+
+    protected void fireCurrentExerciseChanged(Lecture lect) {
+		if (stepModeEnabled())
+			disableStepMode();
+
+        for (GameListener v : this.listeners) {
+            v.currentExerciseHasChanged(lect);
+        }
+
+        if(lect instanceof Exercise){
+            for(ProgressSpyListener p: this.progressSpyListeners){
+                p.switched((Exercise)lect);
+            }
+        }
+    }
+
+	protected void fireSelectedWorldHasChanged(World w) {
+		for (GameListener v : this.listeners) {
+			v.selectedWorldHasChanged(w);
+		}
+	}
+
+	protected void fireSelectedWorldWasUpdated() {
+		for (GameListener v : this.listeners) {
+			v.selectedWorldWasUpdated();
+		}
+	}
+
+	protected void fireSelectedEntityHasChanged() {
+		for (GameListener v : this.listeners) {
+			v.selectedEntityHasChanged();
+		}
+	}
+
+	public void addGameStateListener(GameStateListener l) {
+		this.gameStateListeners.add(l);
+	}
+
+	public void removeGameStateListener(GameStateListener l) {
+		this.gameStateListeners.remove(l);
+	}
+
+	protected void fireStateChanged(GameState status) {
+		for (GameStateListener l : this.gameStateListeners) 
+			l.stateChanged(status);
+	}
+
+	private ArrayList<ProgressSpyListener> progressSpyListeners = new ArrayList<ProgressSpyListener>();
+	public void addProgressSpyListener(ProgressSpyListener l) {
+		this.progressSpyListeners.add(l);
+	}
+	public void removeProgressSpyListener(ProgressSpyListener l) {
+		this.progressSpyListeners.remove(l);
+	}
+	public void fireProgressSpy(Exercise exo) {
+		for (ProgressSpyListener l : this.progressSpyListeners) {
+			l.executed(exo);
+		}
+	}
+
+	@Override
+	public void worldHasChanged() {
+		if (selectedWorld.getEntityCount()>0)
+			setSelectedEntity(this.selectedWorld.getEntity(0));
+		fireSelectedWorldWasUpdated();
+	}
+
+	@Override
+	public void worldHasMoved() {
+		// don't really care that something moved within the current world
+	}
+
+	/* Status bar label changing logic */
+	ArrayList<StatusStateListener> statusStateListeners = new ArrayList<StatusStateListener>();
+	public void addStatusStateListener(StatusStateListener l) {
+		this.statusStateListeners.add(l);
+	}
+	public void removeStatusStateListener(StatusStateListener l) {
+		this.statusStateListeners.remove(l);
+	}
+	ArrayList<String> statusArgs = new ArrayList<String>();
+	String stateTxt = "";
+	public void statusRootSet(String txt) {
+		stateTxt = txt;
+	}
+	public void statusArgAdd(String txt) {
+		synchronized (statusArgs) {
+			statusArgs.add(txt);
+			statusChanged();
+		}
+	}
+	public void statusArgRemove(String txt) {
+		synchronized (statusArgs) {
+			statusArgs.remove(txt);
+			statusChanged();
+		}
+	}
+	public void statusArgEmpty(){
+		synchronized (statusArgs) {
+			statusArgs.clear();
+			statusChanged();
+		}
+	}
+	private void statusChanged() {
+		StringBuffer sb = new StringBuffer(stateTxt);
+		boolean first = true;
+		for (String s:statusArgs) {
+			if (first)
+				first = false;
+			else
+				sb.append(", ");
+			sb.append(s);
+		}
+		
+		String msg = first ? "" : sb.toString(); // remove everything if no argument at all 
+		for (StatusStateListener l : this.statusStateListeners) 
+			l.stateChanged(msg);
+	}
+	public void setLocale(Locale lang) {
+		FileUtils.setLocale(lang);
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+		fireHumanLangChange(lang);
+
+		/* FIXME: convert all this to a humanLanguage listener */
+		if (  Game.getInstance() != null && Game.getInstance().getCurrentLesson() != null ) {
+			Game.getInstance().getCurrentLesson().resetAboutLoaded();
+			Lecture lect = Game.getInstance().getCurrentLesson().getCurrentExercise();
+			if ( lect instanceof Exercise )
+				((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).resetAbout();
+		}
+
+		for (Lesson lesson : lessons.values()) {
+			for (Lecture lect:lesson.exercises()) {
+				if (lect instanceof ExerciseTemplated) {
+					lect.loadHTMLMission();
+				}
+			}
+		}
+		setCurrentLesson(getCurrentLesson());
+		currentLesson.setCurrentExercise(currentLesson.getCurrentExercise());
+	}
+	public Locale getLocale(){
+		return FileUtils.getLocale();
+	}
+
+
+
+	public void setProgramingLanguage(ProgrammingLanguage newLanguage) {
+		if (programmingLanguage.equals(newLanguage))
+			return;
+
+		if (isValidProgLanguage(newLanguage)) {
+			//System.out.println("Switch programming language to "+newLanguage);
+			if (newLanguage.equals(Game.SCALA) && !canScala) {
+				JOptionPane.showMessageDialog(null, i18n.tr("Please install Scala version 2.10 or higher to use it in PLM.\n\n")+scalaError ,
+						i18n.tr("Scala is missing"), JOptionPane.ERROR_MESSAGE); 
+				return;
+			}
+			if (newLanguage.equals(Game.PYTHON) && !canPython) {
+				JOptionPane.showMessageDialog(null, i18n.tr("Please install jython and its dependencies to use the python programming language in PLM.\n\n")+pythonError,
+						i18n.tr("Python is missing"), JOptionPane.ERROR_MESSAGE); 
+				return;
+			}
+			this.programmingLanguage = newLanguage;
+			fireProgLangChange(newLanguage);
+			if (newLanguage.equals(Game.JAVA) || newLanguage.equals(Game.PYTHON) || newLanguage.equals(Game.SCALA)) // Only save it if it's stable enough
+				setProperty(PROP_PROGRAMING_LANGUAGE, newLanguage.lang);
+			return;
+		}
+		throw new RuntimeException("Ignoring request to switch the programming language to the unknown "+newLanguage);
+	}
+
+	public static ProgrammingLanguage getProgrammingLanguage() {
+		if (ongoingInitialization) /* break an initialization loop -- the crude way (FIXME) */
+			return JAVA;
+		else
+			return getInstance().programmingLanguage;
+	}
+	public static ProgrammingLanguage[] getProgrammingLanguages(){
+		return programmingLanguages;
+	}
+
+	public boolean isValidProgLanguage(ProgrammingLanguage newL) {
+		for (ProgrammingLanguage pl : programmingLanguages)
+			if (pl.equals(newL))
+				return true;
+		return false;
+	}
+	private List<ProgLangChangesListener> progLangListeners = new Vector<ProgLangChangesListener>();
+	public void addProgLangListener(ProgLangChangesListener l) {
+		progLangListeners.add(l);
+	}
+	public void fireProgLangChange(ProgrammingLanguage newLang) {
+		for (ProgLangChangesListener l : progLangListeners)
+			l.currentProgrammingLanguageHasChanged(newLang);
+	}
+	public void removeProgLangListener(ProgLangChangesListener l) {
+		this.progLangListeners.remove(l);
+	}
+
+	private List<HumanLangChangesListener> humanLangListeners = new Vector<HumanLangChangesListener>();
+	public void addHumanLangListener(HumanLangChangesListener l) {
+		humanLangListeners.add(l);
+	}
+	public void fireHumanLangChange(Locale newLang) {
+		for (HumanLangChangesListener l : humanLangListeners)
+			l.currentHumanLanguageHasChanged(newLang);
+	}
+	public void removeHumanLangListener(HumanLangChangesListener l) {
+		this.humanLangListeners.remove(l);
+	}
+	
+	private boolean doDebug = false;
+	public void switchDebug() {
+		doDebug = !doDebug;
+		if (doDebug) {
+			Lesson l = Game.getInstance().getCurrentLesson();
+			System.out.println("Saving location: "+SAVE_DIR.getAbsolutePath());
+			System.out.println("Lesson: "+(l==null?"None loaded yet":l.getName()));
+			System.out.println("Exercise: "+(l==null?"None loaded yet":l.getCurrentExercise().getName()));
+			System.out.println("PLM version: "+Game.getProperty("plm.major.version","internal",false)+" ("+Game.getProperty("plm.major.version","internal",false)+"."+Game.getProperty("plm.minor.version","",false)+")");
+			System.out.println("Java version: "+System.getProperty("java.version")+" (VM: "+ System.getProperty("java.vm.name")+" "+ System.getProperty("java.vm.version")+")");
+			System.out.println("System: " +System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")");
+			for (ScriptEngineFactory sef : new ScriptEngineManager().getEngineFactories()) {
+				  System.out.println(sef);
+				  System.out.append("  Engine: ")
+				      .append(sef.getEngineName())
+				      .append(" ")
+				      .println(sef.getEngineVersion());
+				  System.out.append("  Language: ")
+				      .append(sef.getLanguageName())
+				      .append(" ")
+				      .println(sef.getLanguageVersion());
+				  System.out.append("  Names: ")
+				      .println(sef.getNames());
+				}
+		}
+	}
+	public boolean isDebugEnabled() {
+		return doDebug;
+	}
+
+    /*
+     * Getter and Setter for the course ID for the current session.
+     * This ID will be used by the ServerSpy, to associate this
+     * PLM student with a course started by a teacher on the server
+     */
+    public String getCourseID() {
+    	if (this.currentCourse == null)
+    		return "";
+    	else
+    		return currentCourse.getCourseId();
+    }
+
+    public String getCoursePassword(){
+        if(this.currentCourse == null)
+            return "";
+        else
+            return currentCourse.getPassword();
+    }
+
+    public void setCourseID(String courseID) {
+    	this.currentCourse.setCourseId(courseID);
+    }
+
+    public Course getCurrentCourse() {
+        return currentCourse;
+    }
+
+    public void setCurrentCourse(Course currentCourse) {
+        this.currentCourse = currentCourse;
+    }
+
+    public HeartBeatSpy getHeartBeatSpy(){ return this.heartBeatSpy; }
+
+    public void setHeartBeatSpy(HeartBeatSpy heartBeatSpy){ this.heartBeatSpy = heartBeatSpy; }
+
+    public ArrayList<ProgressSpyListener> getProgressSpyListeners(){ return this.progressSpyListeners; }
+    
+    
+    /* Mechanism to find where to save our data */
+	
+    private static String HOME_DIR = System.getProperty("user.home");
+	
+	/* These names are tested one after the other, searching for one that exist or that we can create */
+	static String[] rootDirNames = new String[] { 
+		HOME_DIR + File.separator + ".plm", /* preferred, default directory name */
+		HOME_DIR + File.separator + "_plm", /* Some paranoid administrator refuse directories which name starts with a dot */
+		HOME_DIR + File.separator + "plm",  /* one day, hidden directories with make trouble... */
+		"z:"     + File.separator + ".plm", /* windows-preferred directory name */
+		"z:"     + File.separator + "_plm",
+		"z:"     + File.separator + "plm",
+	};
+	private static File SAVE_DIR = initializeSaveDir();
+	private static File initializeSaveDir() {
+		StringBuffer sb = new StringBuffer();
+		for (String path : rootDirNames) {
+			File res = new File(path);
+			sb.append(path);
+			sb.append(", ");
+			try {
+				if (res.exists()) {
+					if (res.isDirectory()) {
+						if (res.canWrite()) {
+							return res;
+						} else {
+							System.out.println(i18n.tr("{0} is not writable",res.getAbsolutePath()));
+							continue;
+						}
+					} else {
+						System.out.println(i18n.tr("{0} is not a directory",res.getAbsolutePath()));
+						continue;
+					}
+				}
+				if (res.mkdir())
+					return res;
+				else {
+					System.out.println(i18n.tr("Cannot create {0}",res.getAbsolutePath()));
+				}
+			} catch (SecurityException e) {
+				e.getLocalizedMessage();
+			}
+		}
+		throw new RuntimeException(i18n.tr("Impossible to find a path for PLM data. Tested {0}",sb.toString()));
+	}
+	public static String getSavingLocation() {
+		return SAVE_DIR.getPath();
+	}
+}
diff --git a/src/plm/core/model/HelpAppEngine.java b/src/plm/core/model/HelpAppEngine.java
new file mode 100644
index 0000000..ec3c118
--- /dev/null
+++ b/src/plm/core/model/HelpAppEngine.java
@@ -0,0 +1,77 @@
+package plm.core.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.json.simple.JSONObject;
+
+/**
+ * Implementation of HelpServer that sends requests to an App Engine server
+ */
+public class HelpAppEngine extends HelpServer {
+
+    private static URL helpServer;
+
+    public HelpAppEngine() {
+    	String url = Game.getProperty(Game.PROP_APPENGINE_URL);
+    	if (! url.equals("")) { // no configuration were provided
+    		try {
+    			helpServer = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/student");
+    		} catch (MalformedURLException e) {
+    			e.printStackTrace();
+    		}
+    	} else {
+    		System.out.println("No course server configured");
+    	}
+    }
+
+    @Override
+    public String sendRequest(String request) {
+        String response = "";
+        try {
+
+            // Send data
+            URLConnection conn = helpServer.openConnection();
+            conn.setDoOutput(true);
+            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
+            wr.write(request);
+            wr.flush();
+
+            // Get response data and print it
+            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = br.readLine()) != null)
+            	response += line;
+
+            wr.close();
+            br.close();
+        } catch (IOException e) {
+            System.out.println("Unable to contact PLMServer to send request " + request);
+        }
+        return response;
+    }
+    
+    /**
+     * Construct a request to ask teacher help in a course
+     */
+    @Override
+    public void setStatus(boolean isRequestingHelp){
+    	super.setStatus(isRequestingHelp);
+
+        JSONObject jsonObject = new JSONObject();
+		jsonObject.put("username", username);
+		jsonObject.put("action", "help");
+        jsonObject.put("course", Game.getInstance().getCourseID());
+        jsonObject.put("password", Game.getInstance().getCoursePassword());
+        jsonObject.put("status", isRequestingHelp ? "true" : "false");
+
+		sendRequest(jsonObject.toString());
+    }
+
+}
+
diff --git a/src/plm/core/model/HelpServer.java b/src/plm/core/model/HelpServer.java
new file mode 100644
index 0000000..4afca28
--- /dev/null
+++ b/src/plm/core/model/HelpServer.java
@@ -0,0 +1,41 @@
+package plm.core.model;
+
+import plm.core.ui.MainFrame;
+
+/**
+ * Abstract class that allows the user to ask help to a teacher by clicking on help button
+ * This class only constructs the request with JSON, an implementation must be done to send requests
+ * For now it's App Engine which is used
+ */
+public abstract class HelpServer {
+	protected String username;
+    // the user is already requesting help
+
+	public HelpServer() {
+		username = System.getenv("USER");
+		if (username == null)
+			username = System.getenv("USERNAME");
+		if (username == null)
+			username = "John Doe";
+	}
+
+    /**
+     * Construct a request to ask teacher help in a course
+     */
+    public void setStatus(boolean isRequestingHelp){
+    	if (isRequestingHelp) {
+    		System.out.println(MainFrame.getInstance().i18n.tr("Asking to the teacher for help"));
+    	} else {
+    		System.out.println(MainFrame.getInstance().i18n.tr("Cancel call for help to the teacher"));
+    	}    
+    }
+
+   	/**
+	 * Method to implement to indicate how/where to send data
+	 *
+	 * @param request
+	 *            request in json to send to the server
+	 */
+    public abstract String sendRequest(String request);
+
+}
diff --git a/src/plm/core/model/LessonLoadingException.java b/src/plm/core/model/LessonLoadingException.java
new file mode 100644
index 0000000..fec6323
--- /dev/null
+++ b/src/plm/core/model/LessonLoadingException.java
@@ -0,0 +1,13 @@
+package plm.core.model;
+
+public class LessonLoadingException extends Exception {
+	private static final long serialVersionUID = 1L;
+
+	public LessonLoadingException(String msg) {
+		super(msg);
+	}
+
+	public LessonLoadingException(String msg, Throwable t) {
+		super(msg,t);
+	}
+}
diff --git a/src/plm/core/model/LessonRunner.java b/src/plm/core/model/LessonRunner.java
new file mode 100644
index 0000000..cc7ace5
--- /dev/null
+++ b/src/plm/core/model/LessonRunner.java
@@ -0,0 +1,144 @@
+package plm.core.model;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.PLMCompilerException;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Exercise.StudentOrCorrection;
+import plm.core.ui.ExerciseFailedDialog;
+import plm.core.ui.ResourcesCache;
+import plm.core.utils.FileUtils;
+
+/** 
+ * This class runs the student code of the current exercise in a separated thread 
+ * when the Run button is clicked. The run and demo buttons are disabled until the demo ends.
+ * 
+ * It sends an update to the remote GoogleAppEngine when the exercise is successfully passed.
+ * 
+ * Activated by {@link Game#startExerciseExecution()} and {@link Game#startExerciseStepExecution()}.
+ */
+public class LessonRunner extends Thread {
+	
+	private Game game;
+	private List<Thread> runners = new LinkedList<Thread>(); // threads who run entities from lesson
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages", FileUtils.getLocale(), I18nFactory.FALLBACK);
+
+	public LessonRunner(Game game) {
+		super();
+		this.game = game;
+	}
+
+	@Override
+	public void run() {
+		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
+		if (! (lect instanceof Exercise))
+			return;
+		final Exercise exo = (Exercise) lect;
+		
+		exo.lastResult = new ExecutionProgress();
+		
+		try {
+			game.saveSession(); // for safety reasons;
+			
+			game.setState(Game.GameState.COMPILATION_STARTED);
+			exo.compileAll(this.game.getOutputWriter(), StudentOrCorrection.STUDENT);
+			game.setState(Game.GameState.COMPILATION_ENDED);
+			
+			game.setState(Game.GameState.EXECUTION_STARTED);
+			exo.reset();
+			
+			exo.run(runners);
+			while (runners.size()>0) {
+				Thread t = runners.remove(0);
+				t.join();
+			}
+			
+			exo.check();
+			game.setState(Game.GameState.EXECUTION_ENDED);
+
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+//			game.getOutputWriter().log(e);
+			game.setState(Game.GameState.EXECUTION_ENDED);
+		} catch (PLMCompilerException e) {
+			game.setState(Game.GameState.COMPILATION_ENDED);
+			game.setState(Game.GameState.EXECUTION_ENDED);
+		} catch (Exception e) {
+			e.printStackTrace();
+//			game.getOutputWriter().log(e);
+			game.setState(Game.GameState.COMPILATION_ENDED);
+			game.setState(Game.GameState.EXECUTION_ENDED);
+		}
+		
+		if (   exo.lastResult.totalTests > 0 
+			&& exo.lastResult.totalTests == exo.lastResult.passedTests) {
+			Game.getInstance().studentWork.setPassed(exo, null, true);
+			
+			Vector<Lecture> nextExercises =  exo.getDependingLectures();	
+			if ( nextExercises.size() == 0) {
+				if (exo.lastResult.passedTests > 1) {
+					JOptionPane.showMessageDialog(null, 
+							i18n.tr("Congratulations, you passed this exercise.\n{0} tests passed.",
+									exo.lastResult.passedTests) + exo.lastResult.details, 
+									i18n.tr("Exercice passed \\o/"), 
+									JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"));
+				} else {
+					JOptionPane.showMessageDialog(null, 
+							i18n.tr("Congratulations, you passed this exercise.",
+									exo.lastResult.passedTests) + exo.lastResult.details, 
+									i18n.tr("Exercice passed \\o/"), 
+									JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"));
+				}
+			} else {
+				Lecture selectedValue;
+				if (exo.lastResult.passedTests > 1) {
+
+					selectedValue = (Lecture) JOptionPane.showInputDialog(null, 
+							i18n.tr("Congratulations, you passed this exercise.\n({0} tests passed)\nWhich exercise will you do now?"), 
+							i18n.tr("Exercice passed \\o/"),
+							JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"),
+							nextExercises.toArray(), nextExercises.get(0));
+				} else {
+					selectedValue = (Lecture) JOptionPane.showInputDialog(null, 
+							i18n.tr("Congratulations, you passed this exercise.\nWhich exercise will you do now?"), 
+							i18n.tr("Exercice passed \\o/"),
+							JOptionPane.PLAIN_MESSAGE, ResourcesCache.getIcon("img/trophy.png"),
+							nextExercises.toArray(), nextExercises.get(0));
+					
+				}
+				if (selectedValue != null) 
+					Game.getInstance().setCurrentExercise(selectedValue);
+			}
+		} else {
+			 SwingUtilities.invokeLater(new Runnable() {
+		            public void run() {
+		            	new ExerciseFailedDialog(exo.lastResult);
+		            }
+		        });
+
+		}
+		Game.getInstance().fireProgressSpy(exo);									
+
+		runners.remove(this);
+	}
+	
+	/** Stop all the threads that were already started. Harmful but who cares? */
+	@SuppressWarnings("deprecation")
+	public void stopAll() {
+		while (runners.size()>0) {
+			Thread t = runners.remove(runners.size() - 1);
+			t.stop(); // harmful but who cares ?
+		}
+	}
+	
+}
diff --git a/src/plm/core/model/LogWriter.java b/src/plm/core/model/LogWriter.java
new file mode 100644
index 0000000..e81b773
--- /dev/null
+++ b/src/plm/core/model/LogWriter.java
@@ -0,0 +1,18 @@
+package plm.core.model;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+/**
+ * Interface that all output consoles that we may use must implement. 
+ * 
+ * There is only one of them, but I was told that interfaces are the right way for a model to speak of its view elements.
+ */
+public interface LogWriter {
+
+	public void log(String msg) ;
+
+	public void log(DiagnosticCollector<JavaFileObject> diagnostics) ;
+	
+	public void log(Exception e) ;
+}
diff --git a/src/plm/core/model/Logger.java b/src/plm/core/model/Logger.java
new file mode 100644
index 0000000..d8e7526
--- /dev/null
+++ b/src/plm/core/model/Logger.java
@@ -0,0 +1,124 @@
+package plm.core.model;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+
+/**
+ * The log console used within PLM. It is setup by Game as the default System.out, 
+ * and points into the console pane at the bottom of the interface.
+ */
+public class Logger extends PrintStream {
+	private LogWriter writer;
+	private static boolean ENABLED = true;
+
+	public static void log(String method, String msg) {
+		if (Logger.ENABLED)
+			System.out.println("[" + System.currentTimeMillis() + "] " + method + " " + msg);
+	}
+	
+	public Logger(LogWriter w){
+		super(new ByteArrayOutputStream());
+		writer = w;
+	}
+
+	@Override
+	public void print(boolean b) {
+		writer.log(""+b);
+	}
+
+	@Override
+	public void print(char c) {
+		writer.log(""+c);
+	}
+
+	@Override
+	public void print(char[] s) {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append(s);
+		writer.log(stringBuilder.toString());
+	}
+
+	@Override
+	public void print(double d) {
+		writer.log(""+d);
+	}
+
+	@Override
+	public void print(float f) {
+		writer.log(""+f);
+	}
+
+	@Override
+	public void print(int i) {
+		writer.log(""+i);
+	}
+
+	@Override
+	public void print(long l) {
+		writer.log(""+l);
+	}
+
+	@Override
+	public void print(Object obj) {
+		writer.log(obj.toString());
+	}
+
+	@Override
+	public void print(String s) {
+		writer.log(s);
+	}
+
+	@Override
+	public void println() {
+		writer.log("\n");
+	}
+
+	@Override
+	public void println(boolean x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(char x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(char[] x) {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append(x);
+		stringBuilder.append("\n");
+		writer.log(stringBuilder.toString());
+	}
+
+	@Override
+	public void println(double x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(float x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(int x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(long x) {
+		writer.log(""+x+"\n");
+	}
+
+	@Override
+	public void println(Object x) {
+		writer.log(x.toString()+"\n");
+	}
+
+	@Override
+	public void println(String x) {
+		writer.log(x+"\n");
+	}
+}
diff --git a/src/plm/core/model/ProgrammingLanguage.java b/src/plm/core/model/ProgrammingLanguage.java
new file mode 100644
index 0000000..d74524d
--- /dev/null
+++ b/src/plm/core/model/ProgrammingLanguage.java
@@ -0,0 +1,47 @@
+package plm.core.model;
+
+import javax.swing.ImageIcon;
+
+public class ProgrammingLanguage implements Comparable<ProgrammingLanguage> {
+	String lang;
+	String ext;
+	ImageIcon icon;
+	public ProgrammingLanguage(String l, String ext, ImageIcon i) {
+		lang = l;
+		this.ext = ext;
+		this.icon = i;
+	}
+	public boolean equals(Object o) {
+		if (!super.equals(o))
+			return false;
+		if (getClass() != o.getClass())
+			return false;
+		return lang.equals(((ProgrammingLanguage)o).lang);
+	}
+	public String getLang() {
+		return lang;
+	}
+	public String getExt() {
+		return ext;
+	}
+	@Override
+	public String toString() {
+		return lang;
+	}
+	@Override
+	public int hashCode() {
+		return lang.hashCode();
+	}
+	@Override
+	public int compareTo(ProgrammingLanguage o) {
+		if (o == null)
+			return 1;
+		int res = lang.compareTo(o.lang);
+		if (res != 0)
+			return res;
+		return ext.compareTo(o.ext);
+	}
+	public ImageIcon getIcon() {
+		return icon;
+	}
+}
diff --git a/src/plm/core/model/ServerAnswer.java b/src/plm/core/model/ServerAnswer.java
new file mode 100644
index 0000000..e289a9e
--- /dev/null
+++ b/src/plm/core/model/ServerAnswer.java
@@ -0,0 +1,8 @@
+package plm.core.model;
+
+/**
+ * Enum that contains all answers that the server can send (errors or success messages)
+ */
+public enum ServerAnswer {
+	ALL_IS_FINE, WRONG_PASSWORD, WRONG_TEACHER_PASSWORD, COURSE_NAME_ALREADY_USED, DATA_NOT_IN_DATABASE
+}
diff --git a/src/plm/core/model/ServerExerciseData.java b/src/plm/core/model/ServerExerciseData.java
new file mode 100644
index 0000000..34228b6
--- /dev/null
+++ b/src/plm/core/model/ServerExerciseData.java
@@ -0,0 +1,73 @@
+package plm.core.model;
+
+import java.util.Date;
+
+/**
+ * Class that contains exercises data sent by the server
+ * It describes an exercise and its results
+ */
+public class ServerExerciseData {
+
+	private String name;
+	private String lang;
+	private int passedTests;
+	private int totalTests;
+	private String source;
+	private Date date;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getLang() {
+		return lang;
+	}
+	
+	public void setLang(String lang) {
+		this.lang = lang;
+	}
+	
+	public int getPassedTests() {
+		return passedTests;
+	}
+	
+	public void setPassedTests(int passedTests) {
+		this.passedTests = passedTests;
+	}
+	
+	public int getTotalTests() {
+		return totalTests;
+	}
+	
+	public void setTotalTests(int totalTests) {
+		this.totalTests = totalTests;
+	}
+	
+	public String getSource() {
+		return source;
+	}
+	
+	public void setSource(String source) {
+		this.source = source;
+	}
+	
+	public Date getDate() {
+		return date;
+	}
+	
+	public void setDate(Date date) {
+		this.date = date;
+	}
+	
+	@Override
+	public String toString() {
+		return "Exercise [name=" + name + ", lang=" + lang + ", passedTests="
+				+ passedTests + ", totalTests=" + totalTests + ", source="
+				+ source + ", date=" + date + "]";
+	}
+
+}
diff --git a/src/plm/core/model/ServerUserData.java b/src/plm/core/model/ServerUserData.java
new file mode 100644
index 0000000..4423bfa
--- /dev/null
+++ b/src/plm/core/model/ServerUserData.java
@@ -0,0 +1,142 @@
+package plm.core.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+
+/**
+ * Class that contains the data sent by the server
+ * It describes a student and its results
+ */
+public class ServerUserData {
+
+    private String username;
+    private List<ServerExerciseData> exercises;
+    private Date lastJoin;
+    private Date lastLeave;
+    private Date lastHeartbeat;
+
+    public ServerUserData() {
+        exercises = new ArrayList<ServerExerciseData>();
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public List<ServerExerciseData> getExercises() {
+        return exercises;
+    }
+
+    public Date getLastJoin() {
+        return lastJoin;
+    }
+
+    public void setLastJoin(Date lastJoin) {
+        this.lastJoin = lastJoin;
+    }
+
+    public Date getLastLeave() {
+        return lastLeave;
+    }
+
+    public void setLastLeave(Date lastLeave) {
+        this.lastLeave = lastLeave;
+    }
+
+    public Date getLastHeartbeat() {
+        return lastHeartbeat;
+    }
+
+    public void setLastHeartbeat(Date lastHeartbeat) {
+        this.lastHeartbeat = lastHeartbeat;
+    }
+
+    @Override
+    public String toString() {
+        return "User [username=" + username + ", exercises=" + exercises
+                + ", lastJoin=" + lastJoin + ", lastLeave=" + lastLeave
+                + ", lastHeartbeat=" + lastHeartbeat + "]";
+    }
+
+    /**
+     * Method to transform a json response from the server to ServerUserData objects
+     * @param answer response to parse
+     * @return list of results by student
+     */
+    public static Map<String, ServerUserData> parse(String answer) {
+        Map<String, ServerUserData> data = new HashMap<String, ServerUserData>();
+
+        JSONObject dataMap = (JSONObject) JSONValue.parse(answer);
+        // for each user
+        for (Object user : dataMap.keySet()) {
+            JSONObject userMap = (JSONObject) dataMap.get(user);
+            ServerUserData sud = new ServerUserData();
+            sud.setUsername((String) userMap.get("username"));
+
+            String lastJoinString = (String) userMap.get("lastJoin");
+            sud.setLastJoin(lastJoinString == null ? null : new Date(lastJoinString));
+
+            String lastHeartbeatString = (String)userMap.get("lastHeartbeat");
+            sud.setLastHeartbeat(lastHeartbeatString == null ? null : new Date(lastHeartbeatString));
+
+            String lastLeaveString = (String)userMap.get("lastLeave");
+            sud.setLastLeave(lastLeaveString == null ? null : new Date(lastLeaveString));
+
+            JSONArray exercisesArray = (JSONArray) userMap.get("exercises");
+            // for each exercise done by the user
+            for (Object anExercisesArray : exercisesArray) {
+                JSONObject exerciseMap = (JSONObject) anExercisesArray;
+                ServerExerciseData sed = new ServerExerciseData();
+                sed.setName((String) exerciseMap.get("name"));
+                sed.setLang((String) exerciseMap.get("lang"));
+                sed.setPassedTests((Integer) exerciseMap.get("passedTests"));
+                sed.setTotalTests((Integer) exerciseMap.get("totalTests"));
+                sed.setSource((String) exerciseMap.get("source"));
+                sed.setDate(new Date((String) exerciseMap.get("date")));
+
+                sud.getExercises().add(sed);
+            }
+
+            data.put((String)user, sud);
+        }
+
+        return data;
+    }
+
+    /**
+     * Get the number of exercises passed successfully in all exercises done
+     * @return the number..
+     */
+    public int getExercisesPassed(){
+        int exercisesPassed = 0;
+        for(ServerExerciseData exercise: exercises){
+            exercisesPassed += exercise.getPassedTests();
+        }
+
+        return exercisesPassed;
+    }
+
+    /**
+     * Get the total number of exercises performed (successfully or with fail)
+     * @return number
+     */
+    public int getExercisesTotal(){
+        int exercisesTotal = 0;
+        for(ServerExerciseData exercise: exercises){
+            exercisesTotal += exercise.getTotalTests();
+        }
+
+        return exercisesTotal;
+    }
+}
diff --git a/src/plm/core/model/UserAbortException.java b/src/plm/core/model/UserAbortException.java
new file mode 100644
index 0000000..8d5d6df
--- /dev/null
+++ b/src/plm/core/model/UserAbortException.java
@@ -0,0 +1,15 @@
+package plm.core.model;
+
+
+/**
+ * Exception raised when the user cancels the "Quit" procedure.
+ */
+public class UserAbortException extends Exception {
+	private static final long serialVersionUID = 1L;
+	public UserAbortException(String msg) {
+		super(msg);
+	}
+	public UserAbortException(String msg, Exception ex) {
+		super(msg,ex);
+	}
+}
diff --git a/src/plm/core/model/lesson/AccessibleExercisesListener.java b/src/plm/core/model/lesson/AccessibleExercisesListener.java
new file mode 100644
index 0000000..d1c4357
--- /dev/null
+++ b/src/plm/core/model/lesson/AccessibleExercisesListener.java
@@ -0,0 +1,5 @@
+package plm.core.model.lesson;
+
+public interface AccessibleExercisesListener {
+	void accessibleExercisesChanged();
+}
diff --git a/src/plm/core/model/lesson/BrokenLessonException.java b/src/plm/core/model/lesson/BrokenLessonException.java
new file mode 100644
index 0000000..3efa093
--- /dev/null
+++ b/src/plm/core/model/lesson/BrokenLessonException.java
@@ -0,0 +1,11 @@
+package plm.core.model.lesson;
+
+public class BrokenLessonException extends RuntimeException {
+
+	public BrokenLessonException(String msg) {
+		super(msg);
+	}
+
+	private static final long serialVersionUID = 1L;
+
+}
diff --git a/src/plm/core/model/lesson/ExecutionProgress.java b/src/plm/core/model/lesson/ExecutionProgress.java
new file mode 100644
index 0000000..46da664
--- /dev/null
+++ b/src/plm/core/model/lesson/ExecutionProgress.java
@@ -0,0 +1,45 @@
+package plm.core.model.lesson;
+
+import java.util.Date;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+
+/** Class representing the result of pressing on the "run" button. Either a compilation error, or a percentage of passed/failed tests + a descriptive message */ 
+public class ExecutionProgress {
+	public String compilationError;
+	public int passedTests, totalTests=0;
+	public String details = "";
+	public Date date = new Date();
+	public ProgrammingLanguage language = Game.getProgrammingLanguage();
+
+	public static ExecutionProgress newCompilationError(String message) {
+		ExecutionProgress ep = new ExecutionProgress();
+		
+		ep.compilationError = message;
+		ep.passedTests = -1;
+		ep.totalTests = -1;
+		if (ep.compilationError == null)
+			ep.compilationError = "Unknown compilation error";
+		return ep;
+	}
+	public static ExecutionProgress newCompilationError(DiagnosticCollector<JavaFileObject> diagnostics) {
+		StringBuffer sb = new StringBuffer();
+		for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {			
+			sb.append(diagnostic.getSource().getName()+":"+diagnostic.getLineNumber()+":"+ diagnostic.getMessage(null));
+			sb.append("\n");
+		}
+		return newCompilationError(sb.toString());
+	}
+	
+	public void setCompilationError(String msg) {
+		compilationError = msg;
+		passedTests = -1;
+	}
+
+
+}
diff --git a/src/plm/core/model/lesson/Exercise.java b/src/plm/core/model/lesson/Exercise.java
new file mode 100644
index 0000000..aefc8b0
--- /dev/null
+++ b/src/plm/core/model/lesson/Exercise.java
@@ -0,0 +1,360 @@
+package plm.core.model.lesson;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.CompilerJava;
+import plm.core.CompilerScala;
+import plm.core.PLMCompilerException;
+import plm.core.model.Game;
+import plm.core.model.LogWriter;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.session.SourceFile;
+import plm.core.model.session.SourceFileRevertable;
+import plm.core.utils.FileUtils;
+import plm.universe.Entity;
+import plm.universe.World;
+
+
+public abstract class Exercise extends Lecture {
+	public static enum WorldKind {INITIAL,CURRENT, ANSWER}
+	public static enum StudentOrCorrection {STUDENT, CORRECTION}
+
+	protected String nameOfCorrectionEntity = getClass().getCanonicalName()+"Entity"; /* name of the entity class computing the answer. Don't change! */
+	protected String tabName = getClass().getSimpleName();/* Name of the tab in editor -- must be a valid java identifier */
+
+	
+	protected Map<ProgrammingLanguage, List<SourceFile>> sourceFiles= new HashMap<ProgrammingLanguage, List<SourceFile>>();
+	
+	public Map<String, Class<Object>> compiledClasses = new TreeMap<String, Class<Object>>(); /* list of entity classes defined in the lesson */
+
+	/* to make sure that the subsequent version of the same class have different names, in order to bypass the cache of the class loader */
+	private static final String packageNamePrefix = "plm.runtime";
+	private int packageNameSuffix = 0;
+
+	protected Vector<World> currentWorld; /* the one displayed */
+	protected Vector<World> initialWorld; /* the one used to reset the previous on each run */
+	protected Vector<World> answerWorld;  /* the one current should look like to pass the test */
+
+	protected Map<String, String> runtimePatterns = new TreeMap<String, String>();
+
+	public ExecutionProgress lastResult;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
+
+	public Exercise(Lesson lesson,String basename) {
+		super(lesson,basename);
+	}
+	
+	public void setupWorlds(World[] w) {
+		currentWorld = new Vector<World>(w.length);
+		initialWorld = new Vector<World>(w.length);
+		answerWorld  = new Vector<World>(w.length);
+		for (int i=0; i<w.length; i++) {
+			currentWorld.add( w[i].copy() );
+			initialWorld.add( w[i].copy() );
+			answerWorld. add( w[i].copy() );
+		}
+	}
+	
+	public abstract void run(List<Thread> runnerVect);	
+	public abstract void runDemo(List<Thread> runnerVect);	
+	
+	public void check() {
+		for (int i=0; i<currentWorld.size(); i++) {
+			currentWorld.get(i).notifyWorldUpdatesListeners();
+			
+			lastResult.totalTests++;
+
+			if (!currentWorld.get(i).equals(answerWorld.get(i))) {
+				String diff = answerWorld.get(i).diffTo(currentWorld.get(i));
+				lastResult.details += i18n.tr("The world ''{0}'' differs",currentWorld.get(i).getName());
+				if (diff != null) 
+					lastResult.details += ":\n"+diff;
+				lastResult.details += "\n";
+			} else {
+				lastResult.passedTests++;
+			}
+		}
+	}
+	/** Reset the current worlds to the state of the initial worlds */
+	public void reset() {
+		lastResult = new ExecutionProgress();
+
+		for (int i=0; i<initialWorld.size(); i++) 
+			currentWorld.get(i).reset(initialWorld.get(i));
+	}
+
+	/*
+	 * +++++++++++++++++++++++++
+	 * Compilation related stuff
+	 * +++++++++++++++++++++++++
+	 * 
+	 */
+	//TODO: why do we instantiate a compiler per exercise ? is there any way to re-use the same compiler. 
+	//TODO: I tried to put it as static, but of course strange behaviors happen afterwards
+	// Create a compiler of classes (using java 1.6)
+	private final CompilerJava compiler = new CompilerJava(Arrays.asList(new String[] { "-target", "1.6" }));
+
+
+	/**
+	 * Generate Java source from the user function
+	 * @param out 
+	 * 			where to display our errors
+	 * @param whatToCompile
+	 * 			either STUDENT's provided data or CORRECTION entity 
+	 * @throws PLMCompilerException 
+	 */
+	public void compileAll(LogWriter out, StudentOrCorrection whatToCompile) throws PLMCompilerException {
+		/* Make sure each run generate a new package to avoid that the loader cache prevent the reloading of the newly generated class */
+		packageNameSuffix++;
+		runtimePatterns.put("\\$package", "package "+packageName()+";");
+
+		/* Do the compile (but only if the current language is Java or Scala: scripts are not compiled of course)
+		 * Instead, scripting languages get the source code as text directly from the sourceFiles 
+		 */
+		if (Game.getProgrammingLanguage().equals(Game.JAVA)) {
+			/* Prepare the source files */
+			Map<String, String> sources = new TreeMap<String, String>();
+			if (sourceFiles.get(Game.JAVA) != null)
+				for (SourceFile sf: sourceFiles.get(Game.JAVA)) 
+					sources.put(className(sf.getName()), sf.getCompilableContent(runtimePatterns,whatToCompile)); 
+			
+			if (sources.isEmpty()) 
+				return;
+			
+			try {
+				DiagnosticCollector<JavaFileObject> errs = new DiagnosticCollector<JavaFileObject>();			
+				compiledClasses = compiler.compile(sources, errs);
+
+				if (out != null)
+					out.log(errs);
+			} catch (PLMCompilerException e) {
+				System.err.println(Game.i18n.tr("Compilation error:"));
+				if (out != null)
+					out.log(e.getDiagnostics());
+				lastResult = ExecutionProgress.newCompilationError(e.getDiagnostics());
+
+				if (Game.getInstance().isDebugEnabled() && sourceFiles.get(Game.JAVA) != null)
+					for (SourceFile sf: sourceFiles.get(Game.JAVA)) 
+						System.out.println("Source file "+sf.getName()+":"+sf.getCompilableContent(runtimePatterns,whatToCompile)); 
+
+				throw e;
+			}
+		} else if (Game.getProgrammingLanguage().equals(Game.SCALA)) {
+			List<SourceFile> sfs = sourceFiles.get(Game.SCALA);
+			if (sfs == null || sfs.isEmpty()) {
+				String msg = getName()+": No source to compile";
+				System.err.println(msg);
+				PLMCompilerException e = new PLMCompilerException(msg, null, null);
+				lastResult = ExecutionProgress.newCompilationError(e.getMessage());				
+				throw e;
+			}
+				
+			try {
+				CompilerScala.getInstance().reset();
+				for (SourceFile sf : sfs) 
+					CompilerScala.getInstance().compile(className(sf.getName()), sf.getCompilableContent(runtimePatterns,whatToCompile), sf.getOffset());
+			} catch (PLMCompilerException e) {
+				System.err.println(Game.i18n.tr("Compilation error:"));
+				System.err.println(e.getMessage());
+				lastResult = ExecutionProgress.newCompilationError(e.getMessage());
+				
+				throw e;
+			}
+		} 
+	}
+	
+	private String packageName(){
+		return packageNamePrefix + packageNameSuffix;
+	}
+	public String className(String name) {
+		return packageName() + "." + name;
+	}
+	/** get the list of source files for a given language, or create it if not existent yet */
+	protected List<SourceFile> getSourceFilesList(ProgrammingLanguage lang) {
+		List<SourceFile> res = sourceFiles.get(lang); 
+		if (res == null) {
+			res = new ArrayList<SourceFile>();
+			sourceFiles.put(lang, res);
+		}
+		return res;
+	}
+	public int getSourceFileCount(ProgrammingLanguage lang) {
+		return getSourceFilesList(lang).size();
+	}	
+	public SourceFile getSourceFile(ProgrammingLanguage lang, int i) {
+		return getSourceFilesList(lang).get(i);
+	}
+
+	public void newSource(ProgrammingLanguage lang, String name, String initialContent, String template,int offset,String correctionCtn) {
+		getSourceFilesList(lang).add(new SourceFileRevertable(name, initialContent, template, offset,correctionCtn));
+	}
+
+	public void mutateEntities(WorldKind kind, StudentOrCorrection whatToMutate) {
+		
+		String newClassName= (whatToMutate == StudentOrCorrection.STUDENT ? tabName : nameOfCorrectionEntity);
+		
+		ProgrammingLanguage lang = Game.getProgrammingLanguage();
+		Vector<World> worlds;
+		switch (kind) {
+		case INITIAL: worlds = initialWorld; break;
+		case CURRENT: worlds = currentWorld; break;
+		case ANSWER:  worlds = answerWorld;  break;
+		default: throw new RuntimeException("kind is invalid: "+kind);
+		}
+
+		/* Sanity check for broken lessons: the entity name must be a valid Java identifier */
+		if (Game.getProgrammingLanguage().equals(Game.JAVA)) {
+			String[] forbidden = new String[] {"'","\""};
+			for (String stringPattern : forbidden) {
+				Pattern pattern = Pattern.compile(stringPattern);
+				Matcher matcher = pattern.matcher(newClassName);
+
+				if (matcher.matches())
+					throw new RuntimeException(newClassName+" is not a valid java identifier (forbidden char: "+stringPattern+"). "+
+							"Does your exercise use a broken tabname or entityname?");
+			}
+		}
+
+		for (World current:worlds) {
+			ArrayList<Entity> newEntities = new ArrayList<Entity>();
+			for (Entity old : current.getEntities()) {
+				/* This is never called with lightbot entities, no need to deal with it here */
+				if (lang.equals(Game.JAVA) || lang.equals(Game.SCALA)) {
+					/* Instantiate a new entity of the new type */
+					Entity ent;
+					try {
+						if (lang.equals(Game.JAVA))
+							ent = (Entity) compiledClasses.get(className(newClassName)).newInstance();
+						else
+							ent = (Entity)CompilerScala.getInstance().findClass(className(newClassName)).newInstance();
+							
+					} catch (InstantiationException e) {
+						throw new RuntimeException("Cannot instanciate entity of type "+className(newClassName), e);
+					} catch (IllegalAccessException e) {
+						throw new RuntimeException("Illegal access while instanciating entity of type "+className(newClassName), e);
+					} catch (NullPointerException e) {
+						/* this kind of entity was not written by student. try to get it from default class loader, or complain if it also fails */
+						try {
+							ent = (Entity)compiler.loadClass(newClassName).newInstance(); 
+						} catch (Exception e2) {
+							throw new RuntimeException("Cannot find an entity of name "+className(newClassName)+" or "+newClassName+". Broken lesson.", e2);
+						}
+					}
+					/* change fields of new entity to copy old one */
+					ent.copy(old);
+					ent.initDone();
+					/* Add new entity to the to be returned entities set */
+					newEntities.add(ent);
+				} else { 
+					/* In scripting, we don't need to actually mutate the entity, just set the script to be interpreted later.
+					 * Also, since the classloader don't cross our way, don't mess with package names to force reloads. In other words, don't use className() in here!! 
+					 */	
+					
+					if (whatToMutate == StudentOrCorrection.STUDENT) {
+						boolean foundScript = false;
+
+						for (SourceFile sf : sourceFiles.get(lang)) {
+							if (newClassName.equals(sf.getName())) {
+								old.setScript(lang, sf.getCompilableContent(whatToMutate));
+								old.setScriptOffset(lang, sf.getOffset());
+								foundScript = true;
+							} 
+						}
+						if (!foundScript) {
+							StringBuffer sb = new StringBuffer();
+							for (SourceFile sf: sourceFiles.get(lang)) 
+								sb.append(sf.getName()+", ");
+
+							System.err.println(getClass().getName()+": Cannot retrieve the script for "+newClassName+". Known scripts: "+sb+"(EOL)");
+							throw new RuntimeException(getClass().getName()+": Cannot retrieve the script for "+newClassName+". Known scripts: "+sb+"(EOL)");						
+						}
+					} else { // whatToMutate == StudentOrCorrection.CORRECTION
+						for (World aw : worlds) {
+							for (Entity ent: aw.getEntities()) {
+								StringBuffer sb = null;
+								try {
+									sb = FileUtils.readContentAsText(nameOfCorrectionEntity, lang.getExt(), false);
+								} catch (IOException ex) {
+									throw new RuntimeException(Game.i18n.tr("Cannot compute the answer from file {0}.{1} since I cannot read it (error was: {2}).",nameOfCorrectionEntity,lang.getExt(),ex.getLocalizedMessage()));			
+								}
+
+
+								ent.setScript(lang, sb.toString());
+							}
+						}
+					}
+				}
+			}
+			if (lang.equals(Game.JAVA) || lang.equals(Game.SCALA)) 
+				current.setEntities(newEntities);
+		}
+	}
+			
+	public Vector<World> getWorlds(WorldKind kind) {
+		switch (kind) {
+		case INITIAL: return initialWorld;
+		case CURRENT: return currentWorld;
+		case ANSWER:  return answerWorld;
+		default: throw new RuntimeException("Unhandled kind of world: "+kind);
+		}
+	}
+	
+	public int getWorldCount() {
+		return this.initialWorld.size();
+	}
+	
+	/** Returns the current world number index 
+	 * @see #getAnswerOfWorld(int)
+	 */
+	public World getWorld(int index) {// FIXME: rename to getCurrentWorld or KILLME
+		return this.currentWorld.get(index);
+	}
+	
+	public int indexOfWorld(World w) {
+		int index = 0;
+		do {
+			if (this.currentWorld.get(index) == w)
+				return index;
+			index++;
+		} while (index < this.currentWorld.size());
+		
+		throw new RuntimeException("World not found (please report this bug)");
+	}
+	
+	public World getAnswerOfWorld(int index) { // FIXME: rename or KILLME
+		return this.answerWorld.get(index);
+	}
+	
+	public String toString() {
+		return getName();
+	}
+
+	/* setters and getter of the programming language that this exercise accepts */ 
+	private Set<ProgrammingLanguage> progLanguages = new HashSet<ProgrammingLanguage>();
+
+	public Set<ProgrammingLanguage> getProgLanguages() {
+		return progLanguages;
+	}
+	protected void addProgLanguage(ProgrammingLanguage newL) {
+		progLanguages.add(newL);
+	}
+}
+
diff --git a/src/plm/core/model/lesson/ExerciseTemplated.java b/src/plm/core/model/lesson/ExerciseTemplated.java
new file mode 100644
index 0000000..9059a7f
--- /dev/null
+++ b/src/plm/core/model/lesson/ExerciseTemplated.java
@@ -0,0 +1,462 @@
+package plm.core.model.lesson;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.session.SourceFile;
+import plm.core.utils.FileUtils;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Entity;
+import plm.universe.World;
+
+
+
+public abstract class ExerciseTemplated extends Exercise {
+
+	protected String worldFileName = getClass().getCanonicalName(); /* Name of the save files */
+
+	public ExerciseTemplated(Lesson lesson) {
+		super(lesson,null);
+	}
+	public ExerciseTemplated(Lesson lesson, String basename) {
+		super(lesson,basename);
+	}
+	
+	public void newSourceFromFile(ProgrammingLanguage lang, String name, String filename) throws NoSuchEntityException {
+		newSourceFromFile(lang, name, filename, "");
+	}
+	public void newSourceFromFile(ProgrammingLanguage lang, String name, String filename,String patternString) throws NoSuchEntityException {
+
+		String shownFilename =  filename.replaceAll("\\.", "/")+"."+lang.getExt();
+		StringBuffer sb = null;
+		try {
+			sb = FileUtils.readContentAsText(filename, lang.getExt(), false);
+		} catch (IOException ex) {
+			throw new NoSuchEntityException(Game.i18n.tr("Source file {0}.{1} not found.",filename.replaceAll("\\.","/"),lang.getExt()));			
+		}
+
+		String content;
+		if (lang.equals(Game.JAVA)) {
+			/* Remove line comments since at some point, we put everything on one line only, 
+			 * so this would comment the end of the template and break everything */
+			Pattern lineCommentPattern = Pattern.compile("//.*$", Pattern.MULTILINE);
+			Matcher lineCommentMatcher = lineCommentPattern.matcher(sb.toString());
+			content = lineCommentMatcher.replaceAll("");
+		} else {
+			content = sb.toString();
+		}
+
+		/* Extract the template, the initial content and the solution out of the file */
+		int state = 0;
+		int savedState = 0;
+		StringBuffer head = new StringBuffer(); /* before the template (state 0) */
+		StringBuffer templateHead = new StringBuffer(); /* in template before solution (state 1) */
+		StringBuffer solution = new StringBuffer(); /* the solution (state 2) */
+		StringBuffer templateTail = new StringBuffer(); /* in template after solution (state 3) */
+		StringBuffer tail = new StringBuffer("\n"); /* after the template (state 4) 
+		                                             *   This contains a preliminar \n to help python understanding that the following is not in the same block.
+		                                             *   Not doing Without it, we would have issues if the student puts some empty lines with the indentation marker at tail
+		                                             */
+		StringBuffer skel = new StringBuffer(); /* within BEGIN/END SKEL */
+		StringBuffer correction = new StringBuffer(); /* the unchanged content, but the package and className modification */
+
+		boolean seenTemplate=false; // whether B/E SOLUTION seems included within B/E TEMPLATE
+		for (String line : content.split("\n")) {
+			//if (this.debug)
+			//	System.out.println(state+"->"+line);
+			
+			switch (state) {
+			case 0: /* initial content */
+				if (line.contains("class ")) {
+					String modified = line.replaceAll("class \\S*", "class "+name);
+					head.append(modified);
+					correction.append(modified+"\n");
+				} else if (line.contains("package")) {
+					head.append("$package \n");	
+					correction.append("$package \n");
+				} else if (line.contains("BEGIN TEMPLATE")) {
+					correction.append(line+"\n");
+					seenTemplate = true;
+					state = 1;
+				} else if (line.contains("BEGIN SOLUTION")) {
+					correction.append(line+"\n");
+					state = 2; 
+				} else if (line.contains("BEGIN SKEL")) {
+					correction.append(line+"\n");
+					savedState = state;
+					state = 6; 
+				} else {
+					correction.append(line+"\n");
+					head.append(line+"\n");
+				}
+				break;
+			case 1: /* template head */
+				correction.append(line+"\n");
+				if (line.contains("BEGIN TEMPLATE")) {
+					System.out.println(i18n.tr("{0}: BEGIN TEMPLATE within the template. Please fix your entity.",shownFilename));
+					state = 4;
+				} else if (line.contains("public class "))
+					templateHead.append(line.replaceAll("public class \\S*", "public class "+name)+"\n");
+				else if (line.contains("END TEMPLATE")) {
+					state = 4;
+				} else if (line.contains("BEGIN SOLUTION")) {
+					state = 2; 
+				} else if (line.contains("BEGIN HIDDEN")) {
+					savedState = 1;
+					state = 5; 
+				} else if (line.contains("BEGIN SKEL")) {
+					savedState = state;
+					state = 6; 
+				} else {
+					templateHead.append(line+"\n");
+				}
+				break;
+			case 2: /* solution */
+				correction.append(line+"\n");
+				if (line.contains("END TEMPLATE")) {
+					System.out.println(i18n.tr("{0}: BEGIN SOLUTION is closed with END TEMPLATE. Please fix your entity.",shownFilename));
+					state = 4;
+				} else if (line.contains("END SOLUTION")) {
+					if (seenTemplate)
+						state = 3;  
+					else 
+						state = 4; // Jump directly to end of template
+				} else if (line.contains("BEGIN SKEL")) {
+					savedState = state;
+					state = 6; 
+				} else {
+					solution.append(line+"\n");
+				}
+				break;
+			case 3: /* template tail */
+				correction.append(line+"\n");
+				if (line.contains("END TEMPLATE")) {
+					if (!seenTemplate)
+						System.out.println(i18n.tr("{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity.",shownFilename));
+						
+					state = 4;
+				} else if (line.contains("BEGIN SOLUTION")) {
+					throw new RuntimeException(i18n.tr("{0}: Begin solution in template tail. Change it to BEGIN HIDDEN",shownFilename));
+				} else if (line.contains("BEGIN SKEL")) {
+					savedState = state;
+					state = 6; 
+				} else if (line.contains("BEGIN HIDDEN")) {
+					savedState = 3;
+					state = 5; 
+				} else {
+					templateTail.append(line+"\n");	
+				}
+				break;
+			case 4: /* end of file */
+				correction.append(line+"\n");
+				if (line.contains("BEGIN SKEL")) {
+					savedState = state;
+					state = 6; 
+
+				} else {
+					if (line.contains("END TEMPLATE"))  
+						if (!seenTemplate)
+							System.out.println(i18n.tr("{0}: END TEMPLATE with no matching BEGIN TEMPLATE. Please fix your entity.",shownFilename));
+					
+					tail.append(line+"\n");
+				}
+				break;
+			case 5: /* Hidden but not bodied */
+				correction.append(line+"\n");
+				if (line.contains("END HIDDEN")) {
+					state = savedState;
+				} 
+				break;
+			case 6: /* skeleton */
+				correction.append(line+"\n");
+				if (line.contains("END SKEL")) {
+					state = savedState;
+				} else {
+					skel.append(line+"\n");					
+				}
+				break;
+			default: 	
+				throw new RuntimeException(i18n.tr("Parser error in file {0}. This is a parser bug (state={1}), please report.",filename,state));	
+			}
+		}
+		if (state == 3) {
+			if (seenTemplate)
+				System.out.println(i18n.tr("{0}: End of file unexpected after the solution but within the template. Please fix your entity.",shownFilename,state));
+		} else if (state != 4)
+			System.out.println(i18n.tr("{0}: End of file unexpected (state: {1}). Did you forget to close your template or solution? Please fix your entity.",shownFilename,state));
+
+		String initialContent = templateHead.toString() + templateTail.toString();
+		String skelContent;
+		String headContent;
+		if (lang == Game.PYTHON || lang == Game.SCALA) { 
+			skelContent = skel.toString();
+			headContent = head.toString();
+		} else {
+			skelContent = skel.toString().replaceAll("\n", " ");
+			headContent = head.toString().replaceAll("\n", " ");
+		}
+
+		String template = (headContent+"$body"+tail);
+		int offset = headContent.split("\n").length;
+		
+		/* Remove the unnecessary leading spaces from the initial content */
+		Pattern newLinePattern = Pattern.compile("\n",Pattern.MULTILINE);
+		if (lang != Game.PYTHON) {
+			initialContent = initialContent.replaceAll("\t","    ");
+			String[] ctn = newLinePattern.split(initialContent);
+			/* Compute the minimal amount of leading spaces on all lines */
+			int minAmountOfLeadingSpace = -1;
+			for (String line:ctn) {
+				if (line.equals(""))
+					continue;
+				int len = 0;
+				for (char c:line.toCharArray())
+					if (c == ' ') {
+						len ++;
+					} else { 
+						break;
+					} 
+				if (minAmountOfLeadingSpace == -1 || len<minAmountOfLeadingSpace)
+					minAmountOfLeadingSpace = len;
+			}
+			if (minAmountOfLeadingSpace > 0) {
+				/* Remove that amount of leading spaces on all lines, and rebuilds initialContent */
+				StringBuffer sbCtn = new StringBuffer();
+				for (String line : ctn) 
+					if (line.equals(""))
+						sbCtn.append("\n");
+					else 
+						sbCtn.append(line.substring(minAmountOfLeadingSpace)+"\n");
+				/* Rebuild the initial content */
+				initialContent = sbCtn.toString();
+			}
+		}
+
+		/* remove any \n from template to not desynchronize line numbers between compiler and editor 
+		 * Python: We should obviously not change blank signs in Python
+		 * Scala: no need since our compiler's front-end is aware of these offsets */ 
+		if (lang == Game.JAVA) {
+			Matcher newLineMatcher = newLinePattern.matcher(template);
+			template = newLineMatcher.replaceAll(" ");
+		}
+
+		/* Apply all requested rewrites, if any */
+		if (patternString != null) {
+			Map<String, String> patterns = new HashMap<String, String>();
+			for (String pattern: patternString.split(";")) {
+				String[] parts = pattern.split("/");
+				if (parts.length != 1 || !parts[0].equals("")) {
+					if (parts.length != 3 || !parts[0].equals("s")) 
+						throw new RuntimeException("Malformed pattern for file "+name+": '"+ pattern+"' (from '"+patterns+"')");
+
+					if (Game.getInstance().isDebugEnabled())
+						System.out.println("Replace all "+parts[1]+" to "+parts[2]);
+					template = template.replaceAll(parts[1], parts[2]);
+					initialContent = initialContent.replaceAll(parts[1], parts[2]);
+					skelContent = skelContent.replaceAll(parts[1], parts[2]);
+				}
+			}
+
+		}
+
+		/*if (this.debug) {
+			System.out.println("<<<<<<<<template:"+template);
+			System.out.println("<<<<<<<<debugCtn:"+debugContent);
+			System.out.println("<<<<<<<<initialContent:"+initialContent);
+		    System.out.println("<<<<<<<<Skel: "+skelContent);
+		}*/
+		
+		if (skelContent.length()>0) {
+			if (! (this instanceof ExerciseTemplatingEntity)) 
+				throw new RuntimeException(getName()+": You provided an exercise skeleton, but this is not an ExerciseTemplatingEntity. Are you trying to drive me nuts??");
+			
+			/* 
+			 * HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
+			 *  
+			 * A skeleton was provided! this means that we are in a ExerciseTemplating, for sure. 
+			 * Use the skeleton as a template and correction; ExerciseTemplatingEntity::setup() will do the right thing.
+			 * 
+			 * FIXME: this is a particularly awful design, and I'm ashamed to commit this.
+			 *  
+			 * We should split this function in two parts, one (in charge of the parsing) would remain the same 
+			 * in ExerciseTemplated and ExerciseTemplatingEntity while the other (in charge of using the result of this parsing)
+			 * would be overridden in ExerciseTemplatingEntity.
+			 * 
+			 * As it is now (abusing some fields of the sourceFile structure to pass some values to ExerciseTemplatingEntity::setup), 
+			 * this's half-way between the uber-crude HACK and a plain old troll to object-orientation defenders... 
+			 * 
+			 * Polux would be proud of me. Or maybe not ;)
+			 * 
+			 * HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK 
+			 * 
+			 * See the comment at the beginning of  ExerciseTemplatingEntities for the motivation of this mess 
+			 * (TL;DR: entities in ExerciseTemplatingEntities are Frankenstein monsters built manually from scratch) 
+			 */
+			newSource(lang, name, initialContent, skelContent,offset,
+					/* correction: */ templateHead.toString()+solution.toString()+templateTail.toString());
+		} else {
+			newSource(lang, name, initialContent, template,offset,
+					correction.toString().replaceAll("SimpleBuggle","AbstractBuggle")); // We don't want to have little dialogs when testing
+		}
+	}
+
+	protected final void setup(World w) {
+		setup(new World[] {w});
+	}
+	protected void setup(World[] ws) {
+		boolean foundALanguage=false;
+		setupWorlds(ws);
+
+		for (ProgrammingLanguage lang: Game.getProgrammingLanguages()) {
+			boolean foundThisLanguage = false;
+			String searchedName = null;
+			for (SourceFile sf : getSourceFilesList(lang)) {
+				if (searchedName == null) {//lazy initialization if there is any sourcefile to parse
+					Pattern p = Pattern.compile(".*?([^.]*)$");
+					Matcher m = p.matcher(nameOfCorrectionEntity);
+					if (m.matches())
+						searchedName = m.group(1);
+					p = Pattern.compile("Entity$");
+					m = p.matcher(searchedName);
+					searchedName = m.replaceAll("");
+				}
+				if (Game.getInstance().isDebugEnabled())
+					System.out.println("Saw "+sf.getName()+" in "+lang.getLang()+", searched for "+searchedName+" or "+tabName+" while checking for the need of creating a new tab");
+				if (sf.getName().equals(searchedName)||sf.getName().equals(tabName))
+					foundThisLanguage=true;
+			}
+			if (!foundThisLanguage) {
+				try {
+					newSourceFromFile(lang, tabName, nameOfCorrectionEntity);
+					super.addProgLanguage(lang);
+					foundALanguage = true;
+					if (Game.getInstance().isDebugEnabled())
+						System.out.println("Found suitable templating entity "+nameOfCorrectionEntity+" in "+lang);
+
+				} catch (NoSuchEntityException e) {
+					if (lang.equals(Game.PYTHON) || lang.equals(Game.SCALA) || lang.equals(Game.JAVA)) 
+						System.out.println("No templating entity found: "+e);
+						
+					if (getProgLanguages().contains(lang)) 
+						throw new RuntimeException(
+								Game.i18n.tr("Exercise {0} is said to be compatible with language {1}, but there is no entity for this language: {2}",
+								getName(),lang,e.toString()));
+					/* Ok, this language does not work for this exercise but didn't promise anything. I can deal with it */
+				}
+			} else {
+				foundALanguage = true;
+			}
+		}
+		if (!foundALanguage) 
+			throw new RuntimeException(Game.i18n.tr("{0}: No entity found. You should fix your paths and such",getName()));
+				
+		computeAnswer();
+	}
+	
+	protected void computeAnswer() {
+		Thread t = new Thread() {
+			@Override
+			public void run() {
+				Game.getInstance().statusArgAdd(getClass().getSimpleName());
+				boolean allFound = true;
+				if (answerWorld.get(0).haveIO()) {
+					if (Game.getProperty(Game.PROP_ANSWER_CACHE, "true",true).equalsIgnoreCase("true")) {
+						Vector<World> newAnswer = new Vector<World>();
+						int rank = 0;
+						for (World aw:answerWorld) {
+							String name = worldFileName+"-answer"+(rank++);
+							try {
+								World nw = aw.readFromFile(name);
+								nw.setAnswerWorld();
+								newAnswer.add(nw);
+							} catch (BrokenWorldFileException bwfe) {
+								System.err.println(i18n.tr("World {0} is broken ({1}). Recompute all answer worlds.",name,bwfe.getLocalizedMessage()) );
+								allFound = false;
+								break;
+							} catch (IOException ioe) {
+								System.err.println(i18n.tr("IO exception while reading world {0} ({1}). Recompute all answer worlds.",name,ioe.getLocalizedMessage()));
+								allFound = false;
+								break;
+							}
+						}
+						if (allFound) {
+							answerWorld = newAnswer;
+							Game.getInstance().statusArgRemove(getClass().getSimpleName());
+							return;
+						}
+					} else {
+						System.out.println(i18n.tr("Recompute the answer of {0} despite the cache file, as requested by the property {1}",worldFileName,Game.PROP_ANSWER_CACHE));
+					}
+				}
+				
+				/* I/O didn't work. We have to load the files manually */
+				ExecutionProgress progress = new ExecutionProgress();
+				
+				mutateEntities(WorldKind.ANSWER, StudentOrCorrection.CORRECTION);
+
+				for (World aw : answerWorld) {
+					for (Entity ent: aw.getEntities()) 
+						ent.runIt(progress);
+					aw.setAnswerWorld();
+				}
+				
+				/* Try to write all files for next time */
+				if (answerWorld.get(0).haveIO()) {
+					int rank = 0;
+					for (World aw:answerWorld) {
+						String name = "src/"+worldFileName+"-answer"+(rank++);
+						name = name.replaceAll("\\.", "/") + ".map";
+						if (new File(name).getParentFile().canWrite()) {
+							try {
+								aw.writeToFile(new File(name));
+							} catch (Exception e) {
+								System.err.println(i18n.tr("Error while writing answer world of {0}:",name));
+								e.printStackTrace();
+							}
+						} else {
+							System.err.println(i18n.tr("Cannot write answer world of {0}. Please check the permissions.",name));
+						}
+					}
+				}
+				Game.getInstance().statusArgRemove(getClass().getSimpleName());
+			}
+		};
+		Game.addInitThread(t);
+		t.start();
+	}
+
+	@Override
+	public void run(List<Thread> runnerVect){
+		if (lastResult == null)
+			lastResult = new ExecutionProgress();
+		
+		mutateEntities(WorldKind.CURRENT, StudentOrCorrection.STUDENT);
+
+		for (World cw: getWorlds(WorldKind.CURRENT)) {
+			cw.doDelay();
+			cw.runEntities(runnerVect, lastResult);
+		}
+	}
+
+	@Override
+	public void runDemo(List<Thread> runnerVect){
+		ExecutionProgress ignored = new ExecutionProgress();
+		
+		for (int i=0; i<initialWorld.size(); i++) { 
+			answerWorld.get(i).reset(initialWorld.get(i));
+			answerWorld.get(i).doDelay();
+		}
+		mutateEntities(WorldKind.ANSWER, StudentOrCorrection.CORRECTION);
+
+		for (World aw:getWorlds(WorldKind.ANSWER))
+			aw.runEntities(runnerVect,ignored);
+	}
+}
diff --git a/src/plm/core/model/lesson/ExerciseTemplatingEntity.java b/src/plm/core/model/lesson/ExerciseTemplatingEntity.java
new file mode 100644
index 0000000..397a0e5
--- /dev/null
+++ b/src/plm/core/model/lesson/ExerciseTemplatingEntity.java
@@ -0,0 +1,136 @@
+package plm.core.model.lesson;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.session.SourceFile;
+import plm.universe.World;
+
+/** This class of Exercises are useful to merge the entity and world within the same class.
+ * #BatExercice is a known implementation 
+ *
+ * This class is full of crude hacks. All come from the fact that we want to merge the entity 
+ * and the exercise in the same class. We do so to avoid having too much files on disk. 
+ * Thanks to Java stupid idea preventing to have several public classes in the same file... 
+ * 
+ * Then we don't have any entity on disk and we build some from scratch when we need to 
+ * compile the student code. The exercise must then contain a BEGIN SKEL / END SKEL section 
+ * that we will use as entity content.
+ *  
+ * This injected part is always a method "void run(BatTest t)" that invokes the user provided method (that only the exercise knows) 
+ * with the right prototype (likewise). The values of parameters are taken from the test, and the the result is stored back in the test, too.
+ * 
+ * Example:
+ *  
+ *  // BEGIN SKEL 
+ *  public void run(BatTest t) {
+ *		t.setResult( sleepIn((Boolean)t.getParameter(0),(Boolean)t.getParameter(1)) );		
+ *	}
+ *	// END SKEL 
+ *
+ * Black magic is then at play to reconstruct the entity around this content. 
+ * The classical template (containing the user function prototype, parameters, 
+ * and eventually its body) is added to the mixture as initial student content.
+ * 
+ * The black magic darkens further when compiling the solution, in JUnit tests of Java compilation. 
+ * The content of the solution provided in the templating "entity" is then saved 
+ * during the parsing, specifically for that case, and readded to the entity we build for 
+ * the purpose of testing the compilation. This still constitutes a good test because we want to 
+ * see what happen if the student would have typed the correct solution, so here we are. 
+ * 
+ * Of course, this mess is not used to compute the answers of each tests at initialization. 
+ * Instead, we use the run(BatTest) directly in the ExerciseTemplatingEntity.
+ * 
+ * Python also takes an alternative approach when evaluating the student code: 
+ * the parameters of langTemplate are stored somewhere and reused directly in mutateEntity.
+ * The trick in this case is that the name of each BatTest is a valid chunk of python code. So, this works:
+ * 					engine.put("thetest",test);
+ *					engine.eval("thetest.setResult("+test.getName()+")");
+ * test.getName() will write the python code to evaluate the user function on the provided parameters, 
+ * and its return value is passed to the BatTest that was injected in the scripting world for that. 
+ *  
+ * This becomes particularly hairy for scala, that is both typed and compiled.  
+ * We would like to reuse the skeleton from Java so that the parameters are properly casted,
+ * but the syntax of type casting is very different in Scala and Java, so we provide the types to templateScala and it does the casting on its own. 
+ * The user function's template is provided to templateScala just as in Python. 
+ *  
+ * One limitation is that every such entity must be written in Java, but I can live with it for now.
+ */
+
+public abstract class ExerciseTemplatingEntity extends ExerciseTemplated {
+	protected Map<ProgrammingLanguage,String> corrections = new HashMap<ProgrammingLanguage, String>();
+	private boolean isSetup = false;
+	
+	public ExerciseTemplatingEntity(Lesson lesson) {
+		super(lesson);
+	}
+	protected void setup(World[] ws, String entName, String template) {
+		this.tabName=entName;
+		setupWorlds(ws);
+		
+		
+		try {
+			newSourceFromFile(Game.JAVA, entName, getClass().getCanonicalName());
+			addProgLanguage(Game.JAVA);
+		} catch (NoSuchEntityException e1) {
+			throw new RuntimeException("ExerciseTemplatingEntities must be templated in Java for now, and use langTemplate afterward. Sorry -- patch warmly welcome if you manage to improve that piece of mess.");
+		}
+		
+		SourceFile javaFile = sourceFiles.get(Game.JAVA).get(0);
+		
+		javaFile.setCorrection("$package "+template+" public void run(BatTest t) {\n"+javaFile.getTemplate()+"}\n"+javaFile.getCorrection()+" }");
+		javaFile.setTemplate("$package "+template+" "+javaFile.getTemplate()+" $body }");
+		//System.out.println("New template: "+sf.getTemplate());
+		
+		if (getProgLanguages().contains(Game.SCALA)) {
+			SourceFile scalaFile = sourceFiles.get(Game.SCALA).get(0);
+			String header = "$package\n"
+					+ "import plm.universe.bat.{BatEntity,BatWorld,BatTest}; \n"
+					+ "import plm.universe.World; \n"
+					+ "class "+entName+" extends BatEntity { ";
+			
+			scalaFile.setCorrection(header+scalaFile.getCorrection()+" }");
+			scalaFile.setTemplate(header+" "+javaFile.getTemplate()+" $body }");
+		}
+		
+		computeAnswer();
+		isSetup  = true;
+	}
+	protected void templatePython(String entName, String initialCode, String correction) {
+		/* The following test is intended to make sure that this function is called before setup() right above.
+		 * This is because setup() needs all programming languages to be declared when it runs */
+		if (isSetup)
+			throw new RuntimeException("The exercise "+getName()+" is already setup, too late to add a programming language template.");
+		if (this.getProgLanguages().contains(Game.PYTHON))
+			throw new RuntimeException("The exercise "+getName()+" has two Python templates. Please fix this bug.");
+		
+		newSource(Game.PYTHON, entName, initialCode, "$body",0,"");
+		corrections.put(Game.PYTHON, initialCode+correction);
+		addProgLanguage(Game.PYTHON);
+	}
+	protected void templateScala(String entName, String[] types, String initialCode, String correction) {
+		if (isSetup)
+			throw new RuntimeException("The exercise "+getName()+" is already setup, too late to add a programming language template.");
+		if (this.getProgLanguages().contains(Game.SCALA))
+			throw new RuntimeException("The exercise "+getName()+" has two Scala templates. Please fix this bug.");
+		
+		StringBuffer skeleton = new StringBuffer("   t.setResult( ");
+		skeleton.append(entName);
+		skeleton.append("( ");
+		for (int i=0;i<types.length;i++) {
+			if (i>0)
+				skeleton.append(", ");
+			skeleton.append("t.getParameter(");
+			skeleton.append(i);
+			skeleton.append(").asInstanceOf[");
+			skeleton.append(types[i]);
+			skeleton.append("]");
+		}
+		skeleton.append(") )");
+		
+		newSource(Game.SCALA, entName, initialCode, "$body",7,"\n   override def run(t: BatTest) {\n"+skeleton+"\n   }\n"+initialCode+correction);
+		addProgLanguage(Game.SCALA);
+	}
+}
diff --git a/src/plm/core/model/lesson/Lecture.java b/src/plm/core/model/lesson/Lecture.java
new file mode 100644
index 0000000..fbfa236
--- /dev/null
+++ b/src/plm/core/model/lesson/Lecture.java
@@ -0,0 +1,138 @@
+package plm.core.model.lesson;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.PlmHtmlEditorKit;
+import plm.core.utils.FileUtils;
+
+/** Represents an element of the pedagogic sequence, be it a lecture or 
+ * an exercise. A better name would be useful, but I feel limited in 
+ * English today. Sorry. */
+public abstract class Lecture {
+	private String localId; // lecture's identifier WITHIN THE LESSON 
+	private String id; // global lecture's identifier 
+	
+	public static final String HTMLTipHeader = "<head>\n"+
+			"  <meta content=\"text/html; charset=UTF-8\" />\n"+	
+			"  <style>\n"+
+			"    body { font-family: tahoma, \"Times New Roman\", serif; font-size:10px; margin:10px; }\n"+
+			"    code { background:#EEEEEE; }\n"+
+			"    pre { background: #EEEEEE;\n"+
+			"          margin: 5px;\n"+
+			"          padding: 6px;\n"+
+			"          border: 1px inset;\n"+
+			"          width: 400px;\n"+
+			"          overflow: auto;\n"+
+			"          text-align: left;\n"+
+			"          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"+
+			"   .comment { background:#EEEEEE;\n"+
+			"              font-family: \"Times New Roman\", serif;\n"+
+			"              color:#00AA00;\n"+
+			"              font-style: italic; }\n"+
+			"  </style>\n"+
+			"</head>\n";
+	private String name = "<no name>";                     /** indicate whether this Exercise was successfully done or not */
+	private String mission = "";                        /** The text to display to present the lesson */
+	private Lesson lesson;
+	
+	protected Map<String, String> tips = new HashMap<String, String>();
+	
+	public Lecture(Lesson lesson,String basename) {
+		this.lesson = lesson;
+		localId = (basename!=null?basename:getClass().getName());
+		id = lesson.getId()+"."+ getLocalId();
+		loadHTMLMission();
+	}
+	public String getId() {
+		return id;
+	}
+
+	public void setName(String n) {
+		name = n;
+	}
+	public String getName() {
+		return PlmHtmlEditorKit.filterHTML(name, false);
+	}
+
+	public Lesson getLesson() {
+		return this.lesson;
+	}
+
+
+	public String getMission(ProgrammingLanguage lang) {
+		String res = "<html><head>"+PlmHtmlEditorKit.getCSS()+"</head><body>"+PlmHtmlEditorKit.filterHTML(this.mission,Game.getInstance().isDebugEnabled())+"</body></html>";
+		return res;
+	}
+	public void setMission(String mission) {
+		this.mission=mission;
+	}
+	public String getTip(String tipsId) {
+		return this.tips.get(tipsId);
+	}
+
+	public void loadHTMLMission() {
+		String filename = getLocalId().replace('.',File.separatorChar);
+	
+		StringBuffer sb = null;
+		try {
+			sb = FileUtils.readContentAsText(filename, "html",true);
+		} catch (IOException ex) {
+			setMission(Game.i18n.tr("File {0}.html not found.",filename));
+			return;			
+		}
+		String str = sb.toString();
+	
+		/* search the mission name */
+		Pattern p =  Pattern.compile("<h[123]>([^<]*)<");
+		Matcher m = p.matcher(str);
+		if (!m.find())
+			System.out.println(Game.i18n.tr("Cannot find the name of mission in {0}.html",filename));
+		setName( m.group(1) );
+	
+		/* prepare the tips, if any */
+		Pattern p3 =  Pattern.compile("<div class=\"tip\" id=\"(tip-\\d+?)\" alt=\"([^\"]+?)\">(.*?)</div>",Pattern.MULTILINE|Pattern.DOTALL);
+		Matcher m3 = p3.matcher(str);
+		while (m3.find()) {	
+			tips.put("#"+m3.group(1), m3.group(3));
+		}
+		str = m3.replaceAll("<a href=\"#$1\">$2</a>");
+	
+		Pattern p4 =  Pattern.compile("<div class=\"tip\" id=\"(tip-\\d+?)\">(.*?)</div>",Pattern.MULTILINE|Pattern.DOTALL);
+		Matcher m4 = p4.matcher(str);
+		while (m4.find()) {	
+			tips.put("#"+m4.group(1), m4.group(2));
+		}		
+		str=m4.replaceAll("<a href=\"#$1\">Show Tip</a>");				
+	
+	
+		/* get the mission explanation */
+		setMission(str);
+	}
+
+	protected Vector<Lecture> dependingLectures = new Vector<Lecture>(); /* To display the graph */
+	private DefaultMutableTreeNode myNode;
+	public DefaultMutableTreeNode getNode() {
+		if (myNode == null) {
+			myNode = new DefaultMutableTreeNode(this);
+			for (Lecture l : dependingLectures)
+				myNode.add(l.getNode());
+		}
+		return myNode;
+	}
+	public Vector<Lecture> getDependingLectures() {
+		return dependingLectures;
+	}
+	public String getLocalId() {
+		return localId;
+	}
+}
diff --git a/src/plm/core/model/lesson/Lesson.java b/src/plm/core/model/lesson/Lesson.java
new file mode 100644
index 0000000..37cf649
--- /dev/null
+++ b/src/plm/core/model/lesson/Lesson.java
@@ -0,0 +1,173 @@
+package plm.core.model.lesson;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.utils.FileUtils;
+import plm.universe.BrokenWorldFileException;
+
+
+public abstract class Lesson {
+	private String name;
+	private String id;
+	protected String about = "(no information provided by the lesson)";
+	protected ArrayList<Lecture> lectures = new ArrayList<Lecture>();
+	
+	protected Vector<Lecture> rootLectures = new Vector<Lecture>(); /* To display the graph */
+	
+	protected Lecture currentExercise;
+	
+	final static String LessonHeader = "<head>\n" + "  <meta content=\"text/html; charset=UTF-8\" />\n"
+	+ "  <style>\n"
+	+ "    body { font-family: tahoma, \"Times New Roman\", serif; font-size:10px; margin:10px; }\n"
+	+ "    code { background:#EEEEEE; }\n" + "    pre { background: #EEEEEE;\n" + "          margin: 5px;\n"
+	+ "          padding: 6px;\n" + "          border: 1px inset;\n" + "          width: 640px;\n"
+	+ "          overflow: auto;\n" + "          text-align: left;\n"
+	+ "          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"
+	+ "   .comment { background:#EEEEEE;\n" + "              font-family: \"Times New Roman\", serif;\n"
+	+ "              color:#00AA00;\n" + "              font-style: italic; }\n" + "  </style>\n" + "</head>\n";
+
+	public Lesson() {
+		id = getClass().getCanonicalName().replaceAll(".Main$","");
+		id = id.replaceAll("^lessons.", "");
+		
+		try {
+			loadExercises();
+		} catch (IOException e) {
+			System.err.println("Cannot load the exercises. This lesson is severely broken..");
+			e.printStackTrace();
+		} catch (BrokenWorldFileException e) {
+			System.err.println("Cannot load the exercises. This lesson is severely broken..");
+			e.printStackTrace();
+		} 
+		for (ProgrammingLanguage lang: Game.programmingLanguages) {
+			int possible = 0;
+			int passed = 0;
+			for (Lecture l: lectures) {
+				if (l instanceof Exercise) {
+					Exercise exo = (Exercise) l;
+					if (exo.getProgLanguages().contains(lang)) {
+						possible++;
+						if (Game.getInstance().studentWork.getPassed(l, lang))
+							passed++;
+					}
+				}
+			}
+			Game.getInstance().studentWork.setPassedExercises(id, lang, passed);
+			Game.getInstance().studentWork.setPossibleExercises(id, lang, possible);
+		}
+	}
+	public String getId() {
+		return id;
+	}
+	
+	private boolean aboutLoaded = false;
+
+	public void resetAboutLoaded() {
+		this.aboutLoaded = false;
+	}
+	
+	private void loadAboutAndName() {
+		aboutLoaded = true;		/* read it */
+		String filename = getClass().getCanonicalName().replace('.',File.separatorChar);
+		StringBuffer sb = null;
+		try {
+			sb = FileUtils.readContentAsText(filename,"html",true);
+		} catch (IOException ex) {
+			about = Game.i18n.tr("File {0}.html not found.",filename);
+			name = filename;
+			return;
+		}
+		String str = sb.toString();
+		
+		/* search the mission name */
+		Pattern p =  Pattern.compile("<h[123]>([^<]*)<");
+		Matcher m = p.matcher(str);
+		if (!m.find())
+			System.out.println(Game.i18n.tr("Cannot find the name of mission in {0}.html",filename));
+		name = m.group(1);
+		/* get the mission explanation */
+		about = "<html>"+LessonHeader+"<body>\n"+str+"</body>\n</html>\n";		
+	}
+	public String getName() {
+		if (!aboutLoaded)
+			loadAboutAndName();
+		return this.name;
+	}
+	public String getAbout(){
+		if (!aboutLoaded) {
+			loadAboutAndName();
+		}
+		return about;
+	}
+
+	Lecture rootExo, lastAdded;
+	public Vector<Lecture> getRootLectures() {
+		return rootLectures;
+	}
+	public Lecture addExercise(Lecture exo) {
+		lectures.add(exo);		
+		rootLectures.add(exo);
+		if (rootExo == null) {
+			rootExo = exo;
+		}
+		lastAdded = exo;
+		return exo;
+	}
+	public Lecture addExercise(Lecture exo, Lecture previousExo) {
+		lectures.add(exo);
+		
+		if (rootExo == null) {
+			rootExo = exo;
+		}
+		lastAdded = exo;
+		previousExo.dependingLectures.add(exo);
+		return exo;
+	}
+	public Lecture getCurrentExercise() {
+		if (this.currentExercise == null && lectures.size() > 0) {
+			this.currentExercise = lectures.get(0);
+		}
+		if (currentExercise == null)
+			System.out.print("There is only "+lectures.size()+" lectures so far in the lesson "+getName());
+		return this.currentExercise;
+	}
+
+	abstract protected void loadExercises() throws IOException, BrokenWorldFileException;
+
+	public void setCurrentExercise(Lecture exo) {
+		this.currentExercise = exo;
+	}
+	public void setCurrentExercise(String exoName) {
+		setCurrentExercise(getExercise(exoName));
+	}
+	
+	public int exerciseCount() {
+		return this.lectures.size();
+	}
+
+	public List<Lecture> exercises() {
+		return this.lectures;
+	}
+	public Lecture getExercise(String name) {
+		String searchedName = getClass().getPackage().getName()+"."+name;
+		for (Lecture l: lectures) {
+			if (l.getClass().getCanonicalName().equals(searchedName) ||
+					l.getClass().getCanonicalName().equals(name)||
+					l.getId().equals(searchedName) || l.getId().equals(name)||
+					l.getLocalId().equals(searchedName) || l.getLocalId().equals(name))
+				return l;
+		}
+		return null;
+	}
+	public int getExerciseCount() {
+		return this.lectures.size();
+	}
+}
\ No newline at end of file
diff --git a/src/plm/core/model/lesson/NoSuchEntityException.java b/src/plm/core/model/lesson/NoSuchEntityException.java
new file mode 100644
index 0000000..44cbf41
--- /dev/null
+++ b/src/plm/core/model/lesson/NoSuchEntityException.java
@@ -0,0 +1,11 @@
+package plm.core.model.lesson;
+
+import plm.core.PLMException;
+
+public class NoSuchEntityException extends PLMException {
+	private static final long serialVersionUID = 1L;
+	
+	public NoSuchEntityException(String msg) {
+		super(msg);
+	}
+}
diff --git a/src/plm/core/model/lesson/package-info.java b/src/plm/core/model/lesson/package-info.java
new file mode 100644
index 0000000..e4a45bf
--- /dev/null
+++ b/src/plm/core/model/lesson/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Building bricks for exercises and lessons: 
+ *     storing students' code in memory and compiling it; grouping exercises together, 
+ *     providing templates to students
+ */
+package plm.core.model.lesson;
+
diff --git a/src/plm/core/model/package-info.java b/src/plm/core/model/package-info.java
new file mode 100644
index 0000000..5d02c14
--- /dev/null
+++ b/src/plm/core/model/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Model of the PLM core: Game singleton, ability to save student files, log stuff, etc. 
+ * 
+ *  <p>
+ */
+package plm.core.model;
\ No newline at end of file
diff --git a/src/plm/core/model/session/FileSessionKit.java b/src/plm/core/model/session/FileSessionKit.java
new file mode 100644
index 0000000..0a4c849
--- /dev/null
+++ b/src/plm/core/model/session/FileSessionKit.java
@@ -0,0 +1,209 @@
+package plm.core.model.session;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+
+/**
+ * Implementation of the {@link ISessionKit} saving the student data as a collection of 
+ * separated files. It is not used by default, and you have to edit the source to activate it.
+ *
+ */
+public class FileSessionKit /* FIXME implements ISessionKit  */ {
+
+	private Game game;
+
+	private static String HOME_DIR = System.getProperty("user.home");
+	private static String SEP = System.getProperty("file.separator");
+	private static File SAVE_DIR = new File(HOME_DIR + SEP + ".plm");
+
+	public FileSessionKit(Game game) {
+		this.game = game;
+	}
+
+	public void storeAll() {
+		if (!SAVE_DIR.exists())
+			if (! SAVE_DIR.mkdir()) {
+				Logger.log("FileSessionKit:store", "cannot create session store directory");
+			};
+
+			// File lessonDir;
+			File exerciseDir;
+			for (Lesson lesson : this.game.getLessons()) {
+
+				for (Lecture lecture : lesson.exercises()) {
+					if (lecture instanceof Exercise) {
+						Exercise exercise = (Exercise) lecture;
+						exerciseDir = new File(SAVE_DIR, exercise.getId());
+						if (!exerciseDir.exists())
+							if (! exerciseDir.mkdir()) 
+								Logger.log("FileSessionKit:store", "cannot remove "+exerciseDir+" directory");
+
+
+						// create file DONE if exercise has been successfully passed
+						for (ProgrammingLanguage lang: exercise.getProgLanguages()) {
+							File exerciseFile = new File(exerciseDir, "DONE."+lang.getExt());
+							if (Game.getInstance().studentWork.getPassed(exercise, lang)) {
+								if (!exerciseFile.exists()) {
+									try {
+										exerciseFile.createNewFile();
+									} catch (IOException e) {
+										e.printStackTrace();
+									}
+								}
+							} else {
+								if (exerciseFile.exists()) {
+									if (!exerciseFile.delete()) {
+										Logger.log("FileSessionKit:store", "cannot remove "+exerciseFile+" directory");
+									}
+								}
+							}
+						}
+
+						// save exercise body
+						for (ProgrammingLanguage lang:exercise.getProgLanguages()) 
+							for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
+								SourceFile sf = exercise.getSourceFile(lang,i);
+
+								if (!(sf instanceof SourceFileRevertable))
+									continue;
+
+								SourceFileRevertable srcFile = (SourceFileRevertable)sf;
+								File outputFile = new File(exerciseDir+"/"+lang, srcFile.getName());
+
+								if (srcFile.hasChanged()) {
+									BufferedWriter bw = null;
+									try {
+										bw = new BufferedWriter(new FileWriter(outputFile));
+										bw.write(srcFile.getBody());
+									} catch (IOException e) {
+										e.printStackTrace();
+									} finally {
+										try {
+											bw.close();
+										} catch (IOException e) {
+											e.printStackTrace();
+										}
+									}
+								} else {
+									if (outputFile.exists())
+										if (! outputFile.delete())
+											Logger.log("FileSessionKit:store", "cannot remove "+outputFile);
+								}
+							}
+					} // is exercise
+				} // end-for lecture
+			} // end-for lesson
+	}
+
+	public void loadAll() {
+		if (!SAVE_DIR.exists())
+			return;
+
+		// File lessonDir;
+		File exerciseDir;
+		for (Lesson lesson : this.game.getLessons()) {
+			for (Lecture lecture : lesson.exercises()) {
+				if (lecture instanceof Exercise) {
+					Exercise exercise = (Exercise) lecture;
+					exerciseDir = new File(SAVE_DIR, exercise.getId());
+					if (!exerciseDir.exists())
+						continue;
+
+
+					// load exercise body
+					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
+						File exerciseFile = new File(exerciseDir, "DONE"+lang.getExt());
+						if (exerciseFile.exists()) {
+							Game.getInstance().studentWork.setPassed(lecture, lang, true);
+						}
+						
+						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
+							SourceFile srcFile = exercise.getSourceFile(lang,i);
+
+							File of = new File(exerciseDir+"/"+lang, srcFile.getName());
+							if (!of.exists()) /* try to load using the old format (not specifying the programming language) */
+								of = new File(exerciseDir+"/"+lang, srcFile.getName());
+							if (of.exists()) {
+								BufferedReader br = null;
+								try {
+									br = new BufferedReader(new FileReader(of));
+									String s;
+									StringBuffer b = new StringBuffer();
+
+									while ((s = br.readLine()) != null) {
+										b.append(s);
+										b.append("\n");
+									}
+
+									srcFile.setBody(b.toString());
+								} catch (IOException e) {
+									e.printStackTrace();
+								} finally {
+									try {
+										br.close();
+									} catch (IOException e) {
+										e.printStackTrace();
+									}
+								}
+							}
+						}
+					}
+				} // is exercise
+			} // end-for lecture
+		} // end-for lesson
+	}
+
+	public void cleanUp() {
+		if (!SAVE_DIR.exists())
+			return;
+
+		File exerciseDir;
+		for (Lesson lesson : this.game.getLessons()) {
+			for (Lecture lecture : lesson.exercises()) {
+				if (lecture instanceof Exercise) {
+					Exercise exercise = (Exercise) lecture;
+					exerciseDir = new File(SAVE_DIR, exercise.getId());
+					if (!exerciseDir.exists())
+						continue;
+
+					File exerciseFile = new File(exerciseDir, "DONE");
+					if (exerciseFile.exists()) {
+						if (!exerciseFile.delete()) {
+							Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseFile);
+						};
+					}
+
+					for (ProgrammingLanguage lang:exercise.getProgLanguages()) 
+						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
+							SourceFile srcFile = exercise.getSourceFile(lang, i);
+
+							File of = new File(exerciseDir, srcFile.getName());
+							if (of.exists()) {
+								if (! of.delete()) {
+									Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseDir+"/"+srcFile.getName()+" directory");				
+								}
+							}
+						}
+
+					if (! exerciseDir.delete()) {
+						Logger.log("FileSessionKit:cleanUp", "cannot remove "+exerciseDir+" directory");					
+					}
+				} // is exercise
+			} // end-for lectures
+		} // end-for lesson
+		if (! SAVE_DIR.delete()) {
+			Logger.log("FileSessionKit:cleanup", "cannot remove session store directory");
+		}
+	}
+}
diff --git a/src/plm/core/model/session/ISessionKit.java b/src/plm/core/model/session/ISessionKit.java
new file mode 100644
index 0000000..48344d8
--- /dev/null
+++ b/src/plm/core/model/session/ISessionKit.java
@@ -0,0 +1,41 @@
+package plm.core.model.session;
+
+import java.io.File;
+
+import plm.core.model.UserAbortException;
+import plm.core.model.lesson.Lesson;
+
+/** 
+ * This interface is to be implemented by every session kits, aka mecanisms able to 
+ * save and restore the state of the code written by the students. 
+ * 
+ * For now, 2 sessions kits are implemented in PLM: {@link FileSessionKit} and {@link ZipSessionKit}. 
+ * The one used is hardcoded in the variable {@link plm.core.model.Game#sessionKit}. 
+ * There is no way to switch from the interface.
+ */
+public interface ISessionKit {
+
+	/** Saves the user content of all loaded lessons
+	 * 
+	 *  On error, the user is given an opportunity to cancel the procedure through a dialog window.
+	 */
+	public void storeAll(File path) throws UserAbortException;	
+
+	/** Loads saved user content for all loaded lessons */
+	public void loadAll(File path);
+	
+	/** Saves the user content of the specified lessons
+	 * 
+	 *  On error, the user is given an opportunity to cancel the procedure through a dialog window.
+	 */
+	public void storeLesson(File path, Lesson l) throws UserAbortException;
+	
+	/** Loads saved user content of the specified lessons */
+	public void loadLesson(File path, Lesson l);
+	
+	/** Removes all user content for all loaded lessons */
+	public void cleanAll(File path) ;
+	
+	/** Removes all user content for all loaded lessons */
+	public void cleanLesson(File path, Lesson l);
+}
diff --git a/src/plm/core/model/session/ISourceFileListener.java b/src/plm/core/model/session/ISourceFileListener.java
new file mode 100644
index 0000000..d909fca
--- /dev/null
+++ b/src/plm/core/model/session/ISourceFileListener.java
@@ -0,0 +1,9 @@
+package plm.core.model.session;
+
+public interface ISourceFileListener {
+
+	public void sourceFileContentHasChanged() ;
+
+	public void clear(); /* before removing it */
+	
+}
diff --git a/src/plm/core/model/session/SessionDB.java b/src/plm/core/model/session/SessionDB.java
new file mode 100644
index 0000000..a434468
--- /dev/null
+++ b/src/plm/core/model/session/SessionDB.java
@@ -0,0 +1,150 @@
+package plm.core.model.session;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Lecture;
+
+public class SessionDB {
+	private Map<String, Map<ProgrammingLanguage, Map<String, String>>> body = new HashMap<String, Map<ProgrammingLanguage,Map<String,String>>>(); 
+	private Map<String, Map<ProgrammingLanguage, Boolean>> passed = new HashMap<String, Map<ProgrammingLanguage,Boolean>>();
+	
+	/* Per lesson summary */
+	private Map<String, Map<ProgrammingLanguage, Integer>> passedExercises = new HashMap<String, Map<ProgrammingLanguage,Integer>>();
+	private Map<String, Map<ProgrammingLanguage, Integer>> possibleExercises = new HashMap<String, Map<ProgrammingLanguage,Integer>>();
+	
+	public void setBody(Lecture exo, ProgrammingLanguage lang, String sourceName, String _body) {
+		if (exo == null)
+			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Map<String, String>> bodyE = body.get(exo);
+		if (bodyE == null) {
+			bodyE = new HashMap<ProgrammingLanguage,Map<String, String>>();
+			body.put(exo.getId(), bodyE);
+		}
+		Map<String, String> bodyLEP = bodyE.get(lang);
+		if (bodyLEP == null) {
+			bodyLEP = new HashMap<String, String>();
+			bodyE.put(lang, bodyLEP);
+		}
+		
+		bodyLEP.put(sourceName, _body);
+	}
+	public String getBody(Lecture exo, ProgrammingLanguage lang, String sourceName) {
+		if (exo == null)
+			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Map<String, String>> bodyE = body.get(exo.getId());
+		if (bodyE == null) 
+			return null;
+		Map<String, String> bodyEP = bodyE.get(lang);
+		if (bodyEP == null)
+			return null;
+		return bodyEP.get(sourceName);
+	}
+
+
+	public void setPassed(Lecture exo, ProgrammingLanguage lang, boolean _passed) {
+		if (exo == null)
+			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+		
+		if (getPassed(exo, lang) == _passed)
+			return;
+		
+		setPassedExercises(exo.getLesson().getId(), lang, getPassedExercises(exo.getLesson().getId(), lang) + (_passed?1:-1));
+		
+		Map<ProgrammingLanguage, Boolean> passedE = passed.get(exo.getId());
+		if (passedE == null) {
+			passedE = new HashMap<ProgrammingLanguage, Boolean>();
+			passed.put(exo.getId(), passedE);
+		}
+		passedE.put(lang,_passed);		
+	}
+	
+	/** If the exercise was never attempted (not present in DB), it returns false */
+	public boolean getPassed(Lecture exo, ProgrammingLanguage lang) {
+		if (exo == null)
+			exo = Game.getInstance().getCurrentLesson().getCurrentExercise();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Boolean> passedE = passed.get(exo.getId());
+		if (passedE == null)
+			return false;
+		
+		Boolean res = passedE.get(lang);
+		if (res == null) 
+			return false;
+		return res;
+	}
+	public Integer getPossibleExercises(String lesson, ProgrammingLanguage lang) {
+		if (lesson == null)
+			lesson = Game.getInstance().getCurrentLesson().getId();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Integer> passedL = possibleExercises.get(lesson);
+		if (passedL == null)
+			return 0;
+		
+		Integer res = passedL.get(lang);
+		if (res == null) 
+			return 0;
+		return res;
+	}
+	public void setPassedExercises(String lesson, ProgrammingLanguage lang, int val) {
+		if (lesson == null)
+			lesson = Game.getInstance().getCurrentLesson().getId();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Integer> passedL = passedExercises.get(lesson);
+		if (passedL == null) {
+			passedL = new HashMap<ProgrammingLanguage, Integer>();
+			passedExercises.put(lesson, passedL);
+		}
+		
+		passedL.put(lang, val);
+	}
+	public void setPossibleExercises(String lesson, ProgrammingLanguage lang, int val) {
+		if (lesson == null)
+			lesson = Game.getInstance().getCurrentLesson().getId();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Integer> possibleL = possibleExercises.get(lesson);
+		if (possibleL == null) {
+			possibleL = new HashMap<ProgrammingLanguage, Integer>();
+			possibleExercises.put(lesson, possibleL);
+		}
+		
+		possibleL.put(lang,val);
+	}
+	public Integer getPassedExercises(String lesson, ProgrammingLanguage lang) {
+		if (lesson == null)
+			lesson = Game.getInstance().getCurrentLesson().getId();
+		if (lang == null)
+			lang = Game.getProgrammingLanguage();
+
+		Map<ProgrammingLanguage, Integer> passedL = passedExercises.get(lesson);
+		if (passedL == null)
+			return 0;
+		
+		Integer res = passedL.get(lang);
+		if (res == null) 
+			return 0;
+		return res;
+	}
+	public Set<String> getLessonsNames() {
+		return possibleExercises.keySet();
+	}
+}
diff --git a/src/plm/core/model/session/SourceFile.java b/src/plm/core/model/session/SourceFile.java
new file mode 100644
index 0000000..dcb9e93
--- /dev/null
+++ b/src/plm/core/model/session/SourceFile.java
@@ -0,0 +1,141 @@
+package plm.core.model.session;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.swing.JScrollPane;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise.StudentOrCorrection;
+import plm.core.ui.JavaEditorPanel;
+
+
+public class SourceFile {
+
+	protected String name;
+	private String template;
+	private String body;
+	private int offset;
+	private String correction;
+	private ISourceFileListener listener = null;
+
+	public SourceFile(String name, String initialBody, String template, int _offset, String _correctionCtn) {
+		this.name = name;
+		this.body = initialBody;
+		this.offset = _offset;
+		this.correction = _correctionCtn;
+		setTemplate( template );
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public String getBody() {
+		return this.body;
+	}
+
+	public void setBody(String text) {
+		this.body = text;
+		notifyListener();
+	}
+	public void setTemplate(String string) {
+		this.template = string;
+	}
+	public String getTemplate() {
+		return template;
+	}
+	public void setCorrection(String c) {
+		this.correction = c;
+	}
+	public String getCorrection() {
+		return this.correction;
+	}
+
+	public String getCompilableContent(StudentOrCorrection whatToRetrieve) {
+		return getCompilableContent(null,whatToRetrieve);
+	}
+
+	/**
+	 * Returns the source text that we should compile
+	 * @param runtimePatterns 
+	 * 			some last-minute replacement to do (such as package name adjustment)
+	 * @param whatKind
+	 * 			whether we want to retrieve the student-provided content or the correction
+	 * @return
+	 */
+	public String getCompilableContent(Map<String, String> runtimePatterns, StudentOrCorrection whatToRetrieve) {
+		String res;
+
+		if (whatToRetrieve == StudentOrCorrection.CORRECTION) {
+			res = correction;
+		} else if (template != null) {
+			res = template.replaceAll("\\$body", this.body+" \n");;			
+		} else {
+			res = this.body;
+		}
+		if (runtimePatterns != null)
+			for (Entry<String, String> pattern : runtimePatterns.entrySet()) {
+				res = res.replaceAll(pattern.getKey(), pattern.getValue());
+				// This is a trap to find issue #42 that I fail to reproduce
+				if (pattern.getValue().contains("\n")) { 
+					System.out.println("Damn! I integrated a pattern being more than one line long, line numbers will be wrong."
+							+"Please repport this bug (alongside with the following informations) as it will help us fixing our issue #42!");
+					System.out.println("pattern key: "+pattern.getKey());
+					System.out.println("pattern value: "+pattern.getValue());
+					System.out.println("Exercise: "+Game.getInstance().getCurrentLesson().getCurrentExercise().getName());
+					System.out.println("JLM version: "+Game.getProperty("plm.major.version","internal",false)+" ("+Game.getProperty("plm.major.version","internal",false)+"."+Game.getProperty("plm.minor.version","",false)+")");
+					System.out.println("Java version: "+System.getProperty("java.version")+" (VM version: "+ System.getProperty("java.vm.version")+")");
+					System.out.println("System: " +System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")");
+				}
+			}
+		return res.replaceAll("\\xa0", " "); // Kill those damn \160 chars, which are non-breaking spaces (got them from copy/pasting source examples?)
+	}
+
+	public void setListener(ISourceFileListener l) {
+		this.listener = l;
+	}
+
+	public void removeListener() {
+		this.listener = null;
+	}
+
+	public void notifyListener() {
+		if (this.listener != null)
+			this.listener.sourceFileContentHasChanged();
+	}
+
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + ((body == null) ? 0 : body.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final SourceFile other = (SourceFile) obj;
+		if (body == null) {
+			if (other.body != null)
+				return false;
+		} else if (!body.equals(other.body))
+			return false;
+		return true;
+	}
+
+	public JScrollPane getEditorPanel(ProgrammingLanguage lang) {
+		return new JavaEditorPanel(this, lang);
+	}
+
+	public int getOffset() {
+		return offset;
+	}
+}
diff --git a/src/plm/core/model/session/SourceFileRevertable.java b/src/plm/core/model/session/SourceFileRevertable.java
new file mode 100644
index 0000000..547cfbb
--- /dev/null
+++ b/src/plm/core/model/session/SourceFileRevertable.java
@@ -0,0 +1,48 @@
+package plm.core.model.session;
+
+public class SourceFileRevertable extends SourceFile {
+
+	private String initialBody; 
+	
+	public SourceFileRevertable(String name) {
+		this(name, "", null, 0,"");
+	}
+
+	public SourceFileRevertable(String name, String initialBody, String template, int offset, String correctionCtn) {
+		super(name, initialBody, template, offset,correctionCtn);
+		this.initialBody = initialBody;
+	}
+	
+	public void revert() {
+		setBody(this.initialBody);
+	}
+
+	public boolean hasChanged() {
+		return (! this.initialBody.equals(getBody()));
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = super.hashCode();
+		result = prime * result + ((initialBody == null) ? 0 : initialBody.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (!super.equals(obj))
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		SourceFileRevertable other = (SourceFileRevertable) obj;
+		if (initialBody == null) {
+			if (other.initialBody != null)
+				return false;
+		} else if (!initialBody.equals(other.initialBody))
+			return false;
+		return true;
+	}
+}
diff --git a/src/plm/core/model/session/ZipSessionKit.java b/src/plm/core/model/session/ZipSessionKit.java
new file mode 100644
index 0000000..d308da1
--- /dev/null
+++ b/src/plm/core/model/session/ZipSessionKit.java
@@ -0,0 +1,388 @@
+package plm.core.model.session;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import javax.swing.JOptionPane;
+
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.json.simple.parser.ParseException;
+
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.UserAbortException;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+
+/**
+ * Implementation of the {@link ISessionKit} saving the student data in a zip file.
+ * 
+ * Unless you edit the source, this is the session kit used.
+ */
+public class ZipSessionKit implements ISessionKit {
+
+	private Game game;
+	
+	public ZipSessionKit(Game game) {
+		this.game = game;
+	}
+
+	private File openSaveFile(File path, Lesson lesson) {
+		return new File(path, "plm-"+lesson.getId()+".zip");
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public void storeAll(File path) throws UserAbortException {
+		/* First save the bodies */
+		for (Lesson lesson : this.game.getLessons()) 
+			storeLesson(path, lesson);
+			
+		/* Save the per lesson summaries */
+		JSONObject allLessons = new JSONObject();
+		for (String lessonName : this.game.studentWork.getLessonsNames()) {
+			JSONObject allLangs = new JSONObject();
+			for (ProgrammingLanguage lang: Game.getProgrammingLanguages()) {
+				int possible = Game.getInstance().studentWork.getPossibleExercises(lessonName, lang);
+				int passed = Game.getInstance().studentWork.getPassedExercises(lessonName, lang);
+
+				if (possible>0) {
+					JSONObject oneLang = new JSONObject();
+					oneLang.put("possible",possible);
+					oneLang.put("passed",passed);
+					allLangs.put(lang.getLang(),oneLang);
+				}
+			}
+			if (allLangs.size()>0) 
+				allLessons.put(lessonName, allLangs);
+		}
+		//System.out.println("JSON written: "+allLessons.toJSONString());
+		
+
+		ZipOutputStream zos = null;
+		try {
+			zos = new ZipOutputStream(new FileOutputStream(new File(path, "overview.zip")));
+			zos.setMethod(ZipOutputStream.DEFLATED);
+			zos.setLevel(Deflater.BEST_COMPRESSION);
+
+			zos.putNextEntry(new ZipEntry("passed"));
+			zos.write(allLessons.toJSONString().getBytes());
+			zos.closeEntry();
+		} catch (IOException ex) { // FileNotFoundException or IOException
+			// It's ok to loose this data as it will be recomputed when the lessons are actually loaded
+
+		} finally {
+			try {
+				if (zos != null)
+					zos.close();
+			} catch (IOException ioe) {
+				ioe.printStackTrace();
+			}
+		}
+	}
+
+	@Override
+	public void loadAll(File path) {
+		/* First get the bodies */
+		for (Lesson lesson : this.game.getLessons())
+			loadLesson(path, lesson);
+		
+		/* Also get the per lesson summaries */
+		
+		// get the zip content
+		String content = null;
+		File file = new File(path, "overview.zip");
+		if (!file.exists())
+			return;
+		ZipFile zf = null;
+		BufferedReader br = null;
+		try {
+			zf = new ZipFile(file);
+			ZipEntry entry = zf.getEntry("passed");
+			if (entry == null) 
+				return;
+			
+			InputStream is = zf.getInputStream(entry);
+
+			br = new BufferedReader(new InputStreamReader(is));
+			String s;
+			StringBuffer b = new StringBuffer();
+
+			while ((s = br.readLine()) != null) 
+				b.append(s);
+
+			content = b.toString();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (zf != null)
+					zf.close();
+				if (br != null)
+					br.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		if (content == null)
+			return;
+		//System.out.println("JSON Read: "+content);
+		
+		// now parse it
+		Object value = null;
+		try {
+			value = JSONValue.parseWithException(content);
+		} catch (ParseException e) {
+			System.err.println("Parse error while reading the scores from disk:");
+			e.printStackTrace();
+		}
+		if (! (value instanceof JSONObject)) {
+			System.err.println("Retrieved passed-values is not a JSONObject: "+value);
+			return;
+		}
+		JSONObject allLessons = (JSONObject) value; 
+		for (Object lessonName: allLessons.keySet()) {
+			JSONObject allLangs = (JSONObject) allLessons.get(lessonName);
+			for (Object langName: allLangs.keySet()) {
+				ProgrammingLanguage lang = null;
+				for (ProgrammingLanguage l:Game.getProgrammingLanguages())
+					if (l.getLang().equals(langName))
+						lang = l;
+				
+				JSONObject oneLang = (JSONObject) allLangs.get(langName);
+				int possible = Integer.parseInt(""+oneLang.get("possible"));
+				int passed = Integer.parseInt(""+oneLang.get("passed"));
+				Game.getInstance().studentWork.setPossibleExercises((String) lessonName, lang, possible);
+				Game.getInstance().studentWork.setPassedExercises((String) lessonName, lang, passed);
+			}
+		}
+	}
+
+	@Override
+	public void cleanAll(File path) {
+		for (Lesson lesson : this.game.getLessons())
+			cleanLesson(path, lesson);
+	}
+
+	@Override
+	public void storeLesson(File path, Lesson lesson) throws UserAbortException {
+		File saveFile = openSaveFile(path, lesson);
+
+		if (!saveFile.exists()) {
+			File parentDirectory = saveFile.getParentFile().getAbsoluteFile();
+			if (!parentDirectory.exists()) {
+				if (!parentDirectory.mkdir()) {
+					throw new RuntimeException("cannot create session store directory '" + parentDirectory + "'");
+				}
+			}
+		}
+
+		ZipOutputStream zos = null;
+		boolean wroteSomething = false;
+		try {
+			zos = new ZipOutputStream(new FileOutputStream(saveFile));
+			zos.setMethod(ZipOutputStream.DEFLATED);
+			zos.setLevel(Deflater.BEST_COMPRESSION);
+
+			zos.putNextEntry(new ZipEntry("README"));
+			String text = "This file is a PLM session file. Please see http://www.loria.fr/~quinson/Teaching/PLM/ for more details";
+			zos.write(text.getBytes());
+			zos.closeEntry();
+			
+			for (Lecture lecture : lesson.exercises()) {
+				if (lecture instanceof Exercise) {
+					Exercise exercise = (Exercise) lecture;
+					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
+						// flag successfully passed exercise
+						if (Game.getInstance().studentWork.getPassed(exercise, lang)) {
+							ZipEntry ze = new ZipEntry(exercise.getId() + "/DONE."+lang.getExt());
+							zos.putNextEntry(ze);
+							byte[] bytes = new byte[1];
+							// bytes[0] = 'x';
+							zos.write(bytes);
+							zos.closeEntry();
+							wroteSomething  = true;
+						}
+
+					// save exercise body
+						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
+							SourceFile sf = exercise.getSourceFile(lang,i);
+
+							if (!(sf instanceof SourceFileRevertable))
+								continue;
+
+							SourceFileRevertable srcFile = (SourceFileRevertable) sf;
+
+							ZipEntry ze = new ZipEntry(lang+"/"+exercise.getId() + "/" + srcFile.getName());
+							zos.putNextEntry(ze);
+
+							String content = srcFile.getBody();
+
+							if (content.length() > 0 && content.charAt(content.length() - 1) != '\n') {
+								content = content + "\n";
+							}
+
+							byte[] bytes = srcFile.getBody().getBytes();
+							zos.write(bytes);
+							zos.closeEntry();
+							wroteSomething = true;
+						}
+					} // foreach lang
+				} // is exercise
+			} // end-for lecture
+			ZipEntry ze = new ZipEntry("currently_selected_exercise");
+			zos.putNextEntry(ze);
+			zos.write(lesson.getCurrentExercise().getClass().getCanonicalName().getBytes());
+			zos.closeEntry();
+
+		} catch (IOException ex) { // FileNotFoundException or IOException
+			// FIXME: should raise an exception and not show a dialog (it is not a UI class)
+			ex.printStackTrace();
+			Object[] options = { Game.i18n.tr("Ok, quit and lose my data"), Game.i18n.tr("Please stop! I'll save it myself first") };
+			int n = JOptionPane.showOptionDialog(null, Game.i18n.tr("PLM were unable to save your session file for lesson {0} ({1}:{2}).\n\n"
+					+ " Would you like proceed anyway (and lose any solution typed so far)?",
+					lesson.getName(),ex.getClass().getSimpleName(),ex.getLocalizedMessage()),
+					Game.i18n.tr("Your changes are NOT saved"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE,
+					null, options, options[1]);
+			if (n == 1) {
+				throw new UserAbortException(Game.i18n.tr("User aborted saving on system error"),ex);
+			}
+
+
+		} finally {
+			try {
+				if (zos != null && wroteSomething)
+					zos.close();
+			} catch (IOException ioe) {
+				ioe.printStackTrace();
+			}
+			if (!wroteSomething || saveFile.length() == 0)
+				saveFile.delete();
+		}
+	}
+
+	public void loadLesson(File path, Lesson lesson) {
+		File saveFile = openSaveFile(path, lesson);
+
+		if (!saveFile.exists() || saveFile.length()==0)
+			return;
+
+		ZipFile zf = null;
+		try {
+			zf = new ZipFile(saveFile);
+
+			for (Lecture lecture : lesson.exercises()) {
+				if (lecture instanceof Exercise) {
+					Exercise exercise = (Exercise) lecture;
+
+					for (ProgrammingLanguage lang:exercise.getProgLanguages()) {
+						ZipEntry entry = zf.getEntry(exercise.getId() + "/DONE."+lang.getExt());
+						if (entry != null) {
+							Game.getInstance().studentWork.setPassed(exercise, lang, true);
+						}
+
+						for (int i = 0; i < exercise.getSourceFileCount(lang); i++) {
+							SourceFile srcFile = exercise.getSourceFile(lang,i);
+
+							ZipEntry srcEntry = zf.getEntry(lang+"/"+exercise.getId() + "/" + srcFile.getName());
+							if (srcEntry == null) /* try to load using the old format (not specifying the programming language) */
+								srcEntry = zf.getEntry(exercise.getId() + "/" + srcFile.getName());
+
+							if (srcEntry != null) {
+								InputStream is = zf.getInputStream(srcEntry);
+
+								BufferedReader br = null;
+								try {
+									br = new BufferedReader(new InputStreamReader(is));
+
+									String s;
+									StringBuffer b = new StringBuffer();
+
+									while ((s = br.readLine()) != null) {
+										b.append(s);
+										b.append("\n");
+									}
+
+									srcFile.setBody(b.toString());
+								} catch (IOException e) {
+									e.printStackTrace();
+								} finally {
+									try {
+										br.close();
+									} catch (IOException e) {
+										e.printStackTrace();
+									}
+								}
+							}
+						}
+					} // foreach lang
+				} // is exercise
+			} // end-for lecture
+
+			/* Get the previously selected exercise */
+			ZipEntry entry = zf.getEntry("currently_selected_exercise");
+			if (entry != null) {
+				BufferedReader br = null;
+				try {
+					br = new BufferedReader(new InputStreamReader(zf.getInputStream(entry)));
+					String exoName = br.readLine();
+
+					lesson.setCurrentExercise(exoName);
+				} catch (IOException e) {
+					e.printStackTrace();
+				} finally {
+					try {
+						br.close();
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+				}
+			}
+			
+		} catch (IOException ex) { // ZipExecption or IOException
+			// FIXME: should raise an exception and not show a dialog (it is not a UI class)
+			ex.printStackTrace();
+			Object[] options = { Game.i18n.tr("Proceed"), Game.i18n.tr("Abort") };
+			int n = JOptionPane.showOptionDialog(null, Game.i18n.tr("PLM were unable to load your code for lesson {0} ({1}:{2}).\n\n"
+					+ " Would you like proceed anyway (and lose any solution typed previously)?",
+					lesson.getName(), ex.getClass().getSimpleName(), ex.getMessage()),
+					Game.i18n.tr("Error while loading your session"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE,
+					null, options, options[1]);
+			if (n == 1) {
+				System.err.println(Game.i18n.tr("Abording on user request"));
+				// should throw exception to calling method, no System.exit() here !!!
+				System.exit(1);
+			}
+		} finally {
+			try {
+				if (zf != null)
+					zf.close();
+			} catch (IOException ioe) {
+				ioe.printStackTrace();
+			}
+		}
+	}
+
+	@Override
+	public void cleanLesson(File path, Lesson lesson) {
+		File saveFile = openSaveFile(path, lesson);
+
+		if (saveFile.exists()) {
+			if (saveFile.delete()) {
+				Logger.log("ZipSessionKit:cleanup", "cannot remove session store directory");
+			}
+		}
+	}
+
+}
diff --git a/src/plm/core/model/session/package-info.java b/src/plm/core/model/session/package-info.java
new file mode 100644
index 0000000..efbf95d
--- /dev/null
+++ b/src/plm/core/model/session/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Interface and implementation of session management. 
+ * A session contains the code written by a student. 
+
+ * @author oster
+ *
+ */
+package plm.core.model.session;
diff --git a/src/plm/core/model/tracking/HeartBeatSpy.java b/src/plm/core/model/tracking/HeartBeatSpy.java
new file mode 100644
index 0000000..44103c6
--- /dev/null
+++ b/src/plm/core/model/tracking/HeartBeatSpy.java
@@ -0,0 +1,37 @@
+package plm.core.model.tracking;
+
+import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Class that report the heartbeat of the user
+ * Every minute, the presence of the user on the soft is sent to the server
+ * This allows to know who is still connected on a specific course on PLM
+ */
+public class HeartBeatSpy extends TimerTask{
+
+    private final static int timeOut = 60;
+    private Timer timer;
+    private ArrayList<ProgressSpyListener> spyListeners;
+
+    public HeartBeatSpy(ArrayList<ProgressSpyListener> spyListeners){
+        timer = new Timer();
+        timer.schedule(this, 0, timeOut * 1000);
+        this.spyListeners = spyListeners;
+    }
+
+    @Override
+    public void run() {
+        // Send a report to the server
+        for(ProgressSpyListener listener: spyListeners){
+            if(listener instanceof ServerSpy)
+                listener.heartbeat();
+        }
+    }
+
+    public void die(){
+        timer.cancel();
+    }
+
+}
diff --git a/src/plm/core/model/tracking/LocalFileSpy.java b/src/plm/core/model/tracking/LocalFileSpy.java
new file mode 100644
index 0000000..ea83129
--- /dev/null
+++ b/src/plm/core/model/tracking/LocalFileSpy.java
@@ -0,0 +1,65 @@
+package plm.core.model.tracking;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+
+/**
+ * Spy that registers events in a local file
+ */
+public class LocalFileSpy implements ProgressSpyListener {
+
+    private String username;
+    private String filePath;
+
+    public LocalFileSpy(File path) {
+        username = System.getenv("USER");
+        if (username == null)
+            username = System.getenv("USERNAME");
+        if (username == null)
+            username = "John Doe";
+
+        filePath = path.getAbsolutePath() + System.getProperty("file.separator")+ "progress.spy";
+    }
+
+    @Override
+    public void executed(Exercise exo) {
+        if (Game.getInstance().studentWork.getPassed(exo, exo.lastResult.language)) {
+            write(username + " solved " + exo.getName() + " in "
+                    + exo.lastResult.language + "!");
+        } else {
+            write(username + " failed " + exo.getName() + " in "
+                    + exo.lastResult.language + "!");
+        }
+    }
+
+    private void write(String msg) {
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
+        try {
+            BufferedWriter bw = new BufferedWriter(new FileWriter(filePath,
+                    true));
+            bw.write("[" + formatter.format(new java.util.Date()) + "] " + msg);
+            bw.newLine();
+            bw.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void switched(Exercise exo) {    /* i don't care, i'm a viking */ }
+
+    @Override
+    public void heartbeat() { /* don't talk to me */ }
+
+    @Override
+    public String join() { return ""; }
+
+    @Override
+    public void leave() { /* good idea, go away */ }
+}
diff --git a/src/plm/core/model/tracking/ProgressSpyListener.java b/src/plm/core/model/tracking/ProgressSpyListener.java
new file mode 100644
index 0000000..37e2437
--- /dev/null
+++ b/src/plm/core/model/tracking/ProgressSpyListener.java
@@ -0,0 +1,15 @@
+package plm.core.model.tracking;
+
+import plm.core.model.lesson.Exercise;
+
+public interface ProgressSpyListener {
+	public void executed(Exercise exo);
+
+    public void switched(Exercise exo);
+
+    public void heartbeat();
+
+    public String join();
+
+    public void leave();
+}
diff --git a/src/plm/core/model/tracking/ServerSpy.java b/src/plm/core/model/tracking/ServerSpy.java
new file mode 100644
index 0000000..093c2d9
--- /dev/null
+++ b/src/plm/core/model/tracking/ServerSpy.java
@@ -0,0 +1,119 @@
+package plm.core.model.tracking;
+
+import org.json.simple.JSONObject;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.model.lesson.Exercise;
+
+/**
+ * Abstract class to send users results to a server It constructs the request to
+ * send, you have to extend this class to indicate how/where to send the request
+ */
+public abstract class ServerSpy implements ProgressSpyListener {
+
+	protected String username;
+
+	public ServerSpy() {
+		username = System.getenv("USER");
+		if (username == null)
+			username = System.getenv("USERNAME");
+		if (username == null)
+			username = "John Doe";
+	}
+
+	/**
+	 * Receive an exercise progress from progressSpyListener, and construct the
+	 * request to send to a server in json
+	 * 
+	 * @param exo
+	 *            progress data
+	 */
+	@Override
+	public void executed(Exercise exo) {
+		JSONObject jsonObject = new JSONObject();
+
+		Game game = Game.getInstance();
+		ExecutionProgress lastResult = exo.lastResult;
+		String exoCode = exo.getSourceFile(lastResult.language, 0)
+				.getBody();
+
+		// Retrieve appropriate parameters regarding the current exercise
+		jsonObject.put("username", username);
+		jsonObject.put("course", game.getCourseID());
+        jsonObject.put("password", game.getCoursePassword());
+		jsonObject.put("exoname", exo.getName());
+		jsonObject.put("exolang", lastResult.language.toString());
+        // passedTests and totalTests are initialized at -1 and 0 in case of compilation error...
+		jsonObject.put("passedtests", lastResult.passedTests != -1 ? lastResult.passedTests + "" : 0 + "");
+		jsonObject.put("totaltests", lastResult.totalTests != 0 ? lastResult.totalTests + "" : 1 + "");
+		jsonObject.put("source", exoCode);
+		jsonObject.put("action", "execute");
+
+		sendRequest(jsonObject.toString());
+	}
+
+	@Override
+	public void switched(Exercise exo) {
+		JSONObject jsonObject = new JSONObject();
+
+		Game game = Game.getInstance();
+		ExecutionProgress lastResult = exo.lastResult;
+		// Retrieve appropriate parameters regarding the new exercise
+		jsonObject.put("username", username);
+		jsonObject.put("course", game.getCourseID());
+        jsonObject.put("password", game.getCoursePassword());
+		jsonObject.put("exoname", exo.getName());
+		jsonObject.put("exolang", lastResult != null ? lastResult.language.toString() : "");
+		jsonObject.put("action", "switch");
+
+		sendRequest(jsonObject.toString());
+	}
+
+	/**
+	 * Send a presence report to the server
+	 */
+	@Override
+	public void heartbeat() {
+		JSONObject jsonObject = new JSONObject();
+        Game game = Game.getInstance();
+		jsonObject.put("username", username);
+		jsonObject.put("action", "heartbeat");
+        jsonObject.put("course", game.getCourseID());
+        jsonObject.put("password", game.getCoursePassword());
+
+		sendRequest(jsonObject.toString());
+	}
+
+	@Override
+	public String join() {
+		JSONObject jsonObject = new JSONObject();
+        Game game = Game.getInstance();
+		jsonObject.put("username", username);
+		jsonObject.put("action", "join");
+        jsonObject.put("course", game.getCourseID());
+        jsonObject.put("password", game.getCoursePassword());
+
+        return sendRequest(jsonObject.toString());
+	}
+
+	@Override
+	public void leave() {
+		JSONObject jsonObject = new JSONObject();
+        Game game = Game.getInstance();
+		jsonObject.put("username", username);
+		jsonObject.put("action", "leave");
+        jsonObject.put("course", game.getCourseID());
+        jsonObject.put("password", game.getCoursePassword());
+
+		sendRequest(jsonObject.toString());
+	}
+
+	/**
+	 * Method to implement to indicate how/where to send data
+	 * 
+	 * @param request
+	 *            request in json to send to the server
+	 */
+	public abstract String sendRequest(String request);
+}
diff --git a/src/plm/core/model/tracking/ServerSpyAppEngine.java b/src/plm/core/model/tracking/ServerSpyAppEngine.java
new file mode 100644
index 0000000..1b080ea
--- /dev/null
+++ b/src/plm/core/model/tracking/ServerSpyAppEngine.java
@@ -0,0 +1,59 @@
+package plm.core.model.tracking;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import plm.core.model.Game;
+
+/**
+ * Implementation of the ServerSpy class, to indicate how/where to send json requests
+ * It opens a connection with an App Engine servlet, and send it the request
+ * It listens for answer from the server
+ */
+public class ServerSpyAppEngine extends ServerSpy {
+
+    private URL server;
+
+    public ServerSpyAppEngine() {
+        super();
+
+        try {
+            server = new URL(Game.getProperty(Game.PROP_APPENGINE_URL) + "/student");
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String sendRequest(String request) {
+        String response = "";
+        try {
+
+            // Send data
+            URLConnection conn = server.openConnection();
+            conn.setDoOutput(true);
+            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
+            wr.write(request);
+            wr.flush();
+
+            // Get response data and print it
+            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = br.readLine()) != null)
+                response += line;
+
+            wr.close();
+            br.close();
+
+        } catch (IOException e) {
+            System.out.println("Unable to contact PLMServer to send request " + request);
+        }
+
+        return response;
+    }
+
+}
diff --git a/src/plm/core/model/tracking/TwitterSpy.java b/src/plm/core/model/tracking/TwitterSpy.java
new file mode 100644
index 0000000..9d48638
--- /dev/null
+++ b/src/plm/core/model/tracking/TwitterSpy.java
@@ -0,0 +1,59 @@
+package plm.core.model.tracking;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import twitter4j.Status;
+import twitter4j.Twitter;
+import twitter4j.TwitterFactory;
+import twitter4j.conf.ConfigurationBuilder;
+
+public class TwitterSpy implements ProgressSpyListener {
+	private String username;
+	private Twitter twitter;
+
+	public TwitterSpy() {
+		username = System.getenv("USER");
+		if (username == null)
+			username = System.getenv("USERNAME");
+		if (username == null)
+			username = "John Doe";
+
+		ConfigurationBuilder cb = new ConfigurationBuilder();
+		cb.setDebugEnabled(true)
+		  .setOAuthConsumerKey(Game.getProperty("plm.oauth.consumerKey"))
+		  .setOAuthConsumerSecret(Game.getProperty("plm.oauth.consumerSecret"))
+		  .setOAuthAccessToken(Game.getProperty("plm.oauth.accessToken"))
+		  .setOAuthAccessTokenSecret(Game.getProperty("plm.oauth.tokenSecret"));
+		TwitterFactory tf = new TwitterFactory(cb.build());
+	    twitter = tf.getInstance();
+	}
+
+	@Override
+	public void executed(Exercise exo) {
+		if (Game.getInstance().studentWork.getPassed(exo, exo.lastResult.language)) {
+			try {
+				Status status = twitter.updateStatus(username+" solved "+exo.getName()+" in "+exo.lastResult.language+"!");
+				if (Game.getInstance().isDebugEnabled()) 
+					System.out.println("Twitted! Status: "+status.toString());
+			} catch (Exception e) {
+				// silently ignore network unavailability ;)
+				if (Game.getInstance().isDebugEnabled())
+					e.printStackTrace();
+			}
+		}
+	}
+
+    @Override
+    public void switched(Exercise exo) {    /* i don't care, i'm a viking */    }
+
+    @Override
+    public void heartbeat() {}
+
+    @Override
+    public String join() { return ""; }
+
+    @Override
+    public void leave() {
+    }
+
+}
diff --git a/src/plm/core/model/tracking/package-info.java b/src/plm/core/model/tracking/package-info.java
new file mode 100644
index 0000000..e08d7a7
--- /dev/null
+++ b/src/plm/core/model/tracking/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Track student activities.
+ * 
+ * @author oster
+ *
+ */
+package plm.core.model.tracking;
\ No newline at end of file
diff --git a/src/plm/core/package-info.java b/src/plm/core/package-info.java
new file mode 100644
index 0000000..839a9d5
--- /dev/null
+++ b/src/plm/core/package-info.java
@@ -0,0 +1,18 @@
+/**
+ * Basic PLM infrastructure: Data Model, User Interface, basic exercise building bricks.
+ * 
+ * <p>
+ * The classes defined directly in this package are stuff that were difficult 
+ * to sort properly somewhere. The main sub-packages are
+ * <ul>
+ *   <li>{@link plm.core.model} Model of the PLM core: Game singleton, ability to save student 
+ *                              files, log stuff, etc.</li>
+ *   <li>{@link plm.core.model.lesson} Building bricks for exercises and lessons: storing students'
+ *       code in memory and compiling it; grouping exercises together, providing templates to 
+ *       students</li>                            
+ *   <li>{@link plm.core.ui} User interface.</li>
+ *   <li>{@link plm.core.ui.action} The action listeners of the UI, calling the right functions 
+ *        of the game singleton.</li>
+ * </ul>
+ */
+package plm.core;
diff --git a/src/plm/core/ui/AboutLessonDialog.java b/src/plm/core/ui/AboutLessonDialog.java
new file mode 100644
index 0000000..0f5a91c
--- /dev/null
+++ b/src/plm/core/ui/AboutLessonDialog.java
@@ -0,0 +1,30 @@
+package plm.core.ui;
+
+import javax.swing.JFrame;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+
+
+public class AboutLessonDialog extends AbstractAboutDialog {
+
+	private static final long serialVersionUID = 1766486738385426108L;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public AboutLessonDialog(JFrame parent) {
+		super(parent);
+		currentLessonHasChanged();
+	}
+
+	@Override
+	public void currentLessonHasChanged() {
+		setTitle(i18n.tr("About lesson - ") + Game.getInstance().getCurrentLesson().getName());
+
+		area.setText(Game.getInstance().getCurrentLesson().getAbout());
+		area.setCaretPosition(0);
+	}
+
+}
diff --git a/src/plm/core/ui/AboutPLMDialog.java b/src/plm/core/ui/AboutPLMDialog.java
new file mode 100644
index 0000000..8d06191
--- /dev/null
+++ b/src/plm/core/ui/AboutPLMDialog.java
@@ -0,0 +1,88 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+
+public class AboutPLMDialog extends JDialog {
+
+	private static final long serialVersionUID = -1800747039420103759L;
+	private static AboutPLMDialog instance = null;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	
+	public static AboutPLMDialog getInstance() {
+		if (AboutPLMDialog.instance == null)
+			AboutPLMDialog.instance = new AboutPLMDialog();
+		return AboutPLMDialog.instance;
+	}
+	
+	private AboutPLMDialog() {
+		super(MainFrame.getInstance(), "About PLM", true);
+		this.setTitle(i18n.tr("About PLM dialogTitle"));
+		initComponent();
+	}
+	
+	
+	public void initComponent() {
+		
+		JPanel upperPane = new JPanel();
+		upperPane.setLayout(new BorderLayout());
+		JLabel icon = new JLabel(ResourcesCache.getIcon("img/BuggleQuestBack.png"));
+		upperPane.add(BorderLayout.NORTH, icon);
+		JLabel iconTitle = new JLabel(ResourcesCache.getIcon("img/BuggleQuestBETA.png"));
+		upperPane.add(BorderLayout.CENTER, iconTitle);
+		
+		JLabel text = new JLabel(
+				"<html>"+
+				"<h3 style=\"color:#666666;margin:0px;padding:0px;\">version "+Game.getProperty("plm.major.version","internal",false)+" "+
+				"<span style=\"font-size:8px; color:#AAAAAA;margin:0px;padding:0px;\">("+Game.getProperty("plm.major.version","internal",false)+"."+Game.getProperty("plm.minor.version","",false)+")</span>"+
+				"</h3>"+
+				"<br/>"+
+				"© 2008-2011 Contributors. All rights reserved.<br/>"+
+				"<ul style=\"margin-left:20px;\">" +
+				"<li>Original idea: <i>L. Turbak (Wellesley College)</i></li>"+
+				"<li>Design and code: <i>M. Quinson and G. Oster</i></li>"+
+				"<li>Tests: <i>esial students (class '11, '12, '13, '14)</i></li>"+
+				"</ul><br/>"+
+				"Your code is saved to "+Game.getSavingLocation()+"<br/>"+
+				"</html>"
+		);
+		text.setBackground(Color.white);
+		text.setOpaque(true);
+		upperPane.add(BorderLayout.SOUTH, text);
+		
+		JPanel pane = new JPanel();
+		pane.setLayout(new BorderLayout());
+		pane.add(BorderLayout.CENTER, upperPane);
+		
+		JButton close = new JButton(i18n.tr("Close"));
+		close.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				dispose();
+			}
+		});
+		pane.add(BorderLayout.SOUTH, close);
+		
+		setContentPane(pane);
+		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+		pack();
+		setResizable(false);
+				
+		setLocationRelativeTo(getParent());
+	}
+	
+}
diff --git a/src/plm/core/ui/AboutWorldDialog.java b/src/plm/core/ui/AboutWorldDialog.java
new file mode 100644
index 0000000..727aa93
--- /dev/null
+++ b/src/plm/core/ui/AboutWorldDialog.java
@@ -0,0 +1,48 @@
+package plm.core.ui;
+
+import javax.swing.JFrame;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.ProgLangChangesListener;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Exercise.WorldKind;
+
+
+public class AboutWorldDialog extends AbstractAboutDialog implements ProgLangChangesListener {
+
+	private static final long serialVersionUID = 1766486738385426108L;
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public AboutWorldDialog(JFrame parent) {
+		super(parent);
+		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
+		Game.getInstance().addProgLangListener(this);
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lecture) {
+		if (lecture instanceof Exercise) {
+			Exercise exo = (Exercise) lecture;
+			setTitle(i18n.tr("About world - {0}",
+					exo.getWorlds(WorldKind.CURRENT).get(0).getClass().getSimpleName()));
+			area.setText(exo.getWorlds(WorldKind.CURRENT).get(0).getAbout());
+			area.setCaretPosition(0);
+		} else {
+			// FIXME: should disable the entry menu when seing a lecture, and close any preexisting window when switching to a lecture
+			setVisible(false);
+		}
+	}
+
+	@Override
+	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
+		int pos = area.getCaretPosition();
+		area.setText(((Exercise) Game.getInstance().getCurrentLesson().getCurrentExercise()).getWorlds(WorldKind.CURRENT).get(0).getAbout());
+		area.setCaretPosition(pos);
+	}
+}
diff --git a/src/plm/core/ui/AbstractAboutDialog.java b/src/plm/core/ui/AbstractAboutDialog.java
new file mode 100644
index 0000000..381a94b
--- /dev/null
+++ b/src/plm/core/ui/AbstractAboutDialog.java
@@ -0,0 +1,48 @@
+package plm.core.ui;
+
+import java.awt.Dimension;
+
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+
+import plm.core.GameListener;
+import plm.core.model.Game;
+import plm.core.model.lesson.Lecture;
+import plm.universe.World;
+import net.miginfocom.swing.MigLayout;
+
+public abstract class AbstractAboutDialog extends JFrame implements GameListener {
+
+	private static final long serialVersionUID = -6550658679688214378L;
+	protected JEditorPane area = new JEditorPane("text/html","");
+	
+	protected AbstractAboutDialog(JFrame parent) {
+		super();
+		Game.getInstance().addGameListener(this);
+		
+		setResizable(true);
+		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+		setLocationRelativeTo(getParent());
+		
+		setMinimumSize(new Dimension(600,400));
+		
+		area.setEditorKit(new PlmHtmlEditorKit());
+		area.setEditable(false);
+		
+		setLayout(new MigLayout("fill"));
+		add(new JScrollPane(area),"grow");
+	}
+		
+	@Override
+	public void currentExerciseHasChanged(Lecture l)   { /* I dont care I'm a punk */ }
+	@Override
+	public void currentLessonHasChanged()              { /* I dont care I'm a punk */ }
+	@Override
+	public void selectedEntityHasChanged()             { /* I dont care I'm a punk */ }
+	@Override
+	public void selectedWorldHasChanged(World w)       { /* I dont care I'm a punk */ }
+	@Override
+	public void selectedWorldWasUpdated()              { /* I dont care I'm a punk */ }
+}
diff --git a/src/plm/core/ui/ChooseCourseDialog.java b/src/plm/core/ui/ChooseCourseDialog.java
new file mode 100644
index 0000000..a596f80
--- /dev/null
+++ b/src/plm/core/ui/ChooseCourseDialog.java
@@ -0,0 +1,216 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import plm.core.model.Course;
+import plm.core.model.CourseAppEngine;
+import plm.core.model.Game;
+import plm.core.model.ServerAnswer;
+import plm.core.model.tracking.HeartBeatSpy;
+import plm.core.model.tracking.ProgressSpyListener;
+import plm.core.model.tracking.ServerSpy;
+
+
+/**
+ * Dialog to allow students or teachers to select the current course
+ * It get the updated list of courses from the server, display it
+ * You have to enter the course password, and the admin password if you're teacher
+ */
+public class ChooseCourseDialog extends JDialog {
+
+    private static final long serialVersionUID = 2234402839093122248L;
+
+    protected ArrayList<String> courseListIDs;
+    protected JList jListID = new JList();
+    protected JButton OKButton;
+    protected JPasswordField passwordField;
+    protected JPasswordField teacherPasswordField;
+    
+    private boolean isChoosen;
+
+
+    public ChooseCourseDialog() {
+        super(MainFrame.getInstance(), "PLM Course", false);
+        isChoosen = false;
+
+        initComponent(this.getContentPane());
+
+        setMinimumSize(new Dimension(300, 400));
+        pack();
+
+        setLocationRelativeTo(getParent());
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(false);
+        //setVisible(true);
+    }
+
+    public void initComponent(Container c) {
+        c.setLayout(new BorderLayout());
+        c.add(new JLabel("Please select your course:", JLabel.CENTER), BorderLayout.NORTH);
+
+        // OK/Cancel button
+        OKButton = new JButton("OK");
+        OKButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                selectCourse();
+            }
+        });
+        OKButton.setEnabled(false);
+
+        JButton cancelButton = new JButton("Cancel");
+        cancelButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                setVisible(false);
+            }
+        });
+
+        JPanel bottomButtons = new JPanel();
+        bottomButtons.setLayout(new FlowLayout());
+        bottomButtons.add(cancelButton);
+        bottomButtons.add(OKButton);
+
+        c.add(bottomButtons, BorderLayout.SOUTH);
+
+        JPanel coursesPanel = new JPanel(new BorderLayout());
+
+        // Load the list of available "courses", or a message to say nope.
+        Course currentCourse = Game.getInstance().getCurrentCourse();
+        courseListIDs = currentCourse.getAllCoursesId();
+
+        if (courseListIDs.isEmpty()) {
+            coursesPanel.add(new JLabel("No course currently opened, sorry.", JLabel.CENTER), BorderLayout.CENTER);
+        } else {
+            jListID.setListData(courseListIDs.toArray());
+
+            jListID.setSelectedValue(currentCourse.getCourseId(), true);
+            if(!currentCourse.getCourseId().isEmpty())
+                OKButton.setEnabled(true);
+            jListID.addListSelectionListener(new ListSelectionListener() {
+                @Override
+                public void valueChanged(ListSelectionEvent listSelectionEvent) {
+                    OKButton.setEnabled(true);
+                    isChoosen = true;
+                }
+            });
+            jListID.addKeyListener(new KeyAdapter() {
+                @Override
+                public void keyReleased(KeyEvent e) {
+                    if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
+                        selectCourse();
+                }
+            });
+            coursesPanel.add(jListID, BorderLayout.CENTER);
+        }
+
+        // Password panel and field (for the student and for the teacher)
+        JPanel passwordsPanel = new JPanel(new BorderLayout()); // i hate swing...
+        JLabel passwordLabel = new JLabel("Course password: ");
+        passwordField = new JPasswordField(10);
+        passwordField.addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent e) {
+                if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
+                    selectCourse();
+            }
+        });
+        
+        JPanel passwordPanel = new JPanel(new FlowLayout());
+        passwordPanel.add(passwordLabel);
+        passwordPanel.add(passwordField);
+        passwordsPanel.add(passwordPanel, BorderLayout.NORTH);
+        
+        	//Teacher password field
+        if(Game.getProperty("plm.configuration.teacher").equals("true")) {
+            JLabel teacherPasswordLabel = new JLabel("Teacher password: ");
+            teacherPasswordField = new JPasswordField(10);
+            teacherPasswordField.addKeyListener(new KeyAdapter() {
+                @Override
+                public void keyPressed(KeyEvent e) {
+                    if(e.getKeyCode() == KeyEvent.VK_ENTER && isChoosen)
+                        selectCourse();
+                }
+            });
+            
+            JPanel teacherPasswordPanel = new JPanel(new FlowLayout());
+            teacherPasswordPanel.add(teacherPasswordLabel);
+            teacherPasswordPanel.add(teacherPasswordField);
+            passwordsPanel.add(teacherPasswordPanel, BorderLayout.SOUTH);
+        }
+
+        coursesPanel.add(passwordsPanel, BorderLayout.SOUTH);
+        c.add(coursesPanel, BorderLayout.CENTER);
+    }
+
+    /**
+     * Select a new course in the list
+     * if a course was already selected, send a leave and heartbeat die signal
+     * Launch new heartbeat and join events, change current course
+     */
+    public void selectCourse() {
+        Game game = Game.getInstance();
+
+        // leave the previous course and kill the heartbeat if existing
+        if (game.getHeartBeatSpy() != null)
+            game.getHeartBeatSpy().die();
+        if (game.getCourseID() != null && !game.getCourseID().isEmpty())
+            for (ProgressSpyListener spyListener : game.getProgressSpyListeners())
+                spyListener.leave();
+
+        // select the new course
+        String courseName = (jListID.getSelectedValue() != null) ? jListID.getSelectedValue().toString() : "";
+        String coursePass = (passwordField.getPassword() != null) ? new String(passwordField.getPassword()) : "";
+        
+        String teacherCoursePass =  "";
+        if (teacherPasswordField != null) {
+        	teacherCoursePass = (teacherPasswordField.getPassword() != null) ? new String(teacherPasswordField.getPassword()) : "";
+        }
+        		
+        Course course = new CourseAppEngine(courseName, coursePass);
+        course.setTeacherPassword(teacherCoursePass);
+        game.setCurrentCourse(course);
+
+        // report the user presence on the server and verify password
+        boolean passwordError = false;
+        for (ProgressSpyListener spyListener : game.getProgressSpyListeners()) {
+            String response = spyListener.join();
+            if (spyListener instanceof ServerSpy) {
+                if (ServerAnswer.values()[Integer.parseInt(response)] == ServerAnswer.WRONG_PASSWORD)
+                    passwordError = true;
+            }
+        }
+
+        if (passwordError) {
+            JOptionPane.showMessageDialog(getParent(), "Wrong module password", "Server error",
+                    JOptionPane.ERROR_MESSAGE);
+            game.getCurrentCourse().setCourseId(null);
+            MainFrame.getInstance().appendToTitle("");
+        } else {
+            // launch the heartbeat timertask and change window title
+            game.setHeartBeatSpy(new HeartBeatSpy(game.getProgressSpyListeners()));
+            MainFrame.getInstance().appendToTitle("[ " + jListID.getSelectedValue() + " ]");
+        }
+
+        setVisible(false);
+    }
+
+}
diff --git a/src/plm/core/ui/ChooseLectureDialog.java b/src/plm/core/ui/ChooseLectureDialog.java
new file mode 100644
index 0000000..63651aa
--- /dev/null
+++ b/src/plm/core/ui/ChooseLectureDialog.java
@@ -0,0 +1,92 @@
+package plm.core.ui;
+
+import java.awt.Component;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+
+public class ChooseLectureDialog implements TreeSelectionListener {
+	private JTree tree;
+
+	public ChooseLectureDialog() {
+		Lesson l = Game.getInstance().getCurrentLesson();
+		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
+		for (Lecture lect : l.getRootLectures()) 
+			root.add(lect.getNode());
+		
+		tree = new JTree(root);
+		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+		tree.setRootVisible(false);
+		tree.setShowsRootHandles(true);
+		tree.addTreeSelectionListener(this);
+		tree.setCellRenderer(new DefaultTreeCellRenderer() {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public Component getTreeCellRendererComponent(JTree tree, Object o,
+					boolean selected, boolean expanded, boolean leaf, int row,
+					boolean hasFocus) {
+				super.getTreeCellRendererComponent(tree, o, selected, expanded, leaf, row, hasFocus);
+				Object lect = ((DefaultMutableTreeNode)o).getUserObject();
+
+				ImageIcon icon = null;
+				if (lect instanceof Exercise) {
+					Exercise exo = (Exercise) lect;
+					icon = ResourcesCache.getStarredIcon(exo.getWorld(0).getIcon(), exo);
+				} else {
+					icon = ResourcesCache.getIcon("img/world_lesson.png");
+					if (lect != null && (! (lect instanceof Lecture))) // null may occur -- ignore but don't fail 
+						System.out.println("The exercise chooser contains something that is not a Lecture:"+lect.getClass().getName());
+				}
+				setIcon(icon);
+				return this;
+			}
+		});
+		
+		/* Build the selection */
+		tree.setExpandsSelectedPaths(true);
+		TreeNode[] nodes = l.getCurrentExercise().getNode().getPath();
+		TreePath path = new TreePath(nodes);
+        tree.scrollPathToVisible(path);
+		tree.setSelectionPath(path);
+		
+		JScrollPane jsp = new JScrollPane(tree);
+
+		JPanel p = new JPanel();
+		p.add(jsp);
+		int result = JOptionPane.showConfirmDialog(null, p, "Choose your next exercise",
+				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+		if (result == JOptionPane.OK_OPTION) {
+			DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
+			if (node != null) {
+				Object selection = node.getUserObject();
+
+				if (selection instanceof Lecture) 
+					Game.getInstance().setCurrentExercise((Lecture) selection);
+				else 
+					System.out.println("selection is not a lecture: "+selection);
+			}
+		}
+
+	}
+
+	@Override
+	public void valueChanged(TreeSelectionEvent e) {
+
+	}
+}
diff --git a/src/plm/core/ui/ChooseLessonDialog.java b/src/plm/core/ui/ChooseLessonDialog.java
new file mode 100644
index 0000000..ea425bc
--- /dev/null
+++ b/src/plm/core/ui/ChooseLessonDialog.java
@@ -0,0 +1,256 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JEditorPane;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+import plm.core.model.LessonLoadingException;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.utils.FileUtils;
+
+public class ChooseLessonDialog extends JFrame {
+	private static final long serialVersionUID = 1L;
+	I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public ChooseLessonDialog() {
+		super();
+		setTitle(i18n.tr("Choose your lesson"));
+		FileUtils.setLocale(this.getLocale());
+		initComponents(Game.getInstance());
+	}
+
+	private void initComponents(Game g) {
+		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
+
+		setBackground(Color.white);
+		setLayout(new BorderLayout());
+
+		JEditorPane blurb = new JEditorPane("text/html", "");
+		blurb.setEditable(false);
+		blurb.setEditorKit(new PlmHtmlEditorKit());
+		blurb.setText(i18n.tr("<table border=\"0\" align=\"center\"><tr>\n" +
+				"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n" +
+				"<td valign=\"center\">  <font size=\"+2\">Welcome to the Programmer's Learning Machine</font>  </td>\n" +
+				"<td valign=\"center\"><img src=\"img/world_buggle.png\" /></td>\n" +
+				"</tr></table>\n" +
+				"\n" +
+				"<p><font size=\"+1\">The PLM is a Learning Management System (LMS) aiming at teaching the art of computer " +
+				"programming through interactive exercises. It offers an extensive set of varied " +
+				"exercises, allowing you to practice at your own pace.</font></p><br/>"));
+
+		LessonOverview overview = new LessonOverview(this);
+		
+		LessonMatrix matrix = new LessonMatrix(overview, new String[][] { // WARNING, keep ExoTest.lessons synchronized
+				{"lessons/welcome", "lessons/maze", "lessons/turmites", "lessons/turtleart"},
+				{"lessons/sort", "lessons/sort/baseball", "lessons/sort/pancake"},
+				{"lessons/recursion", "lessons/recursion/hanoi" },
+				{"lessons/lightbot", "lessons/bat/string1" },
+		    }); 
+	
+
+		add(blurb,BorderLayout.NORTH);
+
+		JSplitPane mainPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
+
+		mainPane.setBackground(Color.white);
+		mainPane.setLeftComponent(matrix);
+		mainPane.setRightComponent(overview);
+		
+		add(mainPane, BorderLayout.CENTER);
+
+		pack();
+		setSize(750, 500);
+		setVisible(true);
+		setResizable(false);
+	}
+}
+
+
+class LessonMatrix extends JPanel {
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	private static final long serialVersionUID = 1L;
+
+	public LessonMatrix(LessonOverview overview, String[][] lessons) {
+		setBackground(Color.white);
+		GridBagLayout gl = new GridBagLayout(); 
+		setLayout(gl);
+		
+        GridBagConstraints c = new GridBagConstraints();
+        c.insets = new Insets(3, 3, 3, 3);
+        c.gridwidth = 1;
+
+        int maxCol=0;
+        for (int row = 0; row < lessons.length; row++) {
+        	for (int col=0; col < lessons[row].length; col++) {
+        		LessonButton btLesson = new LessonButton(overview, lessons[row][col]);
+        		
+        		c.gridy = row;
+        		c.gridx = col;
+        		gl.setConstraints(btLesson, c);
+        		add(btLesson);
+        	}
+        	if (row < lessons.length) {
+        		if (lessons[row].length>maxCol)
+        			maxCol = lessons[row].length-1;
+        	} else if (lessons[row].length>maxCol) // React correctly to when the last line is longer than the others
+    			maxCol = lessons[row].length;
+        }
+        /* add a load lesson button */
+        JButton btLoadLesson = new JButton();
+        btLoadLesson.setIcon(ResourcesCache.getIcon("img/bt-load-lesson.png")); 
+		btLoadLesson.setSize(50,50);
+		btLoadLesson.setBackground(Color.white);
+		btLoadLesson.addActionListener(new ActionListener() {
+			
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				JFileChooser fc = new JFileChooser();
+				fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("PLM lesson files"), "plm"));
+				fc.setDialogType(JFileChooser.OPEN_DIALOG);
+				fc.showOpenDialog(MainFrame.getInstance());
+				File selectedFile = fc.getSelectedFile();
+
+				try {
+					if (selectedFile != null)
+						Game.getInstance().loadLessonFromJAR(fc.getSelectedFile());
+				} catch (LessonLoadingException lle) {
+					JOptionPane.showMessageDialog(null, lle.getMessage(), i18n.tr("Error"), JOptionPane.ERROR_MESSAGE); 
+				}
+			}
+		});
+		c.gridy = lessons.length-1;
+		c.gridx = maxCol;
+		gl.setConstraints(btLoadLesson, c);
+		add(btLoadLesson);
+	}
+	
+}
+
+class LessonOverview extends JPanel {
+	private static final long serialVersionUID = 1L;
+	
+	private JButton btGo;
+	private String path;
+	private JEditorPane desc;
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public LessonOverview(final ChooseLessonDialog lc) {
+		setLayout(new BorderLayout());
+		
+		setBackground(Color.white);
+		desc = new JEditorPane("text/html", "");
+		desc.setEditable(false);
+		desc.setEditorKit(new PlmHtmlEditorKit());
+		desc.setText(i18n.tr("<h1>Please pick a lesson</h1>\n" +
+				"<p>Please click on an icon on the left to select a lesson.</p>\n" +
+				"<p>Lessons located above are generally simpler than the ones located below.</p>"));
+
+		JScrollPane descScrol = new JScrollPane(desc);
+		JPanel descPanel = new JPanel(new BorderLayout());
+		descPanel.add(descScrol,BorderLayout.CENTER);
+		descPanel.setBackground(Color.white);
+		descPanel.setSize(new Dimension(27, 15));
+		descPanel.doLayout();
+		add(descPanel,BorderLayout.CENTER);
+		
+		btGo = new JButton(i18n.tr("Go"));
+		btGo.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				Game.getInstance().switchLesson(path.replaceAll("/", "."),false);
+				MainFrame.getInstance().setVisible(true);
+				lc.dispose();
+			}
+		});
+		btGo.setEnabled(false);
+		
+        JPanel bottomButtons = new JPanel();
+        bottomButtons.setBackground(Color.white);
+        bottomButtons.setLayout(new FlowLayout());
+        bottomButtons.add(btGo);
+
+        add(bottomButtons,BorderLayout.SOUTH);
+	}
+	
+	public void setPath(String path) {
+		btGo.setEnabled(true);
+		btGo.requestFocusInWindow();
+		this.path = path;
+		
+		String filename = path.replace('.',File.separatorChar)+"/short_desc";
+		StringBuffer sb = null;
+		try {
+			sb = FileUtils.readContentAsText(filename, "html",true);
+		} catch (IOException ex) {
+			filename += ".html";
+			sb = new StringBuffer(i18n.tr("<p>(unable to display the short description of this lesson: file {0} not found)</p>",filename));
+		}
+
+		sb.append(i18n.tr("<p><b>Your score:</b> "));
+		String id = path.replaceAll("/", ".").replaceAll("^lessons\\.", "");
+		boolean foundOne = false;
+		for (ProgrammingLanguage lang:Game.programmingLanguages) {
+			int possible = Game.getInstance().studentWork.getPossibleExercises(id, lang);
+			int passed = Game.getInstance().studentWork.getPassedExercises(id, lang);
+			if (possible>0) {
+				if (lang == Game.LIGHTBOT) 
+					sb.append(" "+i18n.tr("{0} out of {1} exercises passed.",passed,possible));
+				else {
+					sb.append("<br/>");
+					sb.append("    <img src=\"img/lang_"+lang.getLang().toLowerCase()+".png\">  ");
+					sb.append(i18n.tr("{0} out of {1} exercises passed in {2}.",passed,possible,lang.getLang()));
+				}
+				foundOne = true;
+			}
+		}
+		if (!foundOne) 
+			sb.append(i18n.tr("You never attempted this lesson."));
+		sb.append("</p>");
+		
+		desc.setText(sb.toString());
+		desc.setCaretPosition(0);
+	}	
+}
+
+class LessonButton extends JButton {
+	private static final long serialVersionUID = 1L;
+
+	public LessonButton(final LessonOverview overview, final String path) {
+		super();
+		Icon icon = ResourcesCache.getIcon(path+"/icon.png"); 
+		setIcon(icon);
+		setSize(icon.getIconWidth(), icon.getIconHeight());
+		this.setBackground(Color.white);
+		addActionListener(new ActionListener() {
+			
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				overview.setPath(path);
+			}
+		});
+	}
+}
\ No newline at end of file
diff --git a/src/plm/core/ui/CreateCourseDialog.java b/src/plm/core/ui/CreateCourseDialog.java
new file mode 100644
index 0000000..eee4a88
--- /dev/null
+++ b/src/plm/core/ui/CreateCourseDialog.java
@@ -0,0 +1,166 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+import plm.core.model.Course;
+import plm.core.model.CourseAppEngine;
+import plm.core.model.Game;
+import plm.core.model.ServerAnswer;
+
+/**
+ * Dialog to create a course on the server, with a name, a user password and an administrator password
+ */
+public class CreateCourseDialog extends JDialog {
+
+	private static final long serialVersionUID = 2678745555760465778L;
+	
+	private Course course;
+    private JButton OKButton;
+    private JTextField nameField;
+    private JTextField passwordField;
+    private JTextField teacherPasswordField;
+
+    public CreateCourseDialog() {
+        super(MainFrame.getInstance(), "Add a course", false);
+
+        this.course = new CourseAppEngine();
+        initComponent();
+    }
+
+    public void initComponent() {
+        setLayout(new BorderLayout());
+
+        // OK and Cancel buttons
+
+        OKButton = new JButton("OK");
+        OKButton.setEnabled(false);
+        OKButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                createCourse();
+            }
+        });
+        this.add(OKButton);
+
+        JButton cancelButton = new JButton("Cancel");
+        cancelButton.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                setVisible(false);
+            }
+        });
+        this.add(cancelButton);
+
+        // labels describing fields
+        JLabel nameLabel = new JLabel("Name: ");
+        JLabel passwordLabel = new JLabel("Password (optionnal): ");
+        JLabel teacherPasswordLabel = new JLabel("Teacher password: ");
+
+        // fields where to enter data
+        nameField = new JTextField(10);
+        nameField.addKeyListener(new KeyAdapter() {
+
+            @Override
+            public void keyReleased(KeyEvent e) {
+            	boolean valid = !nameField.getText().isEmpty() && !teacherPasswordField.getText().isEmpty();
+            	
+                OKButton.setEnabled(valid);
+                
+                if(valid && e.getKeyCode() == KeyEvent.VK_ENTER)
+                    createCourse();
+            }
+        });
+
+        passwordField = new JPasswordField(10);
+
+        teacherPasswordField = new JPasswordField(10);
+        teacherPasswordField.addKeyListener(new KeyAdapter() {
+
+            @Override
+            public void keyReleased(KeyEvent e) {
+            	boolean valid = !nameField.getText().isEmpty() && !teacherPasswordField.getText().isEmpty();
+            	
+                OKButton.setEnabled(valid);
+
+                if(valid && e.getKeyCode() == KeyEvent.VK_ENTER)
+                    createCourse();
+            }
+        });
+
+        // panels to contain all those components
+
+        JPanel bottomButtons = new JPanel();
+        bottomButtons.setLayout(new FlowLayout());
+        bottomButtons.add(cancelButton);
+        bottomButtons.add(OKButton);
+
+        JPanel fieldsPanel = new JPanel();
+        fieldsPanel.setLayout(new BorderLayout());
+
+        JPanel namePanel = new JPanel();
+        namePanel.setLayout(new FlowLayout());
+        namePanel.add(nameLabel);
+        namePanel.add(nameField);
+        
+        JPanel passwordPanel = new JPanel();
+        passwordPanel.setLayout(new FlowLayout());
+        passwordPanel.add(passwordLabel);
+        passwordPanel.add(passwordField);
+
+        JPanel teacherPasswordPanel = new JPanel();
+        teacherPasswordPanel.setLayout(new FlowLayout());
+        teacherPasswordPanel.add(teacherPasswordLabel);
+        teacherPasswordPanel.add(teacherPasswordField);
+
+        fieldsPanel.add(namePanel, BorderLayout.NORTH);
+        fieldsPanel.add(passwordPanel, BorderLayout.CENTER);
+        fieldsPanel.add(teacherPasswordPanel, BorderLayout.SOUTH);
+
+        add(fieldsPanel, BorderLayout.CENTER);
+        add(bottomButtons, BorderLayout.SOUTH);
+
+        pack();
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(true);
+
+        setLocationRelativeTo(getParent());
+
+    }
+
+    /**
+     * Create a new course with given name, password and admin password, if name is not empty
+     * We considerate that a course can be created without any password
+     */
+    public void createCourse() {
+        if (!nameField.getText().isEmpty()) {
+            course.setCourseId(nameField.getText());
+            course.setPassword(passwordField.getText());
+            course.setTeacherPassword(teacherPasswordField.getText());
+            setVisible(false);
+
+            if (course.getCourseId() != null){
+                ServerAnswer answer = course.create();
+                if(answer == ServerAnswer.COURSE_NAME_ALREADY_USED)
+                    JOptionPane.showMessageDialog(getParent(), "Course name already used on the server", "Server error",
+                            JOptionPane.ERROR_MESSAGE);
+                else if(answer == ServerAnswer.ALL_IS_FINE){
+                    Game.getInstance().setCurrentCourse(course);
+                    MainFrame.getInstance().appendToTitle("[" + course.getCourseId() + "]");
+                }
+            }
+        }
+    }
+}
diff --git a/src/plm/core/ui/EntityCellRenderer.java b/src/plm/core/ui/EntityCellRenderer.java
new file mode 100644
index 0000000..8d952dc
--- /dev/null
+++ b/src/plm/core/ui/EntityCellRenderer.java
@@ -0,0 +1,44 @@
+package plm.core.ui;
+
+import java.awt.Component;
+
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+
+import plm.universe.Entity;
+
+
+public class EntityCellRenderer extends JLabel implements ListCellRenderer {
+
+	private static final long serialVersionUID = 5274134398293975047L;
+
+	public EntityCellRenderer() {
+		//setOpaque(true);
+	}
+
+	@Override
+	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+			boolean cellHasFocus) {
+
+		if (value instanceof Entity) {
+			Entity b = (Entity) value;
+			setText(b.getName());
+		} else {
+			setText(value!=null?value.toString():"");
+		}     
+       
+        if (isSelected) {
+            setBackground(list.getSelectionBackground());
+            setForeground(list.getSelectionForeground());
+        } else {
+            setBackground(list.getBackground());
+            setForeground(list.getForeground());
+        }
+        
+        setFont(list.getFont());
+        setOpaque(true);
+        return this;
+	}
+
+}
diff --git a/src/plm/core/ui/EntityComboListAdapter.java b/src/plm/core/ui/EntityComboListAdapter.java
new file mode 100644
index 0000000..f34ddda
--- /dev/null
+++ b/src/plm/core/ui/EntityComboListAdapter.java
@@ -0,0 +1,77 @@
+package plm.core.ui;
+
+import javax.swing.AbstractListModel;
+import javax.swing.ComboBoxModel;
+
+import plm.core.GameListener;
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.lesson.Lecture;
+import plm.universe.Entity;
+import plm.universe.World;
+
+
+public class EntityComboListAdapter extends AbstractListModel implements ComboBoxModel, GameListener {
+
+	private static final long serialVersionUID = -4602618861291726344L;
+	private Game game;
+	private World[] worlds;
+
+	public EntityComboListAdapter(Game game) {
+		this.game = game;
+		this.game.addGameListener(this);
+		this.worlds = this.game.getSelectedWorlds();
+	}
+
+	@Override
+	public Object getElementAt(int index) {
+		return this.worlds[0].getEntity(index);
+	}
+
+	@Override
+	public int getSize() {
+		return worlds==null || worlds[0]==null ? 0: this.worlds[0].getEntityCount();
+	}
+
+	@Override
+	public Object getSelectedItem() {
+		return this.game.getSelectedEntity();
+	}
+
+	@Override
+	public void setSelectedItem(Object anItem) {
+		if (anItem instanceof Entity) {
+			Entity e = (Entity) anItem;
+			this.game.setSelectedEntity(e);
+			this.worlds[0].setSelectedEntity(e);
+			/* Also inform the objective world that it was changed */
+			for (World w:worlds)
+				w.notifyWorldUpdatesListeners();
+		} else {
+			Logger.log("entityComboListAdapter:setSelectedItem", "parameter is not an entity");
+		}
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lect) { /* don't care */ }
+
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldHasChanged(World w) {
+		this.worlds = this.game.getSelectedWorlds();
+		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
+	}
+
+	@Override
+	public void selectedEntityHasChanged() {
+		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
+	}
+	
+	@Override
+	public void selectedWorldWasUpdated() {
+		fireContentsChanged(this, 0, this.worlds[0].getEntityCount() - 1);
+	}
+
+}
diff --git a/src/plm/core/ui/ExerciseFailedDialog.java b/src/plm/core/ui/ExerciseFailedDialog.java
new file mode 100644
index 0000000..f583e10
--- /dev/null
+++ b/src/plm/core/ui/ExerciseFailedDialog.java
@@ -0,0 +1,64 @@
+package plm.core.ui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.UIManager;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.lesson.ExecutionProgress;
+
+public class ExerciseFailedDialog extends JDialog {
+	private static final long serialVersionUID = 1L;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+
+	public ExerciseFailedDialog(ExecutionProgress ep) {
+		super(MainFrame.getInstance(), "Exercise failed /o\\", true);
+		
+		this.setTitle(i18n.tr("Exercise failed /o\\"));
+		
+		setLayout(new MigLayout("fill",""));
+		add(new JLabel( (Icon) UIManager.getLookAndFeelDefaults().get("OptionPane.errorIcon") ));
+		
+		JLabel msg;
+		JTextArea ta = new JTextArea();
+		ta.setEditable(false);
+		if (ep.compilationError == null) { 
+			msg = new JLabel(i18n.tr("You didn't manage to reach your objective." ));
+			ta.setText(ep.details);
+		} else {
+			msg = new JLabel( i18n.tr("Compilation error") );
+			ta.setText(ep.compilationError);
+		}
+		ta.setCaretPosition(0);
+		add(msg,"wrap");
+		add(new JScrollPane(ta),"spanx, grow, growprio 200, wrap");
+		
+		JButton close = new JButton(i18n.tr("Close"));
+		close.addActionListener(new ActionListener() {
+			
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				dispose();
+			}
+		});
+		add(close,"span, alignx 50%");
+		
+		
+		pack();
+		close.requestFocusInWindow();
+		setVisible(true);
+	}
+}
diff --git a/src/plm/core/ui/ExerciseView.java b/src/plm/core/ui/ExerciseView.java
new file mode 100644
index 0000000..c451ff1
--- /dev/null
+++ b/src/plm/core/ui/ExerciseView.java
@@ -0,0 +1,381 @@
+package plm.core.ui;
+
+import java.awt.AWTKeyStroke;
+import java.awt.KeyboardFocusManager;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.swing.BoundedRangeModel;
+import javax.swing.InputMap;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
+import javax.swing.KeyStroke;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+import net.miginfocom.swing.MigLayout;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.GameListener;
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Exercise.WorldKind;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
+
+
+public class ExerciseView extends JPanel implements GameListener {
+
+	private static final long serialVersionUID = 6649968807663790018L;
+	private Game game;
+	private WorldView worldView;
+	private WorldView objectivesView;
+
+	private JComboBox entityComboBox;
+	private JComboBox worldComboBox;
+	private EntityControlPanel buttonPanel;
+	private JTabbedPane tabPane;
+	private JPanel controlPane;
+	private JSlider speedSlider;
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public ExerciseView(Game game) {
+		super();
+		this.game = game;
+		this.game.addGameListener(this);
+		initComponents();
+		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
+	}
+
+	public void setEnabledControl(boolean enabled) {
+		if (buttonPanel != null)
+			buttonPanel.setEnabledControl(enabled);
+	}
+
+	public void initComponents() {	
+		JPanel upperPane = new JPanel();
+		
+		// TODO: add key shortcuts
+				
+		upperPane.setLayout(new MigLayout("insets 0 0 0 0,wrap","[fill]"));
+
+		worldComboBox = new JComboBox(new WorldComboListAdapter(Game.getInstance()));
+		worldComboBox.setRenderer(new WorldCellRenderer());
+		worldComboBox.setEditable(false);
+		worldComboBox.setToolTipText(i18n.tr("Switch the displayed world"));
+		upperPane.add(worldComboBox, "growx");
+
+		// TODO: logarithmic slider ?
+		speedSlider = new JSlider(new DelayBoundedRangeModel(Game.getInstance()));
+		speedSlider.setOrientation(JSlider.HORIZONTAL);
+		speedSlider.setMajorTickSpacing(50);
+		speedSlider.setMinorTickSpacing(10);
+		speedSlider.setPaintTicks(true);
+		speedSlider.setPaintLabels(true);
+		speedSlider.setToolTipText(i18n.tr("Change the speed of execution"));
+		upperPane.add(speedSlider, "growx");
+
+		tabPane = new JTabbedPane();
+		removeControlPage(tabPane);
+		if (Game.getInstance().getSelectedWorld() != null) {
+			worldView = Game.getInstance().getSelectedWorld().getView();
+			tabPane.addTab(i18n.tr("World")+worldView.getTabName(), null, worldView, 
+					i18n.tr("Current world")+worldView.getTip());
+		}
+		if (Game.getInstance().getAnswerOfSelectedWorld() != null) {
+			objectivesView = Game.getInstance().getAnswerOfSelectedWorld().getView();
+			tabPane.addTab(i18n.tr("Objective")+objectivesView.getTabName(), null, objectivesView, 
+					i18n.tr("Target world")+objectivesView.getTip());
+		}
+		
+		upperPane.add(tabPane, "grow 100 100,push");
+
+		entityComboBox = new JComboBox(new EntityComboListAdapter(Game.getInstance()));
+		entityComboBox.setRenderer(new EntityCellRenderer());
+		entityComboBox.setEditable(false);
+		entityComboBox.setToolTipText(i18n.tr("Switch the entity"));
+		upperPane.add(entityComboBox, "alignx center");
+
+		/*
+		 * FIXME: strange behavior on OSX, if you click on long time on the
+		 * selected entity item then it tries to edit it and throw an exception.
+		 * Even if the editable property is set to false
+		 */
+
+		
+		controlPane = new JPanel();
+		controlPane.setLayout(new MigLayout("insets 0 0 0 0, fill"));
+		if (Game.getInstance().getSelectedWorld()!=null) {
+			buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
+			controlPane.add(buttonPanel, "grow");
+		}
+		//add(controlPane, "span,growx,wrap");
+		
+		
+		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperPane, controlPane);
+		splitPane.setBorder(null);
+		splitPane.setOneTouchExpandable(true);
+		splitPane.setResizeWeight(1.0);
+		splitPane.setDividerLocation(420);
+		
+		this.setLayout(new MigLayout("insets 0 0 0 0, fill"));
+		this.add(splitPane, "grow");
+		
+		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
+		worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);
+		entityComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).getEntityCount() > 1); 
+	}
+
+	public void selectObjectivePane() {
+		tabPane.setSelectedIndex(1);
+	}
+
+	public void selectWorldPane() {
+		tabPane.setSelectedIndex(0);
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lect) {
+		if (worldComboBox != null)
+			worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);
+	}
+
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldHasChanged(World newWorld) {
+		if (worldView != null && worldView.isWorldCompatible(this.game.getSelectedWorld())) {
+			worldView.setWorld(this.game.getSelectedWorld());
+			objectivesView.setWorld(this.game.getAnswerOfSelectedWorld());
+		} else {
+			tabPane.removeAll();
+			worldView = Game.getInstance().getSelectedWorld().getView();
+			tabPane.addTab(i18n.tr("World")+worldView.getTabName(), null, worldView, 
+					i18n.tr("Current world")+worldView.getTip());
+			objectivesView = Game.getInstance().getAnswerOfSelectedWorld().getView();
+			tabPane.addTab(i18n.tr("Objective")+objectivesView.getTabName(), null, objectivesView, 
+					i18n.tr("Target world")+objectivesView.getTip());
+		}
+		// To refresh the controlPane in any case ( else the SortingWorldPanel is not refreshed )
+		controlPane.removeAll();
+		buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
+		controlPane.add(buttonPanel, "grow");
+		
+		Lecture lect = this.game.getCurrentLesson().getCurrentExercise();
+		entityComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorlds(WorldKind.CURRENT).get(0).getEntityCount() > 1); 
+		worldComboBox.setVisible(lect instanceof Exercise && ((Exercise) lect).getWorldCount() > 1);		
+	}
+
+	// To refresh the controlPane in the BDR & BDR2 exercise from welcome
+	@Override
+	public void selectedEntityHasChanged() { 
+		controlPane.removeAll();
+		buttonPanel = Game.getInstance().getSelectedWorld().getEntityControlPanel();
+		controlPane.add(buttonPanel, "grow");
+	}
+
+	@Override
+	public void selectedWorldWasUpdated() { /* don't care */ }
+	
+	 private static void removeControlPage(JComponent comp)
+	  {
+	    KeyStroke ctrlTab = KeyStroke.getKeyStroke("ctrl TAB");
+	    KeyStroke ctrlShiftTab = KeyStroke.getKeyStroke("ctrl shift TAB");
+	 
+	    // Remove ctrl-tab from normal focus traversal
+	    Set<AWTKeyStroke> forwardKeys = new HashSet<AWTKeyStroke>(comp.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
+	    forwardKeys.remove(ctrlTab);
+	    comp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
+	 
+	    // Remove ctrl-shift-tab from normal focus traversal
+	    Set<AWTKeyStroke> backwardKeys = new HashSet<AWTKeyStroke>(comp.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
+	    backwardKeys.remove(ctrlShiftTab);
+	    comp.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys);
+	 
+	    // Add keys to the tab's input map
+	    InputMap inputMap = comp.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+	    inputMap.put(ctrlTab, "navigateNext");
+	    inputMap.put(ctrlShiftTab, "navigatePrevious");
+	  }
+
+	public JTabbedPane getTabPane() {
+		return tabPane;
+	}
+	 
+}
+
+class DelayBoundedRangeModel implements BoundedRangeModel, GameListener {
+
+	public static int MIN_DELAY = 0;
+	public static int DEFAULT_DELAY = 100;
+	public static int MAX_DELAY = 500;
+
+	protected EventListenerList listenerList = new EventListenerList();
+	protected transient ChangeEvent changeEvent = null;
+
+	private int extent = 0;
+	private int min = MIN_DELAY;
+	private int max = MAX_DELAY;
+	private boolean isAdjusting = false;
+
+	private Game game;
+
+	public DelayBoundedRangeModel(Game game) {
+		this.game = game;
+		this.game.addGameListener(this);
+	}
+
+	@Override
+	public int getMaximum() {
+		return this.max;
+	}
+
+	@Override
+	public void setMaximum(int newMaximum) {
+		this.max = newMaximum;
+	}
+
+	@Override
+	public int getMinimum() {
+		return this.min;
+	}
+
+	@Override
+	public void setMinimum(int newMinimum) {
+		this.min = newMinimum;
+	}
+
+	@Override
+	public int getValue() {
+		return game.getSelectedWorld() == null? 0: game.getSelectedWorld().getDelay();
+	}
+
+	@Override
+	public void setValue(int n) {
+		if (game.getSelectedWorld() != null) {
+			n = Math.min(n, Integer.MAX_VALUE - extent);
+
+			int newValue = Math.max(n, min);
+			if (newValue + extent > max) {
+				newValue = max - extent;
+			}
+			setRangeProperties(newValue, extent, min, max, isAdjusting);
+		}
+	}
+
+	@Override
+	public boolean getValueIsAdjusting() {
+		return isAdjusting;
+	}
+
+	@Override
+	public void setValueIsAdjusting(boolean b) {
+		setRangeProperties(game.getSelectedWorld().getDelay(), extent, min, max, b);
+	}
+
+	@Override
+	public int getExtent() {
+		return this.extent;
+	}
+
+	@Override
+	public void setExtent(int n) {
+        int newExtent = Math.max(0, n);
+        int value = game.getSelectedWorld().getDelay();
+        if(value + newExtent > max) {
+            newExtent = max - value;
+        }
+        setRangeProperties(value, newExtent, min, max, isAdjusting);
+	}
+
+	@Override
+	public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) {
+		if (newMin > newMax) {
+			newMin = newMax;
+		}
+		if (newValue > newMax) {
+			newMax = newValue;
+		}
+		if (newValue < newMin) {
+			newMin = newValue;
+		}
+
+		/*
+		 * Convert the addends to long so that extent can be Integer.MAX_VALUE
+		 * without rolling over the sum. A JCK test covers this, see bug
+		 * 4097718.
+		 */
+		if (((long) newExtent + (long) newValue) > newMax) {
+			newExtent = newMax - newValue;
+		}
+
+		if (newExtent < 0) {
+			newExtent = 0;
+		}
+
+		boolean isChange = (newValue != game.getSelectedWorld().getDelay()) || (newExtent != extent)
+				|| (newMin != min) || (newMax != max) || (adjusting != isAdjusting);
+
+		if (isChange) {
+			for (World w:game.getSelectedWorlds())
+				w.setDelay(newValue);
+			extent = newExtent;
+			min = newMin;
+			max = newMax;
+			isAdjusting = adjusting;
+
+			fireStateChanged();
+		}
+	}
+
+	@Override
+	public void addChangeListener(ChangeListener x) {
+		listenerList.add(ChangeListener.class, x);
+	}
+
+	@Override
+	public void removeChangeListener(ChangeListener x) {
+		listenerList.remove(ChangeListener.class, x);
+	}
+
+	protected void fireStateChanged() {
+		Object[] listeners = listenerList.getListenerList();
+		for (int i = listeners.length - 2; i >= 0; i -= 2) {
+			if (listeners[i] == ChangeListener.class) {
+				if (changeEvent == null) {
+					changeEvent = new ChangeEvent(this);
+				}
+				((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
+			}
+		}
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lect) { /* don't care */ }
+
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldHasChanged(World w) {
+		fireStateChanged();
+	}
+
+	@Override
+	public void selectedEntityHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldWasUpdated() {
+		fireStateChanged();
+	}
+}
diff --git a/src/plm/core/ui/FeedbackDialog.java b/src/plm/core/ui/FeedbackDialog.java
new file mode 100644
index 0000000..9e7bba6
--- /dev/null
+++ b/src/plm/core/ui/FeedbackDialog.java
@@ -0,0 +1,180 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ScrollPaneConstants;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+
+public class FeedbackDialog extends JDialog {
+
+	private static final long serialVersionUID = 0;
+	private static FeedbackDialog instance = null;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	
+	public static FeedbackDialog getInstance() {
+		if (FeedbackDialog.instance == null)
+			FeedbackDialog.instance = new FeedbackDialog();
+		return FeedbackDialog.instance;
+	}
+	
+	private FeedbackDialog() {
+		super(MainFrame.getInstance(), "Report your feedback", true);
+		this.setTitle(i18n.tr("Report your feedback"));
+		initComponent();
+	}
+	
+	
+	public void initComponent() {
+		
+		setLayout(new BorderLayout());
+		JEditorPane explain = new JEditorPane("text/html", "");
+		explain.setText(i18n.tr(
+				"<html><p>Thanks for your feedback on PLM. We deeply need this to make the tool match <br>" +
+				"your needs, so please don't hesitate to report any suggestion, such as typos and <br/>" +
+				"unclear parts in the mission texts, other improvement to the existing exercises<br/>" +
+				"or prospective exercises. We will do our best to integrate your suggestions.</p>" +
+				"<p>Please write here your suggestion (if possible in english or french), with all<br/>" +
+				"necessary details, and then click on 'Send' below.</p>" +
+				"<p><b>Please provide your email address so that we can contact you back</b> but <br/>" +
+				"NEVER DISCLOSE A PASSWORD while reporting issues.</p>" +
+				"<p>Note that some technical information (such as your version of PLM and Java) will <br/>" +
+				"automatically be added to your feedback. None of these automatic information <br/>" +
+				"are personal and you still have to identify yourself if you want to.</p>" +
+
+				"<p>Alternatively, you can use the <a href='http://github.com/oster/JLM/issues'>github interface</a> for feedback.</p></html>"));
+		explain.setBackground(new Color(235,235,235));
+		explain.setOpaque(true);
+		explain.setEditable(false);
+		add(explain, BorderLayout.NORTH);
+		
+		final JEditorPane feedback = new JEditorPane();
+		
+		feedback.setBackground(Color.white);
+		feedback.setOpaque(true);
+		feedback.setEditable(true);
+		JScrollPane jsp =new JScrollPane(feedback);
+		jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+		jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
+		add(jsp,BorderLayout.CENTER);
+		
+		feedback.setContentType("text/plain");
+		feedback.setText(i18n.tr("(your feedback comes here)"));
+		
+		final JButton cancelBtn = new JButton(i18n.tr("Cancel"));
+		cancelBtn.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				int dialogResult = JOptionPane.showConfirmDialog(cancelBtn, 
+						i18n.tr("Do you really want to cancel your feedback and lose any edit?"),
+						i18n.tr("are you sure?"),
+						JOptionPane.YES_NO_OPTION);
+				if(dialogResult==JOptionPane.YES_OPTION)
+					dispose();
+			}
+		});
+		
+		final JButton sendBtn = new JButton(i18n.tr("Send feedback"));
+		sendBtn.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				
+	            DefaultHttpClient httpclient = new DefaultHttpClient();
+	            try {
+	                HttpPost post = new HttpPost(new URI("http://www.loria.fr/~quinson/PLM-feedback/report.php"));
+
+	                List<NameValuePair> formparams = new ArrayList<NameValuePair>();
+	                formparams.add(new BasicNameValuePair("lesson", Game.getInstance().getCurrentLesson().getId()));
+	                formparams.add(new BasicNameValuePair("exercise", Game.getInstance().getCurrentLesson().getCurrentExercise().getId()));
+	                formparams.add(new BasicNameValuePair("language", Game.getProgrammingLanguage().getLang()));
+	                formparams.add(new BasicNameValuePair("locale", Game.getInstance().getLocale().getDisplayName()));
+	                formparams.add(new BasicNameValuePair("java", System.getProperty("java.version")+" (VM: "+System.getProperty("java.vm.name")+"; version: "+System.getProperty("java.vm.version")+")"));
+	                
+	                formparams.add(new BasicNameValuePair("os", System.getProperty("os.name")+" (version: "+System.getProperty("os.version")+"; arch: "+ System.getProperty("os.arch")+")"));
+	                formparams.add(new BasicNameValuePair("plm", Game.getProperty("plm.major.version","internal",false)+" ("+
+	                		Game.getProperty("plm.minor.version","internal",false)+")"));
+	                
+	                formparams.add(new BasicNameValuePair("text", feedback.getText()));
+
+	                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
+	                post.setEntity(entity);
+
+	                HttpResponse response = httpclient.execute(post);
+	                
+	                
+	                BufferedReader reader = new BufferedReader(
+	                        new InputStreamReader(response.getEntity().getContent()));
+	                StringBuffer ctn = new StringBuffer();
+	                while (true) {
+	                	String s = reader.readLine();
+	                	if (s == null)
+	                		break;
+	                	ctn.append(s);
+	                } 
+	                if (response.getStatusLine().getStatusCode() == 200) {
+	    				JOptionPane.showMessageDialog(cancelBtn, 
+	    						ctn.toString(),
+	    						i18n.tr("Thank you for your feedback"),
+	    						JOptionPane.INFORMATION_MESSAGE);
+	    				dispose();	                	
+	                } else {
+	    				JOptionPane.showMessageDialog(cancelBtn, 
+	    						ctn.toString(),
+	    						i18n.tr("Error while uploading your feedback"),
+	    						JOptionPane.ERROR_MESSAGE);
+	                }
+	            } catch (Exception ex) {
+	            	StringBuffer ctn = new StringBuffer(ex.getLocalizedMessage()+"\n");
+	            	for (StackTraceElement elm : ex.getStackTrace())
+	            		ctn.append(elm.toString());
+    				JOptionPane.showMessageDialog(cancelBtn, 
+    						ctn.toString(),
+    						i18n.tr("Error while uploading your feedback"),
+    						JOptionPane.ERROR_MESSAGE);
+	                ex.printStackTrace();
+	            }
+
+			}
+		});
+		
+		JPanel toolbar = new JPanel();
+		toolbar.add(cancelBtn);
+		toolbar.add(sendBtn);
+		add(toolbar,BorderLayout.SOUTH);
+		
+		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+		pack();
+		setMinimumSize(new Dimension(200, 600));
+		setPreferredSize(new Dimension(500, 800));
+		setResizable(true);
+				
+		setLocationRelativeTo(getParent());
+	}
+	
+}
diff --git a/src/plm/core/ui/IEditorPanel.java b/src/plm/core/ui/IEditorPanel.java
new file mode 100644
index 0000000..cbf2e5b
--- /dev/null
+++ b/src/plm/core/ui/IEditorPanel.java
@@ -0,0 +1,5 @@
+package plm.core.ui;
+
+public interface IEditorPanel {
+	public void clear();
+}
diff --git a/src/plm/core/ui/JavaEditorPanel.java b/src/plm/core/ui/JavaEditorPanel.java
new file mode 100644
index 0000000..f60f3a0
--- /dev/null
+++ b/src/plm/core/ui/JavaEditorPanel.java
@@ -0,0 +1,87 @@
+package plm.core.ui;
+
+import javax.swing.JEditorPane;
+import javax.swing.JScrollPane;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.session.SourceFile;
+import plm.universe.Entity;
+import plm.universe.IEntityStackListener;
+
+public class JavaEditorPanel extends JScrollPane implements IEditorPanel,IEntityStackListener {
+	private static final long serialVersionUID = 1L;
+	SourceFile srcFile;
+	SourceFileDocumentSynchronizer sync ;
+	JEditorPane codeEditor;
+	Entity tracedEntity;
+
+	public JavaEditorPanel(SourceFile srcFile, ProgrammingLanguage lang) {
+		super();
+		this.srcFile = srcFile;
+
+		codeEditor = new JEditorPane();
+		setViewportView(codeEditor);
+		codeEditor.setContentType("text/"+lang.getLang().toLowerCase());
+
+		/*
+		InputMap imap = codeEditor.getInputMap();
+		ActionMap amap = codeEditor.getActionMap();		
+		for (KeyStroke ks:imap.allKeys()) 
+			System.out.println("key: "+ks+" -> "+imap.get(ks)+" -> "+amap.get(imap.get(ks)));
+		 */
+		
+		codeEditor.setCaretPosition(0);
+		//((SyntaxDocument) codeEditor.getDocument()).setCurrentEditedLineNumber(0); TODO: find the new way of doing so in jsyntaxpane 0.9.5
+		
+		/* Create a synchronization element, and connect it to the editor */
+		sync = new SourceFileDocumentSynchronizer(codeEditor.getEditorKit());
+		sync.setDocument(codeEditor.getDocument());
+		codeEditor.getDocument().addDocumentListener(sync);
+		
+		/* Connect the synchronization element to the source file */
+		srcFile.setListener(sync);
+		sync.setSourceFile(srcFile);
+		
+		codeEditor.setText(srcFile.getBody());
+		((jsyntaxpane.SyntaxDocument) codeEditor.getDocument()).clearUndos();
+		
+		/* Highlighting stuff, to trace entities */
+		tracedEntity = Game.getInstance().getSelectedEntity();
+		if (tracedEntity != null)
+			tracedEntity.addStackListener(this);
+	}
+	@Override
+	public void clear() {
+		sync.clear();
+		srcFile = null;
+		sync=null;
+		codeEditor=null;
+		if (tracedEntity != null)
+			tracedEntity.removeStackListener(this);
+	}
+	@Override
+	public void entityTraceChanged(Entity e, StackTraceElement[] trace) {
+		/* TODO: The symbol setCurrentEditedLineNumber() is not in jsyntaxpane anymore. 
+		 * But the following code was not working anyway... 
+		for (StackTraceElement elm:trace) {
+			// added defenses against NPE because sometimes (launched from a .jar file, a NullPointerException might happen...)
+			if (elm.getFileName() != null && codeEditor != null && (elm.getFileName().equals(srcFile.getName()) || elm.getFileName().equals(srcFile.getName()+".java from JavaFileObjectImpl"))) {				
+				SyntaxDocument sd = ((SyntaxDocument) codeEditor.getDocument());
+				if (sd != null)
+					sd.setCurrentEditedLineNumber(elm.getLineNumber());
+				codeEditor.repaint();
+			}
+		}		
+		 */
+	}
+	@Override
+	public void tracedEntityChanged(Entity e) {
+		if (tracedEntity != null)
+			tracedEntity.removeStackListener(this);
+
+		tracedEntity = e;
+		if (tracedEntity != null)
+			tracedEntity.addStackListener(this);
+	}
+}
diff --git a/src/plm/core/ui/LoggerPanel.java b/src/plm/core/ui/LoggerPanel.java
new file mode 100644
index 0000000..82f2fc3
--- /dev/null
+++ b/src/plm/core/ui/LoggerPanel.java
@@ -0,0 +1,99 @@
+package plm.core.ui;
+
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.JTextArea;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+import plm.core.model.LogWriter;
+
+
+public class LoggerPanel extends JTextArea implements LogWriter, HumanLangChangesListener {
+
+	private static final long serialVersionUID = 468774822833769775L;
+	
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+
+	public LoggerPanel(Game game) {
+		super();
+		setEditable(false);
+		setToolTipText(i18n.tr("Where error and other messages get written"));
+		game.setOutputWriter(this);
+		game.addHumanLangListener(this);
+	}
+	
+	public void clear() {
+		setText(null);
+	}
+	
+	@Override
+	public void log(String msg) {
+		append(msg);
+	}
+
+	@Override
+	public void log(DiagnosticCollector<JavaFileObject> diagnostics) {
+		boolean warnedJava6= false;
+		Pattern isJava6Pattern = Pattern.compile("major version 51 is newer than 50, the highest major version supported by this compiler");
+		
+		for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
+			String source = diagnostic.getSource() == null ? "(null)" : diagnostic.getSource().getName();
+			String msg = diagnostic.getMessage(getLocale());
+			
+			Matcher isJava6Matcher = isJava6Pattern.matcher(msg);
+			if (isJava6Matcher.find()) {
+				if (!warnedJava6 && Game.getInstance().isDebugEnabled())
+					append("You are using a PLM jarfile that was compiled for Java 6, but you have a Java 7 runtime. This is believed to work.\n");
+				warnedJava6 = true;
+			} else {
+				append(source+":"+diagnostic.getLineNumber()+":"+ msg+"\n");
+			}
+		}
+	}
+
+	/**
+	 * Add an exception into the text area
+	 * 
+	 * @param e
+	 *            what to log
+	 */
+	public void log(Exception e) {
+		append(e.toString() + "\n");
+		for (StackTraceElement s : e.getStackTrace()) {
+			if (s.getClassName().contains("bugglequest.BugglePanel"))
+				break;
+			append("  in " + s.getClassName() + "." + s.getMethodName() + " at " + s.getFileName() + ":"
+					+ s.getLineNumber() + "\n");
+		}
+		Throwable t = e.getCause();
+		if (t != null) {
+			append("Caused by:\n  " + t.toString() + "\n");
+			for (StackTraceElement s : t.getStackTrace()) {
+				if (s.getClassName().contains("bugglequest.BugglePanel"))
+					break;
+				append("    in " + s.getClassName() + "." + s.getMethodName() + " at " + s.getFileName() + ":"
+						+ s.getLineNumber() + "\n");
+			}
+
+		}
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		i18n.setLocale(newLang);
+		
+		setToolTipText(i18n.tr("Where error and other messages get written"));
+		
+	}
+
+}
diff --git a/src/plm/core/ui/MainFrame.java b/src/plm/core/ui/MainFrame.java
new file mode 100644
index 0000000..c739142
--- /dev/null
+++ b/src/plm/core/ui/MainFrame.java
@@ -0,0 +1,723 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.EventQueue;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.util.Locale;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.GameListener;
+import plm.core.GameStateListener;
+import plm.core.HumanLangChangesListener;
+import plm.core.ProgLangChangesListener;
+import plm.core.model.Game;
+import plm.core.model.LessonLoadingException;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.ui.action.AbstractGameAction;
+import plm.core.ui.action.ExportSession;
+import plm.core.ui.action.HelpMe;
+import plm.core.ui.action.ImportSession;
+import plm.core.ui.action.PlayDemo;
+import plm.core.ui.action.QuitGame;
+import plm.core.ui.action.Reset;
+import plm.core.ui.action.RevertExercise;
+import plm.core.ui.action.SetLanguage;
+import plm.core.ui.action.SetProgLanguage;
+import plm.core.ui.action.StartExecution;
+import plm.core.ui.action.StepExecution;
+import plm.core.ui.action.StopExecution;
+import plm.core.ui.action.SwitchExo;
+import plm.core.utils.FileUtils;
+import plm.universe.World;
+
+public class MainFrame extends JFrame implements GameStateListener, GameListener, HumanLangChangesListener {
+
+	private static final long serialVersionUID = -5022279647890315264L;
+
+	private static MainFrame instance = null;
+
+	private ExerciseView exerciseView;
+	private JButton startButton;
+	private JButton debugButton;
+	private JButton stopButton;
+	private JButton resetButton;
+	private JButton demoButton;
+    private JToggleButton helpMeButton;
+    private JButton exoChangeButton;
+    
+    private JMenu menuFile;
+    private JMenuItem miFileLoad,miFileSwitch,miFileExercise,miFileConsole=null,miFileCourse,miFileQuit;
+    private JMenu menuSession;
+    private JMenuItem miSessionRevert, miSessionExport, miSessionImport, miSessionDebug;
+
+    private JMenu menuLanguage, menuLangHuman, menuLangProg;
+    private JMenu menuHelp;
+    private JMenuItem miHelpFeedback, miHelpLesson,miHelpWorld,miHelpAbout;
+        
+	private LoggerPanel outputArea;
+	private MissionEditorTabs met;
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	private JSplitPane mainPanel;
+	
+	private static final String frameTitle = "Programmer's Learning Machine";
+
+	private MainFrame() {
+		super(frameTitle);
+		FileUtils.setLocale(this.getLocale());
+		initComponents(Game.getInstance());
+		this.keyListeners(exerciseView);
+		Game.getInstance().addHumanLangListener(this);
+	}
+
+	public static MainFrame getInstance() {
+		if (MainFrame.instance == null)
+			MainFrame.instance = new MainFrame();
+		return MainFrame.instance;
+	}
+
+	private void initComponents(final Game g) {
+		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
+		getContentPane().setLayout(new BorderLayout());
+
+		JSplitPane logPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
+		logPane.setOneTouchExpandable(true);
+		double ratio = 0.7;
+		logPane.setResizeWeight(ratio);
+		logPane.setDividerLocation((int) (768 * ratio));
+
+		mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
+
+		mainPanel.setOneTouchExpandable(true);
+		double weight = 0.6;
+		mainPanel.setResizeWeight(weight);
+		mainPanel.setDividerLocation((int) (1024 * weight));
+
+		mainPanel.setLeftComponent(met=new MissionEditorTabs());
+		exerciseView = new ExerciseView(g);
+		mainPanel.setRightComponent(exerciseView);
+
+		logPane.setTopComponent(mainPanel);
+		outputArea = new LoggerPanel(g);
+		JScrollPane outputScrollPane = new JScrollPane(outputArea);
+		logPane.setBottomComponent(outputScrollPane);
+		getContentPane().add(logPane, BorderLayout.CENTER);
+
+		initMenuBar(g);
+		initToolBar(g);
+		initStatusBar(g);
+		currentExerciseHasChanged(g.getCurrentLesson().getCurrentExercise()); 
+
+		g.addGameStateListener(this);
+		g.addGameListener(this);
+
+		pack();
+		setSize(1024, 768);
+		setVisible(false);
+	}
+
+	private void initMenuBar(Game g) {
+		JMenuBar menuBar = new JMenuBar();
+		
+		
+		/* === FILE menu === */
+		// for now: leave the calls to i18n.tr: that way one is sure to get all the localized strings...
+		menuFile = new JMenu(i18n.tr("File"));
+		menuFile.setMnemonic(KeyEvent.VK_F);
+		menuFile.getAccessibleContext().setAccessibleDescription(i18n.tr("File related functions"));
+
+		
+		miFileLoad = new JMenuItem(new AbstractGameAction(g, i18n.tr("Load lesson"), null, KeyEvent.VK_L) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				JFileChooser fc = new JFileChooser();
+				fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("PLM lesson files"), "plm"));
+				fc.setDialogType(JFileChooser.OPEN_DIALOG);
+				fc.showOpenDialog(MainFrame.getInstance());
+				File selectedFile = fc.getSelectedFile();
+
+				try {
+					if (selectedFile != null)
+						game.loadLessonFromJAR(fc.getSelectedFile());
+				} catch (LessonLoadingException lle) {
+					JOptionPane.showMessageDialog(null, lle.getMessage(), i18n.tr("Error"), JOptionPane.ERROR_MESSAGE); 
+				}
+			}
+		});
+		menuFile.add(miFileLoad);
+		
+		
+		miFileSwitch = new JMenuItem(new AbstractGameAction(g, i18n.tr("Switch lesson"), null, KeyEvent.VK_L) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				new ChooseLessonDialog();
+				MainFrame.getInstance().setVisible(false);		
+			}
+		});
+		miFileSwitch.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
+		menuFile.add(miFileSwitch);
+		
+		miFileExercise = new JMenuItem(new AbstractGameAction(g, i18n.tr("Switch exercise"), null, KeyEvent.VK_E) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				new ChooseLectureDialog();
+			}
+		});
+		miFileExercise.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, ActionEvent.CTRL_MASK));
+		menuFile.add(miFileExercise);
+		
+		// Teacher console menu item (shown only if defined in the PLM properties)
+        if(Game.getProperty("plm.configuration.teacher").equals("true")) {
+            miFileConsole = new JMenuItem(new AbstractGameAction(g,i18n.tr("Teacher Console")) {
+
+				private static final long serialVersionUID = 1L;
+				private TeacherConsoleDialog dialog = null;
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    // launch teacher console
+					if (dialog == null) {
+						dialog = new TeacherConsoleDialog();
+					}
+                    dialog.setVisible(true);
+                }
+            });
+            miFileConsole.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, ActionEvent.CTRL_MASK));
+            menuFile.add(miFileConsole);
+        }
+        
+        // Menu item to change the current Course
+        miFileCourse = new JMenuItem(new AbstractGameAction(g, i18n.tr("Choose your course")) {
+
+			private static final long serialVersionUID = 1L;
+			private ChooseCourseDialog dialog = null;
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                // launch a dialog to choose the course
+                if (dialog == null) {
+					dialog = new ChooseCourseDialog();
+				}
+				dialog.setVisible(true);
+            }
+        });
+
+        miFileCourse.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.CTRL_MASK));
+        menuFile.add(miFileCourse);
+       
+        
+        miFileQuit = new JMenuItem(new QuitGame(g, i18n.tr("Quit"), null,  KeyEvent.VK_Q));
+        miFileQuit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
+
+		menuFile.add(miFileQuit);
+
+		menuBar.add(menuFile);
+
+		/* === Edit menu === */
+		menuSession = new JMenu(i18n.tr("Session"));
+		menuSession.setMnemonic(KeyEvent.VK_S);
+		menuBar.add(menuSession);
+		menuSession.setEnabled(true);
+		
+		miSessionRevert = new JMenuItem(new RevertExercise(g, i18n.tr("Revert Exercise"), null));
+		menuSession.add(miSessionRevert);
+
+		miSessionExport = new JMenuItem(new ExportSession(g, i18n.tr("Export Session Cache"),	null, this));
+		menuSession.add(miSessionExport);
+
+		miSessionImport = new JMenuItem(new ImportSession(g, i18n.tr("Import Session Cache"),
+				null, this));
+		menuSession.add(miSessionImport);
+
+		miSessionDebug = new JCheckBoxMenuItem(new AbstractGameAction(g, i18n.tr("Debug mode"), null, KeyEvent.VK_D) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				game.switchDebug();
+
+			}
+		});
+		menuSession.add(miSessionDebug);
+
+
+		/* === Language menu === */
+		menuLanguage = new JMenu(i18n.tr("Language"));
+		menuLanguage.setMnemonic(KeyEvent.VK_L);
+		menuBar.add(menuLanguage);
+
+		/* === Programming language changing === */
+		menuLangHuman = new JMenu(i18n.tr("Human"));
+		menuLanguage.add(menuLangHuman);
+
+		ButtonGroup group = new ButtonGroup();
+
+		for (String[] lang : Game.humanLangs) {
+			JMenuItem item = new JRadioButtonMenuItem(new SetLanguage(g, lang[0], new Locale(lang[1])));
+			if (lang[1].equals(FileUtils.getLocale().getLanguage())) 
+				item.setSelected(true);
+			group.add(item);
+			menuLangHuman.add(item);		
+		}
+
+		
+		menuLangProg = new ProgLangSubMenu(i18n.tr("Computer"));
+		menuLanguage.add( menuLangProg );
+
+		/* === Help menu === */
+		menuHelp = new JMenu(i18n.tr("Help"));
+		menuHelp.setMnemonic(KeyEvent.VK_H);
+		menuBar.add(menuHelp);
+
+		miHelpFeedback = new JMenuItem(new AbstractGameAction(g, i18n.tr("Provide feedback")) {
+			private static final long serialVersionUID = 1L;
+
+			public void actionPerformed(ActionEvent arg0) {
+				FeedbackDialog.getInstance().setVisible(true);
+			}			
+		});
+		miHelpFeedback.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, ActionEvent.CTRL_MASK));
+		menuHelp.add(miHelpFeedback);
+		
+		miHelpLesson = new JMenuItem(new AbstractGameAction(g, i18n.tr("About this lesson")) {
+			private static final long serialVersionUID = 1L;
+			private AbstractAboutDialog dialog = null;
+
+			public void actionPerformed(ActionEvent arg0) {
+				if (this.dialog == null) 
+					this.dialog = new AboutLessonDialog(MainFrame.getInstance());
+
+				this.dialog.setVisible(true);
+			}			
+		});
+		menuHelp.add(miHelpLesson);
+
+		miHelpWorld = new JMenuItem(new AbstractGameAction(g, i18n.tr("About this world"), null) {
+			private static final long serialVersionUID = 1L;
+
+			private AbstractAboutDialog dialog = null;
+
+			public void actionPerformed(ActionEvent arg0) {
+				if (this.dialog == null) {
+					this.dialog = new AboutWorldDialog(MainFrame.getInstance());
+				}
+				this.dialog.setVisible(true);
+			}
+		});
+		miHelpWorld.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK));
+		menuHelp.add(miHelpWorld);
+
+		if (!System.getProperty("os.name").startsWith("Mac")) {
+			miHelpAbout = new JMenuItem(new AbstractGameAction(g, i18n.tr("About PLM"), null) {
+				private static final long serialVersionUID = 1L;
+
+				public void actionPerformed(ActionEvent e) {
+					AboutPLMDialog.getInstance().setVisible(true);
+				}
+			});
+			menuHelp.add(miHelpAbout);
+
+		} else {
+			try {
+				OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", (Class[]) null));
+				OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", (Class[]) null));
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			}
+		}
+
+		setJMenuBar(menuBar);
+	}
+	
+	public void appendToTitle(String addendum) {
+		this.setTitle(MainFrame.frameTitle +"      "+ addendum);
+	}
+
+	private void initToolBar(Game g) {
+		JToolBar toolBar = new JToolBar();
+		toolBar.setFloatable(true);
+		toolBar.setBorder(BorderFactory.createEtchedBorder());
+
+		ImageIcon ii = ResourcesCache.getIcon("img/btn-start.png");
+		startButton = new PropagatingButton(new StartExecution(g, i18n.tr("Run"), ii));
+		//shortcut ctrl-r
+		startButton.setMnemonic(KeyEvent.VK_R);
+
+		debugButton = new PropagatingButton(new StepExecution(g, i18n.tr("Step"), 
+				ResourcesCache.getIcon("img/btn-debug.png")));
+		//shortcut ctrl-b
+		debugButton.setMnemonic(KeyEvent.VK_B);
+
+		stopButton = new PropagatingButton(new StopExecution(g, i18n.tr("Stop"), 
+				ResourcesCache.getIcon("img/btn-stop.png")));
+		//shortcut ctrl-s
+		stopButton.setMnemonic(KeyEvent.VK_S);
+		stopButton.setEnabled(false);
+
+		resetButton = new PropagatingButton(new Reset(g, i18n.tr("Reset"), 
+				ResourcesCache.getIcon("img/btn-reset.png")));
+		//shortcut ctrl-z
+		resetButton.setMnemonic(KeyEvent.VK_Z);
+		resetButton.setEnabled(true);
+
+		demoButton = new PropagatingButton(new PlayDemo(g, i18n.tr("Demo"), 
+				ResourcesCache.getIcon("img/btn-demo.png")));
+		//shortcut ctrl-d
+		demoButton.setMnemonic(KeyEvent.VK_D);
+		demoButton.setEnabled(true);
+
+        helpMeButton = new PropagatingToggleButton(new HelpMe(g, i18n.tr("Call for Help"),
+                ResourcesCache.getIcon("img/btn-alert-off.png")));
+
+		toolBar.add(startButton);
+		toolBar.add(debugButton);
+		toolBar.add(stopButton);
+		toolBar.add(resetButton);
+		toolBar.add(demoButton);
+        toolBar.add(helpMeButton);
+
+        toolBar.addSeparator();
+        
+        exoChangeButton = new PropagatingButton(new SwitchExo(g, i18n.tr("Switch exercise"), ResourcesCache.getIcon("img/btn-switch-exo.png")));
+        toolBar.add(exoChangeButton);
+        
+		getContentPane().add(toolBar, BorderLayout.NORTH);
+	}
+
+	private void initStatusBar(Game g) {
+		StatusBar statusBar = new StatusBar(g);
+		getContentPane().add(statusBar, BorderLayout.SOUTH);
+	}
+
+	@Override
+	public void stateChanged(Game.GameState type) {
+		switch (type) {
+		case LOADING:
+		case SAVING:
+			startButton.setEnabled(false);
+			debugButton.setEnabled(false);
+			resetButton.setEnabled(false);
+			demoButton.setEnabled(false);
+			exerciseView.setEnabledControl(false);
+			break;
+		case COMPILATION_STARTED:
+			if (!Game.getInstance().isDebugEnabled())
+				outputArea.clear();
+			startButton.setEnabled(false);
+			debugButton.setEnabled(false);
+			resetButton.setEnabled(false);
+			demoButton.setEnabled(false);
+			exerciseView.setEnabledControl(false);
+			break;
+		case LOADING_DONE:
+		case SAVING_DONE:
+			startButton.setEnabled(true);
+			debugButton.setEnabled(true);
+			resetButton.setEnabled(true);
+			demoButton.setEnabled(true);
+			exerciseView.setEnabledControl(true);
+			break;
+		case COMPILATION_ENDED:
+			// startButton.setEnabled(true);
+			// exerciseView.setEnabledControl(true);
+			break;
+		case EXECUTION_STARTED:
+			exerciseView.selectWorldPane();
+			if (Game.getInstance().stepModeEnabled()) {
+				debugButton.setEnabled(true);
+				startButton.setEnabled(true);
+				debugButton.setText(i18n.tr("Next"));
+				debugButton.setIcon(ResourcesCache.getIcon("img/btn-debug-step.png"));
+			} else {
+				startButton.setEnabled(false);
+				debugButton.setEnabled(false);				
+			}
+			resetButton.setEnabled(false);
+			demoButton.setEnabled(false);
+			stopButton.setEnabled(true);
+			exerciseView.setEnabledControl(false);
+			break;
+		case EXECUTION_ENDED:
+			stopButton.setEnabled(false);
+			startButton.setEnabled(true);
+			debugButton.setEnabled(true);
+			debugButton.setText(i18n.tr("Step"));
+			debugButton.setIcon(ResourcesCache.getIcon("img/btn-debug.png"));
+			resetButton.setEnabled(true);
+			demoButton.setEnabled(true);
+			exerciseView.setEnabledControl(true);
+			break;
+		case DEMO_STARTED:
+			exerciseView.selectObjectivePane();
+			startButton.setEnabled(false);
+			debugButton.setEnabled(false);
+			resetButton.setEnabled(false);
+			demoButton.setEnabled(false);
+			stopButton.setEnabled(true);
+			// exerciseView.setEnabledControl(false);
+			break;
+		case DEMO_ENDED:
+			stopButton.setEnabled(false);
+			startButton.setEnabled(true);
+			debugButton.setEnabled(true);
+			resetButton.setEnabled(true);
+			demoButton.setEnabled(true);
+			exerciseView.setEnabledControl(true);
+			break;
+		default:
+		}
+
+	}
+
+	public void hideWorldView() {
+		mainPanel.getBottomComponent().setVisible(false);
+		mainPanel.setDividerSize(0);
+		validate();
+	}
+	public void showWorldView() {
+		mainPanel.getBottomComponent().setVisible(true);
+		mainPanel.setDividerSize(10);
+
+		validate();
+	}
+	public void lessonChooser() {
+
+	}
+
+
+	public void quit() {
+		MainFrame.getInstance().dispose();
+		Game.getInstance().quit();
+	}
+
+	public void about() {
+		EventQueue.invokeLater(new Runnable() {
+			public void run() {
+				EventQueue.invokeLater(new Runnable() {
+					public void run() {
+						AboutPLMDialog.getInstance().setVisible(true);
+					}
+				});
+			}
+		});
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lecture) {
+		Game g = Game.getInstance();
+		if (lecture instanceof Exercise) {
+			showWorldView();
+			Exercise exo = (Exercise) lecture;
+			for (ProgrammingLanguage l:exo.getProgLanguages()) {
+				if (!g.isValidProgLanguage(l)) 
+					System.err.println("Request to add the programming language '"+l+"' to exercise "+exo.getName()+" ignored. Fix your exercise or upgrade your PLM.");
+			}
+		} else {
+			hideWorldView();
+		}
+	}
+
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedEntityHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldHasChanged(World w) { /* don't care */ }
+
+	@Override
+	public void selectedWorldWasUpdated() { /* don't care */ }
+
+	/** Simple JButton which pass the enabled signals to their action */
+	class PropagatingButton extends JButton {
+		private static final long serialVersionUID = 1L;
+		public PropagatingButton(AbstractGameAction act) {
+			super(act);
+			setBorderPainted(false);
+		}
+		@Override
+		public void setEnabled(boolean enabled) {
+			getAction().setEnabled(enabled);
+			super.setEnabled(enabled);
+		}
+	}
+
+    /** Simple JToggleButton which pass the enabled signals to their action */
+	class PropagatingToggleButton extends JToggleButton {
+		private static final long serialVersionUID = 1L;
+		public PropagatingToggleButton(AbstractGameAction act) {
+			super(act);
+			setBorderPainted(false);
+		}
+		@Override
+		public void setEnabled(boolean enabled) {
+			getAction().setEnabled(enabled);
+			super.setEnabled(enabled);
+		}
+	}
+
+	public void keyListeners(ExerciseView e){
+		//CTLR PAGEUP
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0 ), null );
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0), null );
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,0), "action pageup" );
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,0 ), "action pagedown" );
+		this.getRootPane().getActionMap().put("action pageup", new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			public void actionPerformed(ActionEvent ae) {
+				int index=(met.getSelectedIndex()==0?met.getTabCount()-1:met.getSelectedIndex()-1);
+				met.setSelectedIndex(index);
+			}
+		});
+		this.getRootPane().getActionMap().put("action pagedown", new AbstractAction() {
+			private static final long serialVersionUID = 1L;
+
+			public void actionPerformed(ActionEvent ae) {
+				int index=(met.getSelectedIndex()==met.getTabCount()-1?0:met.getSelectedIndex()+1);
+				met.setSelectedIndex(index);
+			}
+		});
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("left"), "action left" );
+		
+		//F1
+		this.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("F1" ), "action F1" );
+		this.getRootPane().getActionMap().put("action F1", new AbstractAction() {
+			/**
+			 * 
+			 */
+			private static final long serialVersionUID = 1L;
+
+			public void actionPerformed(ActionEvent ae) {
+				System.out.println("touche F1 press��e" );
+			}
+		}
+				);
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		i18n.setLocale(newLang);
+		//Buttons
+		startButton.setText(i18n.tr("Run"));
+		debugButton.setText(i18n.tr("Step"));
+		stopButton.setText(i18n.tr("Stop"));
+		resetButton.setText(i18n.tr("Reset"));
+		demoButton.setText(i18n.tr("Demo"));
+        helpMeButton.setText(i18n.tr("Call for Help"));
+        exoChangeButton.setText(i18n.tr("Switch exercise"));
+
+        // Menus
+		menuFile.setText(i18n.tr("File"));
+		miFileLoad.setText(i18n.tr("Load lesson"));
+		miFileSwitch.setText(i18n.tr("Switch lesson"));
+		miFileExercise.setText(i18n.tr("Switch exercise"));
+		if (miFileConsole != null)
+			miFileConsole.setText(i18n.tr("Teacher Console"));
+		miFileCourse.setText(i18n.tr("Choose your course"));
+        miFileQuit.setText(i18n.tr("Quit"));
+
+		menuSession.setText(i18n.tr("Session"));
+		menuSession.getAccessibleContext().setAccessibleDescription(i18n.tr("Lesson related functions"));
+		miSessionRevert.setText(i18n.tr("Revert Exercise"));
+		miSessionExport.setText(i18n.tr("Export Session Cache"));
+		miSessionImport.setText(i18n.tr("Import Session Cache"));
+		miSessionDebug.setText(i18n.tr("Debug mode"));
+
+		
+		menuLanguage.setText(i18n.tr("Language"));
+		menuLangHuman.setText(i18n.tr("Human"));
+		menuLangProg.setText(i18n.tr("Computer"));
+		
+		menuHelp.setText(i18n.tr("Help"));
+		miHelpFeedback.setText(i18n.tr("Provide feedback"));
+		miHelpLesson.setText(i18n.tr("About this lesson"));
+		miHelpWorld.setText(i18n.tr("About this world"));
+		if (miHelpAbout != null)
+			miHelpAbout.setText(i18n.tr("About PLM"));
+
+
+
+	}
+}
+
+class ProgLangSubMenu extends JMenu implements ProgLangChangesListener, GameListener {
+	private static final long serialVersionUID = 1L;
+
+	public ProgLangSubMenu(String name) {
+		super(name);
+		Game.getInstance().addGameListener(this);
+		Game.getInstance().addProgLangListener(this);
+		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
+	}
+
+	@Override
+	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
+		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());		
+	}
+	@Override
+	public void currentExerciseHasChanged(Lecture lecture) {
+		Game g = Game.getInstance();
+		if (lecture instanceof Exercise) {
+			setEnabled(true);
+			Exercise exo = (Exercise) lecture;
+			removeAll();
+			for (ProgrammingLanguage pl : exo.getProgLanguages()) {
+				ButtonGroup group = new ButtonGroup();
+				JMenuItem item = new JRadioButtonMenuItem(new SetProgLanguage(g,pl));
+				if (pl.equals(Game.getProgrammingLanguage()))
+					item.setSelected(true);
+				group.add(item);
+				add(item);
+			}
+		} else {
+			setEnabled(false);
+		}
+	}
+
+	@Override
+	public void currentLessonHasChanged() {   /* don't care */ }
+	@Override
+	public void selectedWorldHasChanged(World w) {   /* don't care */ }
+	@Override
+	public void selectedEntityHasChanged() {  /* don't care */ }
+	@Override
+	public void selectedWorldWasUpdated() {   /* don't care */ }
+
+}
diff --git a/src/plm/core/ui/MissionEditorTabs.java b/src/plm/core/ui/MissionEditorTabs.java
new file mode 100644
index 0000000..bb3d371
--- /dev/null
+++ b/src/plm/core/ui/MissionEditorTabs.java
@@ -0,0 +1,182 @@
+package plm.core.ui;
+
+import java.awt.Component;
+
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.KeyStroke;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.GameListener;
+import plm.core.ProgLangChangesListener;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.lesson.Lesson;
+import plm.core.model.session.SourceFile;
+import plm.core.utils.PlmSyntaxPane;
+import plm.universe.IEntityStackListener;
+import plm.universe.World;
+
+
+
+public class MissionEditorTabs extends JTabbedPane implements GameListener, ProgLangChangesListener {
+	private static final long serialVersionUID = 1L;
+
+	private Game game;
+	private JEditorPane missionTab = new JEditorPane("text/html", "");
+	
+	/* for code tabs */
+	private Lecture currentExercise;
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+	
+	public MissionEditorTabs() {
+		super();
+		
+		/* Setup the mission tab */
+		missionTab.setEditable(false);
+		missionTab.setEditorKit(new PlmHtmlEditorKit());
+
+		missionTab.addHyperlinkListener(new HyperlinkListener() {
+			TipsDialog tipsDialog = null;
+			
+			@Override
+			public void hyperlinkUpdate(HyperlinkEvent event) {
+				if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+					String desc = event.getDescription();
+					if (desc.startsWith("#tip-")) {
+						if (this.tipsDialog == null) {
+							this.tipsDialog = new TipsDialog(MainFrame.getInstance());
+						}
+						this.tipsDialog.setText("<html>\n"+Lecture.HTMLTipHeader+"<body>\n"+currentExercise.getTip(desc)+"</body>\n</html>\n");
+						this.tipsDialog.setVisible(true);
+					}
+					if (desc.startsWith("plm://")) {
+						//Load a regular lesson
+						String lessonName = desc.substring(new String("plm://").length());
+						String exoName = null;
+						int sep = lessonName.indexOf("/");
+						if (sep != -1) {
+							exoName = lessonName.substring(sep+1);
+							lessonName = lessonName.substring(0, sep);
+							if (exoName.length()==0)
+								exoName = null;
+						}
+						if (Game.getInstance().isDebugEnabled()) 
+							System.out.println("Following a link to lesson: "+lessonName+( (exoName != null) ? "; exo: "+exoName : " (no exo specified)"));
+								
+						Lesson lesson = Game.getInstance().switchLesson(lessonName,false);
+						Game.getInstance().setCurrentLesson(lesson);
+						if (exoName != null && exoName.length()>0) {
+							Lecture lect = lesson.getExercise(exoName);
+							if (lect != null) {
+								Game.getInstance().setCurrentExercise(lect);
+							} else {
+								System.err.println("Broken link: no such lecture '"+exoName+"' in lesson "+lessonName);
+							}
+						}					 
+					}
+				}
+			}
+		});
+		
+		this.addTab(i18n.tr("Mission"), null, new JScrollPane(missionTab),
+				i18n.tr("Description of the work to do"));
+		
+		PlmSyntaxPane.initKits();
+
+		/* Register to game engine */
+		this.game = Game.getInstance();
+		this.game.addGameListener(this);
+		this.game.addProgLangListener(this);
+		
+		/* add code tabs */
+		currentExerciseHasChanged(game.getCurrentLesson().getCurrentExercise());
+		
+		/* removes keybindings from the JTextField
+		 * Used to permit CTRL-PageUp and CTR-PageDown to change tabs */
+		
+//		this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ctrl pressed PAGE_DOWN"), null );
+//		this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ctrl pressed PAGE_UP" ), null );
+//		this.missionTab.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN,InputEvent.CTRL_DOWN_MASK ), null );
+//		this.missionTab.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP,InputEvent.CTRL_DOWN_MASK ), null );
+//		System.out.println(showKeys(this, "MissionEditorTabs"));
+//		System.out.println(showKeys(missionTab, "JEditorPane"));
+	}
+	
+	public static String showKeys(JComponent jc, String nom) {
+		String res="";
+		res+=nom+" : "; 
+		
+		KeyStroke[] tab = jc.getInputMap().allKeys();
+		for (int i = 0; i < tab.length-1; i++) {
+			res+=tab[i].toString()+" , ";
+			if(tab[i].toString().contains("PAGE_UP")||tab[i].toString().contains("PAGE_DOWN"))
+				System.err.println(tab[i].toString());
+		}
+		res+=tab[tab.length-1].toString()+"";
+		return res;
+	}
+	@Override
+	public void currentExerciseHasChanged(Lecture lecture) {
+		currentExercise = lecture;		
+
+		currentProgrammingLanguageHasChanged(Game.getProgrammingLanguage()); /* Redo any code panel, and reload the mission */
+		selectedEntityHasChanged();
+		doLayout();
+	}
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+	@Override
+	public void selectedWorldHasChanged(World w) { 
+		selectedEntityHasChanged();
+	}
+	
+	@Override
+	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) { /* Redo any code panel */
+		int tabPosition = getSelectedIndex();
+		/* Remove every tabs, but the mission one */
+		while (getTabCount()>1) {
+			IEditorPanel p = (IEditorPanel) this.getComponentAt(getTabCount()-1);
+			p.clear();
+			removeTabAt(getTabCount()-1);
+		}
+
+		if (currentExercise instanceof Exercise) {
+			/* Add back the right amount of tabs */
+			int publicSrcFileCount = ((Exercise) currentExercise).getSourceFileCount(newLang);
+			for (int i = 0; i < publicSrcFileCount; i++) {
+				/* Create the code editor */
+				SourceFile srcFile = ((Exercise) currentExercise).getSourceFile(newLang, i);
+
+				/* Create the tab with the code editor as content */
+				this.addTab(srcFile.getName(), null, srcFile.getEditorPanel(newLang), i18n.tr("Type your code here")); 
+			}		
+			if (getTabCount()>tabPosition)
+				setSelectedIndex(tabPosition);
+		}
+		/* Change the mission text, because the CSS changed */
+		missionTab.setEditorKit(new PlmHtmlEditorKit(game.getCurrentLesson().getCurrentExercise()));
+		missionTab.setText(this.game.getCurrentLesson().getCurrentExercise().getMission(newLang));
+		missionTab.setCaretPosition(0);
+	}
+
+	@Override
+	public void selectedEntityHasChanged() { /* the code panels may want to know */
+		for (int i=1;i<getTabCount();i++) {
+			Component c = this.getComponentAt(getTabCount()-1);
+			if (c instanceof IEntityStackListener)
+				((IEntityStackListener) c).tracedEntityChanged(game.getSelectedEntity());
+		}
+	}
+	@Override
+	public void selectedWorldWasUpdated() { /* don't care */ }
+}
diff --git a/src/plm/core/ui/OSXAdapter.java b/src/plm/core/ui/OSXAdapter.java
new file mode 100644
index 0000000..3625dc6
--- /dev/null
+++ b/src/plm/core/ui/OSXAdapter.java
@@ -0,0 +1,246 @@
+/*
+
+File: OSXAdapter.java
+
+Abstract: Hooks existing preferences/about/quit functionality from an
+    existing Java app into handlers for the Mac OS X application menu.
+    Uses a Proxy object to dynamically implement the 
+    com.apple.eawt.ApplicationListener interface and register it with the
+    com.apple.eawt.Application object.  This allows the complete project
+    to be both built and run on any platform without any stubs or 
+    placeholders. Useful for developers looking to implement Mac OS X 
+    features while supporting multiple platforms with minimal impact.
+      
+Version: 2.0
+
+Disclaimer: IMPORTANT:  This Apple software is supplied to you by 
+Apple Inc. ("Apple") in consideration of your agreement to the
+following terms, and your use, installation, modification or
+redistribution of this Apple software constitutes acceptance of these
+terms.  If you do not agree with these terms, please do not use,
+install, modify or redistribute this Apple software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, Apple grants you a personal, non-exclusive
+license, under Apple's copyrights in this original Apple software (the
+"Apple Software"), to use, reproduce, modify and redistribute the Apple
+Software, with or without modifications, in source and/or binary forms;
+provided that if you redistribute the Apple Software in its entirety and
+without modifications, you must retain this notice and the following
+text and disclaimers in all such redistributions of the Apple Software. 
+Neither the name, trademarks, service marks or logos of Apple Inc. 
+may be used to endorse or promote products derived from the Apple
+Software without specific prior written permission from Apple.  Except
+as expressly stated in this notice, no other rights or licenses, express
+or implied, are granted by Apple herein, including but not limited to
+any patent rights that may be infringed by your derivative works or by
+other works in which the Apple Software may be incorporated.
+
+The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Copyright © 2003-2007 Apple, Inc., All Rights Reserved
+
+ */
+
+// http://developer.apple.com/referencelibrary/Java/idxPorting-date.html
+package plm.core.ui;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+public class OSXAdapter implements InvocationHandler {
+
+	protected Object targetObject;
+	protected Method targetMethod;
+	protected String proxySignature;
+
+	static Object macOSXApplication;
+
+	// Pass this method an Object and Method equipped to perform application
+	// shutdown logic
+	// The method passed should return a boolean stating whether or not the quit
+	// should occur
+	public static void setQuitHandler(Object target, Method quitHandler) {
+		setHandler(new OSXAdapter("handleQuit", target, quitHandler));
+	}
+
+	// Pass this method an Object and Method equipped to display application
+	// info
+	// They will be called when the About menu item is selected from the
+	// application menu
+	public static void setAboutHandler(Object target, Method aboutHandler) {
+		boolean enableAboutMenu = (target != null && aboutHandler != null);
+		if (enableAboutMenu) {
+			setHandler(new OSXAdapter("handleAbout", target, aboutHandler));
+		}
+		// If we're setting a handler, enable the About menu item by calling
+		// com.apple.eawt.Application reflectively
+		try {
+			Method enableAboutMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledAboutMenu",
+					new Class[] { boolean.class });
+			enableAboutMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enableAboutMenu) });
+		} catch (Exception ex) {
+			System.err.println("OSXAdapter could not access the About Menu");
+			ex.printStackTrace();
+		}
+	}
+
+	// Pass this method an Object and a Method equipped to display application
+	// options
+	// They will be called when the Preferences menu item is selected from the
+	// application menu
+	public static void setPreferencesHandler(Object target, Method prefsHandler) {
+		boolean enablePrefsMenu = (target != null && prefsHandler != null);
+		if (enablePrefsMenu) {
+			setHandler(new OSXAdapter("handlePreferences", target, prefsHandler));
+		}
+		// If we're setting a handler, enable the Preferences menu item by
+		// calling
+		// com.apple.eawt.Application reflectively
+		try {
+			Method enablePrefsMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledPreferencesMenu",
+					new Class[] { boolean.class });
+			enablePrefsMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enablePrefsMenu) });
+		} catch (Exception ex) {
+			System.err.println("OSXAdapter could not access the About Menu");
+			ex.printStackTrace();
+		}
+	}
+
+	// Pass this method an Object and a Method equipped to handle document
+	// events from the Finder
+	// Documents are registered with the Finder via the CFBundleDocumentTypes
+	// dictionary in the
+	// application bundle's Info.plist
+	public static void setFileHandler(Object target, Method fileHandler) {
+		setHandler(new OSXAdapter("handleOpenFile", target, fileHandler) {
+			// Override OSXAdapter.callTarget to send information on the
+			// file to be opened
+			@Override
+			public boolean callTarget(Object appleEvent) {
+				if (appleEvent != null) {
+					try {
+						Method getFilenameMethod = appleEvent.getClass().getDeclaredMethod("getFilename",
+								(Class[]) null);
+						String filename = (String) getFilenameMethod.invoke(appleEvent, (Object[]) null);
+						this.targetMethod.invoke(this.targetObject, new Object[] { filename });
+					} catch (SecurityException ex) {
+						ex.printStackTrace();
+					} catch (NoSuchMethodException ex) {
+						ex.printStackTrace();
+					} catch (IllegalArgumentException ex) {
+						ex.printStackTrace();
+					} catch (IllegalAccessException ex) {
+						ex.printStackTrace();
+					} catch (InvocationTargetException ex) {
+						ex.printStackTrace();
+					}
+				}
+				return true;
+			}
+		});
+	}
+
+	// setHandler creates a Proxy object from the passed OSXAdapter and adds it
+	// as an ApplicationListener
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	public static void setHandler(OSXAdapter adapter) {
+		try {
+			Class applicationClass = Class.forName("com.apple.eawt.Application");
+			if (macOSXApplication == null) {
+				macOSXApplication = applicationClass.getConstructor((Class[]) null).newInstance((Object[]) null);
+			}
+			Class applicationListenerClass = Class.forName("com.apple.eawt.ApplicationListener");
+			Method addListenerMethod = applicationClass.getDeclaredMethod("addApplicationListener",
+					new Class[] { applicationListenerClass });
+			// Create a proxy object around this handler that can be
+			// reflectively added as an Apple ApplicationListener
+			Object osxAdapterProxy = Proxy.newProxyInstance(OSXAdapter.class.getClassLoader(),
+					new Class[] { applicationListenerClass }, adapter);
+			addListenerMethod.invoke(macOSXApplication, new Object[] { osxAdapterProxy });
+		} catch (ClassNotFoundException cnfe) {
+			System.err
+					.println("This version of Mac OS X does not support the Apple EAWT.  ApplicationEvent handling has been disabled ("
+							+ cnfe + ")");
+		} catch (Exception ex) { // Likely a NoSuchMethodException or an
+			// IllegalAccessException loading/invoking
+			// eawt.Application methods
+			System.err.println("Mac OS X Adapter could not talk to EAWT:");
+			ex.printStackTrace();
+		}
+	}
+
+	// Each OSXAdapter has the name of the EAWT method it intends to listen for
+	// (handleAbout, for example),
+	// the Object that will ultimately perform the task, and the Method to be
+	// called on that Object
+	protected OSXAdapter(String proxySignature, Object target, Method handler) {
+		this.proxySignature = proxySignature;
+		this.targetObject = target;
+		this.targetMethod = handler;
+	}
+
+	// Override this method to perform any operations on the event
+	// that comes with the various callbacks
+	// See setFileHandler above for an example
+	public boolean callTarget(Object appleEvent) throws InvocationTargetException, IllegalAccessException {
+		Object result = targetMethod.invoke(targetObject, (Object[]) null);
+		if (result == null) {
+			return true;
+		}
+		return Boolean.valueOf(result.toString()).booleanValue();
+	}
+
+	// InvocationHandler implementation
+	// This is the entry point for our proxy object; it is called every time an
+	// ApplicationListener method is invoked
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if (isCorrectMethod(method, args)) {
+			boolean handled = callTarget(args[0]);
+			setApplicationEventHandled(args[0], handled);
+		}
+		// All of the ApplicationListener methods are void; return null
+		// regardless of what happens
+		return null;
+	}
+
+	// Compare the method that was called to the intended method when the
+	// OSXAdapter instance was created
+	// (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
+	protected boolean isCorrectMethod(Method method, Object[] args) {
+		return (targetMethod != null && proxySignature.equals(method.getName()) && args.length == 1);
+	}
+
+	// It is important to mark the ApplicationEvent as handled and cancel the
+	// default behavior
+	// This method checks for a boolean result from the proxy method and sets
+	// the event accordingly
+	protected void setApplicationEventHandled(Object event, boolean handled) {
+		if (event != null) {
+			try {
+				Method setHandledMethod = event.getClass().getDeclaredMethod("setHandled",
+						new Class[] { boolean.class });
+				// If the target method returns a boolean, use that as a hint
+				setHandledMethod.invoke(event, new Object[] { Boolean.valueOf(handled) });
+			} catch (Exception ex) {
+				System.err.println("OSXAdapter was unable to handle an ApplicationEvent: " + event);
+				ex.printStackTrace();
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/plm/core/ui/PlmHtmlEditorKit.java b/src/plm/core/ui/PlmHtmlEditorKit.java
new file mode 100644
index 0000000..a305498
--- /dev/null
+++ b/src/plm/core/ui/PlmHtmlEditorKit.java
@@ -0,0 +1,393 @@
+package plm.core.ui;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.UIManager;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+import javax.swing.text.IconView;
+import javax.swing.text.Position;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Lecture;
+
+
+public class PlmHtmlEditorKit extends HTMLEditorKit {
+	private static final long serialVersionUID = 1L;
+
+	private static Map<String,String> langColors = null;
+	/** Filters out the part that should not be displayed in the current programming language
+	 * 
+	 *  If current language is java, then we will:
+	 *    - keep parts such as [!java] ... [/!]  (that is, replace the whole group by what's within the tag)
+	 *    - remove parts such as [!python] ... [/!] 
+	 *    - remove parts such as [!scala] ... [/!]
+	 *     
+	 *    - keep parts such as [!java|python] ... [/!] 
+	 *    - keep parts such as [!python|java] ... [/!] 
+	 *    - keep parts such as [!java|scala] ... [/!] 
+	 *    - keep parts such as [!scala|java] ... [/!] 
+	 *    - remove parts such as [!scala|python] ... [/!] 
+	 *    - remove parts such as [!python|scala] ... [/!] 
+	 * 
+	 * Other automagic conversions:
+	 *  [!thelang] displays the name of the current programming language.
+	 *  [!configfile] displays where the PLM config file is stored on disk.
+	 * 
+	 */
+	public static String filterHTML(String in, boolean showAll) {
+		if (langColors == null) {
+			langColors = new HashMap<String, String>();
+			langColors.put("java", "FF0000");
+			langColors.put("python", "008000");
+			langColors.put("scala",  "0000FF");
+			
+			langColors.put("java|python", "FF8000");
+			langColors.put("java|scala",  "FF00FF");
+			langColors.put("python|java", "FF8000");
+			langColors.put("python|scala", "0080FF");
+			langColors.put("scala|java",  "FF00FF");
+			langColors.put("scala|python", "0080FF");
+		}
+		
+		String res = in.replaceAll("\\[!thelang/?\\]", "[!java]Java[/!][!python]python[/!][!scala]Scala[/!]");
+		res = res.replaceAll("\\[!configfile/?\\]", Game.getSavingLocation()+File.separator+"plm.properties");
+		
+		/* Display everything when in debug mode, with shiny colors */
+		if (showAll) {
+			// Process any block with one language first so that they can be nested in blocks with more than one language.
+			for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
+				String l = lang.getLang().toLowerCase();
+				res = res.replaceAll("(?s)\\[!"+l+"\\](.*?)\\[/!\\]",
+						"<font color=\""+langColors.get(l)+"\">$1</font>");
+			}
+			for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
+				String l = lang.getLang().toLowerCase();
+				for (ProgrammingLanguage lang2 : Game.getProgrammingLanguages()) {
+					if (!lang2.equals(lang)) {
+						String l2 = lang2.getLang().toLowerCase();
+						res = res.replaceAll("(?s)\\[!"+l+"\\|"+l2+"\\](.*?)\\[/!\\]",
+								"<font color=\""+langColors.get(l+"|"+l2)+"\">$1</font>");
+
+					}
+				}
+			}
+			return res;
+		}
+		
+		/* filter out irrelevant stuff when not in debug */
+		ProgrammingLanguage currLang = Game.getProgrammingLanguage();
+		String cl = currLang.getLang().toLowerCase();
+		
+		// Process any block with one language first so that they can be nested in blocks with more than one language.
+		res = res.replaceAll(      "(?s)\\[!"+cl+"\\](.*?)\\[/!\\]","$1");
+		//System.out.println("Keep "+"(?s)\\[!"+cl+"\\](.*?)\\[/!\\]");
+		for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
+			if (!lang.equals(currLang)) {
+				String l = lang.getLang().toLowerCase();
+				
+				res = res.replaceAll(      "(?s)\\[!"+l+"\\](.*?)\\[/!\\]",   "");
+				//System.out.println("Kill "+"(?s)\\[!"+l+"\\](.*?)\\[/!\\]");
+			}
+		}
+		for (ProgrammingLanguage lang : Game.getProgrammingLanguages()) {
+			if (!lang.equals(currLang)) {
+				String l = lang.getLang().toLowerCase();
+				
+				res = res.replaceAll(      "(?s)\\[!"+l +"\\|"+cl+"\\](.*?)\\[/!\\]",   "$1");
+				//System.out.println("Keep "+"(?s)\\[!"+l +"\\|"+cl+"\\](.*?)\\[/!\\]");
+				res = res.replaceAll(      "(?s)\\[!"+cl+"\\|"+l +"\\](.*?)\\[/!\\]",   "$1");
+				//System.out.println("Keep "+"(?s)\\[!"+cl+"\\|"+l +"\\](.*?)\\[/!\\]");
+				
+				for (ProgrammingLanguage lang2 : Game.getProgrammingLanguages()) {
+					if (!lang2.equals(currLang) && !lang2.equals(lang)) {
+						String l2 = lang2.getLang().toLowerCase();
+						res = res.replaceAll(   "(?s)\\[!"+l+"\\|"+l2+"\\](.*?)\\[/!\\]",    "");
+						//System.out.println("Kill (?s)\\[!"+l+"\\|"+l2+"\\](.*?)\\[/!\\]");
+					}
+				}
+			}
+		}
+		return res;
+	}
+	
+	private static boolean hideLang(String cssClass) {
+		if (cssClass == null)
+			return false;
+		if (cssClass.toLowerCase().equals(Game.getProgrammingLanguage().getLang().toLowerCase())) 
+			return false;
+		return true;
+	}
+	
+	public static class HTMLFactoryX extends HTMLEditorKit.HTMLFactory implements ViewFactory {
+		boolean visible=false;
+		@Override
+		public View create(Element element) {
+			Element iterElem = element;
+			String theCSSClass = (String) iterElem.getAttributes().getAttribute(HTML.Attribute.CLASS);
+			/*
+			while (theCSSClass == null && iterElem != null) {
+				iterElem = iterElem.getParentElement();
+				if (iterElem != null)
+					theCSSClass = (String) iterElem.getAttributes().getAttribute(HTML.Attribute.CLASS);
+			}
+			*/
+			if (!Game.getInstance().isDebugEnabled() // Display everything when in debug mode 
+				&& hideLang(theCSSClass)) {
+				return new EmptyView(element);
+			}
+			
+			Object tagName = element.getAttributes().getAttribute(StyleConstants.NameAttribute);
+			if (tagName instanceof HTML.Tag) {
+				HTML.Tag tag = (HTML.Tag) tagName;
+				if (tag == HTML.Tag.IMG)
+					return new MyIconView(element, baseExercise);
+			}
+			return super.create(element);
+		}
+	}
+
+	protected static Lecture baseExercise = null;
+	public PlmHtmlEditorKit() {
+		baseExercise = null;
+	}
+
+	public PlmHtmlEditorKit(Lecture _baseExercise) {
+		baseExercise = _baseExercise;
+	}
+
+	@Override
+	public ViewFactory getViewFactory() {
+		return new HTMLFactoryX();
+	}
+	public static String getCSS() {
+		String header = "  <style type=\"text/css\">\n"+
+		        "    body { font-family: tahoma, \"Times New Roman\", serif; font-size:"+Game.getProperty(Game.PROP_FONT_SIZE, "10px", true)+"; margin:10px; }\n"+
+		        "    code { background:#EEEEEE; }\n"+
+		        "    pre { background: #EEEEEE;\n"+
+		        "          margin: 5px;\n"+
+		        "          padding: 6px;\n"+
+		        "          border: 1px inset;\n"+
+		        "          width: 640px;\n"+
+		        "          overflow: auto;\n"+
+		        "          text-align: left;\n"+
+		        "          font-family: \"Courrier New\", \"Courrier\", monospace; }\n"+
+		        "   .comment { background:#EEEEEE;\n"+
+		        "              font-family: \"Times New Roman\", serif;\n"+
+		        "              color:#00AA00;\n"+
+		        "              font-style: italic; }\n";
+		String res;
+		if (Game.getInstance().isDebugEnabled()) {
+			/* In debugging mode, all languages are displayed, with differing colors */
+			res = header;
+			res += ".Java   {visibility: visible; color:#FF0000}\n";
+			res += ".java   {visibility: visible; color:#FF0000}\n";
+			res += ".python {visibility: visible; color:#008000}\n";
+			res += ".Python {visibility: visible; color:#008000}\n";
+			res += ".scala  {visibility: visible; color:#0000FF}\n";
+			res += ".Scala  {visibility: visible; color:#0000FF}\n";
+			res +=  "  </style>\n";
+			return res;
+		}
+		return header+"  </style>\n";
+	}
+}
+
+class EmptyView extends IconView {
+
+	public EmptyView(Element elem) {
+		super(elem);
+	}
+	@Override
+	public float getPreferredSpan(int axis) {
+		return 0;
+	}
+	@Override
+	public void paint(Graphics g, Shape a) {
+	}
+}
+
+/* This is a crude copy/paste of IconView where all I changed is the constructor. 
+ * The day where swing authors won't fight against subclassing by for example putting the c field as 
+ * private here, I will stop doing such nasty thing. 
+ * 
+ * But I have the feeling that we will move to SWT before that day happens :-/ [Mt] */
+
+class MyIconView extends View {
+	/**
+	 * Creates a new icon view that represents an element.
+	 *
+	 * @param elem the element to create a view for
+	 * @param baseExercise 
+	 * @throws FileNotFoundException 
+	 */
+	public MyIconView(Element elem, Lecture baseExercise) {
+		super(elem);
+		String filename = (String) elem.getAttributes().getAttribute(HTML.Attribute.SRC);
+		if (filename == null) {
+			System.err.println(Game.i18n.tr("<img> tag without src attribute in exercise {0}",baseExercise.getName()));
+			c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
+		} else {
+			c = ResourcesCache.getIcon(filename,true);
+			if (c != null)
+				return;
+			if (baseExercise != null) 
+				c = ResourcesCache.getIcon(baseExercise, filename);
+			if (c != null)
+				return;
+			
+			String resourceName = "/"+filename.replace('.','/');
+			resourceName = resourceName.replaceAll("/png$", ".png").replaceAll("/jpg$", ".jpg");
+			resourceName = resourceName.replaceAll("/jpeg$", ".jpeg").replaceAll("/gif$", ".gif");
+
+			InputStream s = getClass().getResourceAsStream(resourceName);
+			
+			try {
+				if (s == null) {
+					c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
+					System.out.println("Broken image link: "+resourceName);
+				} else
+					c = new ImageIcon(ImageIO.read(s));
+			} catch (IOException e) {
+				e.printStackTrace();
+				c = (Icon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
+			}
+		}
+	}
+
+	// --- View methods ---------------------------------------------
+
+	/**
+	 * Paints the icon.
+	 * The real paint behavior occurs naturally from the association
+	 * that the icon has with its parent container (the same
+	 * container hosting this view), so this simply allows us to
+	 * position the icon properly relative to the view.  Since
+	 * the coordinate system for the view is simply the parent
+	 * containers, positioning the child icon is easy.
+	 *
+	 * @param g the rendering surface to use
+	 * @param a the allocated region to render into
+	 * @see View#paint
+	 */
+	@Override
+	public void paint(Graphics g, Shape a) {
+		Rectangle alloc = a.getBounds();
+		c.paintIcon(getContainer(), g, alloc.x, alloc.y);
+	}
+
+	/**
+	 * Determines the preferred span for this view along an
+	 * axis.
+	 *
+	 * @param axis may be either View.X_AXIS or View.Y_AXIS
+	 * @return  the span the view would like to be rendered into
+	 *           Typically the view is told to render into the span
+	 *           that is returned, although there is no guarantee.
+	 *           The parent may choose to resize or break the view.
+	 * @exception IllegalArgumentException for an invalid axis
+	 */
+	@Override
+	public float getPreferredSpan(int axis) {
+		switch (axis) {
+		case View.X_AXIS:
+			return c.getIconWidth();
+		case View.Y_AXIS:
+			return c.getIconHeight();
+		default:
+			throw new IllegalArgumentException("Invalid axis: " + axis);
+		}
+	}
+
+	/**
+	 * Determines the desired alignment for this view along an
+	 * axis.  This is implemented to give the alignment to the
+	 * bottom of the icon along the y axis, and the default
+	 * along the x axis.
+	 *
+	 * @param axis may be either View.X_AXIS or View.Y_AXIS
+	 * @return the desired alignment >= 0.0f && <= 1.0f.  This should be
+	 *   a value between 0.0 and 1.0 where 0 indicates alignment at the
+	 *   origin and 1.0 indicates alignment to the full span
+	 *   away from the origin.  An alignment of 0.5 would be the
+	 *   center of the view.
+	 */
+	@Override
+	public float getAlignment(int axis) {
+		switch (axis) {
+		case View.Y_AXIS:
+			return 1;
+		default:
+			return super.getAlignment(axis);
+		}
+	}
+
+	/**
+	 * Provides a mapping from the document model coordinate space
+	 * to the coordinate space of the view mapped to it.
+	 *
+	 * @param pos the position to convert >= 0
+	 * @param a the allocated region to render into
+	 * @return the bounding box of the given position
+	 * @exception BadLocationException  if the given position does not
+	 *   represent a valid location in the associated document
+	 * @see View#modelToView
+	 */
+	@Override
+	public Shape modelToView(int pos, Shape a, Position.Bias b) throws BadLocationException {
+		int p0 = getStartOffset();
+		int p1 = getEndOffset();
+		if ((pos >= p0) && (pos <= p1)) {
+			Rectangle r = a.getBounds();
+			if (pos == p1) {
+				r.x += r.width;
+			}
+			r.width = 0;
+			return r;
+		}
+		throw new BadLocationException(pos + " not in range " + p0 + "," + p1, pos);
+	}
+
+	/**
+	 * Provides a mapping from the view coordinate space to the logical
+	 * coordinate space of the model.
+	 *
+	 * @param x the X coordinate >= 0
+	 * @param y the Y coordinate >= 0
+	 * @param a the allocated region to render into
+	 * @return the location within the model that best represents the
+	 *  given point of view >= 0
+	 * @see View#viewToModel
+	 */
+	@Override
+	public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) {
+		Rectangle alloc = (Rectangle) a;
+		if (x < alloc.x + (alloc.width / 2)) {
+			bias[0] = Position.Bias.Forward;
+			return getStartOffset();
+		}
+		bias[0] = Position.Bias.Backward;
+		return getEndOffset();
+	}
+
+	// --- member variables ------------------------------------------------
+
+	private Icon c;
+}
+
diff --git a/src/plm/core/ui/ProgrammersLearningMachine.java b/src/plm/core/ui/ProgrammersLearningMachine.java
new file mode 100644
index 0000000..266787e
--- /dev/null
+++ b/src/plm/core/ui/ProgrammersLearningMachine.java
@@ -0,0 +1,26 @@
+package plm.core.ui;
+
+import javax.swing.JFrame;
+
+import plm.core.model.Game;
+import plm.core.utils.FileUtils;
+
+
+public class ProgrammersLearningMachine {
+	
+	public static void main(String args[]) {
+		
+		if (System.getProperty("os.name").startsWith("Mac")) {
+			System.setProperty("apple.laf.useScreenMenuBar", "true");
+			System.setProperty("com.apple.mrj.application.apple.menu.about.name", "PLM");
+		}
+		
+		
+		FileUtils.setLocale(new JFrame().getLocale());
+		
+		Game.getInstance().loadChooser();
+		MainFrame.getInstance().setVisible(false);		
+		new ChooseLessonDialog();
+
+	}
+}
diff --git a/src/plm/core/ui/ResourcesCache.java b/src/plm/core/ui/ResourcesCache.java
new file mode 100644
index 0000000..f0b6ce9
--- /dev/null
+++ b/src/plm/core/ui/ResourcesCache.java
@@ -0,0 +1,135 @@
+package plm.core.ui;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+import java.util.Hashtable;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.UIManager;
+
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+
+public class ResourcesCache {
+	private static Hashtable<String, ImageIcon> iconsCache = new Hashtable<String, ImageIcon>();
+
+	private static ImageIcon[] busyIcons;
+
+	public static void loadBusyIconAnimation() {
+		busyIcons = new ImageIcon[30];
+		for (int i=0 ; i<30; i++) {
+			URL url = ResourcesCache.class.getClassLoader().getResource("img/busyicon/anim-"+(i+1)+".png");
+			if (url == null) {
+				busyIcons[i] =  new ImageIcon();
+			} else {
+				busyIcons[i] = new ImageIcon(url);
+			}
+		}
+	}
+	
+	private static Boolean warnedAboutBrokenPath = false;
+	/**
+	 * Lazy loading of ImageIcon resources.
+	 * @param path of the image resource to be loaded.
+	 * @return the ImageIcon or a blank ImageIcon when resource is not found.
+	 */
+	public static ImageIcon getIcon(String path) {
+		return getIcon(path, false);
+	}
+	public static void setIcon(String path, ImageIcon icon) {
+		iconsCache.put(path,icon);
+	}
+	/**
+	 * Lazy loading of ImageIcon resources.
+	 * @param path of the image resource to be loaded.
+	 * @param okNull : whether it's ok to return null (useful to search for several paths) 
+	 * @return the ImageIcon or a blank ImageIcon when resource is not found.
+	 */
+	public static ImageIcon getIcon(String path, boolean okNull) {
+		if (!iconsCache.containsKey(path)) {
+			URL url = ResourcesCache.class.getClassLoader().getResource(path);
+			if (url == null) {
+				if (okNull) 
+					return null;
+				if (!warnedAboutBrokenPath) {
+					Logger.log("plm.ui.ResourcesCache.getIcon()", "Cannot find path "+path+": classloader returned null.");
+					warnedAboutBrokenPath = true;
+				}
+				ImageIcon c = (ImageIcon) UIManager.getLookAndFeelDefaults().get("html.missingImage");
+				iconsCache.put(path, c);
+			} else {
+				ImageIcon img = new ImageIcon(url);
+				iconsCache.put(path, img);
+			}
+		}
+		return iconsCache.get(path);
+	}
+
+	public static ImageIcon getIcon(Object basePath, String path) {
+		String name = basePath.getClass().getPackage().getName().replaceAll("\\.", "/") 
+		        +"/"+path;
+		return getIcon(name);
+	}
+
+	public static int getBusyIconsSize() {
+		return ResourcesCache.busyIcons.length;
+	}
+
+
+	public static Icon getBusyIcons(int busyIconIndex) {
+		return ResourcesCache.busyIcons[busyIconIndex];
+	}
+
+	public static ImageIcon getStarredIcon(ImageIcon icon, Exercise exo) {
+		String path = exo.getWorld(0).getView().getClass().getCanonicalName();
+		for (ProgrammingLanguage lang : exo.getProgLanguages()) {
+			if (Game.getInstance().studentWork.getPassed(exo, lang))
+				path += "_"+lang.getLang()+"ok";
+			else 
+				path += "_"+lang.getLang()+"nok";
+		}
+		if (!iconsCache.containsKey(path)) {
+			BufferedImage combined;
+			if (exo.getProgLanguages().contains(Game.LIGHTBOT)) {
+				combined = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+				Graphics g = combined.getGraphics();
+				g.drawImage(icon.getImage(), 0, 0, null);
+				
+				ImageIcon star = getIcon("resources/star.png");
+				ImageIcon starNo = getIcon("resources/star_white.png");
+				if (Game.getInstance().studentWork.getPassed(exo, Game.LIGHTBOT))  
+					g.drawImage(star.getImage(), 0, 0, null);
+				else 
+					g.drawImage(starNo.getImage(), 0, 0, null);
+				
+			} else {
+				combined = new BufferedImage(icon.getIconWidth()+26, icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+				Graphics g = combined.getGraphics();
+				g.drawImage(icon.getImage(), 0, 0, null);
+				Dimension[] positions = new Dimension[] {new Dimension(26,0), new Dimension(26,16), 
+						                                 new Dimension(42,0), new Dimension(42,16)};
+				int curPos=0;
+				
+				Game.getInstance();
+				for (ProgrammingLanguage lang: Game.getProgrammingLanguages()) {
+					if (lang.equals(Game.LIGHTBOT))
+						continue;
+					
+					if (Game.getInstance().studentWork.getPassed(exo, lang)) {
+						g.drawImage(lang.getIcon().getImage(), positions[curPos].width, positions[curPos].height, null);
+						curPos++;
+					}
+				}
+			}
+			
+			iconsCache.put(path, new ImageIcon(combined));
+		}
+		return iconsCache.get(path);
+	}
+	
+}
diff --git a/src/plm/core/ui/ResultsPanel.java b/src/plm/core/ui/ResultsPanel.java
new file mode 100644
index 0000000..85c30f8
--- /dev/null
+++ b/src/plm/core/ui/ResultsPanel.java
@@ -0,0 +1,77 @@
+package plm.core.ui;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Map;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.UIManager;
+
+import plm.core.model.Game;
+import plm.core.model.ServerUserData;
+
+/**
+ * Panel to display students results from the server
+ * You can add a filter of student to display only a list of usernames depending of a criteria (good, bad student...)
+ */
+public class ResultsPanel extends JPanel {
+	private static final long serialVersionUID = 1L;
+
+    // all data on students from the server
+    private Map<String, ServerUserData> serverData;
+    // list of students to filter the selection to display (null if all data has to be displayed)
+    private ArrayList<String> userFilter;
+
+    public ResultsPanel(ArrayList<String> userFilter) {
+        this.userFilter = userFilter;
+
+        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+        setBorder(BorderFactory.createTitledBorder("Results by student"));
+        displayResults();
+    }
+
+    public void displayResults() {
+        this.removeAll();
+        serverData = Game.getInstance().getCurrentCourse().getServerData();
+
+        UIManager.put("ProgressBar.background", Color.RED); //color of the background
+        UIManager.put("ProgressBar.foreground", Color.GREEN);  //color of progress bar
+
+        if (serverData != null) {
+            // Add the results graph of each student to serverDataPanel
+            // if a filter has been set, iterate only through these students
+            // else, iterate through all students of the course
+            for (final String student : (userFilter == null ? serverData.keySet() : userFilter)) {
+                JPanel studentPanel = new JPanel();
+                studentPanel.add(new JLabel(student));
+
+                JProgressBar graph = new JProgressBar(0, serverData.get(student).getExercisesTotal());
+                graph.setValue(serverData.get(student).getExercisesPassed());
+                studentPanel.add(graph);
+                JButton studentButton = new JButton();
+                studentButton.setContentAreaFilled(false);
+                studentButton.add(studentPanel);
+                studentButton.addActionListener(new ActionListener() {
+                    @Override
+                    public void actionPerformed(ActionEvent actionEvent) {
+                        new StudentDetailsDialog(serverData.get(student));
+                    }
+                });
+
+                add(studentButton);
+            }
+
+        } else {
+            add(new JLabel("There is no result yet for this course..."));
+        }
+
+        this.repaint();
+    }
+}
diff --git a/src/plm/core/ui/SourceFileDocumentSynchronizer.java b/src/plm/core/ui/SourceFileDocumentSynchronizer.java
new file mode 100644
index 0000000..5f9e40f
--- /dev/null
+++ b/src/plm/core/ui/SourceFileDocumentSynchronizer.java
@@ -0,0 +1,105 @@
+package plm.core.ui;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.EditorKit;
+
+import plm.core.model.session.ISourceFileListener;
+import plm.core.model.session.SourceFile;
+
+
+/*
+ * Responsibility: synchronize content between Document instance
+ * used by a JEditorPane and the body field of a SourceFile instance.
+ * 
+ */
+
+public class SourceFileDocumentSynchronizer implements DocumentListener, ISourceFileListener {
+
+	private Document document;
+	private SourceFile sourceFile;
+	private EditorKit editorKit;
+	private boolean propagationInProgress = false;
+
+	public SourceFileDocumentSynchronizer(EditorKit kit) {
+		this.editorKit = kit;
+	}
+
+	public void clear() {
+		document.removeDocumentListener(this);
+		sourceFile.removeListener();
+		this.document = null;
+		this.sourceFile = null;
+		editorKit = null;
+	}
+
+	public void setDocument(Document doc) {
+		this.document = doc;
+	}
+
+	public void setSourceFile(SourceFile srcFile) {
+		this.sourceFile = srcFile;
+	}
+
+	private void copyDocumentContentToSourceFileBody() {
+		if (this.propagationInProgress)
+			return ;
+
+		this.propagationInProgress = true;
+		try {
+			this.sourceFile.setBody(this.document.getText(0, this.document.getLength()));
+		} catch (BadLocationException e1) {
+			e1.printStackTrace();
+		} finally {
+			this.propagationInProgress = false;
+		}
+	}
+
+	private void copySourceFileBodyToDocumentContent() {
+		if (this.propagationInProgress)
+			return ;
+		
+		this.propagationInProgress = true;
+		try {
+			this.document.remove(0, this.document.getLength());
+			String body = this.sourceFile.getBody();
+			if (body == null || body.equals("")) {
+				return;
+			}
+			Reader reader = new StringReader(body);
+			this.editorKit.read(reader, this.document, 0);
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (BadLocationException e) {
+			e.printStackTrace();
+		} finally {
+			this.propagationInProgress = false;
+		}
+	}
+
+	@Override
+	public void changedUpdate(DocumentEvent e) {
+		copyDocumentContentToSourceFileBody();
+	}
+
+	@Override
+	public void insertUpdate(DocumentEvent e) {
+		copyDocumentContentToSourceFileBody();
+	}
+
+	@Override
+	public void removeUpdate(DocumentEvent e) {
+		copyDocumentContentToSourceFileBody();
+	}
+
+	@Override
+	public void sourceFileContentHasChanged() {
+		copySourceFileBodyToDocumentContent();
+	}
+}
diff --git a/src/plm/core/ui/StatusBar.java b/src/plm/core/ui/StatusBar.java
new file mode 100644
index 0000000..6696fa9
--- /dev/null
+++ b/src/plm/core/ui/StatusBar.java
@@ -0,0 +1,185 @@
+package plm.core.ui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingConstants;
+import javax.swing.Timer;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.GameListener;
+import plm.core.GameStateListener;
+import plm.core.ProgLangChangesListener;
+import plm.core.StatusStateListener;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.ui.action.SetProgLanguage;
+import plm.universe.World;
+
+public class StatusBar extends JPanel implements GameListener,GameStateListener,StatusStateListener, ProgLangChangesListener {
+
+	private static final long serialVersionUID = 8443305863958273495L;
+	private Game game;
+	private JLabel statusMessageLabel;
+	private JLabel statusAnimationLabel;
+	private JLabel progLangLabel;
+	private JPopupMenu popup = new JPopupMenu();
+	
+	private int busyIconIndex = 0;
+
+	private Timer busyIconTimer;
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	public StatusBar(Game game) {
+		super();
+		this.game = game;
+		this.game.addGameStateListener(this);
+		game.addStatusStateListener(this);
+		game.addProgLangListener(this);
+		game.addGameListener(this);
+		initComponents();
+	}
+	
+	public void initComponents() {
+		this.setBorder(BorderFactory.createEtchedBorder());
+
+		// JSeparator separator = new JSeparator(SwingConstants.VERTICAL);
+		statusMessageLabel = new JLabel("");
+		statusAnimationLabel = new JLabel();
+		statusAnimationLabel.setHorizontalAlignment(SwingConstants.LEFT);
+		statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
+		
+		setupLanguages(Game.getInstance().getCurrentLesson().getCurrentExercise());
+		progLangLabel = new JLabel();
+		progLangLabel.setHorizontalAlignment(SwingConstants.LEFT);
+		progLangLabel.setIcon(Game.getProgrammingLanguage().getIcon());
+		progLangLabel.addMouseListener(new MouseListener() {			
+			public void mouseReleased(MouseEvent e) {
+				maybeShowPopup(e);
+			}
+			public void mousePressed(MouseEvent e) {
+				maybeShowPopup(e);
+			}
+			public void mouseExited(MouseEvent e) {}
+			public void mouseEntered(MouseEvent e) {}
+			public void mouseClicked(MouseEvent e) {
+                popup.show(e.getComponent(),
+                        e.getX(), e.getY());
+			}
+			void maybeShowPopup(MouseEvent e) {
+				if (e.isPopupTrigger())
+					mouseClicked(e);
+			}
+		});
+
+		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+		this.add(Box.createHorizontalStrut(10));
+		this.add(statusMessageLabel);
+		this.add(Box.createHorizontalGlue());
+		this.add(statusAnimationLabel);
+		this.add(Box.createHorizontalStrut(20));
+		this.add(progLangLabel);
+		this.add(Box.createHorizontalStrut(10));
+
+		ResourcesCache.loadBusyIconAnimation();
+
+		busyIconTimer = new Timer(30, new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				busyIconIndex = (busyIconIndex + 1) % ResourcesCache.getBusyIconsSize();
+				statusAnimationLabel.setIcon(ResourcesCache.getBusyIcons(busyIconIndex));
+			}
+		});
+
+	}
+
+	@Override
+	public void stateChanged(Game.GameState type) {
+		switch (type) {
+		case SAVING:
+			statusMessageLabel.setText(i18n.tr("Saving"));
+			busyIconTimer.start();
+			break;
+		case COMPILATION_STARTED:
+			statusMessageLabel.setText(i18n.tr("Compiling"));
+			busyIconTimer.start();
+			break;
+		case LOADING_DONE:
+		case SAVING_DONE:
+		case COMPILATION_ENDED:
+		case DEMO_ENDED:
+		case EXECUTION_ENDED:
+			game.statusRootSet("");
+			game.statusArgEmpty();
+			busyIconTimer.stop();
+			statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
+			break;
+		case EXECUTION_STARTED:
+			game.statusRootSet(i18n.tr("Running "));
+			busyIconTimer.start();
+			break;
+		case DEMO_STARTED:
+			game.statusRootSet(i18n.tr("Playing demo "));
+			busyIconTimer.start();
+			break;		
+		case LOADING:
+			game.statusRootSet(i18n.tr("Loading "));
+			busyIconTimer.start();
+			break;
+		default:
+			statusMessageLabel.setText("");
+			statusAnimationLabel.setIcon(ResourcesCache.getIcon("img/busyicon/idle.png"));
+		}
+	}
+
+	@Override
+	public void stateChanged(final String txt) {
+		statusMessageLabel.setText(txt);
+		//RepaintManager.currentManager(statusMessageLabel).markCompletelyDirty(statusMessageLabel);
+		//RepaintManager.currentManager(statusMessageLabel).paintDirtyRegions();
+	}
+
+	public void setupLanguages(Lecture lecture) {
+		popup.removeAll();
+		Game g = Game.getInstance();
+		if (lecture instanceof Exercise) {
+			Exercise exo = (Exercise) lecture;
+			for (ProgrammingLanguage pl : exo.getProgLanguages()) {
+				JMenuItem item = new JMenuItem(pl.getIcon());
+			    item.addActionListener(new SetProgLanguage(g,pl));
+				popup.add(item);
+			}
+		}
+	}
+	@Override
+	public void currentProgrammingLanguageHasChanged(ProgrammingLanguage newLang) {
+		progLangLabel.setIcon(newLang.getIcon());
+	}
+	@Override
+	public void currentExerciseHasChanged(Lecture lecture) {
+		setupLanguages(lecture);
+	}
+	@Override
+	public void currentLessonHasChanged() {
+		setupLanguages(Game.getInstance().getCurrentLesson().getCurrentExercise());
+	}
+	@Override
+	public void selectedWorldHasChanged(World newWorld) { /* don't care */ }
+	@Override
+	public void selectedEntityHasChanged() { /* tell your mum */ }
+	@Override
+	public void selectedWorldWasUpdated() { /* go away */ }
+}
diff --git a/src/plm/core/ui/StudentDetailsDialog.java b/src/plm/core/ui/StudentDetailsDialog.java
new file mode 100644
index 0000000..d2cb828
--- /dev/null
+++ b/src/plm/core/ui/StudentDetailsDialog.java
@@ -0,0 +1,54 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import plm.core.model.ServerExerciseData;
+import plm.core.model.ServerUserData;
+
+/**
+ * Dialog to display detailed data about a student in a course
+ * For now, it is only text, but it could be graphs of progression, ...
+ */
+public class StudentDetailsDialog extends JDialog {
+	private static final long serialVersionUID = 1L;
+
+    public StudentDetailsDialog(ServerUserData userData) {
+        super(MainFrame.getInstance(), "Details on " + userData.getUsername(), false);
+        setLayout(new BorderLayout());
+
+        JPanel infosPanel = new JPanel();
+        infosPanel.setLayout(new BoxLayout(infosPanel, BoxLayout.PAGE_AXIS));
+        infosPanel.setBorder(BorderFactory.createTitledBorder("Infos on " + userData.getUsername()));
+
+        infosPanel.add(new JLabel("Last Join: " + userData.getLastJoin()));
+        infosPanel.add(new JLabel("Last Leave: " + userData.getLastLeave()));
+        infosPanel.add(new JLabel("Last Heartbeat: " + userData.getLastHeartbeat()));
+        infosPanel.add(new JLabel("Total number of exercises passed: " + userData.getExercisesTotal()));
+        infosPanel.add(new JLabel("Total number of exercises passed with success: " + userData.getExercisesPassed()));
+
+        JPanel exercisesPanel = new JPanel();
+        exercisesPanel.setLayout(new BoxLayout(exercisesPanel, BoxLayout.PAGE_AXIS));
+        exercisesPanel.setBorder(BorderFactory.createTitledBorder("Exercises done"));
+        for(ServerExerciseData exo: userData.getExercises()){
+            exercisesPanel.add(new JLabel(exo.getName() + " (" + exo.getLang() + ") " + exo.getPassedTests()
+            + "/" + exo.getTotalTests() + " - " + exo.getDate()));
+        }
+
+        add(infosPanel, BorderLayout.NORTH);
+        add(exercisesPanel, BorderLayout.CENTER);
+
+        pack();
+        setMinimumSize(new Dimension(500, 300));
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(true);
+        setVisible(true);
+        setLocationRelativeTo(getParent());
+    }
+}
diff --git a/src/plm/core/ui/TeacherConsoleDialog.java b/src/plm/core/ui/TeacherConsoleDialog.java
new file mode 100644
index 0000000..2635f9b
--- /dev/null
+++ b/src/plm/core/ui/TeacherConsoleDialog.java
@@ -0,0 +1,145 @@
+package plm.core.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.KeyEvent;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JToolBar;
+
+import plm.core.model.Course;
+import plm.core.model.Game;
+import plm.core.model.ServerAnswer;
+import plm.core.ui.action.CreateCourse;
+import plm.core.ui.action.DeleteCourse;
+import plm.core.ui.action.RefreshCourse;
+
+/**
+ * Dialog to display all options available to the teacher
+ * Once the course selected, he can view its students results in this console
+ * He can also manage courses : create or delete
+ */
+public class TeacherConsoleDialog extends JDialog {
+	private static final long serialVersionUID = 1L;
+
+    //private Game game;
+    //private Course course;
+    private JLabel courseNameLabel;
+    private ResultsPanel allResultsPanel;
+    private ResultsPanel helpPanel;
+    private ResultsPanel layaboutPanel;
+    private ResultsPanel badPanel;
+    private ResultsPanel goodPanel;
+
+    public TeacherConsoleDialog() {
+        super(MainFrame.getInstance(), "PLM Teacher Console", false);
+
+        Game game = Game.getInstance();
+        Course course = game.getCurrentCourse();
+
+        // automatically refresh the course to display in the teacher console if it's empty
+        if (course.getCourseId() != null && !course.getCourseId().isEmpty()
+                && course.getServerData() == null){
+            String answer = course.refresh();
+            try {
+                if (ServerAnswer.values()[Integer.parseInt(answer)] == ServerAnswer.WRONG_TEACHER_PASSWORD)
+                    JOptionPane.showMessageDialog(this, "Wrong teacher password for the course",
+                            "Server error", JOptionPane.ERROR_MESSAGE);
+            } catch (NumberFormatException nfe) {
+             // the answer was not a status message, it contains course data
+            }
+            // refresh the needing help, layout, bad and good students lists
+            course.refreshStudentsLists();
+        }
+
+        initComponent();
+    }
+
+    public void initComponent() {
+        setLayout(new BorderLayout());
+
+        //Top toolbar
+        JToolBar toolBar = new JToolBar();
+        toolBar.setBorder(BorderFactory.createEtchedBorder());
+
+        Game game = Game.getInstance();
+        
+        courseNameLabel = new JLabel(game.getCourseID().isEmpty() ? "No course selected" : "[" + game.getCourseID() + "]");
+
+        JButton newButton = new JButton(new CreateCourse(game, "New course",
+                ResourcesCache.getIcon("img/console_add.png"), this));
+        newButton.setBorderPainted(false);
+
+        JButton refreshButton = new JButton(new RefreshCourse(game, "Refresh",
+                ResourcesCache.getIcon("img/console_refresh.png"), this));
+        refreshButton.setBorderPainted(false);
+
+        JButton deleteButton = new JButton(new DeleteCourse(game, "Delete",
+                ResourcesCache.getIcon("img/console_delete.png"), this));
+        deleteButton.setBorderPainted(false);
+
+        toolBar.add(courseNameLabel);
+        toolBar.add(newButton);
+        toolBar.add(refreshButton);
+        toolBar.add(deleteButton);
+        
+        add(BorderLayout.NORTH, toolBar);
+        
+        //Center tabbed panel, with the different resultsPanel
+        JTabbedPane tabbedPanel = new JTabbedPane();
+        
+        allResultsPanel = new ResultsPanel(null);
+        tabbedPanel.addTab("All results", new JScrollPane(allResultsPanel));
+        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_A);
+        
+        Course course = game.getCurrentCourse();
+        
+        helpPanel = new ResultsPanel(course.getNeedingHelpStudents());
+        tabbedPanel.addTab("Need help", null,
+                new JScrollPane(helpPanel), "Students requesting help");
+        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_H);
+
+        layaboutPanel = new ResultsPanel(course.getLayaboutStudents());
+        tabbedPanel.addTab("No activity", null,
+                new JScrollPane(layaboutPanel), "Students with no recorded activity");
+        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_L);
+
+        badPanel = new ResultsPanel(course.getBadStudents());
+        tabbedPanel.addTab("Failing", null,
+                new JScrollPane(badPanel), "Students failing completely");
+        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_B);
+
+        goodPanel = new ResultsPanel(course.getGoodStudents());
+        tabbedPanel.addTab("Successful", null,
+                new JScrollPane(goodPanel), "Students doing good");
+        tabbedPanel.setMnemonicAt(0, KeyEvent.VK_G);
+        
+        add(BorderLayout.CENTER, tabbedPanel);
+
+        pack();
+        setMinimumSize(new Dimension(500, 300));
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(true);
+        setVisible(true);
+
+        setLocationRelativeTo(getParent());
+
+    }
+
+    public void refresh() {
+    	Game game = Game.getInstance();
+        courseNameLabel.setText(game.getCourseID().isEmpty() ? "" : "[" + game.getCourseID() + "]");
+        allResultsPanel.displayResults();
+        helpPanel.displayResults();
+        layaboutPanel.displayResults();
+        badPanel.displayResults();
+        goodPanel.displayResults();
+        this.repaint();
+    }
+}
diff --git a/src/plm/core/ui/TipsDialog.java b/src/plm/core/ui/TipsDialog.java
new file mode 100644
index 0000000..faed4ad
--- /dev/null
+++ b/src/plm/core/ui/TipsDialog.java
@@ -0,0 +1,28 @@
+package plm.core.ui;
+
+import javax.swing.JFrame;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Lecture;
+
+ at SuppressWarnings("serial")
+public class TipsDialog extends AbstractAboutDialog {
+
+	public TipsDialog(JFrame parent) {
+		super(parent);
+		currentExerciseHasChanged(Game.getInstance().getCurrentLesson().getCurrentExercise());
+	}
+
+	@Override
+	public void currentExerciseHasChanged(Lecture lect) {
+		setTitle("Tips");
+		this.area.setText("no tips");
+		this.area.setCaretPosition(0);
+	}
+	
+	public void setText(String txt) {
+		this.area.setText(txt);
+		this.area.setCaretPosition(0);
+	}
+
+}
diff --git a/src/plm/core/ui/WorldCellRenderer.java b/src/plm/core/ui/WorldCellRenderer.java
new file mode 100644
index 0000000..2bf99c8
--- /dev/null
+++ b/src/plm/core/ui/WorldCellRenderer.java
@@ -0,0 +1,46 @@
+package plm.core.ui;
+
+import java.awt.Component;
+
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+
+import plm.universe.World;
+
+
+
+
+public class WorldCellRenderer extends JLabel implements ListCellRenderer {
+
+ 	private static final long serialVersionUID = -8332490521368971733L;
+
+	public WorldCellRenderer() {
+		//setOpaque(true);
+	}
+
+	@Override
+	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+			boolean cellHasFocus) {
+
+		if (value instanceof World) {
+			World w = (World) value;
+			setText(w.getName());
+		} else {
+			setText(value!=null?value.toString():"");
+		}
+       
+        if (isSelected) {
+            setBackground(list.getSelectionBackground());
+            setForeground(list.getSelectionForeground());
+        } else {
+            setBackground(list.getBackground());
+            setForeground(list.getForeground());
+        }
+                     
+        setFont(list.getFont());
+        setOpaque(true);
+        return this;
+	}
+
+}
diff --git a/src/plm/core/ui/WorldComboListAdapter.java b/src/plm/core/ui/WorldComboListAdapter.java
new file mode 100644
index 0000000..43950f8
--- /dev/null
+++ b/src/plm/core/ui/WorldComboListAdapter.java
@@ -0,0 +1,82 @@
+package plm.core.ui;
+
+import javax.swing.AbstractListModel;
+import javax.swing.ComboBoxModel;
+
+import plm.core.GameListener;
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.universe.World;
+
+public class WorldComboListAdapter extends AbstractListModel implements ComboBoxModel, GameListener {
+
+	private static final long serialVersionUID = -4669130955472219209L;
+	private Game game;
+	private World selectedWorld;
+	private Exercise currentExercise;
+	
+	public WorldComboListAdapter(Game game) {
+		this.game = game;
+		this.game.addGameListener(this);
+		if (game.getCurrentLesson().getCurrentExercise() instanceof Exercise) {
+			this.currentExercise = (Exercise) this.game.getCurrentLesson().getCurrentExercise();
+			this.selectedWorld = this.game.getSelectedWorld();
+		}
+	}
+
+	@Override
+	public Object getElementAt(int index) {
+		return currentExercise == null?null: this.currentExercise.getWorld(index);
+	}
+
+	@Override
+	public int getSize() {
+		return currentExercise == null?0: currentExercise.getWorldCount();
+	}
+
+	@Override
+	public Object getSelectedItem() {
+		return currentExercise == null?null: selectedWorld;
+	}
+
+	@Override
+	public void setSelectedItem(Object anItem) {
+		if (anItem instanceof World) {
+			World w = (World) anItem;
+			this.selectedWorld = w;
+			this.game.setSelectedWorld(w);
+		} else {
+			Logger.log("WordComboListAdapter:setSelectedItem", "parameter is not a world");
+		}
+	}
+
+	
+	@Override
+	public void currentExerciseHasChanged(Lecture lect) {
+		if (lect instanceof Exercise) {
+			this.currentExercise = (Exercise) lect;
+			this.selectedWorld = game.getSelectedWorld();
+			fireContentsChanged(this, 0, this.currentExercise.getWorldCount()-1);
+		} else {
+			currentExercise = null;
+			selectedWorld = null;
+		}
+	}
+	
+	@Override
+	public void currentLessonHasChanged() { /* don't care */ }
+
+	@Override
+	public void selectedWorldHasChanged(World w) {
+		this.selectedWorld = w;
+		fireContentsChanged(this, 0, this.currentExercise.getWorldCount()-1);		
+	}
+	
+	@Override
+	public void selectedEntityHasChanged() { /* don't care */ }
+	
+	@Override
+	public void selectedWorldWasUpdated() { /* don't care */ }
+}
diff --git a/src/plm/core/ui/WorldView.java b/src/plm/core/ui/WorldView.java
new file mode 100644
index 0000000..2bd2b38
--- /dev/null
+++ b/src/plm/core/ui/WorldView.java
@@ -0,0 +1,61 @@
+package plm.core.ui;
+
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+
+import plm.universe.IWorldView;
+import plm.universe.World;
+
+
+
+public abstract class WorldView extends JComponent  implements IWorldView {
+
+	private static final long serialVersionUID = -4599730915218800968L;
+
+	protected World world;
+	
+	public WorldView(World w) {
+		this.world = w;
+		w.doDelay();
+		this.world.addWorldUpdatesListener(this);
+	}
+	
+	public void setWorld(World w) {
+		this.world.removeWorldUpdatesListener(this);
+		this.world = w;
+		this.world.addWorldUpdatesListener(this);
+		worldHasMoved();
+	}
+
+	@Override
+	public void worldHasMoved() {
+		if (SwingUtilities.isEventDispatchThread()) {
+			repaint();
+		} else {
+			SwingUtilities.invokeLater(new Runnable() {
+				public void run() {
+					repaint();
+				}
+			});			
+		}
+	}
+	
+	@Override
+	public void worldHasChanged() {
+		/* nothing specific to do here since we already react to HasMoved */
+	}
+
+	public boolean isWorldCompatible(World world) {
+		return world.getClass().equals(this.world.getClass());
+	}
+
+	/** Returns what should be added to the tab name */
+	public String getTabName() {
+		return ""; 
+	}
+
+	/** Returns what should be added to the tooltip */
+	public String getTip() {
+		return "";
+	}
+}
diff --git a/src/plm/core/ui/action/AbstractGameAction.java b/src/plm/core/ui/action/AbstractGameAction.java
new file mode 100644
index 0000000..0a4c1d7
--- /dev/null
+++ b/src/plm/core/ui/action/AbstractGameAction.java
@@ -0,0 +1,60 @@
+package plm.core.ui.action;
+
+import java.util.Locale;
+
+import javax.swing.AbstractAction;
+import javax.swing.ImageIcon;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+
+
+public abstract class AbstractGameAction extends AbstractAction {
+
+	private static final long serialVersionUID = -1190103028775831188L;
+	private String descEnabled, descDisabled;
+
+	protected Game game;
+	protected Locale locale;
+	protected I18n i18n;
+
+	public AbstractGameAction(Game game, String text) {
+		super(text);
+		this.game = game;
+	}
+	
+	public AbstractGameAction(Game game, String text, ImageIcon icon) {
+		super(text, icon);
+		this.game = game;
+		this.i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",game.getLocale(), I18nFactory.FALLBACK);
+
+	}
+	
+	protected void setDescription(String descEnabled, String descDisabled) {
+		putValue(SHORT_DESCRIPTION, descEnabled);
+		this.descEnabled = descEnabled;
+		this.descDisabled = descDisabled;		
+	}
+
+	public AbstractGameAction(Game game, String text, ImageIcon icon, Integer mnemonic) {
+		this (game,text,icon);
+		putValue(MNEMONIC_KEY, mnemonic);
+	}
+
+	public Game getGame() {
+		return this.game;
+	}
+
+	@Override
+	public void setEnabled(boolean enabled) {
+		if (enabled)
+			putValue(SHORT_DESCRIPTION, descEnabled);
+		else
+			putValue(SHORT_DESCRIPTION, descDisabled);
+			
+		super.setEnabled(enabled);
+	}
+
+}
diff --git a/src/plm/core/ui/action/CleanUpSession.java b/src/plm/core/ui/action/CleanUpSession.java
new file mode 100644
index 0000000..defb0b4
--- /dev/null
+++ b/src/plm/core/ui/action/CleanUpSession.java
@@ -0,0 +1,23 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+
+
+public class CleanUpSession extends AbstractGameAction {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+
+	public CleanUpSession(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		game.clearSession();
+	}
+
+}
diff --git a/src/plm/core/ui/action/CreateCourse.java b/src/plm/core/ui/action/CreateCourse.java
new file mode 100644
index 0000000..19a7c12
--- /dev/null
+++ b/src/plm/core/ui/action/CreateCourse.java
@@ -0,0 +1,34 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.ui.CreateCourseDialog;
+import plm.core.ui.TeacherConsoleDialog;
+
+/**
+ * Controller to handle clicks on the create button from the teacher console
+ */
+public class CreateCourse extends AbstractGameAction {
+	private static final long serialVersionUID = 1L;
+
+    private TeacherConsoleDialog teacherConsoleDialog;
+
+    public CreateCourse(Game game, String text, TeacherConsoleDialog teacherConsoleDialog) {
+        super(game, text);
+        this.teacherConsoleDialog = teacherConsoleDialog;
+    }
+
+    public CreateCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog teacherConsoleDialog) {
+        super(game, text, icon);
+        this.teacherConsoleDialog = teacherConsoleDialog;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent actionEvent) {
+        new CreateCourseDialog().setVisible(true);
+        teacherConsoleDialog.refresh();
+    }
+}
diff --git a/src/plm/core/ui/action/DeleteCourse.java b/src/plm/core/ui/action/DeleteCourse.java
new file mode 100644
index 0000000..fe8a546
--- /dev/null
+++ b/src/plm/core/ui/action/DeleteCourse.java
@@ -0,0 +1,54 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import plm.core.model.Course;
+import plm.core.model.CourseAppEngine;
+import plm.core.model.Game;
+import plm.core.model.ServerAnswer;
+import plm.core.ui.MainFrame;
+import plm.core.ui.TeacherConsoleDialog;
+
+/**
+ * Controller to handle clicks on the Delete button from the teacher console
+ */
+public class DeleteCourse extends AbstractGameAction {
+	private static final long serialVersionUID = 1L;
+
+    private Course course;
+    private TeacherConsoleDialog parentComponent;
+
+    public DeleteCourse(Game game, String text, TeacherConsoleDialog parentComponent) {
+        super(game, text);
+        course = game.getCurrentCourse();
+        this.parentComponent = parentComponent;
+    }
+
+    public DeleteCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog parentComponent) {
+        super(game, text, icon);
+        course = game.getCurrentCourse();
+        this.parentComponent = parentComponent;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent actionEvent) {
+        if (course.getCourseId() != null) {
+            int choice = JOptionPane.showConfirmDialog(MainFrame.getInstance(), "Do you really want to delete the course on the server?");
+            if (choice == JOptionPane.OK_OPTION) {
+                String answer = course.delete();
+                ServerAnswer serverAnswer = ServerAnswer.values()[Integer.parseInt(answer)];
+                if (serverAnswer == ServerAnswer.WRONG_TEACHER_PASSWORD)
+                    JOptionPane.showMessageDialog(parentComponent, "Wrong module teacher password", "Server error",
+                            JOptionPane.ERROR_MESSAGE);
+                if(serverAnswer == ServerAnswer.ALL_IS_FINE){
+                    Game.getInstance().setCurrentCourse(new CourseAppEngine());
+                    MainFrame.getInstance().appendToTitle("");
+                    parentComponent.refresh();
+                }
+            }
+        }
+    }
+}
diff --git a/src/plm/core/ui/action/ExportSession.java b/src/plm/core/ui/action/ExportSession.java
new file mode 100644
index 0000000..3723350
--- /dev/null
+++ b/src/plm/core/ui/action/ExportSession.java
@@ -0,0 +1,43 @@
+package plm.core.ui.action;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.File;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+
+import plm.core.model.Game;
+import plm.core.model.UserAbortException;
+import plm.core.model.session.ZipSessionKit;
+
+public class ExportSession extends AbstractGameAction {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+	private Component parent;
+
+	public ExportSession(Game game, String text, ImageIcon icon, Component parent) {
+		super(game, text, icon);
+		this.parent = parent;
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		JFileChooser fc = new JFileChooser();
+		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+		fc.setAcceptAllFileFilterUsed(false);
+		int returnValue = fc.showSaveDialog(this.parent);
+
+		if (returnValue == JFileChooser.APPROVE_OPTION) {
+			File sessionFileToExportTo = fc.getSelectedFile();
+			
+			ZipSessionKit kit = new ZipSessionKit(this.game);
+			try {
+				kit.storeAll(sessionFileToExportTo);
+			} catch (UserAbortException e1) {
+				e1.printStackTrace();
+			}
+		}
+	}
+
+}
diff --git a/src/plm/core/ui/action/HelpMe.java b/src/plm/core/ui/action/HelpMe.java
new file mode 100644
index 0000000..d49c02c
--- /dev/null
+++ b/src/plm/core/ui/action/HelpMe.java
@@ -0,0 +1,41 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JToggleButton;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+import plm.core.model.HelpAppEngine;
+import plm.core.model.HelpServer;
+import plm.core.ui.ResourcesCache;
+import plm.core.utils.FileUtils;
+
+/**
+ * Class that handle clicks on HELP button
+ * It sends a request to the PLM server
+ */
+public class HelpMe extends AbstractGameAction {
+	private static final long serialVersionUID = 1L;
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",FileUtils.getLocale(), I18nFactory.FALLBACK);
+
+    private HelpServer helpServer;
+    private boolean isRequestingHelp = false;
+
+    public HelpMe(Game game, String text, ImageIcon icon) {
+        super(game, text, icon);
+        helpServer = new HelpAppEngine();
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    	isRequestingHelp = ! isRequestingHelp;
+        helpServer.setStatus(isRequestingHelp);
+        ((JToggleButton)e.getSource()).setText(isRequestingHelp ? i18n.tr("Cancel call") : i18n.tr("Call for Help"));
+        ((JToggleButton)e.getSource()).setIcon(ResourcesCache.getIcon("img/btn-alert-"+(isRequestingHelp?"on":"off")+".png"));
+    }
+
+}
diff --git a/src/plm/core/ui/action/ImportSession.java b/src/plm/core/ui/action/ImportSession.java
new file mode 100644
index 0000000..020ec37
--- /dev/null
+++ b/src/plm/core/ui/action/ImportSession.java
@@ -0,0 +1,38 @@
+package plm.core.ui.action;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.io.File;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+
+import plm.core.model.Game;
+import plm.core.model.session.ZipSessionKit;
+
+public class ImportSession extends AbstractGameAction {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+
+	private Component parent;
+
+	public ImportSession(Game game, String text, ImageIcon icon, Component parent) {
+		super(game, text, icon);
+		this.parent = parent;
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		JFileChooser fc = new JFileChooser();
+		fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+		int returnValue = fc.showOpenDialog(this.parent);
+
+		if (returnValue == JFileChooser.APPROVE_OPTION) {
+			File sessionFileToImportFrom = fc.getSelectedFile();
+			
+			ZipSessionKit kit = new ZipSessionKit(this.game);
+			kit.loadAll(sessionFileToImportFrom);
+		}
+	}
+
+}
diff --git a/src/plm/core/ui/action/OneStep.java b/src/plm/core/ui/action/OneStep.java
new file mode 100644
index 0000000..743c9f4
--- /dev/null
+++ b/src/plm/core/ui/action/OneStep.java
@@ -0,0 +1,22 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+
+
+public class OneStep extends AbstractGameAction {
+
+	private static final long serialVersionUID = 930451111824072175L;
+
+	public OneStep(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		this.game.allowOneStep();		
+	}
+}
diff --git a/src/plm/core/ui/action/PlayDemo.java b/src/plm/core/ui/action/PlayDemo.java
new file mode 100644
index 0000000..f2d8018
--- /dev/null
+++ b/src/plm/core/ui/action/PlayDemo.java
@@ -0,0 +1,30 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+
+public class PlayDemo extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = 5113775865916404566L;
+
+	public PlayDemo(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		this.game.startExerciseDemoExecution();		
+	}
+	
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Run the demo of what you should code for this exercise"),
+				i18n.tr("Impossible to run the demo right now"));		
+	}
+}
diff --git a/src/plm/core/ui/action/QuitGame.java b/src/plm/core/ui/action/QuitGame.java
new file mode 100644
index 0000000..bd7cb9d
--- /dev/null
+++ b/src/plm/core/ui/action/QuitGame.java
@@ -0,0 +1,31 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+
+public class QuitGame extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+
+	public QuitGame(Game game, String text, ImageIcon icon, Integer mnemonic) {
+		super(game, text, icon, mnemonic);
+		game.addHumanLangListener(this);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		game.quit();
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Quit the application"),i18n.tr("Impossible to quit the application right now"));		
+	}
+
+}
diff --git a/src/plm/core/ui/action/RefreshCourse.java b/src/plm/core/ui/action/RefreshCourse.java
new file mode 100644
index 0000000..ae30aa0
--- /dev/null
+++ b/src/plm/core/ui/action/RefreshCourse.java
@@ -0,0 +1,53 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import plm.core.model.Course;
+import plm.core.model.Game;
+import plm.core.model.ServerAnswer;
+import plm.core.ui.TeacherConsoleDialog;
+
+/**
+ * Controller to handle clicks on the refresh button from the teacher console
+ * It download updated data from the server and refresh the console ui
+ */
+public class RefreshCourse extends AbstractGameAction {
+
+	private static final long serialVersionUID = 1L;
+	
+	private Course course;
+    private TeacherConsoleDialog parentComponent;
+
+    public RefreshCourse(Game game, String text, TeacherConsoleDialog parentComponent) {
+        super(game, text);
+        course = game.getCurrentCourse();
+        this.parentComponent = parentComponent;
+    }
+
+    public RefreshCourse(Game game, String text, ImageIcon icon, TeacherConsoleDialog parentComponent) {
+        super(game, text, icon);
+        course = game.getCurrentCourse();
+        this.parentComponent = parentComponent;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent actionEvent) {
+        if (course.getCourseId() != null) {
+            String answer = course.refresh();
+            try {
+                if (ServerAnswer.values()[Integer.parseInt(answer)] == ServerAnswer.WRONG_TEACHER_PASSWORD)
+                    JOptionPane.showMessageDialog(parentComponent, "Wrong teacher password for the course",
+                            "Server error", JOptionPane.ERROR_MESSAGE);
+            } catch (NumberFormatException nfe) {
+             // the answer was not a status message, it contains course data
+            }
+            // refresh the needing help, layabout, bad and good students lists
+            course.refreshStudentsLists();
+
+            parentComponent.refresh();
+        }
+    }
+}
diff --git a/src/plm/core/ui/action/Reset.java b/src/plm/core/ui/action/Reset.java
new file mode 100644
index 0000000..e653332
--- /dev/null
+++ b/src/plm/core/ui/action/Reset.java
@@ -0,0 +1,32 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+
+public class Reset extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = 5113775865916404566L;
+
+	public Reset(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+		game.addHumanLangListener(this);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		this.game.reset();
+	}
+	
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Reset your world to the initial state"),i18n.tr("World cannot be reset right now"));		
+	}
+
+}
diff --git a/src/plm/core/ui/action/RevertExercise.java b/src/plm/core/ui/action/RevertExercise.java
new file mode 100644
index 0000000..d6245d6
--- /dev/null
+++ b/src/plm/core/ui/action/RevertExercise.java
@@ -0,0 +1,52 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.Exercise;
+import plm.core.model.lesson.Lecture;
+import plm.core.model.session.SourceFile;
+import plm.core.model.session.SourceFileRevertable;
+
+public class RevertExercise extends AbstractGameAction {
+
+	private static final long serialVersionUID = -1509545929438458599L;
+
+	public RevertExercise(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		Object[] options = { "OK", "CANCEL" };
+		int choice = 
+			JOptionPane.showOptionDialog(null, "Reverting this exercise will erase all your work and cannot be undone.\n Are you sure that you want to proceed?", "Warning",
+				JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,
+				null, options, options[0]);
+		if (choice != 0) {
+			System.out.println("Revert canceled on user request -- your work was preserved.");
+			return;
+		}
+
+		Lecture lect = game.getCurrentLesson().getCurrentExercise();
+		if (! (lect instanceof Exercise)) 
+			return;
+
+		Exercise ex = (Exercise) lect;
+		for (ProgrammingLanguage lang: ex.getProgLanguages())
+			for (int i=0; i<ex.getSourceFileCount(lang); i++) {
+				SourceFile sf = ex.getSourceFile(lang,i);
+				if (sf instanceof SourceFileRevertable)
+					((SourceFileRevertable) sf).revert();
+			}
+		for (ProgrammingLanguage pl:Game.programmingLanguages) 
+			Game.getInstance().studentWork.setPassed(ex, pl, false);
+		
+		System.out.println("Exercise reverted");
+	}
+
+}
diff --git a/src/plm/core/ui/action/SetLanguage.java b/src/plm/core/ui/action/SetLanguage.java
new file mode 100644
index 0000000..7e189a1
--- /dev/null
+++ b/src/plm/core/ui/action/SetLanguage.java
@@ -0,0 +1,24 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import plm.core.model.Game;
+
+public class SetLanguage extends AbstractGameAction {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+
+	private Locale lang;
+
+	public SetLanguage(Game game, String text, Locale lang) {
+		super(game, text, null);
+		this.lang = lang;
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		game.setLocale(lang);
+	}
+
+}
diff --git a/src/plm/core/ui/action/SetProgLanguage.java b/src/plm/core/ui/action/SetProgLanguage.java
new file mode 100644
index 0000000..1ecb8a9
--- /dev/null
+++ b/src/plm/core/ui/action/SetProgLanguage.java
@@ -0,0 +1,23 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+
+public class SetProgLanguage extends AbstractGameAction {
+
+	private static final long serialVersionUID = 5778501209753480269L;
+
+	private ProgrammingLanguage lang;
+
+	public SetProgLanguage(Game game, ProgrammingLanguage lang) {
+		super(game, lang.toString(), null);
+		this.lang = lang;
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		game.setProgramingLanguage(lang);
+	}
+}
diff --git a/src/plm/core/ui/action/StartExecution.java b/src/plm/core/ui/action/StartExecution.java
new file mode 100644
index 0000000..b345ac2
--- /dev/null
+++ b/src/plm/core/ui/action/StartExecution.java
@@ -0,0 +1,35 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+/** Action launched when the Start button gets hit */
+public class StartExecution extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = -4326617501298324713L;
+	
+	public StartExecution(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+		game.addHumanLangListener(this);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		if (game.getState().equals(Game.GameState.EXECUTION_STARTED) && game.stepModeEnabled()) {
+			game.disableStepMode();
+			game.allowOneStep();
+		} else
+			this.game.startExerciseExecution();		
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Launch the execution of your code"),
+				i18n.tr("Cannot launch the execution right now. Wait a bit, or interrupt current activity with the stop button"));		
+	}
+}
diff --git a/src/plm/core/ui/action/StepExecution.java b/src/plm/core/ui/action/StepExecution.java
new file mode 100644
index 0000000..12830cf
--- /dev/null
+++ b/src/plm/core/ui/action/StepExecution.java
@@ -0,0 +1,33 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+
+public class StepExecution extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = 930451111824072175L;
+
+	public StepExecution(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+		game.addHumanLangListener(this);
+	}
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Execute one step of your code"), 
+				i18n.tr("Impossible to step your code now. Need to stop the execution first?"));
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		if (game.getState().equals(Game.GameState.EXECUTION_STARTED))
+			game.allowOneStep();
+		else			
+			game.startExerciseStepExecution();		
+	}
+}
diff --git a/src/plm/core/ui/action/StopExecution.java b/src/plm/core/ui/action/StopExecution.java
new file mode 100644
index 0000000..6c574d3
--- /dev/null
+++ b/src/plm/core/ui/action/StopExecution.java
@@ -0,0 +1,30 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+
+public class StopExecution extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = -4563140493957678216L;
+	
+	public StopExecution(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+		game.addHumanLangListener(this);
+	}
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Stop your code"), 
+				i18n.tr("No execution to stop right now"));
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		this.game.stopExerciseExecution();		
+	}
+}
diff --git a/src/plm/core/ui/action/SwitchExo.java b/src/plm/core/ui/action/SwitchExo.java
new file mode 100644
index 0000000..94c9a9b
--- /dev/null
+++ b/src/plm/core/ui/action/SwitchExo.java
@@ -0,0 +1,32 @@
+package plm.core.ui.action;
+
+import java.awt.event.ActionEvent;
+import java.util.Locale;
+
+import javax.swing.ImageIcon;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+import plm.core.ui.ChooseLectureDialog;
+
+
+public class SwitchExo extends AbstractGameAction implements HumanLangChangesListener {
+
+	private static final long serialVersionUID = 5113775865916404566L;
+
+	public SwitchExo(Game game, String text, ImageIcon icon) {
+		super(game, text, icon);
+		game.addHumanLangListener(this);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		new ChooseLectureDialog();
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		setDescription(i18n.tr("Switch to another exercise"),"");
+	}
+
+}
diff --git a/src/plm/core/ui/action/package-info.java b/src/plm/core/ui/action/package-info.java
new file mode 100644
index 0000000..27d6602
--- /dev/null
+++ b/src/plm/core/ui/action/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * The action listeners of the UI, calling the right functions of the game singleton.
+ */
+package plm.core.ui.action;
+
diff --git a/src/plm/core/ui/editor/MissionEditor.java b/src/plm/core/ui/editor/MissionEditor.java
new file mode 100644
index 0000000..3fe1cda
--- /dev/null
+++ b/src/plm/core/ui/editor/MissionEditor.java
@@ -0,0 +1,355 @@
+package plm.core.ui.editor;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import javax.swing.AbstractAction;
+import javax.swing.JEditorPane;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+import plm.core.ui.PlmHtmlEditorKit;
+import plm.core.utils.FileUtils;
+import plm.core.utils.PlmSyntaxPane;
+
+public class MissionEditor extends JFrame {
+	private static final long serialVersionUID = 1L;
+
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	private JEditorPane display = new JEditorPane("text/html", "");
+	private JEditorPane editor;
+	
+	private String lastPathSelected;
+	private boolean modified = false;
+	
+	private String TITLE_MODIFIED = i18n.tr("PLM - Mission Editor (modified)");
+	private String TITLE_NOT_MODIFIED = i18n.tr("PLM - Mission Editor");
+	
+	public MissionEditor() {
+		super();
+		setTitle(TITLE_NOT_MODIFIED);
+		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+	    addWindowListener(new WindowAdapter() {
+	    	@Override
+	        public void windowOpened(WindowEvent e) {}
+	    	@Override
+	        public void windowClosing(WindowEvent e) {
+	        	confirmQuit();
+	        }
+	    });
+		setSize(1200, 800);
+		Game.getInstance();
+		PlmSyntaxPane.initKits();
+		initComponents();
+		setVisible(true);
+	}
+
+	private void initComponents() {
+
+		JMenuBar menuBar = new JMenuBar();
+
+		JMenu fileMenu = new JMenu("File");
+		JMenuItem mi;
+		
+		/*
+		mi = new JMenuItem(new NewMissionAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+		*/
+		
+		mi = new JMenuItem(new OpenMissionAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+		
+		mi = new JMenuItem(new SaveMissionAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+		
+		mi = new JMenuItem(new SaveAsMissionAction());
+		fileMenu.add(mi);
+
+		mi = new JMenuItem(new QuitAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+
+		menuBar.add(fileMenu);
+		this.setJMenuBar(menuBar);
+
+		editor = new JEditorPane();
+		
+		getContentPane().setLayout(new BorderLayout());
+		JToolBar toolBar = new JToolBar();
+		// TODO: add buttons
+		getContentPane().add(toolBar, BorderLayout.NORTH);
+
+		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
+		sp.setOneTouchExpandable(false);
+		sp.setLeftComponent(new JScrollPane(editor));
+		sp.setRightComponent(new JScrollPane(display));
+		double weight = 0.5;
+		sp.setResizeWeight(weight);
+		sp.setDividerLocation((int) (((double)getWidth()) * weight));
+
+		getContentPane().add(sp, BorderLayout.CENTER);
+		
+		editor.setContentType("text/xhtml");
+		editor.setEditable(true);
+		
+		display.setEditorKit(new PlmHtmlEditorKit());
+		display.setEditable(false);
+		editor.getDocument().addDocumentListener(new DocumentListener() {
+			private void updateHTML() {
+				if (!modified) {
+					setTitle(TITLE_MODIFIED);
+					modified = true;
+				}
+				String ctn = "<html><head>"+PlmHtmlEditorKit.getCSS()+"</head><body>"+
+						PlmHtmlEditorKit.filterHTML(editor.getText(),true)+
+						"</body></html>";
+				display.setText(ctn);
+				javax.swing.text.Document doc = display.getDocument();
+				int pos = (int) ( (double)doc.getLength()*editor.getCaretPosition()/editor.getDocument().getLength());
+				if (pos>doc.getLength())
+					pos = doc.getLength()-1;
+				if (pos<0)
+					pos = 0;
+				display.setCaretPosition( pos );
+			}
+			@Override
+			public void removeUpdate(DocumentEvent e) {
+				updateHTML();
+			}
+			@Override
+			public void insertUpdate(DocumentEvent e) {
+				updateHTML();
+			}
+			@Override
+			public void changedUpdate(DocumentEvent e) {
+				updateHTML();
+			}
+		});		
+	}
+	
+	public void loadMission(String path) {
+		lastPathSelected = path;
+		try {
+			BufferedReader reader = FileUtils.newFileReader(path, "html", false);
+			StringBuffer content = new StringBuffer();
+			String line;
+			while (null != (line = reader.readLine())) {
+				content.append(line);
+				content.append("\n");
+			}
+
+			editor.setText(content.toString());
+			((jsyntaxpane.SyntaxDocument) editor.getDocument()).clearUndos();
+			modified = false;
+			setTitle(TITLE_NOT_MODIFIED);
+		} catch (IOException e1) {
+			JOptionPane.showMessageDialog(null, e1.getLocalizedMessage(),i18n.tr("Error while reading {0}",lastPathSelected), JOptionPane.ERROR_MESSAGE);
+		}
+	}
+	
+	public void confirmQuit() {
+		if (modified) {
+			int choice = JOptionPane.showConfirmDialog(MissionEditor.this, 
+					Game.i18n.tr("You did not save you changes. Do you want to save it before quiting?"), 
+					Game.i18n.tr("Save or loose your change?"),
+					JOptionPane.YES_NO_CANCEL_OPTION,
+					JOptionPane.QUESTION_MESSAGE);
+
+			switch (choice) {
+			case JOptionPane.CANCEL_OPTION: 
+				return;
+			case JOptionPane.YES_OPTION:
+				SaveMissionAction act = new SaveMissionAction();
+				act.actionPerformed(null);
+				break;
+			case JOptionPane.NO_OPTION:
+				System.out.println("Your changes were lost as you requested.");
+			}
+		}
+		System.exit(0);
+	}
+
+	class SaveMissionAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public SaveMissionAction() {
+			super("Save");
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (!modified)
+				return;
+			
+			if (lastPathSelected == null) {
+				SaveAsMissionAction act = new SaveAsMissionAction();
+				act.actionPerformed(e);
+				return;
+			}
+			File file = new File(lastPathSelected);
+
+			BufferedWriter bw = null;
+			FileWriter fw = null;
+			try {
+				fw = new FileWriter(file);
+				bw = new BufferedWriter(fw);
+				bw.write(editor.getText());
+				bw.close();
+				fw.close();
+			} catch (IOException ex) {
+				// TODO: error dialog
+				System.err.println(ex);
+			} finally {
+				try {
+					if (bw != null)
+						bw.close();
+				} catch (IOException e1) {
+					// TODO: error dialog
+					e1.printStackTrace();
+				}
+			}
+			setTitle(TITLE_NOT_MODIFIED);
+			modified = false;
+		}
+	}
+	class SaveAsMissionAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public SaveAsMissionAction() {
+			super("Save As...");
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			JFileChooser fc;
+			if (lastPathSelected != null)
+				fc = new JFileChooser(lastPathSelected);
+			else
+				fc = new JFileChooser();
+			int status = fc.showSaveDialog(MissionEditor.this);
+
+			if (status == JFileChooser.APPROVE_OPTION) {
+				File file = fc.getSelectedFile();
+
+				BufferedWriter bw = null;
+				FileWriter fw = null;
+				try {
+					fw = new FileWriter(file);
+					bw = new BufferedWriter(fw);
+					bw.write(editor.getText());
+					bw.close();
+					fw.close();
+				} catch (IOException ex) {
+					// TODO: error dialog
+					System.err.println(ex);
+				} finally {
+					try {
+						if (bw != null)
+							bw.close();
+					} catch (IOException e1) {
+						// TODO: error dialog
+						e1.printStackTrace();
+					}
+				}
+			}
+			
+			setTitle(TITLE_NOT_MODIFIED);
+			modified = false;
+		}
+	}
+
+	class OpenMissionAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public OpenMissionAction() {
+			super(i18n.tr("Open Mission..."));
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			if (modified) {
+				int choice = JOptionPane.showConfirmDialog(MissionEditor.this, 
+						Game.i18n.tr("You did not save you changes. Do you want to save it before opening another file?"), 
+						Game.i18n.tr("Save or loose your change?"),
+						JOptionPane.YES_NO_CANCEL_OPTION,
+						JOptionPane.QUESTION_MESSAGE);
+
+				switch (choice) {
+				case JOptionPane.CANCEL_OPTION: 
+					return;
+				case JOptionPane.YES_OPTION:
+					SaveMissionAction act = new SaveMissionAction();
+					act.actionPerformed(e);
+					break;
+				case JOptionPane.NO_OPTION:
+					System.out.println("Your changes were lost as you requested.");
+				}
+				modified = false;	
+			}
+			JFileChooser fc = new JFileChooser(lastPathSelected);
+			fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("HTML files"), "html"));
+			int status = fc.showOpenDialog(MissionEditor.this);
+
+			if (status == JFileChooser.APPROVE_OPTION) {
+				String path = fc.getSelectedFile().getAbsolutePath();
+				for (String[] lang : Game.humanLangs) 
+					if (path.endsWith("."+lang[1]+".html")) { 
+						int choice = JOptionPane.showConfirmDialog(MissionEditor.this, 
+								Game.i18n.tr("You chose a translated mission text for edition ({0}).\n"
+										+ "This is wrong. The translations should be handled with po4a in PLM.\n"
+										+ "Please refer to https://github.com/oster/JLM/wiki/Working-with-the-translations for more information.\n\n"
+										+ "Proceed anyway?",path), 
+										Game.i18n.tr("This is a translated mission text"),
+										JOptionPane.YES_NO_OPTION,
+										JOptionPane.ERROR_MESSAGE);
+						if (choice == JOptionPane.NO_OPTION)
+							return;
+					}
+				lastPathSelected = path;
+				loadMission(lastPathSelected);
+			}
+		}
+
+	}
+
+	class QuitAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public QuitAction() {
+			super(i18n.tr("Quit Map Editor"));
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			confirmQuit();
+		}
+
+	}
+}
diff --git a/src/plm/core/ui/editor/MissionEditorApp.java b/src/plm/core/ui/editor/MissionEditorApp.java
new file mode 100644
index 0000000..05da3ed
--- /dev/null
+++ b/src/plm/core/ui/editor/MissionEditorApp.java
@@ -0,0 +1,22 @@
+package plm.core.ui.editor;
+
+import java.io.File;
+
+import plm.core.model.Game;
+
+public class MissionEditorApp {
+
+	public static void main(String[] args) {
+		MissionEditor editor = new MissionEditor();
+		Game.getInstance().switchDebug(); // Forces the PlmHTMLEditorKit to also display all blocks marked with a class
+		if (args.length>0)
+			editor.loadMission(args[0]);
+		else {
+			String path = System.getProperty("user.dir")+"/src/lessons/welcome/Main.html";
+			File f = new File(path);
+			if (f.exists())
+				editor.loadMission(path);
+		}
+	}
+
+}
diff --git a/src/plm/core/ui/package-info.java b/src/plm/core/ui/package-info.java
new file mode 100644
index 0000000..e3bf4ef
--- /dev/null
+++ b/src/plm/core/ui/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * User interface
+ */
+package plm.core.ui;
+
diff --git a/src/plm/core/utils/ColorMapper.java b/src/plm/core/utils/ColorMapper.java
new file mode 100644
index 0000000..2d889f4
--- /dev/null
+++ b/src/plm/core/utils/ColorMapper.java
@@ -0,0 +1,48 @@
+package plm.core.utils;
+
+import java.awt.Color;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class ColorMapper {
+	static String[] choices = {
+		"white","black","blue","cyan","darkGray","gray","green","lightGray","magenta","orange","pink","red","yellow"};
+	static Color[] colors = {
+		Color.white,Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,Color.red,Color.yellow};
+	static Pattern colorName = Pattern.compile("(\\d+)/(\\d+)/(\\d+)");
+
+	public static Color name2color(String name) throws InvalidColorNameException {
+		for (int i=0; i<choices.length; i++) 
+			if (choices[i].equalsIgnoreCase(name))
+				return colors[i];
+		Matcher m = colorName.matcher(name);
+		if (m.matches()) {
+			try {
+				int r=Integer.parseInt( m.group(1) );
+				int g=Integer.parseInt( m.group(2) );
+				int b=Integer.parseInt( m.group(3) );
+				
+				if (r<0 || r>255) 
+					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Red value is not between 0 and 255");
+				if (g<0 || g>255) 
+					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Green value is not between 0 and 255");
+				if (b<0 || b>255) 
+					throw new InvalidColorNameException("Name "+name+" is not a valid color name: Blue value is not between 0 and 255");
+					
+				return new Color(r,g,b);
+			} catch (NumberFormatException nfe) {
+				throw new InvalidColorNameException("Name "+name+" is not a valid color name since one of its component is not a number",nfe);
+			}
+		} else {
+			throw new InvalidColorNameException("Name "+name+" is not a valid color name");
+		}
+	}
+	
+	public static String color2name(Color c) {
+		for (int i=0; i<choices.length; i++) 
+			if (colors[i].equals(c))
+				return choices[i];
+		return c.getRed()+"/"+c.getGreen()+"/"+c.getBlue();
+	}
+}
diff --git a/src/plm/core/utils/FileUtils.java b/src/plm/core/utils/FileUtils.java
new file mode 100644
index 0000000..8494ccb
--- /dev/null
+++ b/src/plm/core/utils/FileUtils.java
@@ -0,0 +1,135 @@
+package plm.core.utils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+import plm.core.model.lesson.ExerciseTemplated;
+
+/** This class is in charge of loading the resources from disk into memory
+ * 
+ * 	It solves 2 main difficulties. The first one is to find the files in any case, be 
+ *  them in the distributed jar file, or on the disk (as it happens when we develop PLM: 
+ *  we don't build a jar for each run, we directly from our source tree). It also deals 
+ *  with the windows/unix incompatibilities about directory separators (/ or \).
+ * 
+ *  The second problem it deals with is about translations. When looking for a help file, 
+ *  it first search for a suitable translated version. If not found, it fallbacks to the 
+ *  English version. This is done through the locale static variable. Yeah, that's not 
+ *  clean but it just works.
+ */
+public class FileUtils {
+	private static Locale locale;
+	
+	private final static String[] directories = { "", "lib/", "src/" };                
+
+	
+	/** Specifies the locale that we have to use when looking for translated files */
+	public static void setLocale(Locale l) {
+		locale = l;
+	}
+	public static Locale getLocale() {
+		return locale==null?new Locale("en"):locale;
+	}
+	
+	public static BufferedReader newFileReader(String file, String extension, boolean translatable) throws FileNotFoundException, UnsupportedEncodingException {
+		/* first check if we can find it unmodified */
+		int i = 0;
+		if (!translatable) { // extension is ignored in this case. That's useful to get it from a file chooser
+			while (i<directories.length) {
+				if ((new File(directories[i] + file)).exists()) {
+					return new BufferedReader(new FileReader(directories[i] + file));
+				} else {
+					i++;
+				}   	
+			}
+		}
+		
+		if (translatable && locale == null)
+			throw new RuntimeException("locale is null: you cannot request for translated material (yet)");
+		
+		/* Build the list of filenames we will iterate (translated if any, and raw) */
+		String[] fileNames;
+		if (translatable && ! locale.getLanguage().equals("en")) {
+			fileNames = new String[] {
+					file.replace('.', '/') + "." + locale.getLanguage(),
+					file.replace('.', '/')
+			};
+		} else { // not translatable, or currently in English: only search for non-translated form
+				fileNames = new String[] {
+						file.replace('.', '/')
+				};
+		}
+		/* Do that iteration */
+		for (String fileName : fileNames ) {        
+			/* change class name to directories */
+			fileName = fileName + (extension != null ? "." + extension : "");
+			
+			i = 0;
+			while (i<directories.length) {
+				if ((new File(directories[i] + fileName)).exists()) {
+					return new BufferedReader(new FileReader(directories[i] + fileName));
+				} else {
+					i++;
+				}   	
+			}
+        
+			// external HTML file of this exercise not found on file system. Try as resource, in case we are in a jar file
+			String resourceName =  "/"+fileName;
+        	resourceName = resourceName.replace('\\', '/'); /* just in case we were passed a windows path */
+
+        	InputStream s = ExerciseTemplated.class.getResourceAsStream(resourceName);
+        	if (s == null) 
+        		continue; // test next name in the list
+
+        	BufferedReader br = null;
+        	try {
+        		br = new BufferedReader(new InputStreamReader(s, "UTF-8"));
+        	} catch (UnsupportedEncodingException e1) {
+        		e1.printStackTrace();
+        		System.err.println("File encoding of " + fileName + " is not supported on this platform (please report this bug)");
+        		//return null;
+        		throw e1;
+        		//throw new FileNotFoundException(file + "with extension " + extension + " is encoded in an unsupported encoding.");
+        	}
+        	if (br != null) 
+				return br;
+        }
+		// file not found, give up. No logs here, as it is ok that some entities do not exist in some languages
+		if (extension == null)
+			throw new FileNotFoundException(file + " (without extension) could not be found.");
+		throw new FileNotFoundException(file + " with extension " + extension + " could not be found.");
+	}	
+	
+	public static StringBuffer readContentAsText(String file, String extension, boolean translatable) throws FileNotFoundException, UnsupportedEncodingException {
+		BufferedReader br = FileUtils.newFileReader(file, extension, translatable);
+		String newLine = System.getProperty("line.separator");
+		
+		StringBuffer sb = new StringBuffer();
+		try {
+			String s;
+			s = br.readLine();
+			while (s != null) {
+				sb.append(s);
+				sb.append(newLine);
+				s = br.readLine();
+			}
+			
+		} catch (IOException e) {
+			e.printStackTrace();			
+		} finally {
+			try {
+				br.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		return sb;
+	}
+}
diff --git a/src/plm/core/utils/InvalidColorNameException.java b/src/plm/core/utils/InvalidColorNameException.java
new file mode 100644
index 0000000..79a68aa
--- /dev/null
+++ b/src/plm/core/utils/InvalidColorNameException.java
@@ -0,0 +1,11 @@
+package plm.core.utils;
+
+public class InvalidColorNameException extends Exception {
+	private static final long serialVersionUID = 1L;
+	public InvalidColorNameException(String msg){
+		super(msg);
+	}
+	public InvalidColorNameException(String msg, Exception e) {
+		super(msg,e);
+	}
+}
diff --git a/src/plm/core/utils/PlmSyntaxPane.java b/src/plm/core/utils/PlmSyntaxPane.java
new file mode 100644
index 0000000..313b52c
--- /dev/null
+++ b/src/plm/core/utils/PlmSyntaxPane.java
@@ -0,0 +1,90 @@
+package plm.core.utils;
+
+import java.awt.Color;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Properties;
+
+import plm.core.model.Game;
+import jsyntaxpane.DefaultSyntaxKit;
+import jsyntaxpane.SyntaxStyle;
+import jsyntaxpane.SyntaxStyles;
+import jsyntaxpane.TokenType;
+import jsyntaxpane.syntaxkits.JavaSyntaxKit;
+import jsyntaxpane.syntaxkits.PythonSyntaxKit;
+import jsyntaxpane.syntaxkits.ScalaSyntaxKit;
+import jsyntaxpane.syntaxkits.XHTMLSyntaxKit;
+import jsyntaxpane.util.Configuration;
+
+public class PlmSyntaxPane {
+
+	public static void initKits() {
+		DefaultSyntaxKit.initKit();
+        //Configuration conf = DefaultSyntaxKit.getConfig(DefaultSyntaxKit.class);
+
+
+		//TODO: can be configured through a property file in the new version of jsyntaxpane
+		SyntaxStyles st = SyntaxStyles.getInstance();
+		st.put(TokenType.OPERATOR, new SyntaxStyle(Color.BLACK, false, false)); // black
+		st.put(TokenType.KEYWORD, new SyntaxStyle(new Color(0x8d0056), true, false)); // violet,
+																						// bold
+		st.put(TokenType.TYPE, new SyntaxStyle(Color.BLACK, false, false)); // black
+		st.put(TokenType.COMMENT, new SyntaxStyle(new Color(0x29825e), false, false)); // dark
+																						// green
+		st.put(TokenType.NUMBER, new SyntaxStyle(Color.BLACK, false, false)); // black
+		// st.add(TokenType.REGEX, new SyntaxStyle(new Color(0xcc6600), false, false)); // not used in Java
+		// st.add(TokenType.IDENT, new SyntaxStyle(new Color(0x1300c5), false, false)); // dark blue
+		st.put(TokenType.IDENTIFIER, new SyntaxStyle(Color.black, false, false)); // black
+		st.put(TokenType.STRING, new SyntaxStyle(new Color(0x3600ff), false, false)); // blue
+		st.put(TokenType.DEFAULT, new SyntaxStyle(Color.BLACK, false, false)); // black
+
+		Configuration javaConf = JavaSyntaxKit.getConfig(JavaSyntaxKit.class);
+		Configuration pyConf = PythonSyntaxKit.getConfig(PythonSyntaxKit.class);
+		Configuration scalaConf = ScalaSyntaxKit.getConfig(ScalaSyntaxKit.class);
+		Configuration xhtmlConf = XHTMLSyntaxKit.getConfig(XHTMLSyntaxKit.class);
+
+		javaConf.put("DefaultFont", "monospaced 12");
+		pyConf.put("DefaultFont", "monospaced 12");
+		scalaConf.put("DefaultFont", "monospaced 12");
+
+		setupKit(javaConf);
+		setupKit(pyConf);
+		setupKit(scalaConf);
+		setupKit(xhtmlConf);
+	}
+	
+	private static void setupKit(Configuration conf) {
+		Properties props = new Properties();
+		File bindings = new File(Game.getSavingLocation()+File.separatorChar+"bindings.properties");
+		BufferedWriter out = null;
+		try {
+			if (!bindings.exists()) {
+				System.out.println("Bootstraping "+bindings);
+				out = new BufferedWriter(new FileWriter(bindings));
+				// TODO: document the content of this file
+				out.write("Action.find = jsyntaxpane.actions.FindReplaceAction, control H\n");
+				out.write("Action.undo = jsyntaxpane.actions.UndoAction, control Z\n");
+				out.write("Action.redo = jsyntaxpane.actions.RedoAction, control Y\n");
+				out.write("complete-word = jsyntaxpane.actions.CompleteWordAction, control SPACE\n");
+				out.write("Action.toggle-comments = jsyntaxpane.actions.ToggleCommentsAction, control SEMICOLON\n");
+				out.write("PopupMenu = cut-to-clipboard,copy-to-clipboard,paste-from-clipboard,-,select-all,-,undo,redo,-,find,find-next,goto-line,jump-to-pair,-,complete-word,-,toggle-comments\n");
+				out.close();
+			}
+			props.load(new FileReader(bindings));				
+			conf.putAll(props);				
+		} catch (Exception e) {
+			System.out.println("Error while reading the plm bindings: "+e.getLocalizedMessage());
+		} finally {
+			if (out != null)
+				try {
+					out.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+		}
+
+	}
+}
diff --git a/src/plm/universe/BrokenWorldFileException.java b/src/plm/universe/BrokenWorldFileException.java
new file mode 100644
index 0000000..eb3a3df
--- /dev/null
+++ b/src/plm/universe/BrokenWorldFileException.java
@@ -0,0 +1,9 @@
+package plm.universe;
+
+public class BrokenWorldFileException extends Exception {
+	private static final long serialVersionUID = 1L;
+	
+	public BrokenWorldFileException(String msg) {
+		super(msg);
+	}
+}
diff --git a/src/plm/universe/Direction.java b/src/plm/universe/Direction.java
new file mode 100644
index 0000000..69f834d
--- /dev/null
+++ b/src/plm/universe/Direction.java
@@ -0,0 +1,112 @@
+package plm.universe;
+
+import java.awt.Point;
+
+
+// TODO: rewrite using enumeration
+public class Direction {
+	private int value;
+
+	public static final int NORTH_VALUE = 0;
+
+	public static final int EAST_VALUE = 1;
+
+	public static final int SOUTH_VALUE = 2;
+
+	public static final int WEST_VALUE = 3;
+
+	public static final Direction NORTH = new Direction(NORTH_VALUE);
+
+	public static final Direction EAST = new Direction(EAST_VALUE);
+
+	public static final Direction SOUTH = new Direction(SOUTH_VALUE);
+
+	public static final Direction WEST = new Direction(WEST_VALUE);
+
+	private static final Direction rights[] = { EAST, SOUTH, WEST, NORTH };
+
+	private static final Direction lefts[] = { WEST, NORTH, EAST, SOUTH };
+
+	private static final Direction opposites[] = { SOUTH, WEST, NORTH, EAST };
+
+	private Direction(int d) {
+		value = d;
+	}
+
+	public boolean equals(Direction d) {
+		return value == d.value;
+	}
+	
+	public Direction copy() {
+		return new Direction(value);
+	}
+
+	public Direction right() {
+		return rights[value];
+	}
+
+	public Direction left() {
+		return lefts[value];
+	}
+
+	public Direction opposite() {
+		return opposites[value];
+	}
+
+	@Override
+	public String toString() {
+		switch (value) {
+		case NORTH_VALUE:
+			return "NORTH";
+		case EAST_VALUE:
+			return "EAST";
+		case SOUTH_VALUE:
+			return "SOUTH";
+		case WEST_VALUE:
+			return "WEST";
+		default:
+			return "Unknown direction";
+		}
+	}
+
+	public Point toPoint() {
+		switch (value) {
+		case NORTH_VALUE:
+			return new Point(0, -1);
+		case EAST_VALUE:
+			return new Point(1, 0);
+		case SOUTH_VALUE:
+			return new Point(0, 1);
+		case WEST_VALUE:
+			return new Point(-1, 0);
+		default:
+			return null;
+		}
+	}
+	
+	public int intValue() {
+		return this.value;
+	}
+
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + value;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final Direction other = (Direction) obj;
+		if (value != other.value)
+			return false;
+		return true;
+	}
+}
diff --git a/src/plm/universe/Entity.java b/src/plm/universe/Entity.java
new file mode 100644
index 0000000..ff16efb
--- /dev/null
+++ b/src/plm/universe/Entity.java
@@ -0,0 +1,270 @@
+package plm.universe;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import plm.core.PythonExceptionDecipher;
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.universe.lightbot.LightBotEntity;
+
+/* Entities cannot have their own org.xnap.commons.i18n.I18n, use the static Game.i18n instead.
+ * 
+ * This is because we have to pass the classname to the I18nFactory, but it seems to break 
+ * stuff that our code generate new package names. This later case being forced by our use 
+ * of the compiler, we cannot initialize an I18n stuff. 
+ * 
+ * Instead, the solution is to use the static field Game.i18n, as it is done in AbstractBuggle::diffTo().
+ */
+
+public abstract class Entity {
+	protected String name;
+	protected World world;
+
+	private Semaphore oneStepSemaphore = new Semaphore(0);
+
+	public Entity() {}
+
+	public Entity(String name) {
+		this.name=name;
+	}
+	public Entity(String name, World w) {
+		this.name=name;
+		if (w != null) {
+			this.world = w;
+			world.addEntity(this);
+		}
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}	
+
+	public World getWorld() {
+		return world;
+	}
+
+	public void setWorld(World world) {
+		this.world = world;
+	}
+
+	/* This is to allow exercise to forbid the use by students of some functions 
+	 * which are mandatory for core mechanism. See welcome.ArrayBuggle to see how it forbids setPos(int,int)  
+	 */
+	private boolean inited = false;
+	public boolean isInited() {
+		return inited;
+	}
+	public void initDone() {
+		inited = true;		
+	}
+
+	public void allowOneStep() {
+		this.oneStepSemaphore.release();
+	}
+
+	/** Delays the entity to let the user understand what's going on.
+	 *  
+	 * Calls to this function should be placed in important operation of the entity. There e.g. one such call in BuggleEntity.forward().  
+	 */
+	protected void stepUI() {		
+		fireStackListener();
+		world.notifyWorldUpdatesListeners();
+		if (world.isDelayed()) {
+			if (Game.getInstance().stepModeEnabled()) {
+				this.oneStepSemaphore.acquireUninterruptibly();
+			} else {	
+				try {
+					if (world.getDelay()>0) // seems that sleep(0) takes time (yield thread?)
+						Thread.sleep(world.getDelay());
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		}		
+	}
+
+	/** Copy fields of the entity passed in argument */
+	public void copy(Entity other) {
+		setName(other.getName());
+		setWorld(other.getWorld());
+	}
+	/** Copy constructor */
+	public abstract Entity copy();
+
+
+	/* Stuff related to tracing mechanism.
+	 * 
+	 * This is the ability to highlight the current instruction in step-by-step execution. 
+	 * 
+	 * Right now, this is only used for LightBot because I'm not sure of how to retrieve the current point of execution in java or scripting
+	 */
+	ArrayList<IEntityStackListener> stackListeners = new ArrayList<IEntityStackListener>();
+	public void addStackListener(IEntityStackListener l) {
+		stackListeners.add(l);
+	}
+	public void removeStackListener(IEntityStackListener l) {
+		stackListeners.remove(l);
+	}
+	public void fireStackListener() {
+		StackTraceElement[] trace = getCurrentStack();
+		for (IEntityStackListener l:stackListeners)
+			l.entityTraceChanged(this, trace);		
+	}
+	public StackTraceElement[] getCurrentStack() {
+		return Thread.currentThread().getStackTrace();
+	}
+
+	/** Retrieve one parameter from the world */
+	public Object getParam(int i) {
+		return world.parameters[i];
+	}	
+	protected int getParamsAmount() {
+		return world.parameters.length;
+	}
+	
+	/** Returns whether this is the entity selected in the interface */
+	public boolean isSelected() {
+		return this == Game.getInstance().getSelectedEntity();
+	}
+
+	/** Run this specific entity, encoding the student logic to solve a given exercise. 
+	 * 
+	 *  This method is redefined by the leafs of the inheritance tree (the entities involved in exercises)   
+	 *   
+	 *  @see #runIt() that execute an entity depending on the universe and programming language
+	 *    
+	 */
+	protected abstract void run() throws Exception;
+
+	/** Make the entity run, according to the used universe and programming language.
+	 * 
+	 * This task is not trivial given that it depends on the universe and the programming language:
+	 *  * In most universes, the active part is the entity itself. But in the Bat universe, the 
+	 *    student-provided method (that is not a real entity but part of the world directly) 
+	 *    is run against all testcase, that are not real worlds either.
+	 *    
+	 *  * Java entities are launched by just executing their {@link #run()} method that 
+	 *    was redefined by the student (possibly with some templating)
+	 *  * LightBot entities are launched by executing the {@link LightBotEntity#run()} method, 
+	 *    that is NOT defined by the student, but interprets the code of the students.
+	 *  * Python (and other scripting language) entities are launched by injecting the 
+	 *    student-provided code within a {@link ScriptEngine}. 
+	 *    In this later case, the java entity is injected within the scripting world so that it 
+	 *    can forward the student commands to the world. 
+	 * 
+	 *  @see #run() that encodes the student logic in Java
+	 */
+	public void runIt(ExecutionProgress progress) {
+		ProgrammingLanguage progLang = Game.getProgrammingLanguage();
+		ScriptEngine engine = null;
+		if (progLang.equals(Game.JAVA)||progLang.equals(Game.SCALA)||progLang.equals(Game.LIGHTBOT)) {
+			try {
+				run();
+			} catch (Exception e) {
+				String msg = Game.i18n.tr("The execution of your program raised a {0} exception: {1}\n" + 
+						" Please fix your code.\n",e.getClass().getName(),e.getLocalizedMessage());
+				
+				for (StackTraceElement elm : e.getStackTrace())
+					msg+= "   at "+elm.getClassName()+"."+elm.getMethodName()+" ("+elm.getFileName()+":"+elm.getLineNumber()+")"+"\n";
+				
+				System.err.println(msg);
+				progress.setCompilationError(msg);
+				e.printStackTrace();
+			}
+		} else {
+			try {
+				ScriptEngineManager manager = new ScriptEngineManager();       
+				engine = manager.getEngineByName(progLang.getLang().toLowerCase());
+				if (engine==null)
+					throw new RuntimeException(Game.i18n.tr("No ScriptEngine for {0}. Please check your classpath and similar settings.",progLang.getLang()));
+
+				/* Inject the entity into the scripting world so that it can forward script commands to the world */
+				engine.put("entity", this);
+				
+				
+				/* Inject commands' wrappers that forward the calls to the entity */
+				this.getWorld().setupBindings(progLang,engine);
+
+				/* getParam is in every Entity, so put it here to not request the universe to call super.setupBinding() */
+				if (progLang.equals(Game.PYTHON)) 
+					engine.eval(
+							"def getParam(i):\n"+
+							"  return entity.getParam(i)\n" +
+							"def isSelected():\n" +
+							"  return entity.isSelected()\n");		
+
+				String script = getScript(progLang);
+
+				if (script == null) { 
+					System.err.println(Game.i18n.tr("No {0} script source for entity {1}. Please report that bug against PLM.",progLang,this));
+					return;
+				}
+				if (progLang.equals(Game.PYTHON)) {
+					/* that's not really clean to get the output working when we 
+					 * redirect to the graphical console, but it works. */
+					setScriptOffset(progLang, getScriptOffset(progLang)+7);
+					script= "import sys;\n" +
+							"import java.lang;\n" +
+							"class PLMOut:\n" +
+							"  def write(obj,msg):\n" +
+							"    java.lang.System.out.print(str(msg))\n" +
+							"sys.stdout = PLMOut()\n" +
+							"sys.stderr = PLMOut()\n" +
+							script;
+				}
+				engine.eval(script);
+				
+			} catch (ScriptException e) {
+				if (Game.getInstance().isDebugEnabled()) 
+					System.err.println("Here is the script in "+progLang.getLang()+" >>>>"+script+"<<<<");
+				if (Game.getInstance().canPython && PythonExceptionDecipher.isPythonException(e))
+					PythonExceptionDecipher.handlePythonException(e,this,progress);
+				else {
+					System.err.println(Game.i18n.tr("Received a ScriptException that does not come from Python.\n")+e);
+					e.printStackTrace();
+				}
+
+			} catch (Exception e) {
+				String msg = Game.i18n.tr("Script evaluation raised an exception that is not a ScriptException but a {0}.\n"+
+						" Please report this as a bug against PLM, with all details allowing to reproduce it.\n" +
+						"Exception message: {1}\n",e.getClass(),e.getLocalizedMessage());
+				System.err.println(msg);
+				for (StackTraceElement elm : e.getStackTrace()) 
+					msg += elm.toString()+"\n";
+				
+				progress.setCompilationError(msg);
+				e.printStackTrace();
+			}
+		}
+
+	}
+
+	private Map<ProgrammingLanguage,String> script = new HashMap<ProgrammingLanguage, String>(); /* What to execute when running a scripting language */
+	public void setScript(ProgrammingLanguage lang, String s) {
+		script.put(lang,  s);
+	}
+	public String getScript(ProgrammingLanguage lang) {
+		return script.get(lang);
+	}
+
+	private Map<ProgrammingLanguage,Integer> scriptOffset = new HashMap<ProgrammingLanguage, Integer>(); /* the offset to apply to error messages */
+	public void setScriptOffset(ProgrammingLanguage lang, int offset) {
+		scriptOffset.put(lang,  offset);
+	}
+	public Integer getScriptOffset(ProgrammingLanguage lang) {
+		Integer res = scriptOffset.get(lang);
+		return res == null ? 0:res;
+	}
+}
diff --git a/src/plm/universe/EntityControlPanel.java b/src/plm/universe/EntityControlPanel.java
new file mode 100644
index 0000000..0f2297e
--- /dev/null
+++ b/src/plm/universe/EntityControlPanel.java
@@ -0,0 +1,22 @@
+package plm.universe;
+
+import java.util.Locale;
+
+import javax.swing.JPanel;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+
+public abstract class EntityControlPanel extends JPanel implements HumanLangChangesListener {
+	private static final long serialVersionUID = 1L;
+	public abstract void setEnabledControl(boolean enabled);
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
+	
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",newLang, I18nFactory.FALLBACK);
+	}
+}
diff --git a/src/plm/universe/GridWorld.java b/src/plm/universe/GridWorld.java
new file mode 100644
index 0000000..9e21769
--- /dev/null
+++ b/src/plm/universe/GridWorld.java
@@ -0,0 +1,94 @@
+package plm.universe;
+
+
+
+
+
+
+public abstract class GridWorld extends World {
+
+	protected GridWorldCell[][] cells;
+	protected int sizeX;
+	protected int sizeY;
+	protected boolean visibleGrid=true;
+
+	public GridWorld(String name, int x, int y) {
+		super(name);
+		create(x, y);
+	}
+
+	public GridWorld(GridWorld world2) {
+		super(world2);
+		sizeX = world2.getWidth();
+		sizeY = world2.getHeight();
+		visibleGrid = world2.visibleGrid;
+		this.cells = new GridWorldCell[sizeX][sizeY];
+		for (int i = 0; i < sizeX; i++)
+			for (int j = 0; j < sizeY; j++) {
+				cells[i][j] = world2.getCell(i, j).copy(this);
+			}
+	}
+
+	protected void create(int width, int height) {
+		this.sizeX = width;
+		this.sizeY = height;
+		this.cells = new GridWorldCell[sizeX][sizeY];
+		for (int i = 0; i < sizeX; i++)
+			for (int j = 0; j < sizeY; j++)
+				setCell(newCell(i, j), i, j) ;
+	}
+	protected abstract GridWorldCell newCell(int x, int y);
+	
+	public void setWidth(int width) {
+		GridWorldCell[][] oldCells = cells;
+		this.cells = new GridWorldCell[width][sizeY];
+		for (int i = 0; i< Math.min(width, sizeX); i++) 
+			for (int j = 0; j < sizeY; j++)
+				cells[i][j] = oldCells[i][j];
+		
+		if (width>sizeX) // need to increase the table size
+			for (int i = sizeX; i< width; i++) 
+				for (int j = 0; j < sizeY; j++)
+					cells[i][j] = newCell(i, j);
+			
+		sizeX = width;
+	}
+
+	public void setHeight(int height) {
+		GridWorldCell[][] oldCells = cells;
+		this.cells = new GridWorldCell[sizeX][height];
+		for (int i = 0; i< sizeX; i++)  {
+			for (int j = 0; j < Math.min(height, sizeY); j++)
+				cells[i][j] = oldCells[i][j];
+			if (height>sizeY) // need to increase the table size
+				for (int j = sizeY; j < height; j++)
+					cells[i][j] = newCell(i, j);
+		}
+		
+		sizeY = height;
+	}
+
+	
+	public GridWorldCell getCell(int x, int y) {
+		return this.cells[x][y];
+	}
+
+	public void setCell(GridWorldCell c, int x, int y) {
+		this.cells[x][y] = c;
+		notifyWorldUpdatesListeners();
+	}
+
+	public int getWidth() {
+		return this.sizeX;
+	}
+
+	public int getHeight() {
+		return this.sizeY;
+	}
+	public boolean getVisibleGrid() {
+		return visibleGrid;
+	}
+	public void setVisibleGrid(boolean s) {
+		visibleGrid=s;
+	}
+}
diff --git a/src/plm/universe/GridWorldCell.java b/src/plm/universe/GridWorldCell.java
new file mode 100644
index 0000000..5bf7559
--- /dev/null
+++ b/src/plm/universe/GridWorldCell.java
@@ -0,0 +1,42 @@
+package plm.universe;
+
+
+
+
+public abstract class GridWorldCell {
+
+	protected GridWorld world;
+	protected int x;
+	protected int y;
+
+	public GridWorldCell(GridWorld w, int x, int y) {
+		world = w;
+		this.x = x;
+		this.y = y;
+	}
+	public abstract GridWorldCell copy(GridWorld world);
+
+	public GridWorld getWorld() {
+		return this.world;
+	}
+
+	public int getX() {
+		return this.x;
+	}
+
+	public void setX(int newX) {
+		this.x = newX;
+	}
+
+	public int getY() {
+		return this.y;
+	}
+
+	public void setY(int newY) {
+		this.y = newY;
+	}
+
+	public void setWorld(GridWorld w) {
+		this.world = w;
+	}
+}
diff --git a/src/plm/universe/IEntityStackListener.java b/src/plm/universe/IEntityStackListener.java
new file mode 100644
index 0000000..df0e4be
--- /dev/null
+++ b/src/plm/universe/IEntityStackListener.java
@@ -0,0 +1,7 @@
+package plm.universe;
+
+public interface IEntityStackListener {
+	public void entityTraceChanged(Entity e, StackTraceElement[] trace);
+
+	public void tracedEntityChanged(Entity selectedEntity);
+}
diff --git a/src/plm/universe/IWorldView.java b/src/plm/universe/IWorldView.java
new file mode 100644
index 0000000..fc1c672
--- /dev/null
+++ b/src/plm/universe/IWorldView.java
@@ -0,0 +1,15 @@
+package plm.universe;
+
+public interface IWorldView {
+
+	/**
+	 * Called every time something changes: entity move, new entity, entity gets destroyed, etc.
+	 */
+	public void worldHasMoved();
+	
+	/**
+	 * Called when entities are created or destroyed, not when they move
+	 */
+	public void worldHasChanged(); 
+
+}
\ No newline at end of file
diff --git a/src/plm/universe/World.java b/src/plm/universe/World.java
new file mode 100644
index 0000000..48aa18f
--- /dev/null
+++ b/src/plm/universe/World.java
@@ -0,0 +1,335 @@
+package plm.universe;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.swing.ImageIcon;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+import plm.core.model.Logger;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.ui.PlmHtmlEditorKit;
+import plm.core.ui.WorldView;
+import plm.core.utils.FileUtils;
+
+public abstract class World {
+	private boolean isDelayed = false; // whether we display interactively or not
+	private boolean isAnswer = false;
+	private int delay = 100; // delay between two instruction executions of an entity.
+
+	protected ArrayList<Entity> entities = new ArrayList<Entity>();
+
+	private String name;
+
+	public I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",Game.getInstance().getLocale(), I18nFactory.FALLBACK);
+
+	public World(String name) {
+		this.name = name;
+	}
+
+	public World(World w2) {
+		this(w2.getName());
+		reset(w2);
+	}
+
+	public World copy() {
+		World res=null;
+		try {
+			res = this.getClass().getConstructor(this.getClass()).newInstance(this);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new RuntimeException(e);
+		}
+		return res;
+	}
+
+	/**
+	 * Reset the content of a world to be the same than the one passed as
+	 * argument
+	 * 
+	 * @param initialWorld
+	 */
+	public void reset(World initialWorld) {
+		entities = new ArrayList<Entity>();
+		for (Entity b : initialWorld.entities) {
+			Entity br = b.copy();
+			br.setWorld(this);
+			entities.add(br);
+		}
+		this.isDelayed = initialWorld.isDelayed;
+		this.delay = initialWorld.delay;
+		this.parameters = (initialWorld.parameters!=null?initialWorld.parameters.clone():null);
+		notifyEntityUpdateListeners();
+		notifyWorldUpdatesListeners();
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	public void setName(String n) {
+		name = n;
+	}
+
+	public boolean isDelayed() {
+		return isDelayed;
+	}
+	/** returns the delay to apply */
+	public int getDelay() {
+		return this.delay;
+	}
+	/** set the value of the UI delay which will be used on doDelay() */
+	public void setDelay(int d) {
+		this.delay = d;
+		notifyWorldUpdatesListeners(); // notify the speed slider model
+	}
+	/** set current UI delay to what was defined as max UI delay with setDelayUI() */
+	public void doDelay() {
+		isDelayed = true;
+	}
+	/** set current UI delay to 0 */
+	public void doneDelay() {
+		isDelayed = false;
+	}
+	public void setAnswerWorld() {
+		isAnswer = true;
+	}
+	public boolean isAnswerWorld() {
+		return isAnswer;
+	}
+
+	public void addEntity(Entity b) {
+		entities.add(b);
+		notifyEntityUpdateListeners();
+	}
+	public void removeEntity(Entity b) {
+		if (!entities.remove(b)) 
+			System.out.println("Ignoring a request to remove an unknown entity");
+		notifyEntityUpdateListeners();		
+	}
+
+	public void emptyEntities() {
+		entities = new ArrayList<Entity>();
+		notifyEntityUpdateListeners();
+	}
+
+	public void setEntities(ArrayList<Entity> l) {
+		entities = l;
+		notifyEntityUpdateListeners();
+	}
+
+	public int getEntityCount() {
+		return entities.size();
+	}
+
+	public Entity getEntity(int i) {
+		return entities.get(i);
+	}
+	public List<Entity> getEntities() {
+		return entities;
+	}
+	
+	public void runEntities(List<Thread> runnerVect, final ExecutionProgress progress) {
+		if (Game.getInstance().isDebugEnabled())
+			Logger.log("World:runEntities","Programming language: "+Game.getProgrammingLanguage());
+		
+		for (final Entity b : entities) {
+			Thread runner = new Thread(new Runnable() {
+				public void run() {
+					Game.getInstance().statusArgAdd(getName());
+					b.runIt(progress);
+					Game.getInstance().statusArgRemove(getName());
+				}
+			});
+
+			// So that we can still stop it from the AWT Thread, even if an infinite loop occures
+			runner.setPriority(Thread.MIN_PRIORITY);
+
+			runner.start();
+			runnerVect.add(runner);
+		}
+	}
+
+	/* who's interested in every details of the world changes */
+	private ArrayList<IWorldView> worldUpdatesListeners = new ArrayList<IWorldView>();
+
+	/* who's only interested in entities creation and destructions */
+	private ArrayList<IWorldView> entitiesUpdateListeners = new ArrayList<IWorldView>();
+
+	public void addWorldUpdatesListener(IWorldView v) {
+		synchronized (this.worldUpdatesListeners) {
+			this.worldUpdatesListeners.add(v);
+		}
+	}
+
+	public void removeWorldUpdatesListener(IWorldView v) {
+		synchronized (this.worldUpdatesListeners) {
+			this.worldUpdatesListeners.remove(v);
+		}
+	}
+
+	public void notifyWorldUpdatesListeners() {
+		synchronized (this.worldUpdatesListeners) {
+			for (IWorldView v : this.worldUpdatesListeners) {
+				v.worldHasMoved();
+			}
+		}
+	}
+
+	public void addEntityUpdateListener(IWorldView v) {
+		synchronized (this.entitiesUpdateListeners) {
+			this.entitiesUpdateListeners.add(v);
+		}
+	}
+
+	public void removeEntityUpdateListener(IWorldView v) {
+		synchronized (this.entitiesUpdateListeners) {
+			this.entitiesUpdateListeners.remove(v);
+		}
+	}
+
+	public void notifyEntityUpdateListeners() {
+		synchronized (this.entitiesUpdateListeners) {
+			for (IWorldView v : this.entitiesUpdateListeners) {
+				v.worldHasChanged();
+			}
+		}
+	}
+
+	/* IO related */
+	/** Returns whether this universe implements world I/O */
+	public boolean haveIO() { 
+		return false; 
+	}
+	public World readFromFile(String path) throws IOException, BrokenWorldFileException {
+		throw new RuntimeException("This universe does not implement world I/O");
+	}
+
+	public void writeToFile(BufferedWriter f) throws IOException {}
+
+	public void writeToFile(File outputFile) throws IOException {
+		BufferedWriter bw = null;
+		FileWriter fw = null;
+		try {
+			fw = new FileWriter(outputFile);
+			bw = new BufferedWriter(fw);
+			this.writeToFile(bw);
+		} catch (IOException e) {
+			throw e;
+		} finally {
+			if (bw != null)
+				bw.close();
+		}
+	}
+
+	/* Find my UI */
+	public WorldView getView() {
+		return new WorldView(this) {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public boolean isWorldCompatible(World world) {
+				return false;
+			}
+		};
+	}
+	public EntityControlPanel getEntityControlPanel() {
+		return new EntityControlPanel() {
+			private static final long serialVersionUID = 1L;
+			@Override
+			public void setEnabledControl(boolean enabled) {
+			}
+		};
+	}
+	public abstract ImageIcon getIcon();
+
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((entities == null) ? 0 : entities.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if ( !(obj instanceof World))
+			return false;
+		World other = (World) obj;
+		if (entities == null) {
+			if (other.entities != null)
+				return false;
+		} else if (!entities.equals(other.entities))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		return true;
+	}
+
+	String about = null;
+
+	public String getAbout() {
+		if (about == null) {
+			String filename = getClass().getCanonicalName().replace('.', File.separatorChar);
+			StringBuffer sb = null;
+			try {
+				sb = FileUtils.readContentAsText(filename, "html", true);
+			} catch (IOException ex) {
+				about = "File "+filename+".html not found.";
+				return about;
+			}
+			/* read it */
+			about = sb.toString();
+		}
+		return "<html>\n" + PlmHtmlEditorKit.getCSS() + "<body>\n" + PlmHtmlEditorKit.filterHTML(about,Game.getInstance().isDebugEnabled()) + "</body>\n</html>\n";
+	}
+	
+	/**
+	 * Set about to null in order to allows it to be reloaded in the right language
+	 */
+	public void resetAbout() {
+		this.about = null ;
+	}
+
+	protected Object[] parameters = null;
+	public void setParameter(Object[] parameters) {
+		this.parameters = parameters;		
+	}
+	public Object[] getParameters() {
+		return parameters;
+	}
+	public Object getParameter(int i){
+		return parameters[i];
+	}
+
+	public void setSelectedEntity(Entity e) {
+		notifyWorldUpdatesListeners();//EntityUpdateListeners();
+	}
+	/** Returns the script except that must be injected within the environment before running user code
+	 * 
+	 * It should pass all order to the java entity, which were injected independently  
+	 * @throws ScriptException 
+	 */
+	public abstract void setupBindings(ProgrammingLanguage lang,ScriptEngine engine) throws ScriptException;
+
+	/** Returns a textual representation of the differences from the receiver world to the one in parameter*/
+	public abstract String diffTo(World world);
+}
diff --git a/src/plm/universe/bat/BatEntity.java b/src/plm/universe/bat/BatEntity.java
new file mode 100644
index 0000000..16b8ce9
--- /dev/null
+++ b/src/plm/universe/bat/BatEntity.java
@@ -0,0 +1,102 @@
+package plm.universe.bat;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.universe.Entity;
+import plm.universe.World;
+
+public class BatEntity extends Entity {
+	
+	public BatEntity() {
+		super();
+	}
+	
+	public BatEntity(String name, World w) {
+		super(name,w);
+	}
+	
+	public BatEntity(BatEntity other) {
+		super();
+		copy(other);
+	}
+
+	@Override
+	public Entity copy() {
+		return new BatEntity(this);
+	}
+	
+	
+	@Override
+	public void copy(Entity o) {
+		super.copy(o);
+	}
+	
+
+	@Override
+	public boolean equals(Object o) {
+		if (!(o instanceof BatEntity)) {
+			return false;
+		}
+		return (super.equals(o));
+	}
+	
+	@Override
+	protected void run() {
+		throw new RuntimeException ("I thought this method was useless. Please report.");
+	}
+
+	protected void run(BatTest t) {
+		// To be overriden by child classes
+	}
+	
+	@Override 
+	public void runIt(ExecutionProgress progress) {
+		ProgrammingLanguage pl = Game.getProgrammingLanguage();
+		if (pl.equals(Game.JAVA) || pl.equals(Game.SCALA)) {
+			for (BatTest t:((BatWorld) world).getTests())
+				try {
+					run(t);
+				} catch (Exception e) {
+					t.setResult(Game.i18n.tr("This test raised an exception: {0}",e.getMessage()));
+				}
+		} else if (pl.equals(Game.PYTHON)) {
+			ScriptEngine engine ;
+
+			ScriptEngineManager manager = new ScriptEngineManager();       
+			engine = manager.getEngineByName("python");
+			if (engine==null) 
+				throw new RuntimeException("Failed to start an interpreter for python");
+			
+			try {
+				engine.eval(
+						"import java.lang.System.err\n"+
+						"def log(a):\n"+
+						"  java.lang.System.err.print(\"%s: %s\" %(entity.getName(),a))\n");
+				String script = getScript(Game.PYTHON);
+				if (script == null)
+					throw new RuntimeException("No script found for "+Game.getInstance().getCurrentLesson().getCurrentExercise());
+				engine.eval(script);
+			} catch (ScriptException e1) {
+				progress.setCompilationError( e1.getCause().toString() );
+				e1.printStackTrace();
+			}									
+
+			for (BatTest t:((BatWorld) getWorld()).getTests())
+				try {
+					engine.put("thetest",t);
+					engine.eval("thetest.setResult("+t.getName()+")");
+				} catch (Exception e) {
+					t.setResult(Game.i18n.tr("This test raised an exception: {0}",e.getMessage()));
+				}
+		} else {
+			throw new RuntimeException("BatWorld was not ported to "+pl.getLang()+" yet.");
+		}
+		
+	}
+
+}
diff --git a/src/plm/universe/bat/BatExercise.java b/src/plm/universe/bat/BatExercise.java
new file mode 100644
index 0000000..6216539
--- /dev/null
+++ b/src/plm/universe/bat/BatExercise.java
@@ -0,0 +1,69 @@
+package plm.universe.bat;
+
+import java.util.List;
+import java.util.Vector;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.lesson.ExerciseTemplatingEntity;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+
+public abstract class BatExercise extends ExerciseTemplatingEntity {
+	public static final boolean INVISIBLE = false;
+	public static final boolean VISIBLE = true;
+	
+	public BatExercise(Lesson lesson) {
+		super(lesson);
+	}
+
+	protected void setup(World[] ws) {
+		if (ws.length > 1)
+			throw new RuntimeException("Bat exercises must have at most one world");
+		
+		String entName = ws[0].getName();
+		
+		/* Install the corrections: the first time setResult is called, it set 'expected' instead */
+		for (BatTest t : ((BatWorld)ws[0]).tests)
+			run(t);
+		
+		super.setup(ws,entName,
+				"import plm.universe.bat.BatEntity; "+
+		        "import plm.universe.bat.BatWorld; "+
+		        "import plm.universe.bat.BatTest; "+
+		        "import plm.universe.World; "+
+		        "public class "+entName+" extends BatEntity { ");
+	}
+	
+	@Override
+	public void runDemo(List<Thread> runnerVect){
+		/* No demo in bat exercises */
+	}
+
+	public abstract void run(BatTest t);
+	
+	@Override 
+	public void mutateEntities(WorldKind kind, StudentOrCorrection whatToMutate) {
+		if (whatToMutate == StudentOrCorrection.STUDENT) {
+			super.mutateEntities(kind, whatToMutate);
+			return;
+		}
+		/* compute the correction */
+			
+		Vector<World> worlds;
+		switch (kind) {
+		case INITIAL: worlds = initialWorld; break;
+		case CURRENT: worlds = currentWorld; break;
+		case ANSWER:  worlds = answerWorld;  break;
+		default: throw new RuntimeException("kind is invalid: "+kind);
+		}
+
+		for (ProgrammingLanguage pl : getProgLanguages()) {
+			if (!pl.equals(Game.JAVA) && !pl.equals(Game.SCALA)) 
+				worlds.get(0).getEntity(0).setScript(pl, corrections.get(pl));
+		}
+		
+		for (BatTest t : ((BatWorld)worlds.get(0)).tests) 
+			t.objectiveTest = true;
+	}
+}
diff --git a/src/plm/universe/bat/BatTest.java b/src/plm/universe/bat/BatTest.java
new file mode 100644
index 0000000..268d349
--- /dev/null
+++ b/src/plm/universe/bat/BatTest.java
@@ -0,0 +1,235 @@
+package plm.universe.bat;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+
+public class BatTest {
+	Object[] parameters;
+	
+	protected Object result;
+	protected Object expected;
+	
+	private boolean visible;
+	private boolean correct,answered;
+	public boolean objectiveTest=false; // ExoTest messes with it, sorry
+	private String funName;
+	
+	public BatTest(String funName, boolean visible,Object parameters) {
+		this.funName = funName;
+		this.visible = visible;
+		this.correct = false;
+		this.answered = false;
+		
+		/* Cast parameters into an array on need */
+		if (parameters.getClass().isArray()) {
+			this.parameters = (Object[]) parameters;
+		} else {
+			this.parameters = new Object[] {parameters};
+		}
+	}
+	public BatTest copy() {
+		BatTest res = new BatTest(funName,visible,parameters.clone());
+		res.result = result;
+		res.expected = expected;
+		return res;
+	}
+	
+	public boolean isVisible() {
+		return visible;
+	}
+	
+	@Override
+	public boolean equals(Object o) {  
+		if (!(o instanceof BatTest)) 
+			return false;
+		BatTest other = (BatTest) o;
+		if (other.parameters.length != parameters.length) {
+			//System.out.println("While comparing a Bat test, the amount of parameters differs: "+parameters.length+" != "+other.parameters.length);
+			return false;
+		}
+		for (int i=0;i<parameters.length;i++)
+			if (!parameters[i].equals(other.parameters[i])) {
+				//System.out.println("While comparing a Bat test, the parameter "+i+" differs: "+parameters[i]+" != "+other.parameters[i]);
+				return false;
+			}
+		if (isObjective() && !other.isObjective()) {
+			/* We seem to be called as answer.equals(current) from the check() method. 
+			 * Act accordingly by comparing our expected to their result
+			 */
+			if (expected == null && other.result != null) {
+				return false;			
+			}
+			if (expected !=null && !expected.equals(other.result)) {
+				return false;
+			}
+		} else if (!isObjective() && other.isObjective()) {
+			/* We seem to be called as current.equals(answer). Weird I thought it was impossible. Anyway. */
+			if (result == null && other.expected != null) {
+				return false;			
+			}
+			if (result !=null && !result.equals(other.expected)) {
+				return false;
+			}
+		} else {
+			/* Act as an usual equal method as we don't seem to be called from check(). From the UI maybe? */
+			if (result == null && other.result != null) {
+				//System.out.println("While comparing a Bat test, the result differs: null != "+other.result);
+				return false;			
+			}
+			if (result !=null && !result.equals(other.result)) {
+				//System.out.println("While comparing a Bat test, the result differs: "+result+" != "+other.result);
+				return false;
+			}
+			if (expected == null && other.result != null) {
+				return false;			
+			}
+			if (expected != null && !expected.equals(other.expected)) {
+				//System.out.println("While comparing a Bat test, the expected value differs: "+expected+" != "+other.expected);
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public Object getParameter(int i) {
+		return parameters[i];
+	}
+
+	public boolean isAnswered() {
+		return answered;
+	}
+	public boolean isCorrect() {
+		return correct;
+	}
+	
+	private String name = null;
+
+	private void displayParameter(Object o, StringBuffer sb, ProgrammingLanguage pl) {
+		if (o == null) {
+			sb.append("null");
+			
+		} else if (o instanceof String[]) {
+			if (pl.equals(Game.JAVA)) {
+				sb.append("{");
+			} else if (pl.equals(Game.SCALA)) {
+				sb.append("Array(");
+			} else if (pl.equals(Game.PYTHON)) { 
+				sb.append("[");
+			} else {
+				throw new RuntimeException("Please port me to "+pl.getLang());
+			}
+			
+			String[]a = (String[]) o;
+			for (String i:a) {
+				sb.append(i+",");
+			}
+			
+			sb.deleteCharAt(sb.length()-1);
+			if (pl.equals(Game.JAVA)) {
+				sb.append("}");
+			} else if (pl.equals(Game.SCALA)) {
+				sb.append(")");
+			} else if (pl.equals(Game.PYTHON)) { 
+				sb.append("]");
+			} else {
+				throw new RuntimeException("Please port me to "+pl.getLang());
+			}
+		} else if (o.getClass().isArray()){
+			if (pl.equals(Game.JAVA)) {
+				sb.append("{");
+			} else if (pl.equals(Game.SCALA)) {
+				sb.append("Array(");
+			} else if (pl.equals(Game.PYTHON)) { // Python
+				sb.append("[");
+			} else {
+				throw new RuntimeException("Please port me to "+pl.getLang());
+			}
+			if (o.getClass().getComponentType().equals(Integer.TYPE)) {
+				int[]a = (int[]) o;
+				for (int i:a) 
+					sb.append(i+",");
+				
+				if (a.length > 0) // Don't kill the last comma if there is none
+					sb.deleteCharAt(sb.length()-1);
+			} else {
+				throw new RuntimeException("Unhandled internal type (only integer arrays are handled so far)");
+			}
+			if (pl.equals(Game.JAVA)) {
+				sb.append("}");
+			} else if (pl.equals(Game.SCALA)) {
+				sb.append(")");
+			} else if (pl.equals(Game.PYTHON)) { 
+				sb.append("]");
+			} else {
+				throw new RuntimeException("Please port me to "+pl.getLang());
+			}
+		} else if (o instanceof Boolean) {
+			Boolean b = (Boolean) o;
+			if (pl.equals(Game.JAVA) || pl.equals(Game.SCALA)) {
+				sb.append(b ? "true":"false");
+			} else if (pl.equals(Game.PYTHON)) { 
+				sb.append(b ? "True" : "False");
+			} else {
+				throw new RuntimeException("Please port me to "+pl.getLang());
+			}
+		} else if (o instanceof String && pl.equals(Game.PYTHON)) {
+			sb.append("\""+o+"\"");
+		} else {
+			sb.append(o.toString());
+		}		
+	}
+	public String getName() {
+		ProgrammingLanguage pl = Game.getProgrammingLanguage();
+		if (name == null) {
+			StringBuffer sb=new StringBuffer(funName+"(");
+			
+			for (Object o:parameters) {
+				displayParameter(o, sb, pl);
+				sb.append(",");
+			}
+			
+			sb.deleteCharAt(sb.length()-1);
+			sb.append(")");					
+			name=sb.toString();
+
+		}
+		return name;
+	}
+	public boolean isObjective() {
+		return objectiveTest;
+	}
+	
+	public String toString() {
+		ProgrammingLanguage pl = Game.getProgrammingLanguage();
+		StringBuffer res = new StringBuffer(getName());
+		res.append("=");
+		displayParameter(result, res, pl);
+		res.append(" (expected: ");
+		displayParameter(expected, res, pl);
+		res.append("; isObjective: "+isObjective()+")");
+		return res.toString();
+	}
+	public String getResult() {
+		Object o = result;
+		if (isObjective())
+			o = expected;
+		
+		if (o != null) {
+			StringBuffer sb = new StringBuffer();
+			displayParameter(o, sb, Game.getProgrammingLanguage());
+			return sb.toString();
+		} else {
+			return "(null)";
+		}
+	}
+	public void setResult(Object r) {
+		result = r;
+		if (expected == null) {
+			expected = r; // The first time we're set, that's an answer which comes in
+		} else {
+			if (expected != null)
+				correct = expected.equals(result);
+			answered = true;
+		}
+	}
+}
diff --git a/src/jlm/universe/bat/BatWorld.fr.html b/src/plm/universe/bat/BatWorld.fr.html
similarity index 100%
rename from src/jlm/universe/bat/BatWorld.fr.html
rename to src/plm/universe/bat/BatWorld.fr.html
diff --git a/src/jlm/universe/bat/BatWorld.html b/src/plm/universe/bat/BatWorld.html
similarity index 100%
rename from src/jlm/universe/bat/BatWorld.html
rename to src/plm/universe/bat/BatWorld.html
diff --git a/src/plm/universe/bat/BatWorld.java b/src/plm/universe/bat/BatWorld.java
new file mode 100644
index 0000000..8d86291
--- /dev/null
+++ b/src/plm/universe/bat/BatWorld.java
@@ -0,0 +1,96 @@
+package plm.universe.bat;
+
+import java.util.List;
+import java.util.Vector;
+
+import javax.script.ScriptEngine;
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.World;
+
+public class BatWorld extends World {
+	public List<BatTest> tests = new Vector<BatTest>();
+	
+	public BatWorld(String funName) {
+		super(funName);
+		
+		BatEntity e = new BatEntity();
+		addEntity(e);
+		e.setWorld(this);
+	}
+	public BatWorld(BatWorld w2) {
+		super(w2);
+		this.tests = new Vector<BatTest>();
+		for (BatTest t:w2.tests) 
+			tests.add(t.copy());
+	}
+	
+	@Override
+	public void reset(World w) {
+		BatWorld anotherWorld = (BatWorld) w;
+		this.tests = new Vector<BatTest>();
+		for (BatTest t:anotherWorld.tests) 
+			tests.add(t.copy());
+		super.reset(anotherWorld);		
+	}
+	@Override
+	public boolean equals(Object o){
+		if (!(o instanceof BatWorld)) {
+			return false;
+		}
+		BatWorld other = (BatWorld) o;
+		if (other.tests.size() != tests.size()) {
+			//System.out.println("Amount of tests differ between worlds: "+tests.size()+" != "+other.tests.size());
+			return false;
+		}
+		for (int i=0;i<tests.size();i++)
+			if (!tests.get(i).equals(other.tests.get(i))) {
+				//throw new RuntimeException("Test "+i+" differs: "+tests.get(i)+" != "+other.tests.get(i));
+				return false;
+			}
+		return true;
+	}
+	@Override
+	public WorldView getView() {
+		return new BatWorldView(this);
+	}
+	@Override
+	public ImageIcon getIcon() {
+		return ResourcesCache.getIcon("img/world_bat.png");
+	}
+	
+	/* So that the view can display them */
+	protected List<BatTest> getTests() {
+		return tests;
+	}
+
+	/* World logic */
+	public void addTest(boolean visible, Object...params) {
+		tests.add(new BatTest(getName(),visible, params));
+	}
+	@Override
+	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) {
+		/* No need of any binding for this world */
+	}
+	@Override
+	public String diffTo(World w) {
+		BatWorld other = (BatWorld) w;
+		StringBuffer sb = new StringBuffer();
+		boolean foundError = false;
+		for (int i=0;i<tests.size();i++) {
+			if (foundError && !tests.get(i).isVisible() && !Game.getInstance().isDebugEnabled()) 
+				return sb.toString();
+					
+			if (!tests.get(i).equals(other.tests.get(i))) { 
+				sb.append(other.tests.get(i).getName()+" returned "+other.tests.get(i).getResult()+
+						                               " while "+         tests.get(i).getResult()+" were expected.\n");
+				foundError = true;
+			}
+		}
+		return sb.toString();
+	}
+}
diff --git a/src/plm/universe/bat/BatWorldView.java b/src/plm/universe/bat/BatWorldView.java
new file mode 100644
index 0000000..c13570d
--- /dev/null
+++ b/src/plm/universe/bat/BatWorldView.java
@@ -0,0 +1,70 @@
+package plm.universe.bat;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+import plm.core.ui.WorldView;
+import plm.universe.World;
+
+public class BatWorldView extends WorldView {
+
+	private static final long serialVersionUID = 1L;
+
+	public BatWorldView(World w) {
+		super(w);
+	}
+
+	@Override
+	public boolean isWorldCompatible(World world) {
+		return world instanceof BatWorld;
+	}
+
+	@Override
+	public void paintComponent(Graphics g) {
+
+		super.paintComponent(g);
+
+		Graphics2D g2 = (Graphics2D) g;
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setColor(Color.white);
+		g2.fill(new Rectangle2D.Double(0.,0.,(double)getWidth(),(double)getHeight()));
+
+		List<BatTest> tests = ((BatWorld) world).getTests();
+		boolean foundError=false;
+		for (int i=0;i<tests.size();i++) {
+			BatTest currTest = tests.get(i);
+			if (!currTest.isVisible() && foundError) 
+				break;
+
+			if (currTest.isObjective()) {
+				if (currTest.isVisible()) 
+					g2.setColor(Color.black);
+				else 
+					g2.setColor(Color.white);
+			} else {
+				if (currTest.isAnswered()) {
+
+					if (currTest.isCorrect()) 
+						g2.setColor(Color.blue);
+					else { 
+						g2.setColor(Color.red);
+						foundError = true;
+					}
+				} else {
+					if (currTest.isVisible()) 
+						g2.setColor(Color.black);
+					else 
+						g2.setColor(Color.white);						
+				}
+			}
+			g2.drawString(currTest.getName()+"="+currTest.getResult()
+					+(currTest.isAnswered() && !currTest.isCorrect() ?" (expected: "+currTest.expected+")":"")
+					, 0, (i+1)*20);
+		}
+
+	}
+}
diff --git a/src/plm/universe/bat/package-info.java b/src/plm/universe/bat/package-info.java
new file mode 100644
index 0000000..d8d8f49
--- /dev/null
+++ b/src/plm/universe/bat/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Universe aiming at exercising tactical programming through simple exercises imported from JavaBat.
+ */
+package plm.universe.bat;
diff --git a/src/plm/universe/bugglequest/AbstractBuggle.java b/src/plm/universe/bugglequest/AbstractBuggle.java
new file mode 100644
index 0000000..79a308d
--- /dev/null
+++ b/src/plm/universe/bugglequest/AbstractBuggle.java
@@ -0,0 +1,482 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+import java.awt.Point;
+
+import plm.core.model.Game;
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.GridWorld;
+import plm.universe.World;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.universe.bugglequest.exception.BuggleInOuterSpaceException;
+import plm.universe.bugglequest.exception.BuggleWallException;
+import plm.universe.bugglequest.exception.NoBaggleUnderBuggleException;
+
+public abstract class AbstractBuggle extends Entity {
+	int k_val = 0;
+	int[] k_seq = {0,0, 1,1, 2,3, 2,3, 4,5};
+	
+	Color color;
+	
+	Color brushColor;
+
+	private int x;
+	private int y;
+
+	Direction direction;
+
+	boolean brushDown;
+
+	private Baggle baggle;
+
+	/* This is for the simple buggle to indicate that it did hit a wall, and is thus not a valid
+	 * candidate for exercise completion.
+	 */
+	private boolean seenError = false;
+	public void seenError() {
+		this.seenError = true;
+	}
+	public void seenError(String msg) {
+		System.err.println(msg);
+		this.seenError = true;
+	}
+	public boolean haveSeenError() {
+		return seenError;
+	}	
+	
+	/**
+	 * Constructor with no argument so that child classes can avoid declaring a
+	 * constructor. But it should not be used as most methods assert on world
+	 * being not null. After using it, {@link Entity#setWorld(BuggleWorld)} must be used
+	 * ASAP.
+	 */
+	public AbstractBuggle() {
+		this(null, "John Doe", 0, 0, Direction.NORTH, Color.red, Color.red);
+	}
+
+	public AbstractBuggle(BuggleWorld w) {
+		this(w, "John Doe", 0, 0, Direction.NORTH, Color.red, Color.red);
+	}
+
+	public AbstractBuggle(BuggleWorld world, String name, int x, int y, Direction direction, Color c) {
+		this(world, name, 0, 0, Direction.NORTH, c, c);
+	}
+
+	public AbstractBuggle(World world, String name, int x, int y, Direction direction, Color color, Color brushColor) {
+		super(name,world);
+		this.color = color;
+		this.brushColor = brushColor;
+		this.x = x;
+		this.y = y;
+		this.direction = direction;
+	}
+	@Override
+	public void copy(Entity e) {
+		super.copy(e);
+		AbstractBuggle other = (AbstractBuggle)e;
+		this.color = other.color;
+		this.brushColor = other.brushColor;
+		this.x = other.x;
+		this.y = other.y;
+		this.direction = other.direction;
+	}
+	@Override
+	public Entity copy() {
+		return new Buggle(this);
+	}
+
+	public boolean isBrushDown() {
+		return brushDown;
+	}
+
+	public void brushDown() {
+		this.brushDown = true;
+		BuggleWorldCell cell = (BuggleWorldCell) ((BuggleWorld)world).getCell(x, y);
+		cell.setColor(brushColor);
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public void brushUp() {
+		if (k_seq[k_val]==4) k_val++; else k_val = 0;
+		this.brushDown = false;
+	}
+
+	public Color getGroundColor() {
+		return getCell().getColor();
+	}
+
+	public Color getBrushColor() {
+		return brushColor;
+	}
+
+	public void setBrushColor(Color c) {
+		if (c != null)
+			brushColor = c;
+		if (brushDown) // mark the ground
+			brushDown();
+	}
+
+	public Color getColor() {
+		return color;
+	}
+
+	public void setColor(Color c) {
+		if (c != null) {
+			this.color = c;
+			world.notifyWorldUpdatesListeners();
+		}
+	}
+
+	public Direction getDirection() {
+		return direction;
+	}
+
+	public void setDirection(Direction direction) {
+		if (direction != null) {
+			this.direction = direction;
+			stepUI();
+		}
+	}
+
+	public void left() {
+		if (k_seq[k_val]==2) k_val++; else k_val = 0;
+		setDirection(direction.left());
+	}
+
+	public void right() {
+		if (k_seq[k_val]==3) k_val++; else k_val = 0;
+		setDirection(direction.right());
+	}
+
+	public void back() {
+		setDirection(direction.opposite());
+	}
+	
+	public int getWorldHeight() {
+		return ((GridWorld) world).getHeight();
+	}
+	
+	public int getWorldWidth() {
+		return ((GridWorld) world).getWidth();
+	}
+	protected BuggleWorldCell getCell(){
+		return (BuggleWorldCell) ((GridWorld)world).getCell(x, y);
+	}
+	protected BuggleWorldCell getCell(int u, int v) throws BuggleInOuterSpaceException{
+		BuggleWorld bw = (BuggleWorld) world;
+		if (y>=bw.getHeight())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to access a cell with Y={0}, but the maximal Y in this world is {1}.",y,(bw.getHeight()-1)));
+		if (x>=bw.getWidth())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to access a cell with X={0}, but the maximal X in this world is {1}.",x,(bw.getWidth()-1)));
+
+		return (BuggleWorldCell) ((GridWorld)world).getCell(u, v);
+	}
+	protected BuggleWorldCell getCellFromLesson(int u, int v) {
+		try {
+			return getCell(u,v);
+		} catch (BuggleInOuterSpaceException e) {
+			throw new RuntimeException("Broken lesson: you accessed a cell in outer space",e);
+		}
+	}
+
+	public int getX() {
+		return x;
+	}
+
+	public void setX(int x) throws BuggleInOuterSpaceException {
+		BuggleWorld bw = (BuggleWorld) world;
+		if (x>=bw.getWidth())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to set X to {0}, but the maximal X in this world is {1}.",x,(bw.getWidth()-1)));
+		this.x = x;
+		stepUI();
+	}
+	public void setXFromLesson(int x)  {
+		try {
+			setX(x);
+		} catch (BuggleInOuterSpaceException e) {
+			throw new RuntimeException("Broken lesson: you moved to outer space",e);
+		}
+	}
+
+	public int getY() {
+		return y;
+	}
+
+	public void setY(int y) throws BuggleInOuterSpaceException  {
+		BuggleWorld bw = (BuggleWorld) world;
+		if (y>=bw.getHeight())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to set Y to {0}, but the maximal Y in this world is {1}.",y,(bw.getHeight()-1)));
+		this.y = y;
+		stepUI();
+	}
+	public void setYFromLesson(int y)  {
+		try {
+			setY(y);
+		} catch (BuggleInOuterSpaceException e) {
+			throw new RuntimeException("Broken lesson: you moved to outer space",e);
+		}
+	}
+
+	public void setPos(int x, int y) throws BuggleInOuterSpaceException {
+		BuggleWorld bw = (BuggleWorld) world;
+		if (y>=bw.getHeight())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to set Y to {0}, but the maximal Y in this world is {1}.",y,(bw.getHeight()-1)));
+		if (x>=bw.getWidth())
+			throw new BuggleInOuterSpaceException(Game.i18n.tr("You tried to set X to {0}, but the maximal X in this world is {1}.",x,(bw.getWidth()-1)));
+		this.x = x;
+		this.y = y;
+		stepUI();
+	}
+	public void setPosFromLesson(int x, int y)  {
+		try {
+			setPos(x,y);
+		} catch (BuggleInOuterSpaceException e) {
+			throw new RuntimeException("Broken lesson: you moved to outer space",e);
+		}
+	}
+
+	public void forward() throws BuggleWallException {
+		if (k_seq[k_val]==0) k_val++; else k_val = 0;
+		move(direction.toPoint());
+	}
+
+	public void forward(int count) throws BuggleWallException {
+		for (int i = 0; i < count; i++)
+			forward();
+	}
+
+	public void backward() throws BuggleWallException {
+		if (k_seq[k_val]==1) k_val++; else k_val = 0;
+		move(direction.opposite().toPoint());
+	}
+
+	public void backward(int count) throws BuggleWallException {
+		for (int i = 0; i < count; i++)
+			backward();
+	}
+
+	private boolean lookAtWall(boolean forward) {
+		Direction delta;
+		if (forward)
+			delta = getDirection();
+		else
+			delta = getDirection().opposite();
+
+		BuggleWorldCell cell;
+		switch (delta.intValue()) {
+		case Direction.NORTH_VALUE: /* looking up is easy */
+			cell = getCell();
+			return cell.hasTopWall();
+
+		case Direction.WEST_VALUE: /* looking to the left also */
+			cell = getCell();
+			return cell.hasLeftWall();
+
+		case Direction.SOUTH_VALUE: /* if looking down, look to the top of one cell lower */
+			cell = getCellFromLesson(getX(),                        (getY()+1) % getWorldHeight());
+			return cell.hasTopWall();
+
+		case Direction.EAST_VALUE: /* if looking right, look to the left of one next cell */
+			cell = getCellFromLesson((getX()+1) % getWorldWidth(), getY());
+			return cell.hasLeftWall();
+
+		default: throw new RuntimeException("Invalid direction: "+delta);
+		}
+	}
+	public boolean isFacingWall() {
+		return lookAtWall(true);
+	}
+	public boolean isBackingWall() {
+		return lookAtWall(false);
+	}
+
+	private void move(Point delta) throws BuggleWallException {
+		if (delta == null)
+			return;
+		
+		int newx = (x + delta.x) % getWorldWidth();
+		if (newx < 0)
+			newx += getWorldWidth();
+		int newy = (y + delta.y) % getWorldHeight();
+		if (newy < 0)
+			newy += getWorldHeight();
+
+		if (delta.equals(direction.toPoint())            && isFacingWall() ||
+				delta.equals(direction.opposite().toPoint()) && isBackingWall())	
+
+			throw new BuggleWallException();
+
+		x = newx;
+		y = newy;
+
+		if (brushDown) {
+			getCell().setColor(brushColor);
+		}
+
+		stepUI();
+	}
+
+	public boolean isOverBaggle() {
+		return getCellFromLesson(this.x, this.y).hasBaggle();
+	}
+
+	public boolean isCarryingBaggle() {
+		return this.baggle != null;
+	}
+
+	@Deprecated
+	public void pickUpBaggle() throws NoBaggleUnderBuggleException, AlreadyHaveBaggleException {
+		pickupBaggle();
+	}
+	public void pickupBaggle() throws NoBaggleUnderBuggleException, AlreadyHaveBaggleException {
+		if (k_seq[k_val]==5) k_val++; else k_val = 0;
+		if (k_val>k_seq.length-1) {
+			setName("Easter "+name);
+			System.out.println("EASTEEEER");
+			((BuggleWorld)world).easter= true;
+			k_val=0;
+			return;
+		}
+
+		if (!isOverBaggle())
+			throw new NoBaggleUnderBuggleException(Game.i18n.tr("There is no baggle to pick up here."));
+		if (isCarryingBaggle())
+			throw new AlreadyHaveBaggleException(Game.i18n.tr("Your are already carrying a baggle."));
+		baggle = getCellFromLesson(this.x, this.y).pickupBaggle();
+	}
+
+	public void dropBaggle() throws AlreadyHaveBaggleException {
+		getCellFromLesson(this.x, this.y).setBaggle(this.baggle);
+		baggle = null;
+	}
+
+	public boolean isOverMessage() {
+		return getCell().hasContent();
+	}
+
+	public void writeMessage(String msg) {
+		getCell().addContent(msg);
+	}
+	public void writeMessage(int nb) {
+		writeMessage(""+nb);
+	}
+
+	public String readMessage() {
+		return getCell().getContent();
+	}
+
+	public void clearMessage() {
+		getCell().emptyContent();
+	}
+
+
+
+	@Override
+	public String toString() {
+		return "Buggle (" + this.getClass().getName() + "): x=" + x + " y=" + y + " Direction:" + direction + " Color:"
+		+ color;
+	}
+
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + ((brushColor == null) ? 0 : brushColor.hashCode());
+		result = PRIME * result + (brushDown ? 1231 : 1237);
+		result = PRIME * result + ((color == null) ? 0 : color.hashCode());
+		result = PRIME * result + ((direction == null) ? 0 : direction.hashCode());
+		result = PRIME * result + x;
+		result = PRIME * result + y;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!(obj instanceof AbstractBuggle))
+			return false;
+		
+		final AbstractBuggle other = (AbstractBuggle) obj;
+		if (color == null) {
+			if (other.color != null)
+				return false;
+		} else if (!color.equals(other.color))
+			return false;
+		if (direction == null) {
+			if (other.direction != null)
+				return false;
+		} else if (!direction.equals(other.direction))
+			return false;
+		if (seenError != other.seenError)
+			return false;
+		if (x != other.x)
+			return false;
+		if (y != other.y)
+			return false;
+		return true;
+	}
+	public String diffTo(AbstractBuggle other) {
+		if (other == null) 
+			return Game.i18n.tr("Its value is 'null', which is never good.");
+		/* We cannot use a i18n defined in our class, as we have to pass the classname to the initialization of i18n, 
+		 *    but gettext don't seem to like the fact that we generate at runtime some package names that it does not know at compile time.
+		 * So, use Game.i18n instead.
+		 */
+		StringBuffer sb = new StringBuffer();
+		if (getX() != other.getX() || getY() != other.getY()) 
+			sb.append(Game.i18n.tr("    Its position is ({0},{1}); expected: ({2},{3}).\n",other.getX(),other.getY(),getX(),getY()));
+		if (getDirection() != other.getDirection()) 
+			sb.append(Game.i18n.tr("    Its direction is {0}; expected: {1}.\n",other.getDirection(),getDirection()));
+		if (getColor() != other.getColor()) 
+			sb.append(Game.i18n.tr("    Its color is {0}; expected: {1}.\n",other.getColor(),getColor()));
+		if (getBrushColor() != other.getBrushColor())
+			sb.append(Game.i18n.tr("    The color of its brush is {0}; expected: {1}.\n",other.getBrushColor(),getBrushColor()));
+		if (isCarryingBaggle() && !other.isCarryingBaggle())
+			sb.append(Game.i18n.tr("    It should not carry that baggle.\n"));
+		if (!isCarryingBaggle() && other.isCarryingBaggle())
+			sb.append(Game.i18n.tr("    It is not carrying any baggle.\n"));
+		if (haveSeenError() && other.haveSeenError())
+			sb.append(Game.i18n.tr("    It encountered an issue, such as bumping into a wall.\n"));
+		if (haveSeenError() && !other.haveSeenError())
+			sb.append(Game.i18n.tr("    It didn't encounter any issue, such as bumping into a wall.\n"));
+		return sb.toString();
+	}
+	
+	/* BINDINGS TRANSLATION: French */
+	public void gauche()   { left(); }
+	public void droite()   { right(); }
+	public void retourne() { back(); }
+	public void avance()          throws BuggleWallException { forward(); }
+	public void avance(int steps) throws BuggleWallException { forward(steps); }
+	public void recule()          throws BuggleWallException { backward(); }
+	public void recule(int steps) throws BuggleWallException { backward(steps); }
+	public Color getCouleur()             { return getColor(); }
+	public void setCouleur(Color c)       { setColor(c); }
+	public boolean estFaceMur()           { return isFacingWall(); }
+	public boolean estDosMur()            { return isBackingWall(); }
+	public void leveBrosse()              { brushUp(); }
+	public void baisseBrosse()            { brushDown(); }
+	public boolean estBrosseBaissee()     { return isBrushDown(); }
+	public Color getCouleurBrosse()       { return getBrushColor(); }
+	public void setCouleurBrosse(Color c) { setBrushColor(c); }
+	public Color getCouleurSol()          { return getGroundColor(); }
+	public boolean estSurBiscuit()        { return isOverBaggle(); }
+	public boolean porteBiscuit()         { return isCarryingBaggle(); }
+	public void prendBiscuit() throws AlreadyHaveBaggleException, NoBaggleUnderBuggleException { pickupBaggle(); }
+	public void poseBiscuit()  throws AlreadyHaveBaggleException                               { dropBaggle(); }
+	public boolean estSurMessage()        { return isOverMessage(); }
+	public String litMessage()            { return readMessage(); }
+	public void ecritMessage(String s)    { writeMessage(s); }
+	public void ecritMessage(int i)       { writeMessage(i); }
+	public void effaceMessage()           { clearMessage(); }
+	public int getMondeHauteur()          { return getWorldHeight(); }
+	public int getMondeLargeur()          { return getWorldWidth(); }
+	// get/set X/Y/Pos are not translated as they happen to be the same in French
+	public boolean estChoisi()           { return isSelected(); } // we have to document the version without e, since po4a allows for one variant only
+	public boolean estChoisie()          { return isSelected(); } // But we want to have the grammatically correct form also possible (Buggles are feminine in French)
+	
+}
diff --git a/src/plm/universe/bugglequest/Baggle.java b/src/plm/universe/bugglequest/Baggle.java
new file mode 100644
index 0000000..c12c628
--- /dev/null
+++ b/src/plm/universe/bugglequest/Baggle.java
@@ -0,0 +1,69 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+
+public class Baggle {
+
+	private Color color;
+	private BuggleWorldCell cell;
+
+	public static final Color DEFAULT_COLOR = new Color(0.82f,0.41f,0.12f);
+	
+	
+	public Baggle(BuggleWorldCell c) {
+		this(c, DEFAULT_COLOR);
+	}
+
+	public Baggle(BuggleWorldCell cell, Color c) {
+		this.cell = cell;
+		this.color = c;
+	}
+	
+	public Baggle(Baggle b) {
+		this.color = b.color;
+		this.cell = b.cell;
+	}
+	
+	public void setCell(BuggleWorldCell c) {
+		this.cell = c;
+	}
+		
+	@Override
+	public String toString() {
+		return "Baggle ("+this.getClass().getName()+"): Color:" + color;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((color == null) ? 0 : color.hashCode());
+		//result = prime * result + ((cell == null) ? 0 : cell.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Baggle other = (Baggle) obj;
+		if (color == null) {
+			if (other.color != null)
+				return false;
+		} else if (!color.equals(other.color))
+			return false;
+//		if (cell == null) {
+//			if (other.cell != null)
+//				return false;
+//		} //else if (!cell.equals(other.cell))
+		//	return false;
+		return true;
+	}
+
+	
+
+}
diff --git a/src/plm/universe/bugglequest/Buggle.java b/src/plm/universe/bugglequest/Buggle.java
new file mode 100644
index 0000000..29f0632
--- /dev/null
+++ b/src/plm/universe/bugglequest/Buggle.java
@@ -0,0 +1,33 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+
+import plm.universe.Direction;
+
+
+public final class Buggle extends AbstractBuggle {
+
+	public Buggle(AbstractBuggle b){
+		super();
+		setWorld(b.getWorld());
+		setName(b.getName());
+		setColor(b.color);
+		setBrushColor(b.brushColor);
+		setPosFromLesson(b.getX(), b.getY());
+		setDirection(b.direction);
+		brushDown = b.brushDown;
+	}
+
+	public Buggle(BuggleWorld world, String name, int i, int j, Direction north, Color color, Color brush) {
+		super(world, name, i, j, north, color, brush);
+	}
+
+	public Buggle(BuggleWorld world) {
+		super(world);
+	}
+
+	@Override
+	public void run() {
+		// nothing by default
+	}
+}
diff --git a/src/plm/universe/bugglequest/BuggleWorld.fr.html b/src/plm/universe/bugglequest/BuggleWorld.fr.html
new file mode 100644
index 0000000..6f2a582
--- /dev/null
+++ b/src/plm/universe/bugglequest/BuggleWorld.fr.html
@@ -0,0 +1,78 @@
+<h1>Le monde des Buggles</h1>
+Ce monde a été inventé par Lyn Turbak, du Wellesley College. Il est peuplé
+de Buggles, petites bêtes qui comprennent des ordres simples, et offre de
+nombreuses possibilités d'interaction avec le monde: prendre ou poser des
+objets, colorier le sol, se cogner à des murs, etc.
+
+<h2>Méthodes comprises par les buggles</h2>
+<table border=1>
+<tr><td colspan=2 align=center><b>Bouger</b><br/> (voir aussi la note sur les exceptions, plus bas)</td></tr>
+  <tr><td><b>Tourner à gauche<br/>Tourner à droite<br/>Se retourner<br/>Avancer<br/>Reculer</b></td>
+      <td>[!java]void [/!]gauche()<br/>
+          [!java]void [/!]droite()<br/>
+          [!java]void [/!]retourne()<br/>
+          [!java]void [/!]avance() ou [!java]void [/!]avance([!java]int
+[/!]steps[!scala]:Int[/!])<br/>
+          [!java]void [/!]recule() or [!java]void [/!]recule([!java]int
+[/!]steps[!scala]:Int[/!])<br/></td></tr>
+  <tr><td><b>Obtenir l'abcisse<br/>Obtenir l'ordonnée<br/>Changer l'abcisse<br/>Changer l'ordonnée<br/>Changer la position</b></td>
+      <td>[!java]int [/!]getX()[!scala]:Int[/!]<br/>
+          [!java]int [/!]getY()[!scala]:Int[/!]<br/>
+          [!java]void [/!]setX([!java]int [/!]x[!scala]:Int[/!])<br/>
+          [!java]void [/!]setY([!java]int [/!]y[!scala]:Int[/!])<br/>
+          [!java]void [/!]setPos([!java]int [/!]x[!scala]:Int[/!], [!java]int
+[/!]y[!scala]:Int[/!])</td></tr>
+
+<tr><td colspan=2 align=center><b>Informations sur la buggle</b></td></tr>
+  <tr><td><b>Obtenir la couleur<br/>Changer la couleur</b></td>
+      <td>[!java]Color [/!]getCouleur()[!scala]:Color[/!]<br/>
+          [!java]void [/!]setCouleur([!java]Color [/!]c[!scala]:Color[/!])</td></tr>				
+  <tr><td><b>Chercher un mur devant<br/>Chercher un mur derriere</b></td>
+      <td>[!java]boolean [/!]estFaceMur()[!scala]:Boolean[/!]<br/>
+          [!java]boolean [/!]estDosMur()[!scala]:Boolean[/!]</td></tr>				
+  <tr><td><b>Obtenir la direction<br/>Changer la direction</b><br/>Les directions valides sont :</td>
+      <td>[!java]Direction [/!]getDirection()[!scala]:Direction[/!]<br/>
+          [!java]void [/!]setDirection([!java]Direction [/!]dir[!scala]:Direction[/!])<br/>
+          Direction.NORTH (le nord), Direction.EAST (l'est), Direction.SOUTH (le sud)
+et Direction.WEST (l'ouest)</td></tr>
+  <tr><td>Renvoi si la buggle est actuellement <b>sélectionnée dans l'interface</b></td>
+      <td>[!java]boolean [/!]estChoisie()[!scala]:Boolean[/!]</td></tr>
+ 
+<tr><td colspan=2 align=center><b>À propos de la brosse</b></td></tr>
+  <tr><td><b>Baisser la brosse<br/>Lever la brosse<br/>Obtenir la position de la brosse</b></td>
+      <td>[!java]void [/!]leveBrosse()<br/>
+          [!java]void [/!]baisseBrosse()<br/>
+          [!java]boolean [/!]estBrosseLevee()[!scala]:Boolean[/!]</td></tr>
+  <tr><td><b>Modifier la couleur de la brosse<br/>Obtenir la couleur de la brosse</b></td>
+      <td>[!java]void [/!]setCouleurBrosse([!java]Color [/!]c[!scala]:Color[/!])<br/>
+          [!java]Color [/!]getCouleurBrosse()[!scala]:Color[/!]</td></tr>
+
+<tr><td colspan=2 align=center><b>Interagir avec le monde</b></td></tr>
+  <tr><td><b>Obtenir la couleur du sol</b></td>
+      <td>[!java]Color [/!]getCouleurSol()[!scala]:Color[/!]</td></tr>
+
+  <tr><td><b>Chercher un biscuit par terre<br/>Chercher un biscuit dans ses poches<br/>Prendre un biscuit<br/>Poser un biscuit</b><br/>
+      (voir la note sur les exceptions)</td>
+      <td>[!java]boolean [/!]estSurBiscuit()[!scala]:Boolean[/!]<br/>
+          [!java]boolean [/!]porteBiscuit()[!scala]:Boolean[/!]<br/>
+          [!java]void [/!]prendBiscuit()<br/>
+          [!java]void [/!]poseBiscuit()</td></tr>
+
+  <tr><td><b>Chercher un message<br/>Ajouter un message<br/>Lire le message<br/>Effacer le message</b></td>
+      <td>[!java]boolean [/!]estSurMessage()[!scala]:Boolean[/!]<br/>
+          [!java]void [/!]ecritMessage([!java]String [/!]msg[!scala]:String[/!])<br/>
+          [!java]String [/!]litMessage()[!scala]:String[/!]<br/>
+          [!java]void [/!]effaceMessage()</td></tr>
+</table>
+
+<h2>Note sur les exceptions</h2>
+Les buggles normales lèvent une exception BuggleWallException si on cherche
+à leur faire traverser un mur.
+Elles lèvent une exception NoBaggleUnderBuggleException si vous cherchez à
+prendre un baggle dans une case qui n'en contient pas, ou une exception
+AlreadyHaveBaggleException si vous portez déjà un baggel.
+Tenter de déposer un baggel sur une case qui en contient déjà lève une
+exception AlreadyHaveBaggleException.
+<p>Les "SimpleBuggles" (ie, celles utilisées dans les premiers exercices)
+affiche un message d'erreur sans que vous ayez à vous soucier de ce qu'est
+une exception.</p>
diff --git a/src/plm/universe/bugglequest/BuggleWorld.html b/src/plm/universe/bugglequest/BuggleWorld.html
new file mode 100644
index 0000000..d3e3dab
--- /dev/null
+++ b/src/plm/universe/bugglequest/BuggleWorld.html
@@ -0,0 +1,72 @@
+<h1>BuggleWorld</h1>
+This world was invented by Lyn Turbak, at Wellesley College. It is full of
+Buggles, little animals understanding simple orders, and offers numerous
+possibilities of interaction with the world: taking or dropping objects,
+paint the ground, hit walls, etc.
+
+<h2>Methods understood by buggles</h2>
+<table border=1>
+<tr><td colspan=2 align=center><b>Moving</b><br/> (See also the note on exceptions, below)</td></tr>
+  <tr><td><b>Turn left<br/>Turn right<br/>Turn back<br/>Moving forward<br/>Moving back</b></td>
+      <td>[!java]void [/!]left()<br/>
+          [!java]void [/!]right()<br/>
+          [!java]void [/!]back()<br/>
+          [!java]void [/!]forward() or [!java]void [/!]forward([!java]int [/!]steps[!scala]:Int[/!])<br/>
+          [!java]void [/!]backward() or [!java]void [/!]backward([!java]int [/!]steps[!scala]:Int[/!])<br/></td></tr>
+  <tr><td><b>Get X coordinate<br/>Get Y coordinate<br/>Set X coordinate<br/>Set Y coordinate<br/>Set position</b></td>
+      <td>[!java]int [/!]getX()[!scala]:Int[/!]<br/>
+          [!java]int [/!]getY()[!scala]:Int[/!]<br/>
+          [!java]void [/!]setX([!java]int [/!]x[!scala]:Int[/!])<br/>
+          [!java]void [/!]setY([!java]int [/!]y[!scala]:Int[/!])<br/>
+          [!java]void [/!]setPos([!java]int [/!]x[!scala]:Int[/!], [!java]int [/!]y[!scala]:Int[/!])</td></tr>
+
+<tr><td colspan=2 align=center><b>Information on the buggle</b></td></tr>
+  <tr><td><b>Get the color<br/>Set the color</b></td>
+      <td>[!java]Color [/!]getColor()[!scala]:Color[/!]<br/>
+          [!java]void [/!]setColor([!java]Color [/!]c[!scala]:Color[/!])</td></tr>				
+  <tr><td><b>Look for a wall forward<br/>Look for a wall backward</b></td>
+      <td>[!java]boolean [/!]isFacingWall()[!scala]:Boolean[/!]<br/>
+          [!java]boolean [/!]isBackingWall()[!scala]:Boolean[/!]</td></tr>				
+  <tr><td><b>Get heading<br/>Set heading</b><br/>valid directions are:</td>
+      <td>[!java]Direction [/!]getDirection()[!scala]:Direction[/!]<br/>
+          [!java]void [/!]setDirection([!java]Direction [/!]dir[!scala]:Direction[/!])<br/>
+          Direction.NORTH, Direction.EAST, Direction.SOUTH and Direction.WEST</td></tr>
+  <tr><td>Check whether the buggle is currently <b>selected in the interface</b></td>
+      <td>[!java]boolean [/!]isSelected()[!scala]:Boolean[/!]</td></tr>
+ 
+<tr><td colspan=2 align=center><b>About the brush</b></td></tr>
+  <tr><td><b>Brush down<br/>Brush up<br/>Get brush position</b></td>
+      <td>[!java]void [/!]brushUp()<br/>
+          [!java]void [/!]brushDown()<br/>
+          [!java]boolean [/!]isBrushDown()[!scala]:Boolean[/!]</td></tr>
+  <tr><td><b>Change the brush color<br/>Get the color of the brush</b></td>
+      <td>[!java]void [/!]setBrushColor([!java]Color [/!]c[!scala]:Color[/!])<br/>
+          [!java]Color [/!]getBrushColor()[!scala]:Color[/!]</td></tr>
+
+<tr><td colspan=2 align=center><b>Interacting with the world</b></td></tr>
+  <tr><td><b>Get the color of the ground</b></td>
+      <td>[!java]Color [/!]getGroundColor()[!scala]:Color[/!]</td></tr>
+
+  <tr><td><b>Look for a baggle on the ground<br/>Look for a baggle in bag<br/>Pickup a baggle<br/>Drop a baggle</b><br/>
+      (see the note on exceptions)</td>
+      <td>[!java]boolean [/!]isOverBaggle()[!scala]:Boolean[/!]<br/>
+          [!java]boolean [/!]isCarryingBaggle()[!scala]:Boolean[/!]<br/>
+          [!java]void [/!]pickupBaggle()<br/>
+          [!java]void [/!]dropBaggle()</td></tr>
+
+  <tr><td><b>Look for a message<br/>Add a message<br/>Read the message<br/>Erase the message</b></td>
+      <td>[!java]boolean [/!]isOverMessage()[!scala]:Boolean[/!]<br/>
+          [!java]void [/!]writeMessage([!java]String [/!]msg[!scala]:String[/!])<br/>
+          [!java]String [/!]readMessage()[!scala]:String[/!]<br/>
+          [!java]void [/!]clearMessage()</td></tr>
+</table>
+
+<h2>Note on exceptions</h2>
+Regular buggles throw a BuggleWallException exception if you ask them to
+traverse a wall.  They throw a NoBaggleUnderBuggleException exception if you
+ask them to pickup a baggle from an empty cell, or a
+AlreadyHaveBaggleException exception if they already carry a baggle.  Trying
+to drop a baggle on a cell already containing one throws an
+AlreadyHaveBaggleException exception.
+<p>SimpleBuggles (ie, the one used in first exercises) display an error message
+on problem so that you don't need to know what an exception is.</p>
diff --git a/src/plm/universe/bugglequest/BuggleWorld.java b/src/plm/universe/bugglequest/BuggleWorld.java
new file mode 100644
index 0000000..0115ba0
--- /dev/null
+++ b/src/plm/universe/bugglequest/BuggleWorld.java
@@ -0,0 +1,555 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.utils.ColorMapper;
+import plm.core.utils.FileUtils;
+import plm.core.utils.InvalidColorNameException;
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.EntityControlPanel;
+import plm.universe.GridWorld;
+import plm.universe.GridWorldCell;
+import plm.universe.World;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.universe.bugglequest.ui.BuggleButtonPanel;
+import plm.universe.bugglequest.ui.BuggleWorldView;
+
+
+public class BuggleWorld extends GridWorld {
+
+	public BuggleWorld(String name, int x, int y) {
+		super(name,x,y);
+	}
+	@Override
+	protected GridWorldCell newCell(int x, int y) {
+		return new BuggleWorldCell(this, x, y);
+	}
+	/** 
+	 * Create a new world being almost a copy of the first one. Beware, all the buggles of the copy are changed to BuggleRaw. 
+	 * @param world2
+	 */
+	public BuggleWorld(BuggleWorld world2) {
+		super(world2);
+	}
+
+	/**
+	 * Reset the content of a world to be the same than the one passed as argument
+	 * does not affect the name of the initial world.
+	 */
+	@Override
+	public void reset(World iw) {
+		BuggleWorld initialWorld = (BuggleWorld)iw;
+		for (int i = 0; i < sizeX; i++)
+			for (int j = 0; j < sizeY; j++) {
+				BuggleWorldCell c = (BuggleWorldCell) initialWorld.getCell(i, j);
+				cells[i][j] = new BuggleWorldCell(c, this);
+			}
+		easter=false;
+
+		super.reset(initialWorld);
+	}	
+	@Override
+	public void setWidth(int w) {
+		super.setWidth(w);
+		if (selectedCell != null && selectedCell.getX()>=w)
+			selectedCell = null;
+		for (int i=0; i<entities.size();i++) {
+			AbstractBuggle b = (AbstractBuggle) entities.get(i);
+			if (b.getX()>w)
+				entities.remove(i--); // -- to counter the effect of ++ at the  end of body loop
+		}
+	}
+	@Override
+	public void setHeight(int h) {
+		super.setHeight(h);
+		if (selectedCell != null && selectedCell.getY()>=h)
+			selectedCell = null;
+		for (int i=0; i<entities.size();i++) {
+			AbstractBuggle b = (AbstractBuggle) entities.get(i);
+			if (b.getY()>h)
+				entities.remove(i--); // -- to counter the effect of ++ at the  end of body loop
+		}
+	}
+
+	@Override
+	public BuggleWorldView getView() {
+		return new BuggleWorldView(this);
+	}
+	@Override
+	public EntityControlPanel getEntityControlPanel() {
+		return new BuggleButtonPanel();
+	}
+	@Override
+	public ImageIcon getIcon() {
+		return ResourcesCache.getIcon("img/world_buggle.png");
+	}
+
+	public boolean easter = false;
+	/* IO related */
+	@Override
+	public boolean haveIO() {
+		return true;
+	}
+	public static World newFromFile(String path) throws IOException, BrokenWorldFileException {
+		BuggleWorld res = new BuggleWorld("toto", 1, 1);
+		return res.readFromFile(path);
+	}
+	@Override
+	public World readFromFile(String path) throws IOException, BrokenWorldFileException {
+		BuggleWorld res = new BuggleWorld("toto", 1, 1);
+
+		return readFromFile(path,"BuggleWorld",res);
+	}
+	
+	public World readFromFile(String path, String classname, BuggleWorld res) throws IOException, BrokenWorldFileException {
+		String name;
+		if (path.endsWith(".map"))
+			System.err.println(Game.i18n.tr("{0}: The path to the map on disk should not include the .map extension (or it won''t work in jarfiles). Please fix your exercise.",path));
+		
+		BufferedReader reader = FileUtils.newFileReader(path, "map", false);
+		
+		/* Get the world name from the first line */
+		String line = reader.readLine();
+		if (line == null)
+			throw new BrokenWorldFileException(Game.i18n.tr(
+					"{0}.map: this file does not seem to be a serialized BuggleWorld (the file is empty!)",path));
+		
+		Pattern p = Pattern.compile("^"+classname+": ");
+		Matcher m = p.matcher(line);
+		if (!m.find())
+			throw new RuntimeException(Game.i18n.tr(
+					"{0}.map: This file does not seem to be a serialized BuggleWorld (malformated first line: {1})", path, line));
+		name = m.replaceAll("");
+		
+		/* Get the dimension from the second line that is eg "Size: 20x20" */
+		line = reader.readLine();
+		if (line == null)
+			throw new RuntimeException(Game.i18n.tr("" +
+					"{0}.map: End of file reached before world size specification",path));
+		p = Pattern.compile("^Size: (\\d+)x(\\d+)$");
+		m = p.matcher(line);
+		if (!m.find()) 
+			throw new RuntimeException(Game.i18n.tr("{0}.map:1: Expected ''Size: NNxMM'' but got ''{0}''", line));
+		int width = Integer.parseInt(m.group(1)); 
+		int height = Integer.parseInt(m.group(2));
+
+		res.setName(name);
+		res.setWidth(width);
+		res.setHeight(height);
+		
+		line = reader.readLine();
+		
+		Pattern bugglePattern = Pattern.compile("^Buggle\\((\\d+),(\\d+)\\): (\\w+),([^,]+),([^,]+),(.+)$"); // direction, color, brush, name
+		Matcher buggleMatcher = bugglePattern.matcher(line);
+		String cellFmt = "^Cell\\((\\d+),(\\d+)\\): ([^,]+?),(\\w+),(\\w+),(\\w+),(.*)$";
+		Pattern cellPattern = Pattern.compile(cellFmt);
+		Matcher cellMatcher = cellPattern.matcher(line);
+
+		do {
+			cellMatcher = cellPattern.matcher(line);
+			buggleMatcher = bugglePattern.matcher(line);
+
+			if (buggleMatcher.matches()) { 
+				int x=Integer.parseInt( buggleMatcher.group(1) );
+				int y=Integer.parseInt( buggleMatcher.group(2) );
+
+				if (x<0 || x > width || y<0 || y>height)
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Cannot put a buggle on coordinate {0},{1}: that''s out of the world",x,y));
+
+				String dirName = buggleMatcher.group(3);
+				Direction direction;
+				if (dirName.equalsIgnoreCase("north"))
+					direction = Direction.NORTH;
+				else if (dirName.equalsIgnoreCase("south"))
+					direction = Direction.SOUTH;
+				else if (dirName.equalsIgnoreCase("east"))
+					direction = Direction.EAST;
+				else if (dirName.equalsIgnoreCase("west"))
+					direction = Direction.WEST;
+				else 
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Invalid buggle''s direction: {0}", buggleMatcher.group(3)));
+
+				Color color;
+				try {
+					color = ColorMapper.name2color( buggleMatcher.group(4));
+				} catch (InvalidColorNameException e) {
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Invalid buggle''s color name: {0}", buggleMatcher.group(4)));
+				}
+				Color brushColor;
+				try {
+					brushColor = ColorMapper.name2color( buggleMatcher.group(5));
+				} catch (InvalidColorNameException e) {
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Invalid buggle''s color name: {0}", buggleMatcher.group(5)));
+				}
+				String buggleName = buggleMatcher.group(6);
+
+				new Buggle(res, buggleName, x, y, direction, color, brushColor);
+			} else if (cellMatcher.matches()) {
+				/* Get the info */
+				int x=Integer.parseInt( cellMatcher.group(1) );
+				int y=Integer.parseInt( cellMatcher.group(2) );
+
+				if (x<0 || x > width || y<0 || y>height)
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Cannot define a cell on coordinate {0},{1}: that''s out of the world",x,y));
+
+
+				String colorName = cellMatcher.group(3);
+				Color color;
+				String baggleFlag = cellMatcher.group(4);
+				String topWallFlag = cellMatcher.group(5);
+				String leftWallFlag = cellMatcher.group(6);
+				String content = cellMatcher.group(7);
+
+				try {
+					color = ColorMapper.name2color(colorName);
+				} catch (InvalidColorNameException e) {
+					throw new BrokenWorldFileException(Game.i18n.tr("Invalid color name: {0}",colorName));
+				}
+
+				/* Make sure that this info makes sense */
+				if (!baggleFlag.equalsIgnoreCase("baggle") && !baggleFlag.equalsIgnoreCase("nobaggle"))
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Expecting ''baggle'' or ''nobaggle'' but got {0} instead",baggleFlag));
+
+				if (!topWallFlag.equalsIgnoreCase("topwall") && !topWallFlag.equalsIgnoreCase("notopwall"))
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Expecting ''topwall'' or ''notopwall'' but got {0} instead",topWallFlag));
+
+				if (!leftWallFlag.equalsIgnoreCase("leftwall") && !leftWallFlag.equalsIgnoreCase("noleftwall"))
+					throw new BrokenWorldFileException(Game.i18n.tr(
+							"Expecting ''leftwall'' or ''noleftwall'' but got {0} instead",leftWallFlag));
+
+				/* Use the info */
+				BuggleWorldCell cell = new BuggleWorldCell(res, x, y);
+
+				if (baggleFlag.equalsIgnoreCase("baggle"))
+					try {
+						cell.setBaggle(new Baggle(cell));
+					} catch (AlreadyHaveBaggleException e) {
+						throw new BrokenWorldFileException(Game.i18n.tr(
+								"The cell {0},{1} seem to be defined more than once. At least, there is two baggles here, which is not allowed.",x,y));
+					}
+
+				if (topWallFlag.equalsIgnoreCase("topwall"))
+					cell.putTopWall();
+				if (leftWallFlag.equalsIgnoreCase("leftwall"))
+					cell.putLeftWall();		
+
+				cell.setColor(color);
+
+				if (content.length()>0)
+					cell.setContent(content);
+
+				res.setCell(cell, x, y);
+			} else {
+				throw new BrokenWorldFileException(Game.i18n.tr(
+						"Parse error. I was expecting a cell or a buggle description but got: {0}",line));					
+			}
+
+			line = reader.readLine();
+		} while (line != null);
+
+		return res;
+	}
+
+	@Override
+	public void writeToFile(BufferedWriter writer) throws IOException {
+
+		writer.write("BuggleWorld: "+getName() + "\n");
+		writer.write("Size: "+getWidth() + "x"+ getHeight() + "\n");
+
+		for (Entity e : getEntities()) {
+			AbstractBuggle b = (AbstractBuggle) e;
+			writer.write("Buggle("+b.getX()+","+b.getY()+"): ");
+			
+			if (b.getDirection().equals(Direction.NORTH)) 
+				writer.write("north,");
+			if (b.getDirection().equals(Direction.SOUTH)) 
+				writer.write("south,");
+			if (b.getDirection().equals(Direction.EAST)) 
+				writer.write("east,");
+			if (b.getDirection().equals(Direction.WEST)) 
+				writer.write("west,");
+			
+			writer.write(ColorMapper.color2name(b.getColor())+",");
+			writer.write(ColorMapper.color2name(b.getBrushColor())+",");
+			writer.write(b.getName());
+			writer.write("\n");
+		}
+			
+		
+		for (int x = 0; x < getWidth(); x++) {
+			for (int y = 0; y < getHeight(); y++) {
+				BuggleWorldCell cell = (BuggleWorldCell) getCell(x, y);
+
+				if ((!cell.getColor().equals(Color.white)) || cell.hasBaggle() || 
+						cell.hasLeftWall() || cell.hasTopWall() || cell.hasContent()
+						) {
+					
+					writer.write("Cell("+x+","+y+"): ");
+					writer.write(ColorMapper.color2name(cell.getColor())+",");
+					
+					if (cell.hasBaggle()) 
+						writer.write("baggle,");
+					else 
+						writer.write("nobaggle,");
+					
+					if (cell.hasTopWall()) 
+						writer.write("topwall,");
+					else 
+						writer.write("notopwall,");
+
+					if (cell.hasLeftWall()) 
+						writer.write("leftwall,");
+					else 
+						writer.write("noleftwall,");
+					
+					if (cell.hasContent())
+						writer.write(cell.getContent());
+					writer.write("\n");
+				}
+			}
+		}
+	}
+
+	@Override
+	public String toString() {
+		return super.toString(); 
+	}
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		//result = PRIME * result + ((entities == null) ? 0 : entities.hashCode());
+		result = PRIME * result + sizeX;
+		result = PRIME * result + sizeY;
+		result = PRIME * result + Arrays.hashCode(cells);
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if ( !(obj instanceof BuggleWorld) )
+			return false;
+		final BuggleWorld other = (BuggleWorld) obj;
+		if (sizeX != other.sizeX)
+			return false;
+		if (sizeY != other.sizeY)
+			return false;
+		for (int x=0; x<getWidth(); x++) 
+			for (int y=0; y<getHeight(); y++) 
+				if (!getCell(x, y).equals(other.getCell(x, y)))
+					return false;
+
+		return super.equals(obj);
+	}
+
+	/* Cell selection is particularly important to world edition */
+	BuggleWorldCell selectedCell=null;
+	public BuggleWorldCell getSelectedCell() {
+		return selectedCell;
+	}
+	public void setSelectedCell(int x, int y) {
+		selectedCell = getCell(x,y);
+	}
+	public void unselectCell() {
+		selectedCell = null;
+	}
+	
+	/* adapters to the cells */
+	public BuggleWorldCell getCell(int x, int y) {
+		return (BuggleWorldCell) super.getCell(x, y);
+	}
+	public void setColor(int x, int y, Color c) {
+		getCell(x, y).setColor(c);
+	}
+	public void addContent(int x, int y, String string) {
+		getCell(x, y).addContent(string);
+	}
+
+	public void putTopWall(int x, int y) {
+		getCell(x, y).putTopWall();		
+	}
+
+	public void putLeftWall(int x, int y) {
+		getCell(x, y).putLeftWall();		
+	}
+	public void newBaggle(int x, int y) throws AlreadyHaveBaggleException {
+		getCell(x, y).newBaggle();		
+	}
+	@Override
+	public void setupBindings(ProgrammingLanguage lang,ScriptEngine engine) throws ScriptException {
+		if (lang.equals(Game.PYTHON)) {
+			engine.put("Direction", Direction.class);
+			engine.put("Color", Color.class);
+			engine.eval(
+				"def forward(steps=1):\n"+
+				"	entity.forward(steps)\n"+
+				"def backward(steps=1):\n"+
+				"	entity.backward(steps)\n"+
+				"def left():\n"+
+				"	entity.left()\n"+
+				"def back():\n"+
+				"	entity.back()\n"+
+				"def right():\n"+
+				"	entity.right()\n"+
+				"\n"+
+				"def getWorldHeight():\n"+
+				"	return entity.getWorldHeight()\n"+
+				"def getWorldWidth():\n"+
+				"	return entity.getWorldWidth()\n"+
+				"def getX():\n"+
+				"	return entity.getX()\n"+
+				"def getY():\n"+
+				"	return entity.getY()\n"+
+				"def setX(x):\n"+
+				"	entity.setX(x)\n"+
+				"def setY(y):\n"+
+				"	entity.setY(y)\n"+
+				"def setPos(x,y):\n"+
+				"	entity.setPos(x,y)\n"+
+				"def setDirection(d):\n"+
+				"	entity.setDirection(d)\n"+
+				"def brushDown():\n"+
+				"   entity.brushDown()\n"+
+				"def brushUp():\n"+
+				"   entity.brushUp()\n" +
+				"def isBrushDown():\n"+
+				"   entity.isBrushDown()\n" +
+				"def isFacingWall():" +
+				"	return entity.isFacingWall()\n"+
+				"def isBackingWall():" +
+				"	return entity.isBackingWall()\n"+
+				"def getGroundColor():\n"+
+				"   return entity.getGroundColor()\n"+
+				
+				"def errorMsg(str):\n"+
+				"  entity.seenError(str)\n"+
+				
+				"def isOverBaggle():\n"+
+				"	return entity.isOverBaggle()\n"+
+				"def isCarryingBaggle():\n"+
+				"	return entity.isCarryingBaggle()\n"+
+				"def pickupBaggle():\n"+
+				"	return entity.pickupBaggle()\n"+
+				"def dropBaggle():\n"+
+				"	return entity.dropBaggle()\n"+
+				
+				"def isOverMessage():\n"+
+				"	return entity.isOverMessage()\n"+
+				"def readMessage():\n"+
+				"	return entity.readMessage()\n"+
+				"def clearMessage():\n"+
+				"   entity.clearMessage()\n"+
+				"def writeMessage(msg):\n"+
+				"   entity.writeMessage(msg)\n"+
+				
+				"def getDirection():\n"+
+				"   return entity.getDirection()\n"+
+				
+				"def setBrushColor(c):\n"+
+				"    entity.setBrushColor(c)\n"+
+				"def getBrushColor():\n"+
+				"    return entity.getBrushColor()\n"+
+				
+				/* BINDINGS TRANSLATION: French */
+				"def avance(pas=1):\n"+
+				"	entity.forward(pas)\n"+
+				"def recule(pas=1):\n"+
+				"	entity.backward(pas)\n"+
+				"def gauche():\n"+
+				"	entity.left()\n"+
+				"def retourne():\n"+
+				"	entity.back()\n"+
+				"def droite():\n"+
+				"	entity.right()\n"+
+				"\n"+
+				"def getMondeHauteur():\n"+
+				"	return entity.getWorldHeight()\n"+
+				"def getMondeLargeur():\n"+
+				"	return entity.getWorldWidth()\n"+
+				"def baisseBrosse():\n"+
+				"   entity.brushDown()\n"+
+				"def leveBrosse():\n"+
+				"   entity.brushUp()\n" +
+				"def estBrosseBaissee():\n"+
+				"   entity.isBrushDown()\n" +
+				"def estFaceMur():" +
+				"	return entity.isFacingWall()\n"+
+				"def estDosMur():" +
+				"	return entity.isBackingWall()\n"+
+				"def getCouleurSol():\n"+
+				"   return entity.getGroundColor()\n"+
+				
+				"def errorMsg(str):\n"+
+				"  entity.seenError(str)\n"+
+				
+				"def estSurBiscuit():\n"+
+				"	return entity.isOverBaggle()\n"+
+				"def porteBiscuit():\n"+
+				"	return entity.isCarryingBaggle()\n"+
+				"def prendBiscuit():\n"+
+				"	return entity.pickupBaggle()\n"+
+				"def poseBiscuit():\n"+
+				"	return entity.dropBaggle()\n"+
+				
+				"def estSurMessage():\n"+
+				"	return entity.isOverMessage()\n"+
+				"def litMessage():\n"+
+				"	return entity.readMessage()\n"+
+				"def effaceMessage():\n"+
+				"   entity.clearMessage()\n"+
+				"def ecritMessage(msg):\n"+
+				"   entity.writeMessage(msg)\n"+
+				
+				"def setBrossehCouleur(c):\n"+
+				"    entity.setBrushColor(c)\n"+
+				"def getBrosseCouleur():\n"+
+				"    return entity.getBrushColor()\n"
+						);		
+		} else {
+			throw new RuntimeException("No binding of BuggleWorld for "+lang);
+		}
+	}
+	@Override
+	public String diffTo(World world) {
+		BuggleWorld other = (BuggleWorld) world;
+		StringBuffer sb = new StringBuffer();
+		if (! other.getName().equals(getName()))
+			sb.append(i18n.tr("  The world''s name is {0}",other.getName()));
+		for (int x=0; x<getWidth(); x++) 
+			for (int y=0; y<getHeight(); y++) 
+				if (!getCell(x, y).equals(other.getCell(x, y))) 
+					sb.append(i18n.tr("  In ({0},{1})",x,y)+  getCell(x, y).diffTo(other.getCell(x, y))+".\n");
+		for (int i=0; i<entities.size(); i++)  
+			if (! entities.get(i).equals(other.entities.get(i))) 
+				sb.append(i18n.tr("  Something is wrong about buggle ''{0}'':\n",entities.get(i).getName())+
+						((AbstractBuggle) entities.get(i)).diffTo((AbstractBuggle) other.entities.get(i)));
+		return sb.toString();
+	}
+
+}
diff --git a/src/plm/universe/bugglequest/BuggleWorldCell.java b/src/plm/universe/bugglequest/BuggleWorldCell.java
new file mode 100644
index 0000000..62fdf71
--- /dev/null
+++ b/src/plm/universe/bugglequest/BuggleWorldCell.java
@@ -0,0 +1,255 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+import plm.universe.GridWorld;
+import plm.universe.GridWorldCell;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+
+
+public class BuggleWorldCell extends GridWorldCell {
+	private Color color;
+
+	private Color msgColor = DEFAULT_MSG_COLOR; 
+	
+	public static final Color DEFAULT_COLOR = Color.white;
+	public static final Color DEFAULT_MSG_COLOR = new Color(0.5f,0.5f,0.9f);
+
+	private Baggle baggle;
+	
+	private String content = "";
+	
+	private boolean leftWall;
+
+	private boolean topWall;
+
+	public BuggleWorldCell(BuggleWorld w, int x, int y) {
+		this(w, x, y, DEFAULT_COLOR, false, false, null, "");
+	}
+
+	public BuggleWorldCell(BuggleWorldCell c, GridWorld w) {
+		this((BuggleWorld) w, c.x, c.y, c.color, c.leftWall, c.topWall, null, null);
+		if (c.hasBaggle()) {
+			Baggle b = new Baggle(c.getBaggle());
+			b.setCell(this);
+			this.baggle = b;
+		}
+		this.content = c.content;
+	}
+	public BuggleWorldCell copy(GridWorld w) {
+		return new BuggleWorldCell(this,w);
+	}
+
+	public BuggleWorldCell(BuggleWorld w, int x, int y, Color color, boolean leftWall, boolean topWall) {
+		this(w, x, y, color, leftWall, topWall, null, "");
+	}
+
+	public BuggleWorldCell(BuggleWorld w, int x, int y, Color c, boolean leftWall, boolean topWall, Baggle baggle, String content) {
+		super(w,x,y);
+		this.color = c;
+		this.leftWall = leftWall;
+		this.topWall = topWall;
+		this.baggle = baggle;
+		this.content = content;
+	}
+
+	public void setColor(Color c) {
+		this.color = c;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public Color getColor() {
+		return this.color;
+	}
+	
+	public void setMsgColor(Color c) {
+		this.msgColor = c;
+		world.notifyWorldUpdatesListeners();
+	}
+	
+	public Color getMsgColor() {
+		return this.msgColor;
+	}
+
+	public void putTopWall() {
+		this.topWall = true;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public void removeTopWall() {
+		this.topWall = false;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public void putLeftWall() {
+		this.leftWall = true;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public void removeLeftWall() {
+		this.leftWall = false;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	@Override
+	public String toString() {
+		String cell;
+		if (hasContent()) 
+			cell = this.content;
+		if (hasBaggle())
+			cell = "o";
+		else if (color.equals(DEFAULT_COLOR))
+			cell = " ";
+		else
+			cell = "?";
+		return cell;
+	}
+
+	public boolean hasTopWall() {
+		return this.topWall;
+	}
+
+	public boolean hasLeftWall() {
+		return this.leftWall;
+	}
+
+	public boolean hasBaggle() {
+		return this.baggle != null;
+	}
+
+	public Baggle getBaggle() {
+		return this.baggle;
+	}
+
+	public void newBaggle() throws AlreadyHaveBaggleException {
+		//Logger.log("WorldCell:newBaggle", "");
+		if (this.baggle != null) 
+			throw new AlreadyHaveBaggleException(Game.i18n.tr("There is already a baggle here."));
+		this.baggle = new Baggle(this);
+		world.notifyWorldUpdatesListeners();		
+	}
+	
+	public void newBaggle(Color c) throws AlreadyHaveBaggleException {
+		if (this.baggle != null) 
+			throw new AlreadyHaveBaggleException(Game.i18n.tr("There is already a baggle here."));
+		this.baggle = new Baggle(this,c);
+		world.notifyWorldUpdatesListeners();
+	}
+	
+	public void setBaggle(Baggle b) throws AlreadyHaveBaggleException {
+		if (this.baggle != null && b != null) 
+			throw new AlreadyHaveBaggleException(Game.i18n.tr("There is already a baggle here."));
+		this.baggle = b;
+		world.notifyWorldUpdatesListeners();
+	}
+
+	public Baggle pickupBaggle() {
+		Baggle b = this.baggle;
+		this.baggle.setCell(null);
+		baggle = null;		
+		world.notifyWorldUpdatesListeners();
+		return b;
+	}
+	
+	public boolean hasContent() {
+		return (!this.content.equals(""));
+	}
+
+	public String getContent() {
+		return this.content;
+	}
+	
+	public void setContent(String c) {
+		this.content = c;
+		world.notifyWorldUpdatesListeners();
+	}
+	
+	public void addContent(String c) {
+		this.content += c;
+		world.notifyWorldUpdatesListeners();
+	}
+	public void emptyContent() {
+		this.content = "";
+		world.notifyWorldUpdatesListeners();		
+	}
+			
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		//result = prime * result + ((baggle == null) ? 0 : baggle.hashCode());
+		result = prime * result + ((color == null) ? 0 : color.hashCode());
+		result = prime * result + ((content == null) ? 0 : content.hashCode());
+		result = prime * result + (leftWall ? 1231 : 1237);
+		result = prime * result + (topWall ? 1231 : 1237);
+		result = prime * result + ((world == null) ? 0 : world.hashCode());
+		result = prime * result + x;
+		result = prime * result + y;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		BuggleWorldCell other = (BuggleWorldCell) obj;
+		//if (hasBaggle() != other.hasBaggle())
+		//	return false;
+		if (baggle == null) {
+			if (other.baggle != null)
+				return false;
+		} else if (!baggle.equals(other.baggle))
+			return false;
+		if (color == null) {
+			if (other.color != null)
+				return false;
+		} else if (!color.equals(other.color))
+			return false;
+		if (!content.equals(other.content))
+			return false;
+		if (leftWall != other.leftWall)
+			return false;
+		if (topWall != other.topWall)
+			return false;
+		if (x != other.x)
+			return false;
+		if (y != other.y)
+			return false;
+		return true;
+	}
+
+	/* This function is called as answer.diffTo(current) */
+	public String diffTo(BuggleWorldCell current) {
+		StringBuffer sb = new StringBuffer();
+		if (baggle == null && current.baggle != null) 
+			sb.append(this.world.i18n.tr(", there shouldn't be this baggle"));
+		if (baggle != null && current.baggle == null)
+			sb.append(this.world.i18n.tr(", there should be a baggle"));
+		if (baggle != null && current.baggle != null && !baggle.equals(current.baggle))
+			sb.append(this.world.i18n.tr(", the baggle differs"));
+		if (color == null) {
+			if (current.color != null)
+				sb.append(this.world.i18n.tr(", the ground should not be {0}",current.color));
+		} else if (!color.equals(current.color))
+			sb.append(this.world.i18n.tr(", the ground is expected to be {0}, but it is {1}", color, current.color));
+		if (!content.equals(current.content))
+			sb.append(this.world.i18n.tr(", the ground reads ''{0}'' (expected: ''{1}'')", current.content, content));
+		if (leftWall != current.leftWall)
+			if (current.leftWall)
+				sb.append(this.world.i18n.tr(", there shouldn't be any wall at west"));
+			else
+				sb.append(this.world.i18n.tr(", there should be a wall at west"));
+		if (topWall != current.topWall)
+			if (current.topWall)
+				sb.append(this.world.i18n.tr(", there shouldn't be any wall at north"));
+			else
+				sb.append(this.world.i18n.tr(", there should be a wall at north"));
+		return sb.toString();
+	}
+}
diff --git a/src/plm/universe/bugglequest/SimpleBuggle.java b/src/plm/universe/bugglequest/SimpleBuggle.java
new file mode 100644
index 0000000..5ee6309
--- /dev/null
+++ b/src/plm/universe/bugglequest/SimpleBuggle.java
@@ -0,0 +1,136 @@
+package plm.universe.bugglequest;
+
+import java.awt.Color;
+
+import plm.core.model.Game;
+import plm.universe.Direction;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.universe.bugglequest.exception.BuggleInOuterSpaceException;
+import plm.universe.bugglequest.exception.BuggleWallException;
+import plm.universe.bugglequest.exception.NoBaggleUnderBuggleException;
+
+
+
+public abstract class SimpleBuggle extends AbstractBuggle  {
+	public SimpleBuggle(BuggleWorld w, String name, int i, int j, Direction dir, Color c, Color bc) {
+		super(w,name,i,j,dir,c,bc);
+	}
+
+	public SimpleBuggle() {
+		super();
+	}
+
+	@Override
+	public void forward()  {
+		try { 
+			super.forward(); 
+		} catch (BuggleWallException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+
+	@Override
+	public void forward(int count)  {
+		try { 
+			super.forward(count); 
+		} catch (BuggleWallException e) { 
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+
+	@Override
+	public void backward()  {
+		try { 
+			super.backward(); 
+		} catch (BuggleWallException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+
+	@Override
+	public void backward(int count)  {
+		try { 
+			super.backward(count); 
+		} catch (BuggleWallException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+
+	@Deprecated
+	@Override
+	public void pickUpBaggle () { 
+		pickupBaggle();
+	}
+	@Override
+	public void pickupBaggle () { 
+		try { 
+			super.pickupBaggle(); 
+		} catch (NoBaggleUnderBuggleException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		} catch (AlreadyHaveBaggleException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+
+	@Override
+	public void dropBaggle () { 
+		try { 
+			super.dropBaggle(); 
+		} catch (AlreadyHaveBaggleException e) { 
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}	
+	@Override 
+	public void setX(int x) {
+		try {
+			super.setX(x);
+		} catch (BuggleInOuterSpaceException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+	@Override 
+	public void setY(int y) {
+		try {
+			super.setY(y);
+		} catch (BuggleInOuterSpaceException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+	@Override 
+	public void setPos(int x,int y) {
+		try {
+			super.setPos(x,y);
+		} catch (BuggleInOuterSpaceException e) {
+			if (!haveSeenError())
+				javax.swing.JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), Game.i18n.tr("Test failed"), javax.swing.JOptionPane.ERROR_MESSAGE);
+			seenError();
+		}
+	}
+	
+	/* BINDINGS TRANSLATION: French (get/set X/Y/Pos are not translated as they happen to be the same in French) */
+	public void avance()          { forward(); }
+	public void avance(int steps) { forward(steps); }
+	public void recule()          { backward(); }
+	public void recule(int steps) { backward(steps); }
+	public void prendBiscuit()    { pickupBaggle(); }
+	public void poseBiscuit()     { dropBaggle(); }
+
+}
\ No newline at end of file
diff --git a/src/plm/universe/bugglequest/exception/AlreadyHaveBaggleException.java b/src/plm/universe/bugglequest/exception/AlreadyHaveBaggleException.java
new file mode 100644
index 0000000..2663dfd
--- /dev/null
+++ b/src/plm/universe/bugglequest/exception/AlreadyHaveBaggleException.java
@@ -0,0 +1,13 @@
+package plm.universe.bugglequest.exception;
+
+import plm.core.PLMException;
+
+
+public class AlreadyHaveBaggleException extends PLMException {
+
+	private static final long serialVersionUID = -4857249506281940595L;
+
+	public AlreadyHaveBaggleException(String msg) {
+		super(msg);
+	}
+}
diff --git a/src/plm/universe/bugglequest/exception/BuggleInOuterSpaceException.java b/src/plm/universe/bugglequest/exception/BuggleInOuterSpaceException.java
new file mode 100644
index 0000000..092cafb
--- /dev/null
+++ b/src/plm/universe/bugglequest/exception/BuggleInOuterSpaceException.java
@@ -0,0 +1,14 @@
+package plm.universe.bugglequest.exception;
+
+import plm.core.PLMException;
+
+
+public class BuggleInOuterSpaceException extends PLMException {
+
+	public BuggleInOuterSpaceException(String msg) {
+		super(msg);
+	}
+
+	private static final long serialVersionUID = -7246709356730960089L;
+
+}
diff --git a/src/plm/universe/bugglequest/exception/BuggleWallException.java b/src/plm/universe/bugglequest/exception/BuggleWallException.java
new file mode 100644
index 0000000..b50fb7c
--- /dev/null
+++ b/src/plm/universe/bugglequest/exception/BuggleWallException.java
@@ -0,0 +1,15 @@
+package plm.universe.bugglequest.exception;
+
+import plm.core.PLMException;
+import plm.core.model.Game;
+
+
+public class BuggleWallException extends PLMException {
+
+	public BuggleWallException() {
+		super(Game.i18n.tr("Buggles cannot traverse walls"));
+	}
+
+	private static final long serialVersionUID = -7246709356730960089L;
+
+}
diff --git a/src/plm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java b/src/plm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java
new file mode 100644
index 0000000..1aa9897
--- /dev/null
+++ b/src/plm/universe/bugglequest/exception/NoBaggleUnderBuggleException.java
@@ -0,0 +1,14 @@
+package plm.universe.bugglequest.exception;
+
+import plm.core.PLMException;
+
+
+public class NoBaggleUnderBuggleException extends PLMException {
+
+	private static final long serialVersionUID = 8112061605322303567L;
+
+	public NoBaggleUnderBuggleException(String msg) {
+		super(msg);
+	}
+
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/EditionListener.java b/src/plm/universe/bugglequest/mapeditor/EditionListener.java
new file mode 100644
index 0000000..026e794
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/EditionListener.java
@@ -0,0 +1,23 @@
+package plm.universe.bugglequest.mapeditor;
+
+import plm.universe.Entity;
+import plm.universe.World;
+
+public interface EditionListener {
+	/** 
+	 * Inform the listener that the edited world just changed 
+	 * @param w the new world to edit
+	 */
+	void setWorld(World w);
+	/** 
+	 * Event fired each time that something changes in the edited world. That's quite often, actually
+	 */
+	void worldEdited();
+	/**
+	 * Event fired when the currently selection changes
+	 * @param x x-coordinate of selection
+	 * @param y y-coordinate of selection
+	 * @param ent new entity under radar. May be null if there is no entity in selected cell
+	 */
+	void selectedChanged(int x, int y, Entity ent);
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/Editor.java b/src/plm/universe/bugglequest/mapeditor/Editor.java
new file mode 100644
index 0000000..b310448
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/Editor.java
@@ -0,0 +1,125 @@
+package plm.universe.bugglequest.mapeditor;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.universe.BrokenWorldFileException;
+import plm.universe.Entity;
+import plm.universe.World;
+import plm.universe.bugglequest.AbstractBuggle;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Editor {
+
+	private BuggleWorld world;
+	private ArrayList<EditionListener> editionListeners = new ArrayList<EditionListener>();
+	private String command = "topwall";
+	private Color selectedColor = Color.blue;
+	private int selectedColorNumber = 1;
+	public I18n	i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages", new Locale("fr"), I18nFactory.FALLBACK); // FIXME: ugly: french is hardcoded!!!!!
+
+	
+	public Editor() {
+		createNewMap(10, 10);
+		world.setSelectedCell(0, 0);
+	}
+
+	public void createNewMap(int width, int height) {
+		this.world = new BuggleWorld("Brave new world",width, height);
+		
+		for (EditionListener v : this.editionListeners) {
+			v.setWorld(this.world);
+		}
+				
+		notifySetWorld(world);
+	}
+
+	public void saveMap(File file) {
+		try {
+			this.world.writeToFile(file);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public void loadMap(String file) throws IOException {
+		try {
+			world = (BuggleWorld) BuggleWorld.newFromFile(file); 
+		} catch (BrokenWorldFileException e) {
+			e.printStackTrace();
+		}
+		notifySetWorld(world);
+	}
+
+	public BuggleWorld getWorld() {
+		return this.world;
+	}
+	
+	public void addEditionListener(EditionListener v) {
+		this.editionListeners.add(v);
+	}
+
+	public void removeEditionListener(EditionListener v) {
+		this.editionListeners.remove(v);
+	}
+
+	public void notifySetWorld(World w) {
+		for (EditionListener v : this.editionListeners) 
+			v.setWorld(w);
+	}
+	public void notifyWorldEdited(){
+		for (EditionListener el : editionListeners)
+			el.worldEdited();		
+	}
+
+	public void setCommand(String cmd) {
+		command = cmd;
+	}
+	public String getCommand() {
+		return command;
+	}
+
+	public void setSelectedColor(Color c) {
+		selectedColor = c;
+	}
+	public Color getSelectedColor() {
+		return selectedColor;
+	}
+
+	public int getSelectedColorNumber() {
+		return selectedColorNumber ;
+	}
+
+	public void setSelectedColorNumber(int i) {
+		selectedColorNumber = i;		
+	}
+
+	public void setSelectedCell(int x, int y) {
+		AbstractBuggle buggle = null;
+		for (Entity e : getWorld().getEntities()) {
+			AbstractBuggle b = (AbstractBuggle) e;
+			if (b.getX() == x && b.getY() == y)
+				buggle = b;
+		}
+		getWorld().setSelectedCell(x, y);
+		
+		for (EditionListener el : editionListeners)
+			el.selectedChanged(x, y, buggle);
+	}
+	public void setSelectedEntity(AbstractBuggle buggle) {
+		int x = getWorld().getSelectedCell().getX();
+		int y = getWorld().getSelectedCell().getY();
+		
+		getWorld().setSelectedEntity(buggle);
+		for (EditionListener el : editionListeners)
+			el.selectedChanged(x, y, buggle);
+		
+	}
+
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/MainFrame.java b/src/plm/universe/bugglequest/mapeditor/MainFrame.java
new file mode 100644
index 0000000..c68008d
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/MainFrame.java
@@ -0,0 +1,262 @@
+package plm.universe.bugglequest.mapeditor;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.ui.ResourcesCache;
+import plm.core.utils.ColorMapper;
+import plm.core.utils.InvalidColorNameException;
+
+
+public class MainFrame extends JFrame {
+
+	private static final long serialVersionUID = -7243431953648987489L;
+
+	private Editor editor;
+	private ButtonGroup tools;
+	private String path;	
+	
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+	
+	public MainFrame(Editor editor) {
+		super("BuggleQuest - MapEditor");
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		this.editor = editor;
+		initComponents();
+		setSize(800, 600);
+		setVisible(true);
+	}
+
+	public void initComponents() {
+
+		JMenuBar menuBar = new JMenuBar();
+
+		JMenu fileMenu = new JMenu("File");
+		JMenuItem mi;
+		
+		mi = new JMenuItem(new NewMapAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+		
+		mi = new JMenuItem(new OpenMapAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+		
+		mi = new JMenuItem(new SaveMapAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+
+		mi = new JMenuItem(new QuitAction());
+		mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
+		fileMenu.add(mi);
+
+		menuBar.add(fileMenu);
+		this.setJMenuBar(menuBar);
+
+		getContentPane().setLayout(new BorderLayout());
+
+		JToolBar toolBar = new JToolBar();
+
+		JToggleButton topButton = createButton("topwall"); 
+		JToggleButton leftButton = createButton("leftwall"); 
+		JToggleButton baggleButton = createButton("baggle");
+		JToggleButton buggleButton = createButton("buggle");
+		JToggleButton nobuggleButton = createButton("nobuggle");
+		JToggleButton textButton = createButton("text");
+		JToggleButton colorButton = createButton("colors",new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				editor.setCommand("colors");
+				Object[] choices = {
+						"custom", "black","blue","cyan","darkGray","gray","green","lightGray","magenta","orange","pink","red","yellow"};
+				Color[] colors = {
+						new Color(42,42,42), Color.black,Color.blue,Color.cyan,Color.darkGray,Color.gray,Color.green,Color.lightGray,Color.magenta,Color.orange,Color.pink,Color.red,Color.yellow};
+				
+				Object selectedValue = JOptionPane.showInputDialog(null,
+						"Choose a color", "Change color",
+						JOptionPane.INFORMATION_MESSAGE, null,
+						choices, choices[editor.getSelectedColorNumber()]);
+				
+				if (selectedValue == null) // cancel pressed
+					return;
+					
+				if (selectedValue.equals("custom")) {
+					String name = JOptionPane.showInputDialog("What color you want (r/g/b)", 
+							colors[0].getRed()+"/"+colors[0].getGreen()+"/"+colors[0].getBlue());
+					try {
+						Color c = ColorMapper.name2color(name);
+						colors[0] = c;
+					} catch (InvalidColorNameException icne) {
+						/* Ignore */
+					}
+				}
+				for (int i=0; i<choices.length;i++) 
+					if (selectedValue.equals(choices[i])) {
+						editor.setSelectedColorNumber(i);
+						editor.setSelectedColor(colors[i]);
+					}					
+			}	
+		});
+
+		topButton.setSelected(true);
+
+
+		toolBar.add(topButton);
+		toolBar.add(leftButton);
+		toolBar.add(baggleButton);
+		toolBar.add(buggleButton);
+		toolBar.add(nobuggleButton);
+		toolBar.add(colorButton);
+		toolBar.add(textButton);
+
+		tools = new ButtonGroup();
+		tools.add(topButton);
+		tools.add(leftButton);
+		tools.add(baggleButton);
+		tools.add(buggleButton);
+		tools.add(nobuggleButton);
+		tools.add(colorButton);
+		tools.add(textButton);
+
+		getContentPane().add(toolBar, BorderLayout.NORTH);
+
+		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
+		sp.setOneTouchExpandable(false);
+
+		MapView mapView = new MapView(editor);
+		editor.addEditionListener(mapView);
+		sp.setLeftComponent(mapView);
+		sp.setRightComponent(new PropertiesEditor(editor));
+		sp.setResizeWeight(.6);
+		
+		getContentPane().add(sp, BorderLayout.CENTER);
+	}
+
+	private JToggleButton createButton(final String name) {
+		ActionListener l = new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				editor.setCommand(name);
+			}	
+		};
+		return createButton(name,l); 
+	}
+	private JToggleButton createButton(final String name, ActionListener l) {
+		JToggleButton bt = new JToggleButton(ResourcesCache.getIcon("img/edit_"+name+".png"));
+		bt.setActionCommand(name);
+		bt.setBorderPainted(false);
+		bt.addActionListener(l);
+		return bt;
+	}
+
+	class NewMapAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public NewMapAction() {
+			super(i18n.tr("Create New Map"));
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			int w = 10;
+			int h = 10;
+
+			String wString = null;
+			String hString = null;
+
+			wString = JOptionPane.showInputDialog("Enter desired map width", Integer.toString(w));
+			if (wString != null)
+				hString = JOptionPane.showInputDialog("Enter desired map height", Integer.toString(h));
+
+			if (hString != null) {
+				w = Integer.parseInt(wString);
+				h = Integer.parseInt(hString);
+				editor.createNewMap(w, h);
+				MainFrame.this.path = null;
+			}
+		}
+
+	}
+
+	class SaveMapAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public SaveMapAction() {
+			super("Save As...");
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			JFileChooser fc;
+			if (MainFrame.this.path != null)
+				fc = new JFileChooser(MainFrame.this.path);
+			else
+				fc = new JFileChooser();
+			int status = fc.showSaveDialog(MainFrame.this);
+
+			if (status == JFileChooser.APPROVE_OPTION) {
+				File file = fc.getSelectedFile();
+				editor.saveMap(file);
+			}
+		}
+	}
+
+	class OpenMapAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public OpenMapAction() {
+			super(i18n.tr("Open Map..."));
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			JFileChooser fc = new JFileChooser();
+			fc.setFileFilter(new FileNameExtensionFilter(i18n.tr("PLM map files"), "map"));
+			int status = fc.showOpenDialog(MainFrame.this);
+
+			if (status == JFileChooser.APPROVE_OPTION) {
+				MainFrame.this.path = fc.getSelectedFile().getAbsolutePath();
+				try {
+					editor.loadMap(MainFrame.this.path);
+				} catch (IOException e1) {
+					JOptionPane.showMessageDialog(null, e1.getLocalizedMessage(),i18n.tr("Error while reading {0}",path), JOptionPane.ERROR_MESSAGE);
+				}
+			}
+		}
+
+	}
+
+	class QuitAction extends AbstractAction {
+		private static final long serialVersionUID = 1L;
+
+		public QuitAction() {
+			super("Quit Map Editor");
+		}
+
+		@Override
+		public void actionPerformed(ActionEvent e) {
+			dispose();
+		}
+
+	}
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/MapEditorApp.java b/src/plm/universe/bugglequest/mapeditor/MapEditorApp.java
new file mode 100644
index 0000000..3eccc62
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/MapEditorApp.java
@@ -0,0 +1,19 @@
+package plm.universe.bugglequest.mapeditor;
+
+import java.io.IOException;
+
+
+public class MapEditorApp {
+
+	public static void main(String[] args) {
+		Editor editor = new Editor();
+		new MainFrame(editor);
+		if (args.length>0)
+			try {
+				editor.loadMap(args[0]);
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+	}
+
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/MapView.java b/src/plm/universe/bugglequest/mapeditor/MapView.java
new file mode 100644
index 0000000..c32d3b1
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/MapView.java
@@ -0,0 +1,143 @@
+package plm.universe.bugglequest.mapeditor;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.JOptionPane;
+
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.bugglequest.Buggle;
+import plm.universe.bugglequest.BuggleWorldCell;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+import plm.universe.bugglequest.ui.BuggleWorldView;
+
+
+public class MapView extends BuggleWorldView implements EditionListener {
+
+	private static final long serialVersionUID = -8303474674104829723L;
+	private Editor editor;
+	private int buggleCount = 0;
+	
+	public MapView(Editor e) {
+		super(e.getWorld());
+		this.editor = e;
+
+		MouseListener mouseListener = new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				handleMouseEvt(e);
+			}
+			void handleMouseEvt(MouseEvent e) {
+				int x = (int) ((e.getX() - getPadX()) / getCellWidth());
+				int y = (int) ((e.getY() - getPadY()) / getCellWidth());
+				
+				editor.setSelectedCell(x, y);
+				BuggleWorldCell cell = (BuggleWorldCell) editor.getWorld().getSelectedCell();
+				String cmd = editor.getCommand();
+
+				if (cmd.equals("topwall")) {
+					if (cell.hasTopWall()) 
+						cell.removeTopWall();
+					else
+						cell.putTopWall();
+				} else if (cmd.equals("leftwall")) {
+					if (cell.hasLeftWall()) 
+						cell.removeLeftWall();
+					else
+						cell.putLeftWall();
+				} else if (cmd.equals("baggle")) {
+					if (cell.hasBaggle()) 
+						cell.pickupBaggle();
+					else
+						try {
+							cell.newBaggle();
+						} catch (AlreadyHaveBaggleException e1) {
+							System.out.println("The impossible did happen (yet again)");
+							e1.printStackTrace();
+						}
+				} else if (cmd.equals("colors")) {
+					if (cell.getColor().equals(editor.getSelectedColor())) 
+						cell.setColor(Color.white);
+					else
+						cell.setColor(editor.getSelectedColor());
+				} else if (cmd.equals("text")) {
+					String inputValue = (String)JOptionPane.showInputDialog(null,
+							"Choose a new message", "Change message",
+							JOptionPane.QUESTION_MESSAGE, null,
+							null,cell.getContent());
+					
+					if (inputValue == null) // cancel pressed
+						return;
+					cell.emptyContent();
+					cell.addContent(inputValue);
+					
+				} else if (cmd.equals("buggle")) {
+					Buggle thebuggle = null;
+					for (Entity ent:editor.getWorld().getEntities()) {
+						Buggle b = (Buggle) ent;
+						if (b.getX() == x && b.getY() == y) {
+							thebuggle = b;
+							break;
+						}
+					}
+					if (thebuggle == null) {
+						thebuggle = new Buggle(editor.getWorld(),"buggle"+(++buggleCount), x,y,Direction.NORTH,Color.black, Color.black);
+					} 
+					editor.setSelectedEntity(thebuggle);
+				} else if (cmd.equals("nobuggle")) {
+					Buggle thebuggle = null;
+					for (Entity ent:editor.getWorld().getEntities()) {
+						Buggle b = (Buggle) ent;
+						if (b.getX() == x && b.getY() == y) {
+							thebuggle = b;
+							break;
+						}
+					}
+					if (thebuggle != null) {
+						editor.getWorld().removeEntity(thebuggle);
+						if (editor.getWorld().getEntities().contains(thebuggle))
+							System.err.println("The entity is still in "+editor.getWorld().getEntities().indexOf(thebuggle)+"!!");
+
+					}
+					editor.setSelectedEntity(null);
+				}
+			}
+		};
+		addMouseListener(mouseListener);
+	}
+
+	@Override
+	public void worldEdited() {
+		worldHasChanged();// use the callbacks of the regular view -- not really clean but efficient
+	}
+
+	@Override
+	public void selectedChanged(int x, int y, Entity ent) {
+		/* I'm too lazy to react to this */
+		this.repaint();
+	}
+	
+	@Override
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		BuggleWorldCell selection = editor.getWorld().getSelectedCell();
+		if (selection != null) {
+			int padx = (int) getPadX();
+			int pady = (int) getPadY();
+			int ox = (int) (selection.getX()*getCellWidth()); // x-offset of the cell
+			int oy = (int) ((selection.getY())*getCellWidth()); // y-offset of the cell
+			int cellW = (int) getCellWidth();
+
+			g.setColor(Color.RED);
+			g.drawRoundRect(padx+ox+2, pady+oy+2, cellW-4,cellW-4, cellW/10, cellW/10);
+			g.setColor(Color.WHITE);
+			g.drawRoundRect(padx+ox+3, pady+oy+3, cellW-6,cellW-6, cellW/10, cellW/10);
+			g.setColor(Color.RED);
+			g.drawRoundRect(padx+ox+4, pady+oy+4, cellW-8,cellW-8, cellW/10, cellW/10);
+		}
+	}
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java b/src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java
new file mode 100644
index 0000000..37e9509
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/PropertiesEditor.java
@@ -0,0 +1,389 @@
+package plm.universe.bugglequest.mapeditor;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.util.Vector;
+
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableModel;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.utils.ColorMapper;
+import plm.core.utils.InvalidColorNameException;
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.World;
+import plm.universe.bugglequest.AbstractBuggle;
+import plm.universe.bugglequest.Baggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.BuggleWorldCell;
+import plm.universe.bugglequest.exception.AlreadyHaveBaggleException;
+
+public class PropertiesEditor extends JComponent implements EditionListener {
+	private static final long serialVersionUID = 3904327915735497696L;
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+	
+	private AbstractBuggle selectedBuggle;
+
+	private DefaultTableModel model = new DefaultTableModel() {
+		private static final long serialVersionUID = 1L;
+
+		public boolean isCellEditable(int rowIndex, int colIndex) {
+			return colIndex>0;
+		}
+	};
+	private JTable table = new JTable(model);
+
+	private Editor editor; 
+	private int selectedXRank,selectedYRank,topRank,leftRank,baggleRank;
+
+	Vector<PLMProperty> properties = new Vector<PLMProperty>();
+	
+	public PropertiesEditor(Editor _editor) {
+		editor = _editor;
+		editor.addEditionListener(this);
+
+		setLayout(new BorderLayout());
+		add(new JScrollPane(table), BorderLayout.CENTER);
+
+		model.setColumnCount(2);
+		model.setColumnIdentifiers(new Object[] {i18n.tr("Property"), i18n.tr("Value")});
+		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		repopulateTable();
+		setVisible(true);
+		setPreferredSize(new Dimension(100, 500));
+
+		model.addTableModelListener(new MyTableModelListener(editor,table,properties));
+	}
+	private void repopulateTable() {
+		while (model.getRowCount()>0)
+			model.removeRow(0);
+		properties.removeAllElements();
+
+		/* The editor for the name */
+		model.insertRow(0, new Object[] {i18n.tr("World name"), new PLMProperty(properties) { 
+			@Override
+			public void setValue(String value) {
+				editor.getWorld().setName(value);
+			}
+			@Override
+			public String toString() {
+				return editor.getWorld().getName();
+			}
+		}});
+
+		/*---------- world width ---------------*/
+		model.addRow(new Object[] {i18n.tr("World width"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				return ""+editor.getWorld().getWidth();
+			}
+			@Override
+			public void setValue(String value) {
+				Integer i;
+				try {
+					i = Integer.parseInt(value);
+				} catch (NumberFormatException nfe) {
+					table.setValueAt(""+editor.getWorld().getWidth(),rank,1);
+					return; // silently ignore invalid values
+				}
+				editor.getWorld().setWidth(i);
+				editor.getWorld().notifyWorldUpdatesListeners();
+			}
+		}});
+		
+		/*---------- world height ---------------*/
+		model.addRow(new Object[] {i18n.tr("World height"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				return ""+editor.getWorld().getHeight();
+			}
+			@Override
+			public void setValue(String value) {
+				Integer i;
+				try {
+					i = Integer.parseInt(value);
+				} catch (NumberFormatException nfe) {
+					table.setValueAt(""+editor.getWorld().getHeight(),rank,1);
+					return; // silently ignore invalid values
+				}
+				editor.getWorld().setHeight(i);
+				editor.getWorld().notifyWorldUpdatesListeners();
+			}
+		}});
+
+		/*---------- selected cell ---------------*/
+		model.addRow(new Object[] {i18n.tr("Selected cell X"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				selectedXRank = rank;
+				return ""+editor.getWorld().getSelectedCell().getX();
+			}
+			@Override
+			public void setValue(String value) {
+				Integer x;
+				try {
+					x = Integer.parseInt(value);
+					if (x>=editor.getWorld().getWidth() || x<0)
+						throw new NumberFormatException("out of world");
+				} catch (NumberFormatException nfe) {
+					table.setValueAt(""+editor.getWorld().getSelectedCell().getX(),rank,1);
+					return; // silently ignore invalid values
+				}
+				editor.setSelectedCell(x, editor.getWorld().getSelectedCell().getY());
+			}
+		}});
+
+		/*---------- selected cell ---------------*/
+		model.addRow(new Object[] {i18n.tr("Selected cell Y"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				selectedYRank = rank;
+				return ""+editor.getWorld().getSelectedCell().getY();
+			}
+			@Override
+			public void setValue(String value) {
+				Integer y;
+				try {
+					y = Integer.parseInt(value);
+					if (y>=editor.getWorld().getHeight() || y<0)
+						throw new NumberFormatException("out of world");
+				} catch (NumberFormatException nfe) {
+					table.setValueAt(""+editor.getWorld().getSelectedCell().getY(),rank,1);
+					return; // silently ignore invalid values
+				}
+				editor.setSelectedCell(editor.getWorld().getSelectedCell().getX(),y);
+			}
+		}});
+		/*---------- Ground color ---------------*/
+		model.addRow(new Object[] {i18n.tr("Ground color (name or r/g/b)"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				return ColorMapper.color2name( editor.getWorld().getSelectedCell().getColor() );
+			}
+			@Override
+			public void setValue(String value) {
+				try {
+					Color c = ColorMapper.name2color(value);
+					editor.getWorld().getSelectedCell().setColor(c);
+				} catch (InvalidColorNameException icn) {
+					table.setValueAt(ColorMapper.color2name(editor.getWorld().getSelectedCell().getColor()),rank,1);
+				}
+			}
+		}});
+
+		/*---------- top wall cell ---------------*/
+		model.addRow(new Object[] {i18n.tr("Top wall?"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				topRank = rank;
+				return editor.getWorld().getSelectedCell().hasTopWall()?"Y":"N";
+			}
+			@Override
+			public void setValue(String value) {
+				if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
+					table.setValueAt(editor.getWorld().getSelectedCell().hasTopWall()?"Y":"N",rank,1);
+					return;
+					
+				} else if (value.equalsIgnoreCase("Y")) {
+					if (!editor.getWorld().getSelectedCell().hasTopWall()) // only update if needed
+						editor.getWorld().getSelectedCell().putTopWall();
+				} else {
+					if (editor.getWorld().getSelectedCell().hasTopWall()) // only update if needed
+						editor.getWorld().getSelectedCell().removeTopWall();
+				}
+			}
+		}});
+		/*---------- left wall cell ---------------*/
+		model.addRow(new Object[] {i18n.tr("Left wall?"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				leftRank = rank;
+				return editor.getWorld().getSelectedCell().hasLeftWall()?"Y":"N";
+			}
+			@Override
+			public void setValue(String value) {
+				if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
+					table.setValueAt(editor.getWorld().getSelectedCell().hasLeftWall()?"Y":"N",rank,1);
+					return;
+					
+				} else if (value.equalsIgnoreCase("Y")) {
+					if (!editor.getWorld().getSelectedCell().hasLeftWall()) // only update if needed
+						editor.getWorld().getSelectedCell().putLeftWall();
+				} else {
+					if (editor.getWorld().getSelectedCell().hasLeftWall()) // only update if needed
+						editor.getWorld().getSelectedCell().removeLeftWall();
+				}
+			}
+		}});
+		/*---------- have baggle ---------------*/
+		model.addRow(new Object[] {i18n.tr("Baggle?"), new PLMProperty(properties) {
+			@Override
+			public String toString() {
+				baggleRank = rank;
+				return editor.getWorld().getSelectedCell().hasBaggle()?"Y":"N";
+			}
+			@Override
+			public void setValue(String value) {
+				BuggleWorldCell selected = editor.getWorld().getSelectedCell();
+				
+				try {
+					if (!value.equalsIgnoreCase("Y") && !value.equalsIgnoreCase("N")) {
+						table.setValueAt(editor.getWorld().getSelectedCell().hasBaggle()?"Y":"N",rank,1);
+						return;
+
+					} else if (value.equalsIgnoreCase("Y")) {
+						if (!selected.hasBaggle()) // only update if needed
+							selected.setBaggle(new Baggle(selected));
+					} else {
+						if (selected.hasBaggle()) // only update if needed
+							selected.setBaggle(null);
+					}
+				} catch (AlreadyHaveBaggleException e) { 
+					System.err.println("The impossible happened (yet again)");
+					e.printStackTrace();
+				}
+			}
+		}});
+		
+		if (selectedBuggle != null) {
+			/*---------- Buggle name ---------------*/
+			model.addRow(new Object[] {i18n.tr("Buggle name"), new PLMProperty(properties) {
+				@Override
+				public String toString() {
+					return selectedBuggle.getName();
+				}
+				@Override
+				public void setValue(String value) {
+					selectedBuggle.setName(value);
+				}
+			}});
+			/*---------- Buggle direction ---------------*/
+			model.addRow(new Object[] {i18n.tr("Buggle direction (N|S|E|W)"), new PLMProperty(properties) {
+				@Override
+				public String toString() {
+					if (selectedBuggle.getDirection().equals(Direction.NORTH)) 
+						return "N";
+					if (selectedBuggle.getDirection().equals(Direction.SOUTH))
+						return "S";
+					if (selectedBuggle.getDirection().equals(Direction.EAST))
+						return "E";
+					if (selectedBuggle.getDirection().equals(Direction.WEST))
+						return "W";
+					return "?";
+				}
+				@Override
+				public void setValue(String value) {
+					if (value.equalsIgnoreCase("N"))
+						selectedBuggle.setDirection(Direction.NORTH);
+					if (value.equalsIgnoreCase("S"))
+						selectedBuggle.setDirection(Direction.SOUTH);
+					if (value.equalsIgnoreCase("E"))
+						selectedBuggle.setDirection(Direction.EAST);
+					if (value.equalsIgnoreCase("W"))
+						selectedBuggle.setDirection(Direction.WEST);
+					else {
+						table.setValueAt(this.toString(),rank,1);
+					}
+				}
+			}});
+			/*---------- Buggle color ---------------*/
+			model.addRow(new Object[] {i18n.tr("Buggle color (name or r/g/b)"), new PLMProperty(properties) {
+				@Override
+				public String toString() {
+					return ColorMapper.color2name( selectedBuggle.getColor() );
+				}
+				@Override
+				public void setValue(String value) {
+					try {
+						Color c = ColorMapper.name2color(value);
+						selectedBuggle.setColor(c);
+					} catch (InvalidColorNameException icn) {
+						table.setValueAt(ColorMapper.color2name(selectedBuggle.getColor()),rank,1);
+					}
+				}
+			}});
+			/*---------- Buggle color ---------------*/
+			model.addRow(new Object[] {i18n.tr("Brush color (name or r/g/b)"), new PLMProperty(properties) {
+				@Override
+				public String toString() {
+					return ColorMapper.color2name( selectedBuggle.getBrushColor() );
+				}
+				@Override
+				public void setValue(String value) {
+					try {
+						Color c = ColorMapper.name2color(value);
+						selectedBuggle.setBrushColor(c);
+					} catch (InvalidColorNameException icn) {
+						table.setValueAt(ColorMapper.color2name(selectedBuggle.getBrushColor()),rank,1);
+					}
+				}
+			}});
+		}
+	}
+	@Override
+	public void setWorld(World w) {
+		if (((BuggleWorld) w).getSelectedCell() == null)
+			((BuggleWorld) w).setSelectedCell(0,0);
+		repopulateTable();		
+		
+	}
+	@Override
+	public void worldEdited() {
+		BuggleWorldCell selected = editor.getWorld().getSelectedCell();
+		
+		table.setValueAt(""+selected.getX(),selectedXRank,1);
+		table.setValueAt(""+selected.getY(),selectedYRank,1);
+		table.setValueAt(selected.hasTopWall() ?"Y":"N", topRank, 1);
+		table.setValueAt(selected.hasLeftWall()?"Y":"N", leftRank,1);
+		table.setValueAt(selected.hasBaggle()?"Y":"N", baggleRank,1);
+	}
+	@Override
+	public void selectedChanged(int x, int y, Entity ent) {
+		selectedBuggle = (AbstractBuggle) ent;
+		repopulateTable();
+	}
+}
+
+class MyTableModelListener implements TableModelListener {
+	private JTable table;
+	private Vector<PLMProperty> properties;
+
+	private boolean ongoing = false;
+	
+	MyTableModelListener(Editor e, JTable t, Vector<PLMProperty> props) {
+		table = t;
+		properties = props;
+	}
+	public void tableChanged(TableModelEvent e) {
+		if (ongoing) 
+			return;
+		
+		ongoing = true;
+		int row = e.getFirstRow(); // selections are SINGLE_SELECTION anyway, so ignore getLastRow
+
+		if (e.getType() == TableModelEvent.UPDATE) 
+			for (PLMProperty p : properties) 
+				if (p.rank == row) 
+					p.setValue(""+ table.getModel().getValueAt(row, 1));
+		ongoing = false;
+	}
+}
+
+abstract class PLMProperty {
+	public int rank;
+	public PLMProperty(Vector<PLMProperty> props) {
+		rank = props.size();
+		props.add(this);
+	}
+	public abstract void setValue(String value);
+	public abstract String toString();
+}
diff --git a/src/plm/universe/bugglequest/mapeditor/package-info.java b/src/plm/universe/bugglequest/mapeditor/package-info.java
new file mode 100644
index 0000000..e7a25fb
--- /dev/null
+++ b/src/plm/universe/bugglequest/mapeditor/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains another binary, which can be used to edit BuggleWorld maps
+ */
+package plm.universe.bugglequest.mapeditor;
+
diff --git a/src/plm/universe/bugglequest/package-info.java b/src/plm/universe/bugglequest/package-info.java
new file mode 100644
index 0000000..12083d1
--- /dev/null
+++ b/src/plm/universe/bugglequest/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Universe of the buggles, allowing simple control yet rich interactions with the environment.
+ */
+package plm.universe.bugglequest;
+
diff --git a/src/plm/universe/bugglequest/ui/BuggleButtonPanel.java b/src/plm/universe/bugglequest/ui/BuggleButtonPanel.java
new file mode 100644
index 0000000..cb32079
--- /dev/null
+++ b/src/plm/universe/bugglequest/ui/BuggleButtonPanel.java
@@ -0,0 +1,240 @@
+package plm.universe.bugglequest.ui;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.util.Locale;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+
+import plm.core.model.Game;
+import plm.universe.EntityControlPanel;
+import plm.universe.bugglequest.AbstractBuggle;
+import plm.universe.bugglequest.exception.BuggleWallException;
+
+public class BuggleButtonPanel extends EntityControlPanel {
+
+	private static final long serialVersionUID = 1L;
+	private JButton fButton;
+	private JButton bButton;
+	private JButton rButton;
+	private JButton lButton;
+	private JToggleButton brushButton;
+	private JComboBox buggleColorComboBox;
+	private JComboBox brushColorComboBox;
+	private JLabel lBuggleColor;
+	private JLabel lBrushColor;
+	
+	public BuggleButtonPanel() {
+		setLayout(new FlowLayout());
+		
+		initializeButtons();
+		initializeColorsBoxes();
+
+		add(createButtonsPanel());
+		add(createColorsBoxes());
+
+		Game.getInstance().addHumanLangListener(this);
+	}
+
+	/**
+	 * Initialize fButton, bButton, rButton, lButton and brushButton
+	 */
+	private void initializeButtons() {
+		fButton = new JButton(i18n.tr("forward"));
+		fButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				try {
+					((AbstractBuggle)Game.getInstance().getSelectedEntity()).forward();
+				} catch (BuggleWallException e) {
+					showWallHuggingErrorMessageDialog();
+					// e.printStackTrace();
+					//game.getOutputWriter().log(e);
+				}
+			}
+		});
+		fButton.setMnemonic(KeyEvent.VK_UP);
+
+		bButton = new JButton(i18n.tr("backward"));
+		bButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				try {
+					((AbstractBuggle)Game.getInstance().getSelectedEntity()).backward();
+				} catch (BuggleWallException e) {
+					showWallHuggingErrorMessageDialog();
+					// e.printStackTrace();
+					// Game.getInstance().getOutputWriter().log(e);
+				}
+			}
+		});
+		bButton.setMnemonic(KeyEvent.VK_DOWN);
+
+		lButton = new JButton(i18n.tr("left"));
+		lButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				((AbstractBuggle)Game.getInstance().getSelectedEntity()).left();
+			}
+		});
+		lButton.setMnemonic(KeyEvent.VK_LEFT);
+
+		rButton = new JButton(i18n.tr("right"));
+		rButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				((AbstractBuggle)Game.getInstance().getSelectedEntity()).right();
+			}
+		});
+		rButton.setMnemonic(KeyEvent.VK_RIGHT);
+
+		brushButton = new JToggleButton(i18n.tr("mark"));
+		brushButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				AbstractBuggle b = (AbstractBuggle)Game.getInstance().getSelectedEntity();
+				if (b.isBrushDown()) {
+					b.brushUp();
+				} else {
+					b.brushDown();
+				}
+			}
+		});
+		brushButton.setMnemonic(KeyEvent.VK_SPACE);
+		brushButton.setSelected(((AbstractBuggle)(Game.getInstance().getSelectedEntity())).isBrushDown());
+	}
+
+	/**
+	 * Initialize buggleColorComboBox and brushColorComboBox
+	 */
+	private void initializeColorsBoxes() {
+		Color[] colors = {Color.BLUE, Color.BLACK, Color.CYAN, Color.DARK_GRAY,
+				  Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, 
+				  Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW};
+		
+		brushColorComboBox=new JComboBox (colors);
+		brushColorComboBox.setRenderer(new BuggleColorCellRenderer());
+		brushColorComboBox.setSelectedItem(((AbstractBuggle)Game.getInstance().getSelectedEntity()).getBrushColor());
+		brushColorComboBox.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				JComboBox cb = (JComboBox) event.getSource();
+				Color c = (Color) cb.getSelectedItem();
+				cb.setSelectedItem(c);
+				((AbstractBuggle)Game.getInstance().getSelectedEntity()).setBrushColor(c);
+			}
+		});
+		
+		buggleColorComboBox=new JComboBox (colors);
+		buggleColorComboBox.setRenderer(new BuggleColorCellRenderer());
+		buggleColorComboBox.setSelectedItem(((AbstractBuggle)Game.getInstance().getSelectedEntity()).getColor());
+		buggleColorComboBox.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				JComboBox cb = (JComboBox) event.getSource();
+				Color c = (Color) cb.getSelectedItem();
+				cb.setSelectedItem(c);
+				((AbstractBuggle)Game.getInstance().getSelectedEntity()).setColor(c);
+			}
+		});
+	}
+
+	/**
+	 * Add the five buttons to a JPanel and return the JPanel
+	 * @return a JPanel where the five buttons have been added
+	 */
+	private JPanel createButtonsPanel() {
+		JPanel buttonsPanel = new JPanel();
+		
+		GridBagLayout gdLayout = new GridBagLayout();
+		buttonsPanel.setLayout(gdLayout);
+
+		GridBagConstraints c = new GridBagConstraints();
+		c.insets = new Insets(3, 3, 3, 3);
+
+		c.gridy = 1;
+		c.gridx = 1;
+		c.gridwidth = 1;
+		gdLayout.setConstraints(fButton, c);
+		buttonsPanel.add(fButton);
+
+		c.gridy = 2;
+		c.gridx = 0;
+		gdLayout.setConstraints(lButton, c);
+		buttonsPanel.add(lButton);
+
+		c.gridy = 2;
+		c.gridx = 1;
+		c.fill = GridBagConstraints.HORIZONTAL;
+		gdLayout.setConstraints(brushButton, c);
+		buttonsPanel.add(brushButton);
+
+		c.gridy = 2;
+		c.gridx = 2;
+		gdLayout.setConstraints(rButton, c);
+		buttonsPanel.add(rButton);
+
+		c.gridy = 3;
+		c.gridx = 1;
+		gdLayout.setConstraints(bButton, c);
+		buttonsPanel.add(bButton);
+		
+		return buttonsPanel;
+	}
+
+	/**
+	 * Add the two combo boxes to a JPanel and return the JPanel
+	 * @return a JPanel where the two combo boxes have been added
+	 */
+	private JPanel createColorsBoxes() {
+		JPanel colorsPanel = new JPanel();
+		colorsPanel.setLayout(new GridLayout(4,1));
+		
+		lBrushColor = new JLabel("Brush Color");
+		colorsPanel.add(lBrushColor);
+		colorsPanel.add(brushColorComboBox);
+		
+		lBuggleColor = new JLabel("Buggle Color");
+		colorsPanel.add(lBuggleColor);
+		colorsPanel.add(buggleColorComboBox);
+		
+		return colorsPanel;
+	}
+	
+	@Override
+	public void setEnabledControl(boolean enabled) {
+		fButton.setEnabled(enabled);
+		bButton.setEnabled(enabled);
+		lButton.setEnabled(enabled);
+		rButton.setEnabled(enabled);
+		brushButton.setEnabled(enabled);
+		buggleColorComboBox.setEnabled(enabled);
+		brushColorComboBox.setEnabled(enabled);
+	}
+	
+	public void showWallHuggingErrorMessageDialog() {
+		String message ;
+		String title = i18n.tr("Wall hugging error");
+		message = i18n.tr("Your buggle has collided with a wall, it hurts a lot ! ='(");
+		JOptionPane.showMessageDialog(null, message,title, JOptionPane.ERROR_MESSAGE);
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		i18n.setLocale(newLang);
+		
+		bButton.setText(i18n.tr("backward"));
+		fButton.setText(i18n.tr("forward"));
+		lButton.setText(i18n.tr("left"));
+		rButton.setText(i18n.tr("right"));
+		brushButton.setText(i18n.tr("mark"));
+		lBrushColor.setText(i18n.tr("Brush Color"));
+		lBuggleColor.setText(i18n.tr("Buggle Color"));
+	}
+	
+}
diff --git a/src/plm/universe/bugglequest/ui/BuggleColorCellRenderer.java b/src/plm/universe/bugglequest/ui/BuggleColorCellRenderer.java
new file mode 100644
index 0000000..ab07811
--- /dev/null
+++ b/src/plm/universe/bugglequest/ui/BuggleColorCellRenderer.java
@@ -0,0 +1,48 @@
+package plm.universe.bugglequest.ui;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.JButton;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+
+/**
+ * This cell renderer is used by the combo boxes from BuggleButtonPanel in order to show some fancy colored rectangles.
+ * @see ListCellRenderer
+ * @see BuggleButtonPanel
+ */
+public class BuggleColorCellRenderer extends JPanel implements ListCellRenderer{
+
+	private static final long serialVersionUID = 1L;
+
+    private JButton cell;	// The container of the colored rectangle
+    
+    /**
+     * Constructor of BuggleColorCellRenderer
+     * It initializes the cell and add it to the BuggleColorCellRenderer
+     */
+    public BuggleColorCellRenderer() {
+        super();
+        this.cell = new JButton();
+        this.add(this.cell);
+    }
+    
+    /**
+     * Change the color of the cell according to the selected value
+     * @return The BuggleColorCellRenderer with the cell's background of color "value" 
+     * @param list Unused here
+     * @param value The color that we will assign to our cell. Since it's sure that value is an instance of Color, it's not necessary to check it.
+     * @param index Unused here
+     * @param isSelected Unused here
+     * @param cellHasFocus Unused here
+     */
+    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+        this.cell.setBackground((Color) value);
+        this.cell.setOpaque(true);
+        this.cell.setBorderPainted(false);
+        return this;
+    }
+
+}
\ No newline at end of file
diff --git a/src/plm/universe/bugglequest/ui/BuggleWorldView.java b/src/plm/universe/bugglequest/ui/BuggleWorldView.java
new file mode 100644
index 0000000..0e817b0
--- /dev/null
+++ b/src/plm/universe/bugglequest/ui/BuggleWorldView.java
@@ -0,0 +1,318 @@
+package plm.universe.bugglequest.ui;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+
+import plm.core.ui.WorldView;
+import plm.universe.Entity;
+import plm.universe.World;
+import plm.universe.bugglequest.AbstractBuggle;
+import plm.universe.bugglequest.Baggle;
+import plm.universe.bugglequest.BuggleWorld;
+import plm.universe.bugglequest.BuggleWorldCell;
+
+
+
+public class BuggleWorldView extends WorldView {
+
+	private static final long serialVersionUID = -7164642270965762239L;
+
+
+	private static Color DARK_CELL_COLOR = new Color(0.93f,0.93f,0.93f);
+	private static Color LIGHT_CELL_COLOR = new Color(0.95f,0.95f,0.95f);
+	private static Color GRID_COLOR = new Color(0.8f,0.8f,0.8f);
+	private static Color WALL_COLOR = new Color(0.0f,0.0f,0.5f);
+	
+	public BuggleWorldView (World w) {
+		super(w);
+	}
+		
+	protected double getCellWidth() {
+		return (double) Math.min(getHeight() / ((BuggleWorld)world).getHeight() , getWidth() /  ((BuggleWorld)world).getWidth());
+	}
+	
+	protected double getPadX() {
+		return (getWidth() - getCellWidth() * ((BuggleWorld)world).getWidth()) / 2;
+	}
+	protected double getPadY() {
+		return (getHeight() - getCellWidth() * ((BuggleWorld)world).getHeight()) / 2;
+	}
+
+
+	@Override
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		Graphics2D g2 = (Graphics2D) g;
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+		drawBackground(g2);
+		
+		for (Entity ent: world.getEntities()) {
+			AbstractBuggle b = (AbstractBuggle)ent;  	
+			drawBuggle(g2, b);
+		}
+		
+		drawWalls(g2);
+	}
+	
+	// return the color of the cell located at position (x,y)
+	private Color getCellColor(int x, int y) {
+		BuggleWorldCell cell = (BuggleWorldCell) ((BuggleWorld)world).getCell(x, y);
+
+		if (BuggleWorldCell.DEFAULT_COLOR.equals(cell.getColor())) {
+			if (((BuggleWorld) world).getVisibleGrid()) { 
+				if ((x+y)%2==0)
+					return DARK_CELL_COLOR;	
+				else
+					return LIGHT_CELL_COLOR;
+			} else {
+				return Color.WHITE;
+			}
+		} else {
+			return cell.getColor();
+		}		
+	}
+	
+	private void drawBackground(Graphics2D g) {
+		double cellW = getCellWidth();
+		double padx = getPadX();
+		double pady = getPadY();
+		BuggleWorld w = (BuggleWorld)world;
+
+		if (w.getVisibleGrid() == false) {
+			g.setColor(Color.white);
+			g.fill(new Rectangle2D.Double(padx,pady ,(w.getWidth()-1)*cellW,(w.getHeight()-1)*cellW));				
+		}
+		for (int x=0; x<w.getWidth(); x++) {
+			for (int y=0; y<w.getHeight(); y++) {
+				g.setColor(getCellColor(x, y));
+				
+				BuggleWorldCell cell = (BuggleWorldCell) w.getCell(x, y);
+
+				g.fill(new Rectangle2D.Double(padx+x*cellW, pady+y*cellW, cellW, cellW));	
+				
+				if (cell.hasBaggle())
+					drawBaggle(g, cell, cell.getBaggle());
+				if (cell.hasContent())
+					drawMessage(g, cell, cell.getContent());
+			}
+		}
+
+		if (((BuggleWorld) world).getVisibleGrid()) {
+			g.setColor(GRID_COLOR);
+			for (int x=0; x<=w.getWidth(); x++) {
+				g.draw(new Line2D.Double(padx+x*cellW, pady, padx+x*cellW, pady+w.getHeight()*cellW));
+			}
+			for (int y=0; y<=w.getHeight(); y++) {
+				g.draw(new Line2D.Double(padx+0, pady+y*cellW, padx+w.getWidth()*cellW, pady+y*cellW));						
+			}
+		}
+	}
+	
+	private void drawWalls(Graphics2D g) {
+		double cellW = getCellWidth();
+		double padx = getPadX();
+		double pady = getPadY();
+		BuggleWorld w = (BuggleWorld)world;
+
+		int width = w.getWidth();
+		int height = w.getHeight();
+		
+		g.setColor(WALL_COLOR);
+		
+		for (int x = 0; x < width; x++) {
+			for (int y = 0; y < height; y++) {
+				BuggleWorldCell cell = (BuggleWorldCell) w.getCell(x, y);
+
+				if (cell.hasTopWall()) {
+					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW-1, padx+(x+1)*cellW, pady+y*cellW-1));						
+					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW, padx+(x+1)*cellW, pady+y*cellW));						
+					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW+1, padx+(x+1)*cellW, pady+y*cellW+1));						
+				}
+				
+				if (cell.hasLeftWall()) {
+					g.draw(new Line2D.Double(padx+x*cellW-1, pady+y*cellW, padx+x*cellW-1, pady+(y+1)*cellW));
+					g.draw(new Line2D.Double(padx+x*cellW, pady+y*cellW, padx+x*cellW, pady+(y+1)*cellW));
+					g.draw(new Line2D.Double(padx+x*cellW+1, pady+y*cellW, padx+x*cellW+1, pady+(y+1)*cellW));
+				}
+			}
+		}
+
+		// frontier walls (since the world is a torus)
+		for (int y = 0; y < height; y++) {
+			if (((BuggleWorldCell) w.getCell(0, y)).hasLeftWall()) {
+				g.draw(new Line2D.Double(padx+width*cellW-1, pady+y*cellW, padx+width*cellW-1, pady+(y+1)*cellW));
+				g.draw(new Line2D.Double(padx+width*cellW, pady+y*cellW, padx+width*cellW, pady+(y+1)*cellW));
+				g.draw(new Line2D.Double(padx+width*cellW+1, pady+y*cellW, padx+width*cellW+1, pady+(y+1)*cellW));				
+			}
+		}
+
+		for (int x = 0; x < width; x++) {
+			if (((BuggleWorldCell) w.getCell(x, 0)).hasTopWall()) {
+				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW-1, padx+(x+1)*cellW, pady+height*cellW-1));						
+				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW, padx+(x+1)*cellW, pady+height*cellW));						
+				g.draw(new Line2D.Double(padx+x*cellW, pady+height*cellW+1, padx+(x+1)*cellW, pady+height*cellW+1));						
+			}
+		}	
+	}
+	
+	private void drawBuggle(Graphics2D g, AbstractBuggle b) {
+		double scaleFactor = 0.6; // to scale the sprite
+		double pixW = scaleFactor * getCellWidth() / INVADER_SPRITE_SIZE;  // fake pixel width
+		double pad = 0.5*(1.0-scaleFactor)*getCellWidth(); // padding to center sprite in the cell
+		double padx = getPadX();
+		double pady = getPadY();
+	
+		double ox = b.getX()*getCellWidth(); // x-offset of the cell
+		double oy = b.getY()*getCellWidth(); // y-offset of the cell
+		
+		if (b.isBrushDown()) {
+			if (Color.BLACK.equals(b.getBrushColor())) 
+				g.setColor(Color.WHITE);
+			else
+				g.setColor(Color.BLACK);
+		} else
+			g.setColor(b.getColor());
+
+		if (((BuggleWorld)world).easter) {
+			try {
+				InputStream is = getClass().getResourceAsStream("/plm/universe/bugglequest/ui/rabbit.png");
+				ImageIcon ic = new ImageIcon(ImageIO.read(is));
+				g.drawImage(ic.getImage(), (int)(padx+ox),(int)(pady+oy), (int)getCellWidth(),(int)getCellWidth(),null);
+			} catch (IOException e) {
+				// Forget it
+				((BuggleWorld)world).easter = false;
+				return;
+			}
+			
+		} else {
+			for (int dy=0; dy<INVADER_SPRITE_SIZE; dy++) {
+				for (int dx=0; dx<INVADER_SPRITE_SIZE; dx++) {
+					int direction = b.getDirection().intValue();
+					if (INVADER_SPRITE[direction][dy][dx] == 1) {
+						g.fill(new Rectangle2D.Double(padx+pad+ox+dx*pixW, pady+pad+oy+dy*pixW, pixW, pixW));
+					}
+				}				
+			}
+		}
+	}
+	
+	private void drawBaggle(Graphics2D g, BuggleWorldCell cell, Baggle b) {
+		double padx = getPadX();
+		double pady = getPadY();
+	
+		double scaleFactor = 0.8; // to scale the sprite
+
+		double d = scaleFactor*getCellWidth();
+		double pad = 0.5*(1.0-scaleFactor)*getCellWidth(); // padding to center sprite in the cell
+
+		double scaleFactor2 = 0.5; // to scale the sprite
+
+		double d2 = scaleFactor2*scaleFactor*getCellWidth();
+		double pad2 = 0.5*(1.0-scaleFactor*scaleFactor2)*getCellWidth(); // padding to center sprite in the cell
+		
+		double ox = cell.getX()*getCellWidth(); // x-offset of the cell
+		double oy = cell.getY()*getCellWidth(); // y-offset of the cell
+		
+		if (((BuggleWorld)world).easter) {
+			try {
+				InputStream is = getClass().getResourceAsStream("/plm/universe/bugglequest/ui/egg.png");
+				ImageIcon ic = new ImageIcon(ImageIO.read(is));
+				g.drawImage(ic.getImage(), (int)(padx+ox),(int)(pady+oy), (int)getCellWidth(),(int)getCellWidth(),null);
+			} catch (IOException e) {
+				// Forget it
+				((BuggleWorld)world).easter = false;
+				return;
+			}
+			
+		} else {
+			g.setColor(Baggle.DEFAULT_COLOR);
+			g.fill(new Arc2D.Double(padx+ox+pad, pady+oy+pad, d, d, 0, 360, Arc2D.CHORD));
+			g.setColor(getCellColor(cell.getX(), cell.getY()));
+			g.fill(new Arc2D.Double(padx+ox+pad2, pady+oy+pad2, d2, d2, 0, 360, Arc2D.CHORD));
+
+			g.setColor(Baggle.DEFAULT_COLOR.darker().darker());
+			g.draw(new Arc2D.Double(padx+ox+pad, pady+oy+pad, d, d, 0, 360, Arc2D.CHORD));
+			g.draw(new Arc2D.Double(padx+ox+pad2, pady+oy+pad2, d2, d2, 0, 360, Arc2D.CHORD));
+		}
+	}
+	
+	private void drawMessage(Graphics2D g, BuggleWorldCell cell, String msg) {
+		double padx = getPadX();
+		double pady = getPadY();
+		double ox = cell.getX()*getCellWidth(); // x-offset of the cell
+		double oy = (cell.getY()+1)*getCellWidth(); // y-offset of the cell
+
+		
+		g.setColor(cell.getMsgColor());
+		g.drawString(msg, (float) (padx+ox)+1, (float) (pady+oy)-4);	
+	}
+
+	
+
+	// old style ;b
+	private static int INVADER_SPRITE_SIZE = 11;
+	private static int[][][] INVADER_SPRITE = {
+	{
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+		{ 0,0,1,0,0,0,0,0,1,0,0 },
+		{ 0,0,0,1,0,0,0,1,0,0,0 },
+		{ 0,0,1,1,1,1,1,1,1,0,0 },
+		{ 0,1,1,0,1,1,1,0,1,1,0 },
+		{ 1,1,1,1,1,1,1,1,1,1,1 },
+		{ 1,0,1,1,1,1,1,1,1,0,1 },
+		{ 1,0,1,0,0,0,0,0,1,0,1 },
+		{ 0,0,0,1,1,0,1,1,0,0,0 },
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+	},
+	{
+	    { 0,0,0,1,1,1,0,0,0,0,0 },
+		{ 0,0,0,0,0,1,1,0,0,0,0 },
+		{ 0,0,0,1,1,1,1,1,0,1,0 },
+		{ 0,0,1,0,1,1,0,1,1,0,0 },
+		{ 0,0,1,0,1,1,1,1,0,0,0 },
+		{ 0,0,0,0,1,1,1,1,0,0,0 },
+		{ 0,0,1,0,1,1,1,1,0,0,0 },
+		{ 0,0,1,0,1,1,0,1,1,0,0 },
+		{ 0,0,0,1,1,1,1,1,0,1,0 },
+		{ 0,0,0,0,0,1,1,0,0,0,0 },
+		{ 0,0,0,1,1,1,0,0,0,0,0 }
+	},
+	{
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+		{ 0,0,0,1,1,0,1,1,0,0,0 },
+		{ 1,0,1,0,0,0,0,0,1,0,1 },
+		{ 1,0,1,1,1,1,1,1,1,0,1 },
+		{ 1,1,1,1,1,1,1,1,1,1,1 },
+		{ 0,1,1,0,1,1,1,0,1,1,0 },
+		{ 0,0,1,1,1,1,1,1,1,0,0 },
+		{ 0,0,0,1,0,0,0,1,0,0,0 },
+		{ 0,0,1,0,0,0,0,0,1,0,0 },
+		{ 0,0,0,0,0,0,0,0,0,0,0 },
+	},
+	{
+		{ 0,0,0,0,0,1,1,1,0,0,0 },
+		{ 0,0,0,0,1,1,0,0,0,0,0 },
+		{ 0,1,0,1,1,1,1,1,0,0,0 },
+		{ 0,0,1,1,0,1,1,0,1,0,0 },
+		{ 0,0,0,1,1,1,1,0,1,0,0 },
+		{ 0,0,0,1,1,1,1,0,0,0,0 },
+		{ 0,0,0,1,1,1,1,0,1,0,0 },
+		{ 0,0,1,1,0,1,1,0,1,0,0 },
+		{ 0,1,0,1,1,1,1,1,0,0,0 },
+		{ 0,0,0,0,1,1,0,0,0,0,0 },
+		{ 0,0,0,0,0,1,1,1,0,0,0 }
+	}};
+}
diff --git a/src/jlm/universe/bugglequest/ui/egg.png b/src/plm/universe/bugglequest/ui/egg.png
similarity index 100%
rename from src/jlm/universe/bugglequest/ui/egg.png
rename to src/plm/universe/bugglequest/ui/egg.png
diff --git a/src/plm/universe/bugglequest/ui/package-info.java b/src/plm/universe/bugglequest/ui/package-info.java
new file mode 100644
index 0000000..c3ea4c1
--- /dev/null
+++ b/src/plm/universe/bugglequest/ui/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * User interface elements of the buggle world
+ */
+package plm.universe.bugglequest.ui;
+
diff --git a/src/jlm/universe/bugglequest/ui/rabbit.png b/src/plm/universe/bugglequest/ui/rabbit.png
similarity index 100%
rename from src/jlm/universe/bugglequest/ui/rabbit.png
rename to src/plm/universe/bugglequest/ui/rabbit.png
diff --git a/src/plm/universe/lightbot/LightBotEditorPanel.java b/src/plm/universe/lightbot/LightBotEditorPanel.java
new file mode 100644
index 0000000..f52ec74
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotEditorPanel.java
@@ -0,0 +1,137 @@
+package plm.universe.lightbot;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JComboBox;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.BevelBorder;
+
+import plm.core.model.Game;
+import plm.core.model.session.ISourceFileListener;
+import plm.core.ui.IEditorPanel;
+import plm.core.ui.ResourcesCache;
+import plm.universe.Entity;
+import plm.universe.IEntityStackListener;
+import net.miginfocom.swing.MigLayout;
+
+public class LightBotEditorPanel extends JScrollPane implements IEditorPanel,ISourceFileListener,IEntityStackListener {
+	private static final long serialVersionUID = 1L;
+	LightBotSourceFile srcFile;
+	Map<String,InstructionChooser> choosers=new HashMap<String, InstructionChooser>();
+	InstructionChooser selectedChooser = null;
+	Entity tracedEntity;
+	private Map<String,Icon> iconsByNames = new HashMap<String, Icon>();
+	private Map<Icon,String> iconNameByIcons = new HashMap<Icon,String>();
+	private Icon[] iconList;
+
+	public LightBotEditorPanel(LightBotSourceFile srcFile) {
+		super();
+		
+		iconList = new Icon[LightBotInstruction.instructionNames.length];
+		int i=0;
+		for (String n:LightBotInstruction.instructionNames) {
+			iconList[i] =ResourcesCache.getIcon("img/lightbot_"+n+".png");
+			iconNameByIcons.put(iconList[i],n);
+			iconsByNames.put(n,iconList[i]);
+			i++;
+		}
+		
+		this.srcFile = srcFile;
+		srcFile.setListener(this);
+		sourceFileContentHasChanged();
+		tracedEntity = Game.getInstance().getSelectedEntity();
+		tracedEntity.addStackListener(this);
+	}
+	@Override
+	public void clear() {
+		srcFile.removeListener();
+		if (tracedEntity != null)
+			tracedEntity.removeStackListener(this);
+	}
+	@Override
+	public void sourceFileContentHasChanged() {
+
+		/* Main function */
+		JPanel mainPanel = new JPanel();
+		mainPanel.setBorder(BorderFactory.createTitledBorder("Main"));
+		mainPanel.setLayout(new MigLayout("wrap 4, fill"));
+		for (int i=0;i<srcFile.getMain().length;i++) {
+			InstructionChooser chooser = new InstructionChooser(srcFile.getMain(),i);
+			choosers.put("main:"+i, chooser);
+			mainPanel.add(chooser, "grow");
+		}
+
+		/* Func 1 */
+		JPanel func1Panel = new JPanel();
+		func1Panel.setBorder(BorderFactory.createTitledBorder("Function 1"));
+		func1Panel.setLayout(new MigLayout("wrap 4, fill"));
+		for (int i=0;i<srcFile.getFunc1().length;i++) { 
+			InstructionChooser chooser = new InstructionChooser(srcFile.getFunc1(),i);
+			choosers.put("func1:"+i, chooser);
+			func1Panel.add(chooser, "grow");
+		}
+
+		/* Func 2 */
+		JPanel func2Panel = new JPanel();
+		func2Panel.setBorder(BorderFactory.createTitledBorder("Function 2"));
+		func2Panel.setLayout(new MigLayout("wrap 4, fill"));
+		for (int i=0;i<srcFile.getFunc2().length;i++) {
+			InstructionChooser chooser = new InstructionChooser(srcFile.getFunc2(),i); 
+			choosers.put("func2:"+i, chooser);
+			func2Panel.add(chooser, "grow");
+		}
+		for (InstructionChooser ic:choosers.values()) 
+			ic.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
+
+		/* Put everything together */
+		JPanel global = new JPanel();
+		global.setLayout(new MigLayout("wrap 1, fill"));
+		global.add(mainPanel,"grow");
+		global.add(func1Panel,"grow");
+		global.add(func2Panel,"grow");
+		setViewportView(global);
+		doLayout();
+	}
+
+	private class InstructionChooser extends JComboBox {
+		public InstructionChooser(final LightBotInstruction[] func, final int pos) {
+			super(iconList);
+			this.addActionListener(new ActionListener() {
+				@Override
+				public void actionPerformed(ActionEvent arg0) {
+					func[pos] = new LightBotInstruction(iconNameByIcons.get((Icon) InstructionChooser.this.getSelectedItem()));
+				}				
+			});
+			setSelectedItem(iconsByNames.get(func[pos].toString()));
+		}
+
+		private static final long serialVersionUID = 7308818147531552628L;
+
+	}
+
+	@Override
+	public void entityTraceChanged(Entity e, StackTraceElement[] trace) {
+		if (selectedChooser != null)
+			selectedChooser.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
+		if (trace != null && trace[0]!=null) {
+			selectedChooser = choosers.get(trace[0].getMethodName()+":"+trace[0].getLineNumber());
+			if (selectedChooser!=null)
+				selectedChooser.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
+		}
+	}
+
+	@Override
+	public void tracedEntityChanged(Entity e) {
+		if (tracedEntity != null)
+			tracedEntity.removeStackListener(this);
+		tracedEntity =  e;
+		tracedEntity.addStackListener(this);
+		entityTraceChanged(e, tracedEntity.getCurrentStack());
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotEntity.java b/src/plm/universe/lightbot/LightBotEntity.java
new file mode 100644
index 0000000..6cd0a5c
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotEntity.java
@@ -0,0 +1,220 @@
+package plm.universe.lightbot;
+
+import java.awt.Point;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.Exercise;
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.GridWorld;
+import plm.universe.World;
+
+
+
+public class LightBotEntity extends Entity  {
+	private int x;
+	private int y;
+
+	Direction direction;
+	
+	StackTraceElement[] tracedStack = new StackTraceElement[1];
+	
+	/**
+	 * Constructor with no argument so that child classes can avoid declaring a
+	 * constructor. But it should not be used as most methods assert on world
+	 * being not null. After using it, {@link plm.universe.Entity#setWorld(LightBotWorld)} must be used
+	 * ASAP.
+	 */
+	public LightBotEntity() {
+		this(null, "John Doe", 0, 0, Direction.NORTH);
+	}
+
+	public LightBotEntity(GridWorld w) {
+		this(w, "John Doe", 0, 0, Direction.NORTH);
+	}
+
+	public LightBotEntity(World world, String name, int x, int y, Direction direction2) {
+		super(name,world);
+		this.setX(x);
+		this.setY(y);
+		this.direction = direction2;
+	}
+	@Override
+	public void copy(Entity e) {
+		super.copy(e);
+		LightBotEntity other = (LightBotEntity)e;
+		this.setX(other.getX());
+		this.setY(other.getY());
+		this.direction = other.direction;
+	}
+	@Override
+	public Entity copy() {
+		LightBotEntity lb = new LightBotEntity();
+		lb.setWorld(getWorld());
+		lb.setName(getName());
+		lb.setPos(getX(), getY());
+		lb.setDirection(direction);
+		return lb;
+	}
+
+
+	public void setDirection(Direction d) {
+		direction=d;
+	}
+	public Direction getDirection() {
+		return direction;
+	}
+
+	public int getWorldHeight() {
+		return ((GridWorld)world).getHeight();
+	}
+
+	public int getWorldWidth() {
+		return ((GridWorld)world).getWidth();
+	}
+	public LightBotWorldCell getCell(){
+		return (LightBotWorldCell) ((GridWorld) world).getCell(getX(), getY());
+	}
+	protected LightBotWorldCell getCell(int u, int v){
+		return (LightBotWorldCell) ((GridWorld) world).getCell(u, v);
+	}
+	private int bounded(int x,int max) {
+		if (x<0)
+			return 0;
+		if (x>=max)
+			return max-1;
+		return x;
+	}
+	
+	private LightBotWorldCell getCellNeighbor(Point delta) {
+		return getCell( bounded((getX()+delta.x),getWorldWidth()) , bounded((getY()+delta.y),getWorldHeight()));
+	}
+
+
+	public void setPos(int x, int y) {
+		this.setX(x);
+		this.setY(y);
+	}
+	public void forward() {
+		if (getCellNeighbor(getDirection().toPoint()).getHeight() == getCell().getHeight())
+			move();
+		else 
+			System.out.println("facing wall");
+	}
+	public void jump(){
+		int heightHere = getCell().getHeight();
+		int heightThere = getCellNeighbor(getDirection().toPoint()).getHeight();
+		
+		if ( (heightThere - heightHere  == 1 /*jump one up*/) || 
+		     (heightHere > heightThere /*jump down*/))
+			move();
+		else 
+			System.out.println("cannot jump here");
+	}
+
+	private void move() {
+		int newx = bounded(getX() + getDirection().toPoint().x , getWorldWidth());
+		int newy = bounded(getY() + getDirection().toPoint().y , getWorldHeight());
+		setX(newx);
+		setY(newy);
+	}
+
+	public void left() {
+		direction=getDirection().left();
+	}
+	public void right() {
+		direction=getDirection().right();
+	}
+	public void light() {
+		((LightBotWorld) world).switchLight(getX(),getY());
+	}
+	
+
+	@Override
+	public String toString() {
+		return "LightBot (" + this.getClass().getName() + "): x=" + getX() + " y=" + getY() + " Direction:" + direction;
+	}
+
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + ((direction == null) ? 0 : direction.hashCode());
+		result = PRIME * result + getX();
+		result = PRIME * result + getY();
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!(obj instanceof LightBotEntity))
+			return false;
+
+		final LightBotEntity other = (LightBotEntity) obj;
+		if (direction == null) {
+			if (other.direction != null)
+				return false;
+		} else if (!direction.equals(other.direction))
+			return false;
+		if (getX() != other.getX())
+			return false;
+		if (getY() != other.getY())
+			return false;
+		return true;
+	}
+
+
+
+	LightBotSourceFile sf;
+	@Override
+	public void run() {
+		sf = (LightBotSourceFile) ((Exercise) Game.getInstance().getCurrentLesson().getCurrentExercise()).getSourceFile(Game.LIGHTBOT,0);
+				
+		/* Run main */
+		run("main",sf.getMain());
+		tracedStack[0] = new StackTraceElement("LightbotEntity","main","main",1);
+		fireStackListener();
+	}
+	public void runF1(){
+		run("func1",sf.getFunc1());
+	}
+	public void runF2(){
+		run("func2",sf.getFunc2());
+	}
+
+	private void run(String fileName,LightBotInstruction[] file) {
+		if (file == null)
+			return;
+		int line=0;
+		for (LightBotInstruction i: file) {
+			tracedStack[0] = new StackTraceElement("LightbotEntity",fileName,fileName,line++);
+			fireStackListener();
+			if (i!=null && !i.isNoop())
+			stepUI();
+			if (i!=null)
+				i.run(this);
+		}
+	}
+
+	public void setX(int x) {
+		this.x = x;
+	}
+	public int getX() {
+		return x;
+	}
+	public void setY(int y) {
+		this.y = y;
+	}
+	public int getY() {
+		return y;
+	}
+
+	@Override
+	public StackTraceElement[] getCurrentStack() {
+		return tracedStack;
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotExercise.java b/src/plm/universe/lightbot/LightBotExercise.java
new file mode 100644
index 0000000..89adcd4
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotExercise.java
@@ -0,0 +1,82 @@
+package plm.universe.lightbot;
+
+import java.util.List;
+
+import plm.core.model.Game;
+import plm.core.model.lesson.ExecutionProgress;
+import plm.core.model.lesson.ExerciseTemplated;
+import plm.core.model.lesson.Lesson;
+import plm.universe.World;
+
+public class LightBotExercise extends ExerciseTemplated {
+	public LightBotExercise(Lesson lesson) {
+		super(lesson);
+		addProgLanguage(Game.LIGHTBOT);
+		if (getProgLanguages().size()>1) 
+			throw new RuntimeException("More than one language defined in a LightbotExercise. Please report this bug.");
+		getSourceFilesList(Game.LIGHTBOT).add(new LightBotSourceFile("Code"));
+	}
+
+	@Override
+	protected void setup(World[] ws) {
+		for (World w : ws) 
+			((LightBotWorld) w).rotateLeft();
+		
+		setupWorlds(ws);
+		/* remove entities from the answer world: we don't care of where the bot is at the end */
+		for (World w :answerWorld)
+			w.emptyEntities();
+		computeAnswer();
+	}
+
+	@Override
+	protected void computeAnswer() {
+		for (int w=0;w<answerWorld.size();w++) {
+			LightBotWorld.CellIterator ci = ((LightBotWorld)answerWorld.get(w)).new CellIterator();
+			while (ci.hasNext()) {
+				ci.next().setLightOn();
+			}
+		}
+	}
+	@Override
+	public void check() {
+		lastResult = new ExecutionProgress();
+		for (int w=0;w<currentWorld.size();w++) {
+			LightBotWorld.CellIterator ci = ((LightBotWorld)currentWorld.get(w)).new CellIterator();
+			while (ci.hasNext()) {
+				LightBotWorldCell cell = ci.next();
+				if (cell.isLight()) {
+					lastResult.totalTests++;
+					if (cell.isLightOn())
+						lastResult.passedTests++;
+				}
+			}
+			int stillOff = lastResult.totalTests - lastResult.passedTests;
+			if (stillOff == 1) 
+				lastResult.details = "The light is still off";
+			if (stillOff > 1)
+				lastResult.details = stillOff + " lights (out of "+lastResult.totalTests+") are still off";
+
+		}
+	}
+	@Override
+	public void run(List<Thread> runnerVect){ // FIXME: that's a redefinition to the same, right?
+		reset();
+
+		for (int i=0; i<currentWorld.size(); i++)
+			currentWorld.get(i).doDelay();
+
+		for (int i=0; i<currentWorld.size(); i++)
+			currentWorld.get(i).runEntities(runnerVect, lastResult);
+	}
+
+	@Override
+	public void runDemo(List<Thread> runnerVect){		
+		/* No demo for lightbot: this is a puzzle game, you have to search for the answer by yourself */
+	}
+	
+	@Override
+	final public void mutateEntities(WorldKind kind, StudentOrCorrection what) {
+		throw new RuntimeException("Why are you trying to mutate Lightbot entities, you weirdo?! super.mutateEntities() is not ready for that.");
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotInstruction.java b/src/plm/universe/lightbot/LightBotInstruction.java
new file mode 100644
index 0000000..a5017e2
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotInstruction.java
@@ -0,0 +1,98 @@
+package plm.universe.lightbot;
+
+
+
+public class LightBotInstruction {
+	/* instructionNames must match what toString says, and what the string constructor expects, or comboboxes of editor won't work */
+	public final static String[] instructionNames = { "noop","forward", "jump", "left", "right", "light", "f1","f2" };
+
+	private enum InstructionKind {
+		NOOP,FORWARD,JUMP,LIGHT,LEFT,RIGHT,F1,F2;		
+	}
+
+	InstructionKind kind;
+	public LightBotInstruction(InstructionKind kind) {
+		this.kind = kind;
+	}
+	public LightBotInstruction(char c) {
+		switch (c) {
+		case 'F': kind=InstructionKind.FORWARD; break;
+		case 'J': kind=InstructionKind.JUMP; break;
+		case 'L': kind=InstructionKind.LEFT; break;
+		case 'R': kind=InstructionKind.RIGHT; break;
+		case 'O': kind=InstructionKind.LIGHT; break;
+		case '1': kind=InstructionKind.F1; break;
+		case '2': kind=InstructionKind.F2; break;
+		case ' ': kind=InstructionKind.NOOP; break;
+		default:
+			throw new RuntimeException("Char '"+c+"' does not match any known symbol");
+		}
+	}
+	public LightBotInstruction(String str) {
+		/* must match instructionNames, or the comboboxes in the editor won't work */
+		if (str.equalsIgnoreCase("forward")) {
+			kind=InstructionKind.FORWARD;
+		} else if (str.equalsIgnoreCase("jump")) {
+			kind=InstructionKind.JUMP;
+		} else if (str.equalsIgnoreCase("light")) {
+			kind=InstructionKind.LIGHT;
+		} else if (str.equalsIgnoreCase("left")) {
+			kind=InstructionKind.LEFT;
+		} else if (str.equalsIgnoreCase("right")) {
+			kind=InstructionKind.RIGHT;
+		} else if (str.equalsIgnoreCase("f1")) {
+			kind=InstructionKind.F1;
+		} else if (str.equalsIgnoreCase("f2")) {
+			kind=InstructionKind.F2;
+		} else {
+			kind=InstructionKind.NOOP; 
+		}
+	}
+	public void run(LightBotEntity lb) {
+//		System.out.println("exec "+toString());
+		switch (kind) {
+		case FORWARD: lb.forward(); break;
+		case JUMP: lb.jump(); break;
+		case LEFT: lb.left(); break;
+		case RIGHT: lb.right(); break;
+		case LIGHT: lb.light(); break;
+		case F1: lb.runF1(); break;
+		case F2: lb.runF2(); break;
+		case NOOP: /* nothing to do for NOOP :) */
+			break;
+		}
+	}
+	public char toChar() {
+		switch (kind) {
+		case FORWARD: return 'F'; 
+		case JUMP: return 'J'; 
+		case LEFT: return 'L'; 
+		case RIGHT: return 'R';
+		case LIGHT: return 'O';
+		case F1: return '1'; 
+		case F2: return '2'; 
+		case NOOP: 
+		}
+		return ' ';
+	}
+	public static LightBotInstruction noop() {
+		return new LightBotInstruction(InstructionKind.NOOP);
+	}
+	
+	public String toString() {
+		switch (kind) { /* must match instructionNames, or the comboboxes in the editor won't work */
+		case NOOP: return "noop";
+		case FORWARD: return "forward"; 
+		case JUMP: return "jump"; 
+		case LEFT: return "left"; 
+		case RIGHT: return "right";
+		case LIGHT: return "light";
+		case F1: return "f1"; 
+		case F2: return "f2"; 
+		}
+		return "noop";
+	}
+	public boolean isNoop() {
+		return kind == InstructionKind.NOOP;
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotSourceFile.java b/src/plm/universe/lightbot/LightBotSourceFile.java
new file mode 100644
index 0000000..e24c171
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotSourceFile.java
@@ -0,0 +1,78 @@
+package plm.universe.lightbot;
+
+import javax.swing.JScrollPane;
+
+import plm.core.model.ProgrammingLanguage;
+import plm.core.model.session.SourceFileRevertable;
+
+public class LightBotSourceFile extends SourceFileRevertable {
+	private LightBotInstruction[] main;
+	private LightBotInstruction[] func1;
+	private LightBotInstruction[] func2;
+
+	public LightBotSourceFile(String name) {
+		super(name);
+		resetBody();
+	}
+	@Override
+	public String getBody(){
+		StringBuffer sb = new StringBuffer();
+		for (int i=0;i<main.length;i++)
+			sb.append(main[i].toChar());
+		sb.append('\n');
+		for (int i=0;i<func1.length;i++)
+			sb.append(func1[i].toChar());
+		sb.append('\n');
+		for (int i=0;i<func2.length;i++)
+			sb.append(func2[i].toChar());
+		sb.append('\n');
+		return sb.toString();
+	}
+
+	private void resetBody() {
+		main = new LightBotInstruction[12];
+		for (int i=0;i<main.length;i++)
+			main[i]=LightBotInstruction.noop();
+		func1 = new LightBotInstruction[8];
+		for (int i=0;i<func1.length;i++)
+			func1[i]=LightBotInstruction.noop();
+		func2 = new LightBotInstruction[8];
+		for (int i=0;i<func2.length;i++)
+			func2[i]=LightBotInstruction.noop();	
+	}
+	
+	@Override
+	public void setBody(String newBody){
+		/* reset everything to noop */
+		resetBody();
+		
+		/* parse content */
+		String[] lines = newBody.split("\n");
+		int pos=0;
+		if (lines.length>0)
+			for (char c : lines[0].toCharArray()) 
+				main[pos++]=new LightBotInstruction(c);
+		pos=0;
+		if (lines.length>1)
+			for (char c : lines[1].toCharArray()) 
+				func1[pos++]=new LightBotInstruction(c);
+		pos=0;
+		if (lines.length>2)
+			for (char c : lines[2].toCharArray()) 
+				func2[pos++]=new LightBotInstruction(c);
+	}
+
+	@Override
+	public JScrollPane getEditorPanel(ProgrammingLanguage lang){
+		return new LightBotEditorPanel(this);
+	}
+	public LightBotInstruction[] getMain() {
+		return main;
+	}
+	public LightBotInstruction[] getFunc1() {
+		return func1;
+	}
+	public LightBotInstruction[] getFunc2() {
+		return func2;
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotWorld.fr.html b/src/plm/universe/lightbot/LightBotWorld.fr.html
new file mode 100644
index 0000000..3956340
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorld.fr.html
@@ -0,0 +1,32 @@
+<h1>LightBot</h1>
+
+Cet univers introduit un petit puzzle de programmation qui peut être utilisé
+pour introduire la programmation aux enfants ne sachant pas lire. En effet,
+il est programmé de manière graphique. L'objectif de chaque niveau est
+d'allumer toutes les lumières du plateau en utilisant le petit
+robot. Celui-ci comprend les ordres suivants :
+
+<table border=1>
+ <tr><td><b>Ordre</b></td><td><b>Signification</b></td></tr>
+ <tr><td><img src="img/lightbot_forward.png" /></td><td><b>Avancer</b><br />Ne peut être utilisé que si la case d'arrivée est à la même altitude que la
+case de départ.</td></tr>
+ <tr><td><img src="img/lightbot_jump.png" /></td><td><b>Sauter en avant</b><br />Ne peut être utilisé que si la case d'arrivée est un étage plus haute que la
+case de départ, ou si l'arrivée est plus basse que le départ. Il est
+impossible de sauter sur un terrain plat.</td></tr> 
+ <tr><td><img src="img/lightbot_left.png" /></td><td><b>Tourner à gauche</b>.</td></tr>  
+ <tr><td><img src="img/lightbot_right.png" /></td><td><b>Tourner à droite</b>.</td></tr>   
+ <tr><td><img src="img/lightbot_light.png" /></td><td><b>Allumer ou éteindre</b><br />Allumer l'ampoule si elle était éteinte, et éteindre si elle était
+allumée. Sans effet s'il n'y a pas d'ampoule dans la case courante.</td></tr>    
+ <tr><td><img src="img/lightbot_f1.png" /></td><td><b>Appeller la fonction 1</b>.</td></tr>
+ <tr><td><img src="img/lightbot_f2.png" /></td><td><b>Appeller la fonction 2</b>.</td></tr>
+</table>
+
+<p>Veuillez noter que ce jeu n'est pas vraiment adapté aux jeunes enfants
+puisque la principale difficulté vient de la limitation du nombre
+d'instructions utilisable dans chaque programme. Les niveaux avancés ne
+peuvent être résolus sans écrire des fonctions pour factoriser le code, ce
+qui est souvent au delà des capacités des jeunes enfants.</p>
+
+<p>Ce jeu est très largement inspiré d'un jeu en flash du même nom, que l'on
+peut par exemple trouver sur kongregate.com. Il a été écrit par Danny
+Yaroslavski (Coolio-Niato), d'après une idée originale de Matt Chase.</p>      
\ No newline at end of file
diff --git a/src/plm/universe/lightbot/LightBotWorld.html b/src/plm/universe/lightbot/LightBotWorld.html
new file mode 100644
index 0000000..fbc2ffa
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorld.html
@@ -0,0 +1,19 @@
+<h1>LightBot</h1>
+
+This universe introduces a little programming puzzle which can somehow be used to introduce programmation to non-reading kids since it is programmed graphically. 
+The goal of each board is to light up all the lights. Your robot understands the following orders:
+
+<table border=1>
+ <tr><td><b>Order</b></td><td><b>Meaning</b></td></tr>
+ <tr><td><img src="img/lightbot_forward.png" /></td><td><b>Move forward</b><br />Cannot be done if the destination cell is of another height than source cell</td></tr>
+ <tr><td><img src="img/lightbot_jump.png" /></td><td><b>Jump forward</b><br />Can only be done if the destination cell is one step higher than source cell, or if destination is lower than source. Cannot be used for plain moves.</td></tr> 
+ <tr><td><img src="img/lightbot_left.png" /></td><td><b>Turn left</b>.</td></tr>  
+ <tr><td><img src="img/lightbot_right.png" /></td><td><b>Turn right</b>.</td></tr>   
+ <tr><td><img src="img/lightbot_light.png" /></td><td><b>Switch the light</b>.<br />Turn it on if it was off, and off if it was on. No effect if the cell does not contain any light.</td></tr>    
+ <tr><td><img src="img/lightbot_f1.png" /></td><td><b>Call function 1</b>.</td></tr>
+ <tr><td><img src="img/lightbot_f2.png" /></td><td><b>Call function 2</b>.</td></tr>
+</table>
+
+<p>Please note that this world is not completely suited to small kids since the main difficulty comes from the fact that your are highly limited in the amount of instructions you can give to your robot. Advanced levels thus require to write sound functions, and are often above the capacities of small kids.</p>
+
+<p>This game is heavily inspirated from a flash game of the same name, which can for example be played on kongregate.com. It was written by Danny Yaroslavski (Coolio-Niato), the original idea being of Matt Chase.</p>      
\ No newline at end of file
diff --git a/src/plm/universe/lightbot/LightBotWorld.java b/src/plm/universe/lightbot/LightBotWorld.java
new file mode 100644
index 0000000..71dce49
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorld.java
@@ -0,0 +1,204 @@
+package plm.universe.lightbot;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import javax.script.ScriptEngine;
+import javax.swing.ImageIcon;
+
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.Entity;
+import plm.universe.GridWorld;
+import plm.universe.World;
+
+public class LightBotWorld extends plm.universe.GridWorld implements Iterable<LightBotWorldCell> {
+
+	public LightBotWorld(String name, int x, int y) {
+		super(name,x,y);
+		setDelay(200);
+	}
+	protected LightBotWorldCell newCell(int x, int y) {
+		return new LightBotWorldCell(this, x, y);
+	}
+
+	/**
+	 * Create a new world being almost a copy of the first one.
+	 * 
+	 * @param world2
+	 */
+	public LightBotWorld(LightBotWorld world2) {
+		super(world2);
+	}
+
+	/**
+	 * Reset the content of a world to be the same than the one passed as
+	 * argument. Does not affect the name of the initial world.
+	 */
+	@Override
+	public void reset(World iw) {
+		GridWorld initialWorld = (GridWorld) iw;
+		for (int i = 0; i < sizeX; i++)
+			for (int j = 0; j < sizeY; j++) {
+				LightBotWorldCell c = (LightBotWorldCell) initialWorld.getCell(i, j);
+				cells[i][j] = new LightBotWorldCell(c,this);
+			}
+
+		super.reset(initialWorld);
+	}
+
+	public void rotateRight() {	
+		LightBotWorldCell[][] newWorld = new LightBotWorldCell[this.sizeY][this.sizeX];
+		for (int y=0; y<this.sizeY; y++)
+			for (int x=0; x<this.sizeX; x++) {
+				LightBotWorldCell cell = (LightBotWorldCell) this.cells[x][y];
+				cell.setX(this.sizeX-(y+1));
+				cell.setY(x);
+				newWorld[this.sizeX-(y+1)][x] = cell;
+			}
+		this.cells = newWorld;
+		int oldSizeX = this.sizeX;
+		this.sizeX = this.sizeY;
+		this.sizeY = oldSizeX;
+		
+		for (Entity entity : this.entities) {
+			LightBotEntity bot = (LightBotEntity) entity;
+			int x = bot.getX();
+			int y = bot.getY();
+			
+			bot.setX(this.sizeX-(y+1));
+			bot.setY(x);
+			bot.right();
+		}
+		
+		notifyWorldUpdatesListeners();
+	}
+	
+	public void rotateLeft() {
+		LightBotWorldCell[][] newWorld = new LightBotWorldCell[this.sizeY][this.sizeX];
+		for (int y=0; y<this.sizeY; y++)
+			for (int x=0; x<this.sizeX; x++) {
+				LightBotWorldCell cell = (LightBotWorldCell) this.cells[x][y];
+				cell.setX(y);
+				cell.setY(this.sizeX-(x+1));
+				newWorld[y][this.sizeX-(x+1)] = cell;
+			}
+		this.cells = newWorld;
+		int oldSizeX = this.sizeX;
+		this.sizeX = this.sizeY;
+		this.sizeY = oldSizeX;
+		
+		for (Entity entity : this.entities) {
+			LightBotEntity bot = (LightBotEntity) entity;
+			int x = bot.getX();
+			int y = bot.getY();
+			
+			bot.setX(y);
+			bot.setY(this.sizeX-(x+1));
+			bot.left();
+		}
+		
+		notifyWorldUpdatesListeners();		
+	}
+	
+	
+	
+	@Override
+	public WorldView getView() {
+//		return new LightBotWorldView2D(this);
+		return new LightBotWorldViewIsometric(this);
+	}
+	@Override
+	public ImageIcon getIcon() {
+		return ResourcesCache.getIcon("img/world_lightbot.png");
+	}
+	
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + sizeX;
+		result = PRIME * result + sizeY;
+		result = PRIME * result + Arrays.hashCode(cells);
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		final GridWorld other = (GridWorld) obj;
+		if (getWidth() != other.getWidth())
+			return false;
+		if (getHeight() != other.getHeight())
+			return false;
+		for (int x = 0; x < getWidth(); x++)
+			for (int y = 0; y < getHeight(); y++)
+				if (!getCell(x, y).equals(other.getCell(x, y)))
+					return false;
+
+		return super.equals(obj);
+	}
+
+	public class CellIterator implements Iterator<LightBotWorldCell> {
+		private int x = 0;
+		private int y = 0;
+
+		@Override
+		public boolean hasNext() {
+			return x <= LightBotWorld.this.sizeX - 1 && y <= LightBotWorld.this.sizeY - 1;
+		}
+
+		@Override
+		public LightBotWorldCell next() {
+			LightBotWorldCell res = (LightBotWorldCell) LightBotWorld.this.getCell(x, y);
+			if (x >= LightBotWorld.this.sizeX - 1) {
+				x = 0;
+				y++;
+			} else {
+				x++;
+			}
+			return res;
+		}
+
+		@Override
+		public void remove() {
+			throw new RuntimeException("Method not implemented (and not implementable");
+		}
+
+	}
+
+	public void setHeight(int x, int y, int h) {
+		((LightBotWorldCell) getCell(x, y)).setHeight(h);
+	}
+
+	public void addLight(int x, int y) {
+		((LightBotWorldCell) getCell(x, y)).addLight();
+	}
+
+	public void removeLight(int x, int y) {
+		((LightBotWorldCell) getCell(x, y)).removeLight();
+	}
+
+	public void switchLight(int x, int y) {
+		((LightBotWorldCell) getCell(x, y)).lightSwitch();
+	}
+
+	@Override
+	public Iterator<LightBotWorldCell> iterator() {
+		return new CellIterator();
+	}
+	@Override
+	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) {
+		throw new RuntimeException("No binding of LightbotWorld for "+lang);
+	}
+	@Override
+	public String diffTo(World other) {
+		return "null";
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotWorldCell.java b/src/plm/universe/lightbot/LightBotWorldCell.java
new file mode 100644
index 0000000..110abce
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorldCell.java
@@ -0,0 +1,113 @@
+package plm.universe.lightbot;
+
+import plm.universe.GridWorld;
+import plm.universe.GridWorldCell;
+
+
+
+
+public class LightBotWorldCell extends GridWorldCell {
+	private boolean light=false; /* whether we have a light */
+	private boolean lightOn=false; /* if we have a light, whether it's on or off */
+
+	private int height;
+
+	public LightBotWorldCell(GridWorld w, int x, int y) {
+		this(w, x, y, false, false, 0);
+	}
+
+	public LightBotWorldCell(LightBotWorldCell c, GridWorld w) {
+		this(w, c.x, c.y, c.light, c.lightOn, c.height);
+	}
+	@Override
+	public GridWorldCell copy(GridWorld world) {
+		return new LightBotWorldCell(this,world);
+	}
+
+	public LightBotWorldCell(GridWorld w, int x, int y, boolean light, boolean lightOn, int height) {
+		super(w,x,y);
+		this.light = light;
+		this.lightOn = lightOn;
+		this.height = height;
+	}
+
+	public void addLight() {
+		this.light = true;
+		this.lightOn = false;
+		world.notifyWorldUpdatesListeners();
+	}
+	public void removeLight() {
+		this.light = false;
+		world.notifyWorldUpdatesListeners();
+	}
+	public void lightSwitch() {
+		lightOn = !lightOn;
+		world.notifyWorldUpdatesListeners();
+	}
+	public void setLightOn() {
+		lightOn = true;
+		world.notifyWorldUpdatesListeners();
+	}
+	public void setLightOff() {
+		lightOn = false;
+		world.notifyWorldUpdatesListeners();
+	}
+	/** Returns true if the light is on, or if there is no light */
+	public boolean getLightOnOrNone(){
+		return (!light) || lightOn;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (light ? 1231 : 1237);
+		result = prime * result + (lightOn ? 1231 : 1237);
+		result = prime * result + ((world == null) ? 0 : world.hashCode());
+		result = prime * result + x;
+		result = prime * result + y;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		LightBotWorldCell other = (LightBotWorldCell) obj;
+		if (light != other.light)
+			return false;
+		if (lightOn != other.lightOn)
+			return false;
+		if (x != other.x)
+			return false;
+		if (y != other.y)
+			return false;
+		return true;
+	}
+
+	public int getHeight() {
+		return height;
+	}
+
+	public void setHeight(int h) {
+		height = h;
+	}
+
+	public boolean isLight() {
+		return light;
+	}
+
+	public boolean isLightOn() {
+		return lightOn;
+	}
+	
+	@Override
+	public String toString() {
+		return "LBCell[x:"+this.x+";y:"+this.y+";z:"+this.height+";light:"+(light?(lightOn?"on":"off"):"none")+"]";
+	}	
+	
+}
diff --git a/src/plm/universe/lightbot/LightBotWorldView2D.java b/src/plm/universe/lightbot/LightBotWorldView2D.java
new file mode 100644
index 0000000..87cdab6
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorldView2D.java
@@ -0,0 +1,137 @@
+/* This file is not used anymore: it displays a stupid 2D view of the world.
+ * Its main interest were to be able to test the world before the 3D isometric were functional.
+ * I don't kill it so that we have a backup in case the 3D view breaks at some point.
+ */
+
+package plm.universe.lightbot;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Arc2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+
+import plm.core.ui.WorldView;
+import plm.universe.Direction;
+import plm.universe.Entity;
+import plm.universe.GridWorld;
+import plm.universe.GridWorldCell;
+import plm.universe.World;
+
+public class LightBotWorldView2D extends WorldView {
+	private static final long serialVersionUID = 1674820378395646693L;
+
+	private static Color GRID_COLOR = new Color(0.8f, 0.8f, 0.8f);
+	private static Color DARK_CELL_COLOR = new Color(0.93f, 0.93f, 0.93f);
+	private static Color LIGHT_CELL_COLOR = new Color(0.95f, 0.95f, 0.95f);
+	private static Color LIGHT_OFF_COLOR = Color.BLACK;
+	private static Color LIGHT_ON_COLOR = Color.YELLOW;
+	private static Color BOT_COLOR = Color.BLUE;
+
+	private static final double CELL_WIDTH = 50.;
+	
+	public LightBotWorldView2D(World w) {
+		super(w);
+	}
+
+	@Override
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		Graphics2D g2 = (Graphics2D) g;
+
+		GridWorld tw = (GridWorld) this.world;
+
+		double ratio = Math.min(((double) getWidth()) / (tw.getWidth()*LightBotWorldView2D.CELL_WIDTH), ((double) getHeight()) / (tw.getHeight()*LightBotWorldView2D.CELL_WIDTH));
+		g2.translate(Math.abs((getWidth() - ratio * tw.getWidth()*LightBotWorldView2D.CELL_WIDTH) / 2.), Math.abs((getHeight() - ratio * tw.getHeight()*LightBotWorldView2D.CELL_WIDTH) / 2.));
+		g2.scale(ratio, ratio);
+		
+
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setColor(Color.white);
+		g2.fill(new Rectangle2D.Double(0., 0., (double) tw.getWidth()*LightBotWorldView2D.CELL_WIDTH, (double) tw.getHeight()*LightBotWorldView2D.CELL_WIDTH));
+
+		
+		// draw background
+		drawWorld2D(g2);
+		
+		// draw lights (and elevation)
+		for (int x = 0; x < tw.getWidth(); x++) {
+			for (int y = 0; y < tw.getHeight(); y++) {
+				LightBotWorldCell cell = (LightBotWorldCell) tw.getCell(x, y);
+				if (cell.isLight()) {
+					drawLight2D(g2, cell, cell.isLightOn());
+				}
+				
+				
+				g2.setColor(Color.RED);
+				if (cell.getHeight() != 0)
+					g2.drawString(Integer.toString(cell.getHeight()), (int) (x*LightBotWorldView2D.CELL_WIDTH), (int) ((y+1)*LightBotWorldView2D.CELL_WIDTH));
+			}
+		}
+		
+		// draw lightBots
+		for (Entity ent: world.getEntities())
+			drawBot2D(g2, (LightBotEntity) ent);
+	}
+
+	private void drawWorld2D(Graphics2D g) {
+		GridWorld w = (GridWorld) world;
+
+		for (int x = 0; x < w.getWidth(); x++) {
+			for (int y = 0; y < w.getHeight(); y++) {
+				Color cellColor = Color.white;
+				if ((x + y) % 2 == 0)
+					cellColor = LightBotWorldView2D.DARK_CELL_COLOR;
+				else
+					cellColor = LightBotWorldView2D.LIGHT_CELL_COLOR;
+				g.setColor(cellColor);
+				g.fill(new Rectangle2D.Double(x*LightBotWorldView2D.CELL_WIDTH, y*LightBotWorldView2D.CELL_WIDTH, LightBotWorldView2D.CELL_WIDTH, LightBotWorldView2D.CELL_WIDTH));
+			}
+		}
+
+		g.setColor(GRID_COLOR);
+		for (int x = 0; x <= w.getWidth(); x++)
+			g.draw(new Line2D.Double(x*LightBotWorldView2D.CELL_WIDTH, 0., x*LightBotWorldView2D.CELL_WIDTH, w.getHeight()*LightBotWorldView2D.CELL_WIDTH));
+		for (int y = 0; y <= w.getHeight(); y++)
+			g.draw(new Line2D.Double(0., y*LightBotWorldView2D.CELL_WIDTH, w.getWidth()*LightBotWorldView2D.CELL_WIDTH, y*LightBotWorldView2D.CELL_WIDTH));
+	}
+
+	private void drawLight2D(Graphics2D g, GridWorldCell cell, boolean lightOn) {
+		if (lightOn)
+			g.setColor(LightBotWorldView2D.LIGHT_ON_COLOR);
+		else
+			g.setColor(LightBotWorldView2D.LIGHT_OFF_COLOR);
+		g.fill(new Arc2D.Double(cell.getX()*LightBotWorldView2D.CELL_WIDTH + 0.1*LightBotWorldView2D.CELL_WIDTH, cell.getY()*LightBotWorldView2D.CELL_WIDTH + 0.1*LightBotWorldView2D.CELL_WIDTH, 0.8*LightBotWorldView2D.CELL_WIDTH, 0.8*LightBotWorldView2D.CELL_WIDTH, 0, 360, Arc2D.OPEN));
+	}
+
+	private void drawBot2D(Graphics2D g, LightBotEntity bot) {
+		GridWorldCell cell = bot.getCell();
+
+		double width = LightBotWorldView2D.CELL_WIDTH;
+		double height = LightBotWorldView2D.CELL_WIDTH;
+		double cx = cell.getX();
+		double cy = cell.getY();
+		
+		double angle = 0.;
+		switch (bot.getDirection().intValue()) {
+		case Direction.NORTH_VALUE:
+			angle = Math.PI;
+			break;
+		case Direction.SOUTH_VALUE:
+			angle = 0.;
+			break;
+		case Direction.EAST_VALUE:
+			angle = -Math.PI/2.;
+			break;
+		case Direction.WEST_VALUE:
+			angle = Math.PI/2;
+			break;
+		}
+		g.rotate(angle, cx*LightBotWorldView2D.CELL_WIDTH+width/2., cy*LightBotWorldView2D.CELL_WIDTH+height/2.);
+		
+		g.setColor(LightBotWorldView2D.BOT_COLOR);
+		g.fill(new Arc2D.Double((cx-0.25)*LightBotWorldView2D.CELL_WIDTH,(cy+0.1)*LightBotWorldView2D.CELL_WIDTH,1.5*width,1.5*height,60,60, Arc2D.PIE));		
+	}
+}
diff --git a/src/plm/universe/lightbot/LightBotWorldViewIsometric.java b/src/plm/universe/lightbot/LightBotWorldViewIsometric.java
new file mode 100644
index 0000000..cbb652a
--- /dev/null
+++ b/src/plm/universe/lightbot/LightBotWorldViewIsometric.java
@@ -0,0 +1,312 @@
+package plm.universe.lightbot;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GridLayout;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Arc2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+import plm.core.model.Game;
+import plm.core.ui.WorldView;
+import plm.universe.Direction;
+import plm.universe.GridWorld;
+import plm.universe.GridWorldCell;
+import plm.universe.World;
+
+public class LightBotWorldViewIsometric extends WorldView {
+
+	private static final long serialVersionUID = -697923562790202622L;
+
+	private static final Color GRID_COLOR = new Color(0.2f, 0.2f, 0.2f);
+	private static final Color DARK_CELL_COLOR = new Color(0.9f, 0.9f, 0.9f);
+	private static final Color LIGHT_CELL_COLOR = new Color(0.93f, 0.93f, 0.93f);
+
+	private static final Color DARK_WALL_COLOR = new Color(0.7f, 0.7f, 0.7f);
+	private static final Color LIGHT_WALL_COLOR = new Color(0.8f, 0.8f, 0.8f);
+
+	private static final Color LIGHT_OFF_COLOR = Color.BLACK;
+	private static final Color LIGHT_ON_COLOR = Color.YELLOW;
+	private static final Color BOT_COLOR = Color.BLUE;
+
+	private static final double CELL_WIDTH = 40.;
+	private static final double CELL_HEIGHT = 15.;
+
+	private static final double verticalIsometricScaleFactor = 2.;
+	private static final double isometricAngle = Math.PI / 4.;
+
+	private List<LightBotWorldCell> cellsZOrdered = new ArrayList<LightBotWorldCell>();
+
+	public LightBotWorldViewIsometric(World w) {
+		super(w);
+		initComponents();
+		computeZOrders();
+		if (world.getEntityCount() > 1)
+			throw new RuntimeException("Multiple entities in lightbot world not supported");
+	}
+
+	private synchronized void computeZOrders() {
+		this.cellsZOrdered.clear();
+		for (LightBotWorldCell c : ((LightBotWorld) this.world))
+			cellsZOrdered.add(c);
+
+		Collections.sort(cellsZOrdered, new Comparator<LightBotWorldCell>() {
+			@Override
+			public int compare(LightBotWorldCell c1, LightBotWorldCell c2) {
+				return LightBotWorldViewIsometric.computeZOrder(c1) - LightBotWorldViewIsometric.computeZOrder(c2);
+			}
+		});
+	}
+
+	@Override
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+
+		Graphics2D g2 = (Graphics2D) g;
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+		AffineTransform originalTransform = g2.getTransform();
+		
+		
+		GridWorld tw = (GridWorld) this.world;
+
+		double componentWidth = (double) getWidth();
+		double componentHeight = (double) getHeight();
+		double boardWidth = tw.getWidth() * CELL_WIDTH;
+		double boardHeight = tw.getHeight() * CELL_WIDTH;
+		double diagWidth = Math.sqrt(boardWidth * boardWidth + boardHeight * boardHeight);
+		double diagHeight = diagWidth;
+
+		double ratio = Math.min(componentWidth / (diagWidth), (componentHeight * verticalIsometricScaleFactor)
+				/ (1.5 * diagHeight));
+
+		double marginW = (componentWidth - ratio * diagWidth) / 2.;
+		double marginH = (componentHeight - ((1.5 * ratio * diagHeight) / verticalIsometricScaleFactor)) / 2.;
+		double paddingW = (diagWidth - boardWidth) / 2.;
+		double paddingH = (2 * diagHeight - boardHeight) / 2.;
+
+		// center drawing in the middle of the component
+		g2.translate(marginW, marginH);
+
+		// scale to component size + half-size for height
+		g2.scale(ratio, ratio / verticalIsometricScaleFactor);
+
+		// draw bounding-box
+		// g2.setColor(Color.RED);
+		// g2.draw(new Rectangle2D.Double(0., 0., diagWidth, 1.5*diagHeight));
+
+		GradientPaint skyGradient = new GradientPaint((float) (diagWidth / 2.), 0.f, new Color(0.0f, 0.0f, 0.6f),
+				(float) ((2. * diagWidth) / 3.), (float) (diagHeight), Color.BLACK, false);
+		g2.setPaint(skyGradient);
+		g2.fill(new Rectangle2D.Double(0., 0., diagWidth, 1.5 * diagHeight));
+
+		// shift drawing in order to be centered after it has been rotated
+		g2.translate(paddingW, paddingH);
+		g2.rotate(isometricAngle, boardWidth / 2., boardHeight / 2.);
+
+		// draw world and lights
+		drawWorld3D(g2);
+		
+		g2.setTransform(originalTransform);		
+	}
+
+	public static int computeZOrder(GridWorldCell cell) {
+		final int tx = cell.getWorld().getWidth();
+		final int ty = cell.getWorld().getHeight();
+
+		final int x = cell.getY();
+		final int y = cell.getX();
+
+		int val = (x + y) * (x + y + 1) / 2 + x + 1;
+		if (x + y > ty - 1)
+			val -= ((x + y - ty + 1) * (x + y - ty + 2)) / 2;
+		if (x + y > tx)
+			val -= ((x + y - tx) * (x + y - tx + 1)) / 2;
+
+		return val;
+	}
+
+	private synchronized void drawWorld3D(Graphics2D g) {
+		LightBotEntity bot = null;
+		if (world.getEntityCount() > 0)
+			bot = (LightBotEntity) world.getEntity(0);
+
+		for (LightBotWorldCell cell : this.cellsZOrdered) {
+			int x = cell.getX();
+			int y = cell.getY();
+
+			Color cellColor = Color.white;
+			if ((x + y) % 2 == 0)
+				cellColor = DARK_CELL_COLOR;
+			else
+				cellColor = LIGHT_CELL_COLOR;
+			g.setColor(cellColor);
+
+			double cw = CELL_WIDTH;
+			double dx = x * cw;
+			double dy = y * cw;
+			double dz = cell.getHeight() * CELL_HEIGHT;
+
+			GeneralPath face1 = new GeneralPath();
+			face1.moveTo(dx, dy + cw);
+			face1.lineTo(dx - dz, dy + cw - dz);
+			face1.lineTo(dx + cw - dz, dy + cw - dz);
+			face1.lineTo(dx + cw, dy + cw);
+			face1.lineTo(dx, dy + cw);
+
+			GeneralPath face2 = new GeneralPath();
+			face2.moveTo(dx + cw, dy + cw);
+			face2.lineTo(dx + cw - dz, dy + cw - dz);
+			face2.lineTo(dx + cw - dz, dy - dz);
+			face2.lineTo(dx + cw, dy);
+			face2.lineTo(dx + cw, dy + cw);
+
+			// floor
+			g.setColor(GRID_COLOR);
+			g.draw(new Rectangle2D.Double(dx, dy, cw, cw));
+
+			// face 1
+			g.setColor(DARK_WALL_COLOR);
+			g.fill(face1);
+			g.setColor(GRID_COLOR);
+			g.draw(face1);
+
+			// face 2
+			g.setColor(LIGHT_WALL_COLOR);
+			g.fill(face2);
+			g.setColor(GRID_COLOR);
+			g.draw(face2);
+
+			// steps on faces
+			for (int h = 0; h<cell.getHeight(); h++) {
+				g.setColor(GRID_COLOR);
+				double z = h * CELL_HEIGHT;
+				g.draw(new Line2D.Double(dx - z, dy + cw - z, dx + cw - z, dy + cw - z));
+				g.draw(new Line2D.Double(dx + cw -z , dy + cw - z, dx + cw -z , dy - z));
+			}
+	
+			// roof
+			g.setColor(cellColor);
+			g.fill(new Rectangle2D.Double(dx - dz, dy - dz, cw, cw));
+			g.setColor(GRID_COLOR);
+			g.draw(new Rectangle2D.Double(dx - dz, dy - dz, cw, cw));
+
+			if (cell.isLight()) {
+				drawLight2D(g, cell);
+			}
+
+			// print elevation
+			// g.setColor(Color.RED);
+			// g.drawString(Integer.toString(cell.getHeight()), (int) (dx - dz),
+			// (int) (dy + cw - ch));
+
+			// print z-order
+			// g.setColor(Color.BLUE);
+			// g.drawString(Integer.toString(computeZOrder(cell)), (int) (dx +
+			// cw - cw / 3 - dz), (int) (dy + cw - dz));
+
+			// print cell coord
+			//g.setColor(Color.BLACK);
+			//g.drawString(("" + x + ":" + y), (int) (dx + cw - cw / 2. - dz),
+			//(int) (dy + cw / 2. - dz));
+
+			if (bot != null && cell == bot.getCell()) {
+				drawBot2D(g, bot);
+			}
+		}
+
+	}
+
+	private void drawLight2D(Graphics2D g, LightBotWorldCell cell) {
+		final double dx = cell.getX() * CELL_WIDTH;
+		final double dy = cell.getY() * CELL_WIDTH;
+		final double dz = cell.getHeight() * CELL_HEIGHT;
+
+		g.setColor(cell.isLightOn()?LIGHT_ON_COLOR:LIGHT_OFF_COLOR);
+		g.fill(new Arc2D.Double(dx + 0.1 * CELL_WIDTH - dz, dy + 0.1 * CELL_WIDTH - dz, 0.8 * CELL_WIDTH,
+				0.8 * CELL_WIDTH, 0, 360, Arc2D.OPEN));
+	}
+
+	private void drawBot2D(Graphics2D g, LightBotEntity bot) {
+		LightBotWorldCell cell = bot.getCell();
+
+		double width = CELL_WIDTH;
+		double height = CELL_WIDTH;
+		double cx = cell.getX();
+		double cy = cell.getY();
+
+		double angle = 0.;
+		switch (bot.getDirection().intValue()) {
+		case Direction.NORTH_VALUE:
+			angle = Math.PI;
+			break;
+		case Direction.SOUTH_VALUE:
+			angle = 0.;
+			break;
+		case Direction.EAST_VALUE:
+			angle = -Math.PI / 2.;
+			break;
+		case Direction.WEST_VALUE:
+			angle = Math.PI / 2;
+			break;
+		}
+
+		double rx = cx * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT + width / 2.;
+		double ry = cy * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT + height / 2.;
+		g.rotate(angle, rx, ry);
+
+		g.setColor(BOT_COLOR);
+		g.fill(new Arc2D.Double((cx - 0.25) * CELL_WIDTH - cell.getHeight() * CELL_HEIGHT, (cy + 0.1) * CELL_WIDTH
+				- cell.getHeight() * CELL_HEIGHT, 1.5 * width, 1.5 * height, 60, 60, Arc2D.PIE));
+
+		g.rotate(-angle, rx, ry);
+
+	}
+
+	@Override
+	public void worldHasMoved() {
+		computeZOrders();
+		super.worldHasMoved();
+	}	
+	
+	public void initComponents() {
+		JButton rotateLeft = new JButton("left");
+		rotateLeft.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				for (World w : Game.getInstance().getSelectedWorlds())
+					((LightBotWorld) w).rotateLeft();
+			}
+		});
+	
+		JButton rotateRight = new JButton("right");
+		rotateRight.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent event) {
+				for (World w : Game.getInstance().getSelectedWorlds())
+					((LightBotWorld) w).rotateRight();
+			}
+		});
+		
+		JPanel buttonsPanel = new JPanel();
+		buttonsPanel.setLayout(new GridLayout(1,2));
+		buttonsPanel.add(rotateLeft);
+		buttonsPanel.add(rotateRight);
+		
+		setLayout(new BorderLayout());
+		add(BorderLayout.NORTH, buttonsPanel);
+	}
+}
diff --git a/src/plm/universe/lightbot/package-info.java b/src/plm/universe/lightbot/package-info.java
new file mode 100644
index 0000000..8bf25e8
--- /dev/null
+++ b/src/plm/universe/lightbot/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Little programming game universe where you must program a robot to 
+ * light up some lights. You do so graphically and not in java. 
+ */
+package plm.universe.lightbot;
+
diff --git a/src/plm/universe/package-info.java b/src/plm/universe/package-info.java
new file mode 100644
index 0000000..9764c72
--- /dev/null
+++ b/src/plm/universe/package-info.java
@@ -0,0 +1,8 @@
+/**
+ * Constituting elements of each specialized universes.
+ * 
+ * The class defined directly in this class act as ancestors 
+ * to the specialized versions defined in subpackages.
+ */
+package plm.universe;
+
diff --git a/src/plm/universe/sort/CopyVal.java b/src/plm/universe/sort/CopyVal.java
new file mode 100644
index 0000000..c8b44c2
--- /dev/null
+++ b/src/plm/universe/sort/CopyVal.java
@@ -0,0 +1,25 @@
+package plm.universe.sort;
+
+public class CopyVal extends Operation {
+	
+	/**
+	 * Constructor of the class CopyVal
+	 * @param source : the source of the operation
+	 * @param destination : the destination of the operation
+	 */
+	public CopyVal(int source, int destination){
+		super(source,destination);
+	}
+
+	/**
+	 * Compute an operation on init
+	 * @param init the values on which compute the operation 
+	 * @return the array of values after the operation
+	 */
+	@Override
+	public int[] run(int[] init) {
+		init[destination] = init[source];
+		return init;
+	}
+	
+}
diff --git a/src/plm/universe/sort/GetVal.java b/src/plm/universe/sort/GetVal.java
new file mode 100644
index 0000000..a0c72cc
--- /dev/null
+++ b/src/plm/universe/sort/GetVal.java
@@ -0,0 +1,28 @@
+package plm.universe.sort;
+
+public class GetVal extends Operation {
+	
+	public int position;
+
+	/**
+	 * Constructor of the class SetVal
+	 * @param position the source of the operation
+	 * @param destination the destination of the operation
+	 */
+	public GetVal(int position){
+		super(-1,-1);
+		this.position = position; 
+	}
+
+	/**
+	 * Compute an operation on init
+	 * @param init the values on which compute the operation
+	 * @return the array passed as parameter, once the operation is applied to it
+	 */
+	@Override
+	public int[] run(int[] init) {
+		return init;
+	}
+	
+	
+}
diff --git a/src/plm/universe/sort/Operation.java b/src/plm/universe/sort/Operation.java
new file mode 100644
index 0000000..71aafab
--- /dev/null
+++ b/src/plm/universe/sort/Operation.java
@@ -0,0 +1,57 @@
+package plm.universe.sort;
+
+
+public abstract class Operation {
+	
+	protected int source;	// the source of the operation
+	protected int destination;	// the destination of the operation
+	
+	/**
+	 * Constructor of the class Operation
+	 * @param source the source of the operation
+	 * @param destination the destination of the operation
+	 */
+	public Operation(int source, int destination){
+		this.source = source;
+		this.destination = destination;
+	}
+	
+	/**
+	 * Indicate whether some other object is "equal to" this one
+	 * @param o the reference object with which to compare
+	 */
+	public boolean equals(Object o) {
+		if (o == null || !(o instanceof Operation))
+			return false;
+		
+		Operation other = (Operation) o;
+		if (destination != other.destination)
+			return false;
+		if (!getClass().equals(o.getClass()))
+			return false;
+		if (source != other.source)
+			return false;
+		return true;
+	}
+
+	/**
+	 * Returns the source of the operation
+	 */
+	public int getSource() {
+		return this.source;
+	}
+
+	/**
+	 * Returns the destination of the operation
+	 */
+	public int getDestination() {
+		return this.destination;
+	}
+		
+	/**
+	 * Compute an operation on init
+	 * @param init the values on which compute the operation
+	 * @return a new array of values equals to init where the operation had been computed
+	 */
+	public abstract int[] run(int[] init);	
+}
diff --git a/src/plm/universe/sort/SetVal.java b/src/plm/universe/sort/SetVal.java
new file mode 100644
index 0000000..9b3eed6
--- /dev/null
+++ b/src/plm/universe/sort/SetVal.java
@@ -0,0 +1,30 @@
+package plm.universe.sort;
+
+public class SetVal extends Operation {
+	
+	int value;
+
+	/**
+	 * Constructor of the class SetVal
+	 * @param position the source of the operation
+	 * @param destination the destination of the operation
+	 */
+	public SetVal(int position, int value){
+		super(position,-1);
+		this.value = value; 
+	}
+
+	/**
+	 * Compute an operation on init
+	 * @param init the values on which compute the operation
+	 * @return the array passed as parameter, once the operation is applied to it
+	 */
+	@Override
+	public int[] run(int[] init) {
+		init[source] = value;
+		
+		return init;
+	}
+	
+	
+}
diff --git a/src/plm/universe/sort/SortingButtonPanel.java b/src/plm/universe/sort/SortingButtonPanel.java
new file mode 100644
index 0000000..2c742e5
--- /dev/null
+++ b/src/plm/universe/sort/SortingButtonPanel.java
@@ -0,0 +1,104 @@
+package plm.universe.sort;
+
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JPanel;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.model.Game;
+import plm.universe.EntityControlPanel;
+
+/**
+ * The control panel for the sorting world. 
+ * It allows you to use the copy, setValue and swap methods interactively.
+ * @see EntityControlPanel
+ * @see SortingWorld
+ */
+public class SortingButtonPanel extends EntityControlPanel {
+
+	private static final long serialVersionUID = 1L;
+	private JButton validateButton;	// a validate button
+	private JComboBox operationsComboBox;	// the available operations on the array ( setValue, copy and swap )
+	private JComboBox leftValueComboBox;	// the value for the first parameter of the selected operation
+	private JComboBox rightValueComboBox;	// the value for the second parameter of the selected operation
+	
+	private I18n i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages",getLocale(), I18nFactory.FALLBACK);
+
+	/**
+     * Constructor of SortingButtonPanel
+     * It initializes the command panel
+     */
+	public SortingButtonPanel() {
+		super();
+		SortingEntity se = (SortingEntity) Game.getInstance().getSelectedEntity();
+		this.add(this.createCommandPanel(se));
+	}
+	
+	/**
+	 * Initialize the command panel of the SortingButtonPanel
+	 * @param se The current sorting Entity
+	 * @return a JPanel containing the command panel
+	 */
+	private JPanel createCommandPanel(SortingEntity se) {
+		JPanel commandPane = new JPanel();
+		commandPane.setLayout(new FlowLayout());
+		
+		String operationsAvailable[] = { "swap","setValue","copy"};
+		this.operationsComboBox = new JComboBox(operationsAvailable);
+		
+		int n = se.getValueCount();
+		Integer index[] = new Integer[n];
+		for ( int i = 0 ; i < n ; i++) {
+			index[i] = i; 
+		}
+		this.leftValueComboBox = new JComboBox(index) ;
+		this.rightValueComboBox = new JComboBox(index) ;
+		
+		this.validateButton = new JButton(i18n.tr("go"));
+		this.validateButton.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				int i = leftValueComboBox.getSelectedIndex();
+				int j = rightValueComboBox.getSelectedIndex();
+				int selectedOperation = operationsComboBox.getSelectedIndex();
+				SortingEntity se = (SortingEntity) Game.getInstance().getSelectedEntity();
+				switch (selectedOperation)
+				{
+					case 0:
+						se.swap(i,j);
+						break;
+					case 1:
+						se.setValue(i,j);
+						break;
+					case 2:
+						se.copy(i, j);
+						break;
+					default:
+						System.err.println("Unknown operation index: "+selectedOperation);
+				}
+			}
+		}
+		);
+		
+		commandPane.add(this.operationsComboBox);
+		commandPane.add(this.leftValueComboBox);
+		commandPane.add(this.rightValueComboBox);
+		commandPane.add(this.validateButton);
+		
+		return commandPane;
+	}
+
+	@Override
+	public void setEnabledControl(boolean enabled) {
+		this.validateButton.setEnabled(enabled);
+		this.operationsComboBox.setEnabled(enabled);
+		this.leftValueComboBox.setEnabled(enabled);
+		this.rightValueComboBox.setEnabled(enabled);
+	}
+}
diff --git a/src/plm/universe/sort/SortingEntity.java b/src/plm/universe/sort/SortingEntity.java
new file mode 100644
index 0000000..b761f35
--- /dev/null
+++ b/src/plm/universe/sort/SortingEntity.java
@@ -0,0 +1,76 @@
+package plm.universe.sort;
+
+import plm.universe.Entity;
+import plm.universe.World;
+
+public class SortingEntity extends Entity {
+
+	public SortingEntity() {
+		super("Sorting Entity");
+	}
+
+	/** Part of the copy process; Must call super(name) */
+	public SortingEntity(String name) {
+		super(name);
+	}
+	
+	/** Instantiation Constructor (used by exercises to setup the world) */
+	public SortingEntity(String name, World world) {
+		super(name,world);
+	}
+
+	/** A copy constructor needed by the PLM */
+	public Entity copy() {
+		return new SortingEntity(this.name);
+	}
+
+	public void copy(int from,int to) {
+		((SortingWorld) this.world).copy(from,to);
+		stepUI();
+	}
+
+	public int getValue(int i) {
+		return ((SortingWorld) this.world).getValue(i);
+	}
+	
+	public int getValueCount() {
+		return ((SortingWorld) this.world).getValueCount();
+	}
+	
+	public boolean isSmaller(int i, int j) {
+		return ((SortingWorld) this.world).isSmaller(i,j);
+	}
+	
+	public boolean isSmallerThan(int i, int val) {
+		return ((SortingWorld) this.world).isSmallerThan(i,val);
+	}
+	
+	public void run() {
+		// Child implement this
+	}
+	
+	public void setValue(int i,int val) {
+		((SortingWorld) this.world).setValue(i,val);
+		stepUI();
+	}
+	
+	public void swap(int i, int j) {
+		((SortingWorld) this.world).swap(i,j);
+		stepUI();
+	}
+	
+	/* BINDINGS TRANSLATION: French */
+	public int getNombreValeurs() { return getValueCount(); }
+
+	public int getValeur(int i)   { return getValue(i);}
+	public void setValeur(int i,int val) { setValue(i, val); }
+	
+	public boolean plusPetit(int i, int j) { return isSmaller(i, j); }	
+	public boolean plusPetitQue(int i, int value) { return isSmallerThan(i, value); }
+	
+	public void echange(int i, int j) { swap(i,j); }
+	public void copie(int from,int to) { copy(from,to);}
+
+	
+	public boolean estSelectionne() {return isSelected();}
+}
diff --git a/src/plm/universe/sort/SortingWorld.fr.html b/src/plm/universe/sort/SortingWorld.fr.html
new file mode 100644
index 0000000..2baf0af
--- /dev/null
+++ b/src/plm/universe/sort/SortingWorld.fr.html
@@ -0,0 +1,66 @@
+<h1>Monde des tris </h1>
+Ce monde vous donne les outils pour expérimenter les algorithmes de tris. On
+peut l'utiliser de deux manières différentes : la première est bien sûr
+d'écrire les algorithmes de tri demandés. Mais on peut aussi se contenter
+dans un premier temps de lancer la démo de chaque exercice et observer les
+algorithmes de tri fonctionner. Cela permet de mieux se rendre compte des
+différences d'efficacité entre eux.
+
+<h2>Méthodes disponibles pour les algorithmes de tri</h2>
+<table border=1>
+<tr><td><b>Méthode</b></td><td><b>Action</b></td><td><b>Coût</b></td></tr>
+<tr><td>[!java]int [/!]getNombreValeurs() [!scala]:Int[/!]</td>
+    <td>Retourne le nombre de valeurs dans le tableau</td><td>aucun</td></tr>
+
+<tr><td>[!java]boolean [/!]plusPetit([!java]int [/!]i[!scala]:Int[/!], [!java]int
+[/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]</td>
+    <td>Retourne vrai ssi le contenu de la case i est strictement inférieur à celui
+de la case j</td><td>deux lectures</td></tr>
+<tr><td>[!java]boolean [/!]plusPetitQue([!java]int [/!]i[!scala]:Int[/!], [!java]int
+[/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]</td>
+    <td>Retourne vrai ssi le contenu de la case i est strictement inférieur à la
+valeur <code>value</code></td><td>une lecture</td></tr>
+
+<tr><td>[!java]void [/!]echange([!java]int [/!]i[!scala]:Int[/!], [!java]int
+[/!]j[!scala]:Int[/!])</td>
+     <td>Echange le contenu de la case i avec celui de la case j</td><td>deux lectures, deux écritures</td></tr>
+<tr><td>[!java]void [/!]copie([!java]int [/!]depuis[!scala]:Int[/!], [!java]int
+[/!]vers[!scala]:Int[/!])</td>
+    <td>Copie le contenu de la case 'depuis' dans la case 'vers'</td><td>une lecture, une écriture</td></tr>
+
+<tr><td>[!java]int [/!]getValeur([!java]int [/!]idx[!scala]:Int[/!])</td>
+    <td>Retourne la valeur de la case idx</td><td>une lecture</td></tr>
+<tr><td>[!java]void [/!]setValeur([!java]int [/!]idx[!scala]:Int[/!], [!java]int
+[/!]valeur[!scala]:Int[/!])</td>
+    <td>Affecte la valeur 'valeur' à la case 'idx' </td><td>une écriture</td></tr>
+
+<tr><td>[!java]boolean [/!]estSelectionne() [!scala]:Boolean[/!]</td>
+    <td>Renvoi si le monde actuel est sélectionné dans l'interface graphique.</td><td>aucun</td></tr>
+
+</table>
+
+<h2>Vue de l'historique du monde</h2>
+<p>Il ne suffit pas de trier le tableau pour passer les exercices. Votre
+solution doit suivre scrupuleusement le comportement attendu de chaque
+exercice. Ceci est vérifié en comptant le nombre d'opérations de lecture et
+d'écriture sur le tableau effectuées lors de ce tri. En cas de problème, il
+est souvent assez difficile de comprendre la différence entre le
+comportement attendu et le comportement effectif.</p>
+
+<p>Pour cela, il est possible d'explorer graphiquement l'historique de
+n'importe quel monde de tri. Passez par exemple au monde Objectif et
+utilisez son menu contextuel (clic droit) pour choisir entre la vue de
+l'état courant du monde et la vue de son histoire.</p>
+
+<p>La vue de l'historique n'est pas aussi complexe qu'elle en a l'air à
+première vue. Le temps s'écoule de gauche à droite, et les cases du tableau
+sont représentée de haut en bas. Les lignes de différentes couleurs qui
+serpentent représentent les différentes valeurs contenues dans le
+tableau. Quand deux lignes se croises, cela signifie que les valeurs du
+tableau ont été échangées à ce moment de l'historique; un embranchement
+signifie que la valeur a été copiée; une valeur en violet suivie d'un point
+d'interrogation a été lue avec getValeur() et une valeur en rouge suivie
+d'un point d'exclamation a été écrite avec setValeur().</p>
+
+<p>Cette vue, inspirée d'Aldo Cortesi, est très pratique pour comprendre le
+comportement des algorithmes de tri.</p> 
diff --git a/src/plm/universe/sort/SortingWorld.html b/src/plm/universe/sort/SortingWorld.html
new file mode 100644
index 0000000..85eed01
--- /dev/null
+++ b/src/plm/universe/sort/SortingWorld.html
@@ -0,0 +1,57 @@
+<h1>Sorting World </h1>
+This world provides tools to experiment with the sorting algorithms. It can
+be used in two different ways: the first one is naturally to write the
+required sorting algorithms. But it is also possible to simply use the demo
+mode of each exercise to observe the behavior of sorting algorithms. It
+helps understanding the differences between each of them.
+
+<h2>Methods available to sorting algorithms</h2>
+<table border=1>
+<tr><td><b>Method</b></td><td><b>Action</b></td><td><b>Cost</b></td></tr>
+<tr><td>[!java]int [/!]getValueCount() [!scala]:Int[/!]</td>
+    <td>Returns the amount of values in the array</td><td>none</td></tr>
+
+<tr><td>[!java]boolean [/!]isSmaller([!java]int [/!]i[!scala]:Int[/!], [!java]int [/!]j[!scala]:Int[/!]) [!scala]:Boolean[/!]</td>
+    <td>Returns true if the content of cell i is strictly smaller than the one of cell j</td><td>two reads</td></tr>
+<tr><td>[!java]boolean [/!]isSmallerThan([!java]int [/!]i[!scala]:Int[/!], [!java]int [/!]value[!scala]:Int[/!])[!scala] :Boolean[/!]</td>
+    <td>Returns true if the content of cell i is strictly smaller than the <code>value</code></td><td>one read</td></tr>
+
+<tr><td>[!java]void [/!]swap([!java]int [/!]i[!scala]:Int[/!], [!java]int [/!]j[!scala]:Int[/!])</td>
+     <td>Swaps the content of cell i and the one of cell j</td><td>two reads, two writes</td></tr>
+<tr><td>[!java]void [/!]copy([!java]int [/!]from[!scala]:Int[/!], [!java]int [/!]to[!scala]:Int[/!])</td>
+    <td>Copy the content of cell 'from' into the cell 'to'</td><td>one read, one write</td></tr>
+
+<tr><td>[!java]int [/!]getValue([!java]int [/!]idx[!scala]:Int[/!])</td>
+    <td>Returns the value of cell idx</td><td>one read</td></tr>
+<tr><td>[!java]void [/!]setValue([!java]int [/!]idx[!scala]:Int[/!], [!java]int [/!]value[!scala]:Int[/!])</td>
+    <td>Sets cell 'idx' to the <code>value</code> </td><td>one write</td></tr>
+
+<tr><td>[!java]boolean [/!]isSelected() [!scala]:Boolean[/!]</td>
+    <td>Returns whether the current world is selected in the graphical interface.</td><td>none</td></tr>
+
+</table>
+
+<h2>History view</h2>
+<p>It is not enough to sort the array to pass the exercises. Your solution 
+must strictly follow the expected behavior of each exercise. This is
+enforced by checking that your algorithm needs the same amount of read
+and write operations to sort the array. When they don't match,
+understanding the difference between your code and the expected
+solution can reveal very difficult.</p>
+
+<p>To help in this process, it is possible to graphically explore the
+history of your sorting algorithm. Switch to the Objective view and
+use the contextual menu (right click) to switch from the the view of
+the current state to the view of its history.</p>
+
+<p>The history view is a bit hairly at the first glance, but actually rather
+simple: The time flows from left to right on this graph, and each row
+is a cell of your array. The curved lines that go navigate between
+rows represent a given data value. When two lines cross, this means
+that two values were swapped at this time stamp; A line fork represent a 
+value copy; When a value is magenta and followed by an interrogation 
+mark (?), it was read using getValue(); If the value is red and followed with 
+an exclamation point (!), it was written using setValue().</p>
+
+<p>This view, inspired from Aldo Cortesi, reveals very helpful understand the inner
+behavior of sorting algorithms.</p> 
diff --git a/src/plm/universe/sort/SortingWorld.java b/src/plm/universe/sort/SortingWorld.java
new file mode 100644
index 0000000..976fe59
--- /dev/null
+++ b/src/plm/universe/sort/SortingWorld.java
@@ -0,0 +1,358 @@
+package plm.universe.sort;
+
+import java.util.ArrayList;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
+
+public class SortingWorld extends World {
+	private int[] values;	// the values as they are sorted in the array
+	private int[] initValues;	// needed by the chronoview
+	private int readCount = 0;	// the count of the read made
+	private int writeCount = 0;	// the count of the write made
+	/*
+	 * It's needed by the chronoview
+	 * This list contains all the operations ( SetVal, CopyVal or Swap ) made on the world since 
+	 * the moment where it has been shown to the user
+	 */
+	private ArrayList<Operation> operations = new ArrayList<Operation>(1) ;	
+
+	/** Copy constructor used by the PLM internals */
+	public SortingWorld(SortingWorld world) {
+		super(world);
+	}
+
+	/** Constructor used in the exercises */
+	public SortingWorld(String name, int nbValues) {
+		super(name);
+		setDelay(50);
+		this.values = new int[nbValues];
+		for (int i=0 ; i< this.values.length ; i++) 
+		{
+			this.values[i] = i;
+		}
+		scramble();
+		this.initValues = this.values;
+	}
+
+	private void scramble() {
+		while( this.isSorted() )
+		{
+			for ( int caseNumber = 0 ; caseNumber < this.values.length ; caseNumber++)
+			{
+				// Swapping time !
+				if ( Math.random() > 0.5)
+				{
+					this.exchangeValues(caseNumber,(int)(Math.random()*this.values.length));
+				}
+			}
+		}
+	}
+
+	public boolean equals(Object o) {
+		if (o == null || !(o instanceof SortingWorld))
+			return false;
+
+		SortingWorld other = (SortingWorld) o;
+		if (values.length != other.values.length)
+			return false;
+		for (int i = 0 ; i < this.values.length ; i++) 
+			if ( this.values[i] != other.values[i] )
+				return false;
+		
+		if (operations.size() != other.operations.size())
+			return false;
+		for (int i = 0 ; i < this.operations.size() ; i++) 
+			if (! operations.get(i).equals( other.operations.get(i)) )
+				return false;
+		
+		if (! (this.readCount == other.readCount) )
+			return false;
+		if (! (this.writeCount == other.writeCount) )
+			return false;
+		
+		return true;
+	}
+
+	/**
+	 * Tells if the array is Sorted or not
+	 */
+	private boolean isSorted() {
+		boolean sw = true;
+		for ( int i = 0 ; i < this.values.length && sw ; i++ )
+		{
+			if ( this.values[i] != i )
+			{
+				sw = false ;
+			}
+		}
+		return sw;
+	}
+
+	/**
+	 * Copy the value from the cell of index from into the cell of index to<br>
+	 * It costs one read and one write.
+	 * @param from The index of the cell to copy
+	 * @param to The index of the cell where copy the value
+	 */
+	public void copy(int from,int to) {
+		if (from<0) throw new RuntimeException("Out of bounds in copy("+from+","+to+"): "+from+"<0");
+		if (to<0) throw new RuntimeException("Out of bounds in copy("+from+","+to+"): "+to+"<0");
+		if (from>=getValueCount()) throw new RuntimeException("Out of bounds in copy("+from+","+to+"), "+from+">= value count");
+		if (to>=getValueCount()) throw new RuntimeException("Out of bounds in copy("+from+","+to+"), "+to+">= value count");
+
+		this.operations.add(new CopyVal(from, to));
+
+		this.readCount++;
+		this.writeCount++;
+		this.values[to] = this.values[from];
+	}
+
+	/**
+	 * Make a textual description of the differences between the caller and world
+	 * @param world : the world with which you want to compare your world
+	 * @return A textual description of the differences between the caller and world
+	 */
+	@Override
+	public String diffTo(World world) {
+		String s ;
+		if (world == null || !(world instanceof SortingWorld)) {
+			s="This is not a world of sorting :(";
+		} else {
+			SortingWorld other = (SortingWorld) world;
+			StringBuffer sb = new StringBuffer();
+			if ( this.readCount != other.readCount )
+				sb.append("Invalid read count : expected "+this.readCount+" found "+other.readCount+"\n");
+			
+			if ( this.writeCount != other.writeCount )
+				sb.append("Invalid write count : expected "+this.writeCount+" found "+other.writeCount+"\n");
+			
+			for (int i = 0 ; i < this.values.length ; i++) 
+				if ( this.values[i] != other.values[i] )
+					sb.append("Index "+i+": expected "+this.values[i]+" found "+other.values[i]+"\n");
+					
+			s = sb.toString();
+		}
+		return s;
+	}
+
+
+	/** Returns the panel which let the user to interact dynamically with the world */
+	@Override
+	public EntityControlPanel getEntityControlPanel() {
+		return new SortingButtonPanel();
+	}
+	/** Returns the icon of the universe */
+	@Override
+	public ImageIcon getIcon() {
+		return ResourcesCache.getIcon("img/world_sorting.png");
+	}
+
+	/**
+	 * Returns the initial state of the array
+	 */
+	public int[] getInitValues() {
+		return initValues;
+	}
+
+	/**
+	 * Return the list of all the operations made on the world since its initialization/last reset
+	 */
+	public ArrayList<Operation> getOperations() {
+		return this.operations;
+	}
+
+	/**
+	 * Return the read counter
+	 */
+	public int getReadCount() {
+		return this.readCount;
+	}
+
+	/** Returns the amount of values in the array */
+	public int getValueCount() {
+		return values.length;
+	}
+
+	/** Returns the array of values that need to be sorted */
+	public int[] getValues() {
+		return this.values;
+	}
+
+	/** Returns a component able at displaying the world */
+	@Override
+	public WorldView getView() {
+		return new SortingWorldView(this);
+	}
+	
+	/** Returns the write counter */
+	public int getWriteCount() {
+		return this.writeCount;
+	}
+
+	/**
+	 * Tell if the value at the index i is smaller than the value at index j<br>
+	 * It costs two reads.
+	 * @param i the index of the first cell that we want to check
+	 * @param j the index of the second cell that we want to check
+	 * @return if the content of the cell of index i is smaller than the content of the cell of index j
+	 */
+	public boolean isSmaller(int i, int j) {
+		if (i<0) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"): "+i+"<0");
+		if (j<0) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"): "+j+"<0");
+		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"), "+i+">= value count");
+		if (j>=getValueCount()) throw new RuntimeException("Out of bounds in isSmaller("+i+","+j+"), "+j+">= value count");
+
+		this.readCount+=2;
+		return this.values[i]< this.values[j];
+	}
+	
+	/**
+	 * Tell if the value at the index i is smaller than val<br>
+	 * It costs one read.
+	 * @param i the index of case that we want to check
+	 * @param val the value with which compare the cell
+	 * @return if the case of index i is smaller than val
+	 */
+	public boolean isSmallerThan(int i, int val) {
+		if (i<0) throw new RuntimeException("Out of bounds in isSmallerThan("+i+","+val+"): "+i+"<0");
+		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in isSmallerThan("+i+","+val+"), "+i+">= value count");
+
+		this.readCount+=1;
+		return this.values[i]<val;
+	}
+	
+	/** 
+	 * Reset the state of the current world to the one passed in argument
+	 * @param w the world which must be the new start of your current world
+	 */
+	@Override
+	public void reset(World w) {
+		super.reset(w);
+		SortingWorld world = (SortingWorld)w;
+		
+		this.values = world.values.clone();
+		this.initValues = world.initValues.clone();
+		this.readCount = world.readCount ;
+		this.writeCount = world.writeCount;
+		this.operations = new ArrayList<Operation>(1);
+		for ( Operation o: world.operations)
+			this.operations.add(o);
+	}
+
+	/**
+	 * Setup the engine so that it's ready to host the user code
+	 *
+	 * @param lang the programming language used
+	 * @throws ScriptException some error reported by the scripting engine itself
+	 */
+	@Override
+	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) throws ScriptException {
+		if (lang.equals(Game.PYTHON)) {
+			e.eval(
+					"def getValueCount():\n" +
+					"  return entity.getValueCount()\n" +
+					"def swap(i,j):\n" +
+					"  entity.swap(i,j)\n" +
+					"def copy(i,j):\n" +
+					"  entity.copy(i,j)\n" +
+					"def getValue(i):\n" +
+					"  return entity.getValue(i)\n" +
+					"def setValue(i,j):\n" +
+					"  entity.setValue(i,j)\n" +
+					"def isSmaller(i,j):\n"+
+					"  return entity.isSmaller(i,j)\n"+
+					"def isSmallerThan(i,j):\n"+
+					"  return entity.isSmallerThan(i,j)\n"+
+					/* BINDINGS TRANSLATION: French */
+					"def getNombreValeurs():\n" +
+					"  return entity.getValueCount()\n" +
+					"def echange(i,j):\n" +
+					"  entity.swap(i,j)\n" +
+					"def copie(i,j):\n" +
+					"  entity.copy(i,j)\n" +
+					"def getValeur(i):\n" +
+					"  return entity.getValue(i)\n" +
+					"def setValeur(i,j):\n" +
+					"  entity.setValue(i,j)\n" +
+					"def plusPetit(i,j):\n"+
+					"  return entity.isSmaller(i,j)\n"+
+					"def plusPetitQue(i,j):\n"+
+					"  return entity.isSmallerThan(i,j)\n"
+
+			);
+		} else {
+			throw new RuntimeException("No binding of SortingWorld for "+lang);
+		}
+	}
+
+	/**
+	 * Return the value of index i in the array
+	 * @param i the index wanted in the array
+	 * @return the value of index i in the array
+	 */
+	public int getValue(int i) {
+		if (i<0) throw new RuntimeException("Out of bounds in getValue("+i+"): "+i+"<0");
+		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in getValue("+i+"), "+i+">= value count");
+		this.operations.add(new GetVal(i));
+		readCount++;
+		return values[i];
+	}
+
+	/**
+	 * Set the value of the case number i of the array at val<br>
+	 * It costs only one write.
+	 * @param i the index of the cell
+	 * @param val the value that you want to set
+	 */
+	public void setValue(int i,int val) {
+		if (i<0) throw new RuntimeException("Out of bounds in setValue("+i+"): "+i+"<0");
+		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in setValue("+i+"), "+i+">= value count");
+
+		this.operations.add(new SetVal(i, val));
+
+		this.writeCount++;
+		this.values[i]=val;
+	}
+
+	/**
+	 * Swap the value of the case number i with the value of the case number j<br>
+	 * It costs two reads and two writes
+	 * @param i the index of the first cell concerned
+	 * @param j the index of the second cell concerned
+	 */
+	public void swap(int i, int j) {
+		if (i<0) throw new RuntimeException("Out of bounds in swap("+i+","+j+"): "+i+"<0");
+		if (j<0) throw new RuntimeException("Out of bounds in swap("+i+","+j+"): "+j+"<0");
+		if (i>=getValueCount()) throw new RuntimeException("Out of bounds in swap("+i+","+j+"), "+i+">= value count");
+		if (j>=getValueCount()) throw new RuntimeException("Out of bounds in swap("+i+","+j+"), "+j+">= value count");
+
+		this.operations.add(new Swap(i, j));
+
+		this.readCount+=2;
+		this.writeCount+=2;
+
+		exchangeValues(i,j);
+	}
+
+	/**
+	 * Exchange the value of the case number i with the value of the case number j<br>
+	 * It doesn't increase the read or the write counters.
+	 * @param i the index of the first cell concerned
+	 * @param j the index of the second cell concerned
+	 */
+	private void exchangeValues(int i, int j) {
+		int tmp = this.values[i];
+		this.values[i] = this.values[j];
+		this.values[j] = tmp;
+	}
+
+}
diff --git a/src/plm/universe/sort/SortingWorldView.java b/src/plm/universe/sort/SortingWorldView.java
new file mode 100644
index 0000000..8a6f755
--- /dev/null
+++ b/src/plm/universe/sort/SortingWorldView.java
@@ -0,0 +1,335 @@
+package plm.universe.sort;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.Rectangle2D;
+import java.util.Locale;
+
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+
+import org.xnap.commons.i18n.I18n;
+import org.xnap.commons.i18n.I18nFactory;
+
+import plm.core.HumanLangChangesListener;
+import plm.core.model.Game;
+import plm.core.ui.WorldView;
+import plm.universe.World;
+
+class SortingViewActionListener implements ActionListener, HumanLangChangesListener {
+	private JMenuItem item;
+	private SortingWorldView view;
+	private I18n i18n;
+
+	public SortingViewActionListener(JMenuItem i, SortingWorldView v) {
+		item=i;
+		view=v;
+		Game.getInstance().addHumanLangListener(this);
+		currentHumanLanguageHasChanged(item.getLocale());
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		view.setUseStateView(!view.isUseStateView());
+		currentHumanLanguageHasChanged(item.getLocale());
+		view.repaint();
+	}
+
+	@Override
+	public void currentHumanLanguageHasChanged(Locale newLang) {
+		i18n = I18nFactory.getI18n(getClass(),"org.plm.i18n.Messages", newLang, I18nFactory.FALLBACK);
+		if (view.isUseStateView()) {
+			item.setText(i18n.tr("Switch to time view"));
+		} else {
+			item.setText(i18n.tr("Switch to state view"));
+		}
+	}
+	
+	
+}
+
+
+public class SortingWorldView extends WorldView {
+	private static final long serialVersionUID = 1L;
+	private JPopupMenu popup = new JPopupMenu();
+	private boolean useStateView = true; // chronoView if false
+
+	public SortingWorldView(World w) {
+		super(w);
+		JMenuItem menuItem;
+
+		//Create the popup menu allowing to switch between views
+		menuItem = new JMenuItem("Switch to time view");
+		menuItem.addActionListener(new SortingViewActionListener(menuItem,this));
+		popup.add(menuItem);
+
+		//Connect it as contextual menu to this pane
+		MouseListener popupListener = new MouseAdapter() {
+			private void maybeShowPopup(MouseEvent e) {
+				if (e.isPopupTrigger()) {
+					popup.show(e.getComponent(),
+							e.getX(), e.getY());
+				}
+			}
+
+			public void mousePressed(MouseEvent e) {
+				maybeShowPopup(e);
+			}
+
+			public void mouseReleased(MouseEvent e) {
+				maybeShowPopup(e);
+			}
+		};
+		this.addMouseListener(popupListener);
+	}
+
+	/**
+	 * Draw the Chrono view
+	 * @param g2 some 2D graphics
+	 * @param we the sorting world considered
+	 */
+	private void drawAlgoChrono(Graphics2D g2, SortingWorld we) {
+		int operationsAmount = we.getOperations().size();	// little optimization
+		/* getWidth()-12 to keep the room to display the very left value. Do that even if we don't depict them */
+		float stepX = ((float)getWidth()-12) / ((float)(Math.max(operationsAmount, 1)));
+		float stepY = ((float)getHeight()) / ((float)(we.getValueCount()));
+		int x1, y1, x2, y2, tone;
+
+		// If the array is small enough, we print the values
+		boolean drawStr = (stepX > 12) && (stepY>12);
+		
+		// Case without any operation to draw: initial view
+		if (operationsAmount == 0) {
+
+			for (int valueIdx = 0; valueIdx < we.getValueCount(); valueIdx++) { 
+				y1 = (int) (valueIdx * stepY + stepY/2.);
+
+				tone = (int) ((((float) we.getValues()[valueIdx]) / ((float) we.getValueCount())) * 255.);
+				g2.setColor(new Color(tone, tone, 128));
+
+				g2.drawLine(0, y1, (int)stepX, y1);
+
+				//If the array is small enough, we print the values
+				if (drawStr) 
+					g2.drawString("" + we.getValues()[valueIdx], 0, y1);
+			}
+			return;
+		}
+
+		// Draw the values at the very left of the figure (in any case)
+		for (int valueIdx = 0; valueIdx < we.getValueCount(); valueIdx++) { 
+			y1 = (int) (valueIdx * stepY + stepY/2);
+			tone = getValueColor(we.getInitValues()[valueIdx],we.getValueCount());
+			g2.setColor(new Color(tone, tone, 128));
+			g2.drawString("" + we.getInitValues()[valueIdx], 0, y1);
+		}
+		
+		int[] valuesAfter = new int[we.getInitValues().length];
+		int[] valuesBefore = new int[we.getInitValues().length];
+		for (int i = 0; i < we.getInitValues().length; i++) { 
+			valuesBefore[i] = we.getInitValues()[i];
+			valuesAfter[i] = valuesBefore[i];
+		}
+		
+		// Case with several operations
+		for (int opIdx = 0; opIdx < operationsAmount; opIdx++) {
+			Operation op = we.getOperations().get(opIdx);
+
+			valuesAfter = op.run(valuesAfter);
+			
+			x1 = (int) (opIdx * stepX);
+			x2 = (int) (x1 + stepX);
+
+			/* Draw straight lines for unmodified values */
+			for (int valIdx=0; valIdx<we.getValueCount();valIdx++) {
+				y1 = (int) (valIdx * stepY + stepY/2);
+				
+				if ( op.getSource() != valIdx && op.getDestination() != valIdx) {							
+					tone = getValueColor(valuesAfter[valIdx],we.getValueCount());
+					g2.setColor(new Color(tone, tone, 128));
+					
+					g2.drawLine(x1, y1, x2, y1);
+				}
+			}
+			/* Write the values in their new position (if there is not too much values) */
+			if (drawStr) 
+				for (int valIdx=0; valIdx<we.getValueCount();valIdx++) { 
+					y1 = (int) (valIdx * stepY + stepY/2);
+					
+					tone = getValueColor(valuesAfter[valIdx],we.getValueCount());
+					g2.setColor(new Color(tone, tone, 128));
+					g2.drawString("" + valuesAfter[valIdx], x2, y1);		
+				}
+			
+			/* Draw the lines depicting the current operation */
+			if (op instanceof Swap ) { // op is a Swap
+//				System.out.println("Swap "+op.source+" <-> "+op.destination);
+				
+				// draw source->dest
+				y1 = (int) (op.getSource() * stepY + stepY/2);
+				y2 = (int) (op.getDestination() * stepY + stepY/2);
+				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
+				g2.setColor(new Color(tone, tone, 128));
+				g2.drawLine(x1, y1, x2, y2);
+
+				// draw dest->source
+				y1 = (int) (op.getDestination() * stepY + stepY/2);
+				y2 = (int) (op.getSource() * stepY + stepY/2);
+				tone = getValueColor(valuesAfter[op.getSource()],we.getValueCount());
+				g2.setColor(new Color(tone, tone, 128));
+				g2.drawLine(x1, y1, x2, y2);
+
+			} else if (op instanceof CopyVal) {
+//				System.out.println("Copy "+op.source+" -> "+op.destination);
+				
+				// draw the value being copied over
+				y1 = (int) (op.getSource() * stepY + stepY/2);
+				y2 = (int) (op.getDestination() * stepY + stepY/2);
+				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
+				g2.setColor(new Color(tone, tone, 128));
+				g2.drawLine(x1, y1, x2, y2);
+				
+				// draw the old value remaining the same
+				y1 = (int) (op.getSource() * stepY + stepY/2);
+				tone = getValueColor(valuesAfter[op.getDestination()],we.getValueCount());
+				g2.setColor(new Color(tone, tone, 128));
+				g2.drawLine(x1, y1, x2, y1);
+				
+			} else if (op instanceof SetVal) {
+//				System.out.println("Set "+op.source+" (to "+((SetVal)op).value+")");
+				if (drawStr || true) {
+					y1 = (int) (op.source * stepY + stepY/2);
+				
+					tone = getValueColor(valuesAfter[op.source],we.getValueCount());
+					g2.setColor(Color.red);
+					g2.drawString("" + valuesAfter[op.source]+"!", x2, y1);
+				}
+
+				/* Don't draw a line for the modified value, actually */
+			} else if (op instanceof GetVal) {
+//				System.out.println("Get "+((GetVal)op).position);
+				if (drawStr || true) {
+					int pos = ((GetVal) op).position;
+					y1 = (int) (pos * stepY + stepY/2);
+				
+					tone = getValueColor(valuesAfter[pos],we.getValueCount());
+					g2.setColor(Color.MAGENTA);
+					g2.drawString("" + valuesAfter[pos]+"?", x2, y1);
+				}
+			} else {
+				System.out.println("This operation is not depicted because that's a "+op.toString()+"; please report this bug.");
+			}
+			
+
+			for (int k = 0; k < valuesAfter.length; k++) 
+				valuesBefore[k] = valuesAfter[k];
+		}
+	}
+
+	/**
+	 * Draw the state view
+	 * @param g2 some graphics 2D 
+	 * @param world the sorting world considered
+	 * @param maxSize the max size for a rectangle ( which represents a data in the array ) 
+	 */
+	private void drawAlgoState(Graphics2D g2, SortingWorld world, int maxSize) {
+		double scale = ((double)getWidth())/world.getValues().length;
+		int[] values = world.getValues() ;
+		for (int i=0;i< values.length;i++) 
+		{
+			double height = ((double)values[i])*((double)maxSize)/ ((double)(world.getValueCount()-1));
+			Shape rect = new Rectangle2D.Double(scale*i, ((double)maxSize)- height,scale, height);
+
+			g2.setColor( values[i]==i ? Color.GREEN : Color.RED) ;
+
+			g2.fill(rect);
+
+			g2.setColor(Color.black);
+			g2.draw(rect);
+			if (scale > 20) 
+				g2.drawString(""+values[i], (int)scale*i+(int)scale/2, maxSize-2);
+		}
+		g2.setColor(Color.black);
+		g2.drawString(world.getName()+" ("+world.getWriteCount()+" write, "+world.getReadCount()+" read)", 0, 15);
+	}
+
+	/**
+	 * Decide which view we must draw ( state or chrono )
+	 */
+	public void paintComponent(Graphics g) {
+		if (useStateView) { // myExo is null during initialization
+			paintComponentState(g);
+		} else {
+			paintComponentChrono(g);			
+		}
+	}
+
+	/**
+	 * Paint the chrono view into a rectangle
+	 * @param g some graphics indicating where to draw
+	 */
+	private void paintComponentChrono(Graphics g) {
+		super.paintComponent(g);
+		Graphics2D g2 = (Graphics2D) g;
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+				RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setColor(Color.white);
+		g2.fill(new Rectangle2D.Double(0., 0., (double) getWidth(),
+				(double) getHeight()));
+
+		g2.setColor(Color.black);
+		g2.setFont(new Font("Monaco", Font.PLAIN, 12));
+
+		drawAlgoChrono(g2, (SortingWorld) world);
+	}
+
+	/**
+	 * Draw the state view into a rectangle
+	 * @param g some graphics indicating where to draw
+	 */
+	private void paintComponentState(Graphics g) {
+		super.paintComponent(g);
+		Graphics2D g2 = (Graphics2D) g;
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setColor(Color.white);
+		g2.fill(new Rectangle2D.Double(0.,0.,(double)getWidth(),(double)getHeight()));
+
+		g2.setFont(new Font("Monaco", Font.PLAIN, 12));
+
+		if (world.getEntityCount() > 1) 
+			System.err.println("Sorting World does not accept more than one entity anymore. Please fix your exercise.");
+		
+		int maxSize = getHeight();
+
+		drawAlgoState(g2, (SortingWorld) this.world, maxSize);
+	}
+
+	/**
+	 * Return the tone of the value. This tone is used by the chrono view, it's the color of a line.
+	 * @param value the value from which get the tone
+	 * @param valueCount the total amount of values in the array
+	 * @return the tone of the value 
+	 */
+	private int getValueColor(int value,int valueCount) {
+		return (int) ((((float) value) / ((float) valueCount)) * 255.);
+	}
+
+
+	/** Returns if we must use the state view ( else we must use the chrono view ) */
+	protected boolean isUseStateView() {
+		return useStateView;
+	}
+	protected void setUseStateView(boolean useStateView) {
+		this.useStateView = useStateView;
+	}
+
+}
diff --git a/src/plm/universe/sort/Swap.java b/src/plm/universe/sort/Swap.java
new file mode 100644
index 0000000..b917621
--- /dev/null
+++ b/src/plm/universe/sort/Swap.java
@@ -0,0 +1,30 @@
+package plm.universe.sort;
+
+public class Swap extends Operation {
+	
+	/**
+	 * Constructor of the class Swap
+	 * @param source the source of the operation
+	 * @param destination the destination of the operation
+	 */
+	public Swap(int source, int destination){
+		super(source,destination);
+	}
+
+	/**
+	 * Compute an operation on init
+	 * @param init the values on which compute the operation
+	 * @return the array passed as parameter, once the operation has been applied to it
+	 */
+	@Override
+	public int[] run(int[] init) {
+		int src = init[source];
+		int dest = init[destination];
+		init[source] = dest;
+		init[destination] = src;
+		
+		return init;
+	}
+	
+	
+}
diff --git a/src/plm/universe/sort/package-info.java b/src/plm/universe/sort/package-info.java
new file mode 100644
index 0000000..b253079
--- /dev/null
+++ b/src/plm/universe/sort/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Universe to explore the classical sorting algorithms
+ */
+
+package plm.universe.sort;
+
diff --git a/src/plm/universe/turtles/Circle.java b/src/plm/universe/turtles/Circle.java
new file mode 100644
index 0000000..00959f8
--- /dev/null
+++ b/src/plm/universe/turtles/Circle.java
@@ -0,0 +1,57 @@
+package plm.universe.turtles;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+
+public class Circle implements Shape {
+	double x,y,radius;
+	Color color;
+	public Circle(double x,double y, double radius, Color color) {
+		this.x = x;
+		this.y = y;
+		this.radius = radius;
+		this.color = color;
+	}
+	@Override
+	public void draw(Graphics2D g) {
+		g.setColor(color);
+		g.drawOval((int) (x-radius), (int) (y-radius), (int) (2.*radius), (int) (2.*radius));
+	}
+	@Override
+	public Shape copy() {
+		return new Circle(x, y, radius, color);
+	}
+	private boolean doubleEqual(double a, double b) {
+		return (Math.abs(a-b)<0.000001);
+	}
+	@Override
+	public String diffTo(Shape o) {
+		if (o instanceof Circle) {
+			Circle other = (Circle) o;
+			if (!doubleEqual(x,other.x))
+				return "x differs";
+			if (!doubleEqual(y,other.y))
+				return "y differs";
+			if (!doubleEqual(radius,other.radius))
+				return "radius differs";
+			return "I dont see the difference";
+		} else 
+			return "That's not a line";
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (! (obj instanceof Circle))
+			return false;
+		
+		Circle other = (Circle) obj;
+		if (!doubleEqual(x,other.x))
+			return false;
+		if (!doubleEqual(y,other.y))
+			return false;
+		if (!doubleEqual(radius,other.radius))
+			return false;
+				
+		return true;
+	}
+
+}
diff --git a/src/plm/universe/turtles/Direction.java b/src/plm/universe/turtles/Direction.java
new file mode 100644
index 0000000..8de3168
--- /dev/null
+++ b/src/plm/universe/turtles/Direction.java
@@ -0,0 +1,7 @@
+package plm.universe.turtles;
+
+public enum Direction {
+
+	EAST, NORTH, WEST, SOUTH;
+
+}
diff --git a/src/plm/universe/turtles/Line.java b/src/plm/universe/turtles/Line.java
new file mode 100644
index 0000000..19ffbc1
--- /dev/null
+++ b/src/plm/universe/turtles/Line.java
@@ -0,0 +1,69 @@
+package plm.universe.turtles;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Line2D;
+
+
+public class Line implements Shape {
+	public double x1, y1,  x2, y2;
+	public Color color;
+	
+	public Line(double x1, double y1, double x2, double y2, Color color) {
+		this.x1 = x1;
+		this.y1 = y1;
+		this.x2 = x2;
+		this.y2 = y2;
+		this.color = color;
+	}
+	
+	public void draw(Graphics2D g){
+		g.setColor(color);
+		g.draw(new Line2D.Double(x1,y1,x2,y2));
+	}
+
+	public Line copy() {
+		return new Line(x1,y1,x2,y2,color);
+	}
+	private boolean doubleEqual(double a, double b) {
+		return (Math.abs(a-b)<0.000001);
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (! (obj instanceof Line))
+			return false;
+		
+		Line other = (Line) obj;
+		if (!doubleEqual(x1,other.x1))
+			return false;
+		if (!doubleEqual(x2,other.x2))
+			return false;
+		if (!doubleEqual(y1,other.y1))
+			return false;
+		if (!doubleEqual(y2,other.y2))
+			return false;
+				
+		return true;
+	}
+	public String diffTo(Shape o) {
+		if (o instanceof Line) {
+			Line other = (Line) o;
+			if (!doubleEqual(x1,other.x1))
+				return "x1 differs";
+			if (!doubleEqual(x2,other.x2))
+				return "x2 differs";
+			if (!doubleEqual(y1,other.y1))
+				return "y1 differs";
+			if (!doubleEqual(y2,other.y2))
+				return "y2 differs";
+			return "I dont see the difference";
+		} else 
+			return "That's not a line";
+	}
+	
+	@Override
+	public String toString(){
+		return "Line ("+x1+","+y1+";"+x2+","+y2+";"+color+")";
+	}
+}
diff --git a/src/plm/universe/turtles/Shape.java b/src/plm/universe/turtles/Shape.java
new file mode 100644
index 0000000..349df1e
--- /dev/null
+++ b/src/plm/universe/turtles/Shape.java
@@ -0,0 +1,9 @@
+package plm.universe.turtles;
+
+import java.awt.Graphics2D;
+
+public interface Shape {
+	public void draw(Graphics2D g);
+	public Shape copy();
+	public String diffTo(Shape o);
+}
diff --git a/src/plm/universe/turtles/SizeHint.java b/src/plm/universe/turtles/SizeHint.java
new file mode 100644
index 0000000..b65277a
--- /dev/null
+++ b/src/plm/universe/turtles/SizeHint.java
@@ -0,0 +1,71 @@
+package plm.universe.turtles;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+
+public class SizeHint implements ImageObserver {
+	double x1, y1,  x2, y2;
+	static Color color = new Color(255,160,0);
+	String text;
+	public SizeHint(double x1, double y1, double x2, double y2, String msg) {
+		this.x1 = x1;
+		this.y1 = y1;
+		this.x2 = x2;
+		this.y2 = y2;
+		if (msg != null)
+			text = msg;
+		else 
+			text = String.format("%.0f", Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
+	}
+	public void draw(Graphics2D g2) {
+		g2.setColor(color);
+		
+		g2.draw(new Line2D.Double(x1,y1,x2,y2));
+		
+		int cx = (int) ((x1+x2)/2.);
+		int cy = (int) ((y1+y2)/2.);
+		
+		double hyp = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
+		double theta = Math.acos((y2-y1)/hyp) - Math.PI/2;
+		
+		drawString(g2, text, cx, cy, theta);
+		
+	}
+    private BufferedImage createStringImage(Graphics g, String msg) {
+        int w = g.getFontMetrics().stringWidth(msg) + 5;
+        int h = g.getFontMetrics().getHeight();
+
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D imageGraphics = image.createGraphics();
+        imageGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        imageGraphics.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+        imageGraphics.setColor(color);
+        imageGraphics.setFont(g.getFont());
+        imageGraphics.drawString(msg, 0, h - g.getFontMetrics().getDescent());
+        imageGraphics.dispose();
+
+        return image;
+    }
+    private void drawString(Graphics2D g2, String s, double tx, double ty, double theta) {
+    	BufferedImage img = createStringImage(g2, s); 
+        AffineTransform aff = AffineTransform.getTranslateInstance(-((double)img.getWidth() )/2, -((double)img.getHeight() )/2);
+        aff.rotate(theta, tx+((double)img.getWidth() )/2, ty+((double)img.getHeight() )/2);
+        aff.translate(tx, ty);
+
+        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+        g2.drawImage(img, aff, this);
+    }
+	@Override
+	public boolean imageUpdate(Image img, int infoflags, int x, int y,
+			int width, int height) {
+		// TODO Auto-generated method stub
+		return false;
+	}
+}
diff --git a/src/plm/universe/turtles/Turtle.java b/src/plm/universe/turtles/Turtle.java
new file mode 100644
index 0000000..d6cae36
--- /dev/null
+++ b/src/plm/universe/turtles/Turtle.java
@@ -0,0 +1,426 @@
+package plm.universe.turtles;
+
+import java.awt.Color;
+
+import plm.universe.Entity;
+import plm.universe.World;
+import plm.universe.bugglequest.BuggleWorld;
+
+public class Turtle extends Entity {
+
+	public final static int DEGREE = 1;
+	public final static int RADIAN = 2;
+	public static final double EPSILON = .0000001;
+
+	private Color color;
+
+	private double x = 0.;
+	private double y = 0.;
+
+	protected double startX,startY;
+	
+	private double heading = 0.;
+	private boolean penDown = true;
+	private int angularUnit = Turtle.DEGREE;
+
+	/**
+	 * Constructor with no argument so that child classes can avoid declaring a
+	 * constructor. But it should not be used as most methods assert on world
+	 * being not null. After using it, {@link Entity#setWorld(BuggleWorld)} must be
+	 * used ASAP.
+	 */
+	public Turtle() {
+		this(null, "John Doe", 0., 0., 0., Color.black);
+	}
+
+	public Turtle(World w) {
+		this(w, "John Doe", 0., 0., 0., Color.black);
+	}
+
+	public Turtle(World w, String name) {
+		this(w, name, 0., 0., 0., Color.red);
+	}
+
+	public Turtle(World w, String name, double x, double y) {
+		this(w, name, x, y, 0., Color.black);
+	}
+
+	public Turtle(World world, String name, double x, double y, double heading, Color c) {
+		super(name, world);
+		this.color = c;
+		this.x = x;
+		this.y = y;
+		this.startX = x;
+		this.startY = y;
+		this.heading = heading;
+		setHeading(heading);
+	}
+
+	public Turtle(Turtle t) {
+		super();
+		setName(t.getName());
+		setWorld(t.getWorld());
+		this.color = t.color;
+		this.x = t.x;
+		this.y = t.y;
+		this.startX = t.startX;
+		this.startY = t.startY;
+		this.heading = t.heading;
+		this.penDown = t.penDown;
+	}
+
+	@Override
+	public void copy(Entity e) {
+		super.copy(e);
+		Turtle other = (Turtle) e;
+		this.color = other.color;
+		this.x = other.x;
+		this.y = other.y;
+		this.startX = other.startX;
+		this.startY = other.startY;
+		this.heading = other.heading;
+		this.penDown = other.penDown;
+	}
+
+	@Override
+	public Entity copy() {
+		return new Turtle(this);
+	}
+
+	public void forward(double dist) {
+		moveTo(x + dist * Math.cos(heading), y + dist * Math.sin(heading));
+	}
+
+	public void backward(double dist) {
+		moveTo(x + dist * Math.cos(heading + Math.PI), y + dist * Math.sin(heading + Math.PI));
+	}
+	
+	public Direction getHeadingDirection() {
+		final double w = getWorld().getWidth();
+		final double h = getWorld().getHeight();
+		final double angleHeading = 2*Math.PI - this.heading;
+		
+		if (this.heading >=0 && this.heading < Math.PI) {
+			// bottom half-circle
+			final double tangenteAngleToBottomLeftCorner = (this.x>EPSILON)?((h-this.y) / this.x):Double.POSITIVE_INFINITY;
+			final double angleToBottomLeftCorner = Math.PI+Math.atan(tangenteAngleToBottomLeftCorner);
+			final double tangenteAngleToBottomRightCorner = ((w-this.x)>EPSILON)?((h-this.y) / (w-this.x)):Double.POSITIVE_INFINITY;
+			final double angleToBottomRightCorner = 2*Math.PI-Math.atan(tangenteAngleToBottomRightCorner);
+
+			if (angleHeading < angleToBottomLeftCorner) {
+				return Direction.WEST;
+			} else if (angleHeading < angleToBottomRightCorner) {
+				return Direction.SOUTH;
+			} else {
+				return Direction.EAST;
+			}
+		} else {
+			// bottom half-circle			
+			final double tangenteAngleToTopRightCorner = ((w-this.x)>EPSILON)?((this.y) / (w-this.x)):Double.POSITIVE_INFINITY;
+			final double angleToTopRightCorner = Math.atan(tangenteAngleToTopRightCorner);
+			final double tangenteAngleToTopLeftCorner = (this.x>EPSILON)?(this.y / this.x):Double.POSITIVE_INFINITY;
+			final double angleToTopLeftCorner = Math.PI-Math.atan(tangenteAngleToTopLeftCorner);
+					
+			if (angleHeading < angleToTopRightCorner) {
+				return Direction.EAST;
+			} else if (angleHeading < angleToTopLeftCorner) {
+				return Direction.NORTH;
+			} else {
+				return Direction.WEST;
+			}
+		}
+	}
+	public void circle(double radius) {
+		if (penDown)
+			getWorld().addCircle(x, y, radius, color);
+	}
+	
+	public void moveTo(double newX, double newY) {
+		final double w = this.getWorld().getWidth();
+		final double h = this.getWorld().getHeight();
+		
+		double nX = newX;
+		double nY = newY;
+		
+		while (nX < 0 || nX >= w || nY < 0 || nY >= h) { // need to clip			
+			// line equation y = y1+m(x-x1)
+			// where m=(y2-y1)/(x2-x1)
+			final double m = (nY - y) / (nX - x);
+	
+			switch (this.getHeadingDirection()) {
+			case EAST:
+				// intersection with the right boundary (x=r)
+				// x=r and y=y1+m(r-x1)
+				{
+					final double xc = w;
+					final double yc = y + m * (w - x);
+
+					if (this.penDown) {
+						this.getWorld().addLine(x, y, xc, yc, color);
+					}
+					setPos(0., yc);
+					nX = nX - w;
+				}
+				break;
+			case NORTH:
+				// intersection with the top boundary (y=t)
+				// x=(1/m)(t-y1)+x1 and y=t
+				{
+					final double xc = (0 - this.y) / m + this.x;
+					final double yc = 0;
+
+					if (this.penDown) {
+						this.getWorld().addLine(x, y, xc, yc, color);
+					}
+					setPos(xc, h);
+					nY = nY + h;
+				}
+				break;
+			case WEST:
+				// intersection with the left boundary (x=l)
+				// x=l and y=y1+m(l-x1)
+				{
+					final double xc = 0;
+					final double yc = y + m * (0 - x);
+
+					if (this.penDown) {
+						this.getWorld().addLine(x, y, xc, yc, color);
+					}
+					setPos(w, yc);
+					nX = nX + w;
+				}
+				break;
+			case SOUTH:
+				// intersection with the top boundary (y=t)
+				// x=(1/m)(t-y1)+x1 and y=t
+				{
+					final double xc = (h - this.y) / m + this.x;
+					final double yc = h;
+
+					if (this.penDown) {
+						this.getWorld().addLine(x, y, xc, yc, color);
+					}
+					setPos(xc, 0.);
+					nY = nY - h;
+				}
+				break;			
+			}	
+		} 
+		
+		if (this.penDown) {
+			this.getWorld().addLine(x, y, nX, nY, color);
+		}			
+		this.x = nX;
+		this.y = nY;		
+		
+		stepUI();
+	}
+
+	public void left(double angle) {
+		setHeadingRadian(heading - fromAngularUnit(angle));
+	}
+
+	public void right(double angle) {
+		setHeadingRadian(heading + fromAngularUnit(angle));
+	}
+
+	public boolean isPenDown() {
+		return penDown;
+	}
+
+	public void penDown() {
+		this.penDown = true;
+	}
+
+	public void penUp() {
+		this.penDown = false;
+	}
+
+	private double fromAngularUnit(double angle) {
+		switch (angularUnit) {
+		case Turtle.DEGREE:
+			return Math.toRadians(angle);
+		case Turtle.RADIAN:
+			return angle;
+		}
+		throw new RuntimeException("Unknown angular unit:" + angularUnit + " (please report this bug)");
+	}
+
+	private final double toAngularUnit(double angle) {
+		switch (angularUnit) {
+		case Turtle.DEGREE:
+			return Math.toDegrees(angle);
+		case Turtle.RADIAN:
+			return angle;
+		}
+		throw new RuntimeException("Unknown angular unit:" + angularUnit + " (please report this bug)");
+	}
+
+	public double getHeading() {
+		return toAngularUnit(heading);
+	}
+
+	public void setHeading(double heading) {
+		setHeadingRadian(fromAngularUnit(heading));
+	}
+
+	protected void setHeadingRadian(double heading) {
+		this.heading = ((2. * Math.PI) + heading) % (2. * Math.PI);
+		if (world != null)
+			world.notifyWorldUpdatesListeners();
+	}
+	
+	protected double getHeadingRadian() {
+		return this.heading;
+	}
+
+	@Override
+	public TurtleWorld getWorld() {
+		return (TurtleWorld) super.getWorld();
+	}
+	
+	public Color getColor() {
+		return color;
+	}
+
+	public void setColor(Color c) {
+		color = c;
+	}
+
+	public double getX() {
+		return x;
+	}
+
+	public void setX(double x) {
+		this.x = x;
+		stepUI();
+	}
+
+	public double getY() {
+		return y;
+	}
+
+	public void setY(double y) {
+		this.y = y;
+		stepUI();
+	}
+
+	public void setPos(double x, double y) {
+		this.x = x;
+		this.y = y;
+		stepUI();
+	}
+
+	/* let's accept integers as arguments, too */
+	public void forward(int steps) {
+		forward((double) steps);
+	}
+
+	public void backward(int steps) {
+		backward((double) steps);
+	}
+
+	public void left(int a) {
+		left((double) a);
+	}
+
+	public void right(int a) {
+		right((double) a);
+	}
+
+	public void setHeading(int heading) {
+		setHeading((double) heading);
+	}
+
+	public void setX(int x) {
+		setX((double) x);
+	}
+
+	public void setY(int y) {
+		setY((double) y);
+	}
+
+	public void setPos(int x, int y) {
+		setPos((double) x, (double) y);
+	}
+
+	public void setPos(double x, int y) {
+		setPos((double) x, (double) y);
+	}
+
+	public void setPos(int x, double y) {
+		setPos((double) x, (double) y);
+	}
+	
+	public void addSizeHint(int x1, int y1, int x2, int y2,String txt){
+		((TurtleWorld) world).addSizeHint(x1,y1,x2,y2,txt);
+	}
+	public void addSizeHint(int x1, int y1, int x2, int y2){
+		((TurtleWorld) world).addSizeHint(x1,y1,x2,y2,null);
+	}
+	
+	@Override
+	public String toString() {
+		return "Turtle (" + this.getClass().getName() + "): x=" + x + " y=" + y + " Heading:" + heading + " Color:"
+				+ color;
+	}
+
+	@Override
+	public int hashCode() {
+		final int PRIME = 31;
+		int result = 1;
+		result = PRIME * result + ((color == null) ? 0 : color.hashCode());
+		result = PRIME * result + (penDown ? 1231 : 1237);
+		result = PRIME * result + (int) heading;
+		result = PRIME * result + (int) x;
+		result = PRIME * result + (int) y;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!(obj instanceof Turtle))
+			return false;
+
+		final Turtle other = (Turtle) obj;
+		if (color == null) {
+			if (other.color != null)
+				return false;
+		} else if (!color.equals(other.color))
+			return false;
+		if (Math.abs(heading-other.heading) > Turtle.EPSILON)
+			return false;
+		if (Math.abs(x-other.x) > Turtle.EPSILON)
+			return false;
+		if (Math.abs(y-other.y) > Turtle.EPSILON)
+			return false;
+		return true;
+	}
+
+	@Override
+	public void run() {
+		// Overriden by childs
+	}
+
+	/* BINDINGS TRANSLATION: French */
+	public void avance(double steps) { forward(steps); }
+	public void recule(double steps) { backward(steps); }
+	public void gauche(double angle) { left(angle); }
+	public void droite(double angle) { right(angle); }
+	public void cercle(double radius){ circle(radius); }
+	// get/set X/Y/Pos are not translated as they happen to be the same in French
+	public void allerVers(double x, double y) {moveTo(x,y);}
+	public double getCap()           { return getHeading(); }
+	public void setCap(double cap)   { setHeading(cap);     }
+	public void leveCrayon()         { penUp(); }
+	public void baisseCrayon()       { penDown(); }
+	public boolean estCrayonBaisse() { return isPenDown();}
+	public Color getCouleur()        { return getColor(); }
+	public void setCouleur(Color c)  { setColor(c); }
+	public boolean estChoisi()       { return isSelected(); } // we have to document the version without e, since po4a allows for one variant only
+	public boolean estChoisie()      { return isSelected(); } // But we want to have the grammatically correct form also possible (turtles are feminine)
+}
diff --git a/src/plm/universe/turtles/TurtleButtonPanel.java b/src/plm/universe/turtles/TurtleButtonPanel.java
new file mode 100644
index 0000000..2e1a791
--- /dev/null
+++ b/src/plm/universe/turtles/TurtleButtonPanel.java
@@ -0,0 +1,28 @@
+package plm.universe.turtles;
+
+import javax.swing.JLabel;
+import javax.swing.JTextArea;
+
+import plm.universe.EntityControlPanel;
+import net.miginfocom.swing.MigLayout;
+
+public class TurtleButtonPanel extends EntityControlPanel {
+
+	private static final long serialVersionUID = 1L;
+	JLabel lForward;
+	JTextArea taForward;
+	
+	public TurtleButtonPanel() {
+		setLayout(new MigLayout());
+		//lForward = new JLabel("Forward");
+		//taForward = new JTextArea();
+		//add(lForward);
+		//add(taForward,"wrap");	
+	}
+
+	@Override
+	public void setEnabledControl(boolean enabled) {
+		//lForward.setEnabled(enabled);
+		//taForward.setEnabled(enabled);
+	}
+}
diff --git a/src/plm/universe/turtles/TurtleWorld.fr.html b/src/plm/universe/turtles/TurtleWorld.fr.html
new file mode 100644
index 0000000..716c17d
--- /dev/null
+++ b/src/plm/universe/turtles/TurtleWorld.fr.html
@@ -0,0 +1,65 @@
+<h1>L'univers des tortues</h1>
+
+<p>Cet univers est une adaptation de LOGO pour la Java Learning Machine.</p>
+
+<p>Il est directement inspiré des travaux du mathématicien Seymour Papert dans
+les années 60. Inspiré par le psychologue suisse Jean Piaget, il a inventé
+une méthode d'apprentissage de la programmation accessible aux jeunes
+enfants nommée LOGO. Le monde est peuplé de tortues qui laissent une trace
+là où elles marchent et à qui on peut donner des ordres simples.</p>
+
+<h2>Fonctions pour déplacer la tortue</h2>
+
+<pre>[!java]void [/!]avance([!java]double [/!]steps[!scala]:Double[/!])
+[!java]void [/!]recule([!java]double [/!]steps[!scala]:Double[/!])</pre>
+Avance ou recule du nombre de pas demandé.
+
+<pre>[!java]void [/!]droite([!java]double [/!]angle[!scala]:Double[/!])
+[!java]void [/!]gauche([!java]double [/!]angle[!scala]:Double[/!])</pre>
+Tourne à gauche ou à droite de l'angle indiqué (en degrés).
+
+<pre>[!java]double [/!]getX()[!scala]:Double[/!]
+[!java]double [/!]getY()[!scala]:Double[/!]</pre>
+Retourne la position acutelle de la tortue.
+
+<pre>[!java]void [/!]setX([!java]double [/!]x[!scala]:Double[/!])
+[!java]void [/!]setY([!java]double [/!]y[!scala]:Double[/!])
+[!java]void [/!]setPos([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</pre>
+Téléporte la tortue à une nouvelle position (sans laisser de trace).
+
+<pre>[!java]void [/!]allerVers([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</pre>
+Déplace la tortue à une nouvelle position.
+
+<pre>[!java]void [/!]cercle([!java]double [/!]rayon[!scala]:Double[/!])</pre>
+Dessine un cercle du rayon demandé et centré sur la tortue.
+
+<pre>[!java]double [/!]getCap()[!scala]:Double[/!]</pre>
+Retourne le cap actuel de la tortue (en degrés).
+
+<pre>[!java]void [/!]setCap([!java]double [/!]angle[!scala]:Double[/!])</pre>
+Change le cap de la tortue à l'angle indiqué (en degrés).
+
+<h2>Fonctions à propos du stylo</h2>
+
+<pre>[!java]void [/!]leveCrayon()</pre>
+Remonte le crayon de la tortue (les tortues ont des crayons, pas des brosses
+comme les buggles). La tortue ne laissera plus de trace lors de ses
+déplacements suivants.
+
+<pre>[!java]void [/!]baisseCrayon()</pre>
+Descend le stylo. La tortue laissera une trace lors de ses prochains
+déplacements.
+
+<pre>[!java]boolean [/!]estCrayonBaisse()[!scala]:Boolean[/!]</pre>
+Retourne si le stylo est actuellement baissé ou non.
+
+<pre>[!java]Color [/!]getCouleur()[!scala]:Color[/!]</pre>
+Retourne la couleur actuelle du stylo.
+
+<pre>[!java]void [/!]setCouleur([!java]Color [/!]couleur[!scala]:Color[/!])</pre>
+Modifier la couleur du stylo.
+
+<h2>Autres fonctions</h2>
+
+<pre>[!java]boolean [/!]estChoisie()[!scala]:Boolean[/!]</pre>
+Renvoie si la tortue actuelle est sélectionnée dans l'interface graphique.
diff --git a/src/plm/universe/turtles/TurtleWorld.html b/src/plm/universe/turtles/TurtleWorld.html
new file mode 100644
index 0000000..2458712
--- /dev/null
+++ b/src/plm/universe/turtles/TurtleWorld.html
@@ -0,0 +1,63 @@
+<h1>The universe of turtles</h1>
+
+<p>This is an adaptation of LOGO for the Java Learning Machine.</p>
+
+<p>It is directly inspired from the work of the mathematician Seymour
+Papert in the 60's. Inspired from the swiss psycholog Jean Piaget, he came
+up with a learning method called LOGO to teach programming to young
+childs. The world is full of turtles which leave a painting where they go
+and which respond to simple orders.</p>
+
+<h2>Functions to move the turtle</h2>
+
+<pre>[!java]void [/!]forward([!java]double [/!]steps[!scala]:Double[/!])
+[!java]void [/!]backward([!java]double [/!]steps[!scala]:Double[/!])</pre>
+Moves forward or backward of the requested amount of steps.
+
+<pre>[!java]void [/!]right([!java]double [/!]angle[!scala]:Double[/!])
+[!java]void [/!]left([!java]double [/!]angle[!scala]:Double[/!])</pre>
+Turns left or right of the given angle (in degrees).
+
+<pre>[!java]double [/!]getX()[!scala]:Double[/!]
+[!java]double [/!]getY()[!scala]:Double[/!]</pre>
+Returns the current position of the turtle.
+
+<pre>[!java]void [/!]setX([!java]double [/!]x[!scala]:Double[/!])
+[!java]void [/!]setY([!java]double [/!]y[!scala]:Double[/!])
+[!java]void [/!]setPos([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</pre>
+Teleports the turtle to a new position (without leaving any trace).
+
+<pre>[!java]void [/!]moveTo([!java]double [/!]x[!scala]:Double[/!], [!java]double [/!]y[!scala]:Double[/!])</pre>
+Moves the turtle to a new position.
+
+<pre>[!java]void [/!]circle([!java]double [/!]radius[!scala]:Double[/!])</pre>
+Draw a circle of the specified radius centered on the turtle.
+
+<pre>[!java]double [/!]getHeading()[!scala]:Double[/!]</pre>
+Returns the current heading of the turtle (in degrees).
+
+<pre>[!java]void [/!]setHeading([!java]double [/!]angle[!scala]:Double[/!])</pre>
+Sets a new heading to the turtle (in degrees).
+
+<h2>Functions about the pen</h2>
+
+<pre>[!java]void [/!]penUp()</pre>
+Moves the pen up (turtles have pens, not brushes as buggles). The
+turtle will not leave any trace during its subsequent moves.
+
+<pre>[!java]void [/!]penDown()</pre>
+Moves the pen down. The turtle will leave a trace during its subsequent moves.
+
+<pre>[!java]boolean [/!]isPenDown()[!scala]:Boolean[/!]</pre>
+Returns the current pen position as a boolean.
+
+<pre>[!java]Color [/!]getColor()[!scala]:Color[/!]</pre>
+Returns the current pen color.
+
+<pre>[!java]void [/!]setColor([!java]Color [/!]color[!scala]:Color[/!])</pre>
+Changes the pen color.
+
+<h2>Other functions</h2>
+
+<pre>[!java]boolean [/!]isSelected()[!scala]:Boolean[/!]</pre>
+Returns whether the current turtle is selected in the graphical interface.
diff --git a/src/plm/universe/turtles/TurtleWorld.java b/src/plm/universe/turtles/TurtleWorld.java
new file mode 100644
index 0000000..f020f67
--- /dev/null
+++ b/src/plm/universe/turtles/TurtleWorld.java
@@ -0,0 +1,278 @@
+package plm.universe.turtles;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.model.ProgrammingLanguage;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.Entity;
+import plm.universe.EntityControlPanel;
+import plm.universe.World;
+
+public class TurtleWorld extends World {
+
+	ArrayList<Shape> shapes = new ArrayList<Shape>();
+	ArrayList<SizeHint> sizeHints = new ArrayList<SizeHint>();
+
+	private double width;
+	private double height;
+	
+	public TurtleWorld(String name) {
+		super(name);
+	}
+
+	public TurtleWorld(String name, int width, int height) {
+		super(name);
+		this.width = width;
+		this.height = height;
+	}
+	
+	public TurtleWorld(TurtleWorld original) {
+		super(original);
+		sizeHints = new ArrayList<SizeHint>();
+		for (SizeHint sh :original.sizeHints)
+			sizeHints.add(sh);
+		for (Entity e: getEntities()){
+			Turtle t = (Turtle) e;
+			t.startX = t.getX();
+			t.startY = t.getY();
+		}
+	}
+
+	@Override
+	public void reset(World w) {
+		TurtleWorld initialWorld = (TurtleWorld)w;
+		shapes = new ArrayList<Shape>();
+		this.height = initialWorld.height;
+		this.width = initialWorld.width;
+
+		Iterator<Shape> it = initialWorld.shapes();
+		while (it.hasNext()) 
+			shapes.add(it.next().copy());
+		
+		sizeHints = new ArrayList<SizeHint>();
+		for (SizeHint sh : initialWorld.sizeHints)
+			sizeHints.add(sh);
+		
+		super.reset(w);		
+	}
+	
+	public void addSizeHint(int x1, int y1, int x2, int y2) {
+		addSizeHint(x1, y1, x2, y2, null);
+	}
+	public void addSizeHint(int x1, int y1, int x2, int y2, String text) {
+		synchronized (sizeHints) {
+			sizeHints.add(new SizeHint(x1, y1, x2, y2, text));
+			notifyWorldUpdatesListeners();
+		}
+	}
+	public void addLine(double x, double y, double newX, double newY, Color color) {
+		synchronized (shapes) {
+			shapes.add(new Line(x,y,newX,newY,color));
+			notifyWorldUpdatesListeners();
+		}
+	}
+	public void addCircle(double x, double y, double radius, Color color) {
+		synchronized (shapes) {
+			shapes.add(new Circle(x,y,radius,color));
+			notifyWorldUpdatesListeners();
+		}
+	}
+
+	public Iterator<Shape> shapes() {
+		return shapes.iterator();
+	}
+	
+
+	public double getHeight() {
+		return height;
+	}
+	public double getWidth() {
+		return width;
+	}
+	
+	@Override
+	public EntityControlPanel getEntityControlPanel() {
+		return new TurtleButtonPanel();
+	}
+
+	@Override
+	public WorldView getView() {
+		return new TurtleWorldView(this);
+	}
+	@Override
+	public ImageIcon getIcon() {
+		return ResourcesCache.getIcon("img/world_turtle.png");
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (! (obj instanceof TurtleWorld))
+			return false;
+		if (! super.equals(obj))
+			return false;
+		
+		TurtleWorld other = (TurtleWorld) obj;
+		if (shapes.size() != other.shapes.size())
+			return false;
+		Collections.sort(shapes, new ShapeComparator());
+		Collections.sort(other.shapes, new ShapeComparator());
+		for (int i=0;i<shapes.size();i++)
+			if (! shapes.get(i).equals(other.shapes.get(i)))
+				return false;
+		
+		return true;
+	}
+	
+	// TODO implement world IO	
+	
+	@Override
+	public String toString(){
+		String res = "TurtleWorld: name="+getName()+
+			", size="+width+"x"+height+
+			", parameters: " +parameters+
+			", shapes=[";
+		Iterator<Shape> it = shapes();
+		while (it.hasNext()) 
+			res += it.next().toString();
+		res += "]";
+		return res;
+	}
+	@Override
+	public void setupBindings(ProgrammingLanguage lang, ScriptEngine e) throws ScriptException {
+		if (lang.equals(Game.PYTHON)) {
+			e.put("Color", Color.class);
+			e.eval( "def backward(i):\n"+
+					"  entity.backward(i)\n"+
+					"def forward(i):\n"+
+					"  entity.forward(i)\n"+
+					"def penUp():\n"+
+					"  entity.penUp()\n"+
+					"def penDown():\n"+
+					"  entity.penDown()\n"+
+					"def isPenDown():\n"+
+					"  return entity.isPenDown()\n"+
+					"def left(i):\n"+
+					"  entity.left(i)\n"+
+					"def right(i):\n"+
+					"  entity.right(i)\n"+
+					"def setColor(c):\n"+
+					"  entity.setColor(c)\n" +
+					"def getColor():\n"+
+					"  return entity.getColor()\n" +
+					"def setPos(x,y):\n" +
+					"  entity.setPos(x,y)\n" +
+					"def setX(x):\n" +
+					"  entity.setX(x)\n" +
+					"def setY(y):\n" +
+					"  entity.setY(y)\n" +
+					"def getX():\n" +
+					"  return entity.getX()\n" +
+					"def getY():\n" +
+					"  entity.getY()\n" +
+					"def moveTo(x,y):\n" +
+					"  entity.moveTo(x,y)\n"+
+					"def addSizeHint(x,y,z,t):\n"+
+					"  entity.addSizeHint(x,y,z,t)\n"+
+					"def circle(radius):\n"+
+					"  entity.circle(radius)\n"+
+					/* BINDINGS TRANSLATION: French */
+					"def recule(i):\n"+
+					"  entity.backward(i)\n"+
+					"def avance(i):\n"+
+					"  entity.forward(i)\n"+
+					"def leveCrayon():\n"+
+					"  entity.penUp()\n"+
+					"def baisseCrayon():\n"+
+					"  entity.penDown()\n"+
+					"def estCrayonBaisse():\n"+
+					"  return entity.isPenDown()\n"+
+					"def gauche(i):\n"+
+					"  entity.left(i)\n"+
+					"def droite(i):\n"+
+					"  entity.right(i)\n"+
+					"def setCouleur(c):\n"+
+					"  entity.setColor(c)\n" +
+					"def allerVers(x,y):\n" +
+					"  entity.moveTo(x,y)\n"+
+					"def cercle(radius):\n"+
+					"  entity.circle(radius)\n"
+					);
+		} else {
+			throw new RuntimeException("No binding of TurtleWorld for "+lang);
+		}
+	}
+
+	@Override
+	public String diffTo(World world) {
+		StringBuffer sb = new StringBuffer();
+		TurtleWorld other = (TurtleWorld) world;
+		if (shapes.size() != other.shapes.size())
+			sb.append("  There is only "+other.shapes.size()+" lines where "+shapes.size()+" were expected.\n");
+		for (int i=0;i<other.shapes.size();i++)
+			if (! other.shapes.get(i).equals(shapes.get(i)))
+				sb.append("  Got "+other.shapes.get(i)+" where "+shapes.get(i)+" were expected ("+
+						((Line) other.shapes.get(i)).diffTo(shapes.get(i))+")\n");
+		
+		return sb.toString();
+	}
+}
+
+class ShapeComparator implements Comparator<Shape> {
+
+	public ShapeComparator() {
+		super();
+	}
+
+	@Override
+	public int compare(Shape s1, Shape s2) {
+		if (s1 instanceof Line && s2 instanceof Circle)
+			return -1;
+		if (s1 instanceof Circle && s2 instanceof Line)
+			return 1;
+		
+		if (s1 instanceof Line) {
+			Line l1 = (Line) s1;
+			Line l2 = (Line) s2;
+			if (l1.x1 < l2.x1)
+				return -1;
+			if (l1.x1 > l2.x1)
+				return 1;
+
+			if (l1.x2 < l2.x2)
+				return -1;
+			if (l1.x2 > l2.x2)
+				return 1;
+
+			if (l1.y1 < l2.y1)
+				return -1;
+			if (l1.y1 > l2.y1)
+				return 1;
+
+			if (l1.y2 < l2.y2)
+				return -1;
+			if (l1.y2 > l2.y2)
+				return 1;
+			return 0;
+		}
+		if (s1 instanceof Circle) {
+			Circle c1 = (Circle) s1;
+			Circle c2 = (Circle) s2;
+			if (c1.x < c2.x)
+				return -1;
+			if (c1.x > c2.x)
+				return 1;
+		}
+		return 0;
+	}
+	
+}
diff --git a/src/plm/universe/turtles/TurtleWorldView.java b/src/plm/universe/turtles/TurtleWorldView.java
new file mode 100644
index 0000000..0cbde11
--- /dev/null
+++ b/src/plm/universe/turtles/TurtleWorldView.java
@@ -0,0 +1,93 @@
+package plm.universe.turtles;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Stroke;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.Iterator;
+
+import javax.swing.ImageIcon;
+
+import plm.core.model.Game;
+import plm.core.ui.ResourcesCache;
+import plm.core.ui.WorldView;
+import plm.universe.Entity;
+import plm.universe.World;
+
+public class TurtleWorldView extends WorldView {
+	private static final long serialVersionUID = 1674820378395646693L;
+	
+	public TurtleWorldView(World w) {
+		super(w);
+	}
+	
+	@Override
+	public void paintComponent(Graphics g) {
+		doPaint(g,getWidth(),getHeight(),true);
+	}
+	public void doPaint(Graphics g, int sizeX, int sizeY, boolean showTurtle) {
+		super.paintComponent(g);
+		Graphics2D g2 = (Graphics2D) g;
+		
+		TurtleWorld tw = (TurtleWorld) this.world;
+		
+		double ratio = Math.min(((double) sizeX)/tw.getWidth(), ((double)sizeY)/tw.getHeight());
+		g2.translate(Math.abs((sizeX-ratio*tw.getWidth())/2.), Math.abs((sizeY-ratio*tw.getHeight())/2.));
+		g2.scale(ratio, ratio);
+
+		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+		g2.setColor(Color.white);
+		g2.fill(new Rectangle2D.Double(0.,0.,(double)tw.getWidth(),(double)tw.getHeight()));
+		
+		g2.setColor(Color.BLACK);
+		Stroke oldStroke = g2.getStroke();
+	    g2.setStroke(new BasicStroke(1.0f,
+	                        BasicStroke.CAP_BUTT,
+	                        BasicStroke.JOIN_MITER,
+	                        10.0f, new float[]{2f,10.0f}, 0.0f));
+
+		if (Game.getInstance().isDebugEnabled()) {
+			for (int x=50;x<tw.getWidth();x+=50) 
+				g2.drawLine(x, 1, x, (int) tw.getHeight()-1);
+			for (int y=50;y<tw.getHeight();y+=50) 
+				g2.drawLine(1, y, (int)tw.getWidth()-1,y);
+		}
+		g2.setStroke(oldStroke);
+		
+		if (world.isAnswerWorld() || Game.getInstance().isDebugEnabled()) {
+			for (Entity e: world.getEntities()) {
+				Turtle t = (Turtle) e;
+				g2.setColor(SizeHint.color);
+				g2.fillOval((int)(t.startX-5), (int)(t.startY-5), 10, 10);
+			}
+				
+			synchronized (tw.sizeHints) {
+				for (SizeHint indic : tw.sizeHints)
+					indic.draw(g2);			
+			}
+		}
+		if (showTurtle)
+			for (Entity ent : world.getEntities())
+				drawTurtle(g2, (Turtle)ent);
+		
+		
+		synchronized (((TurtleWorld) world).shapes) {
+			Iterator<Shape> it2 = ((TurtleWorld) world).shapes();
+			while (it2.hasNext())
+				it2.next().draw(g2);			
+		}
+		
+		
+	}
+
+	private void drawTurtle(Graphics2D g, Turtle b) {
+		ImageIcon ic = ResourcesCache.getIcon("img/world_turtle.png");
+		AffineTransform t = new AffineTransform(1.0, 0, 0, 1.0, b.getX()-ic.getIconWidth()/2., b.getY()-ic.getIconHeight()/2.);
+		t.rotate(b.getHeadingRadian(), ic.getIconWidth()/2., ic.getIconHeight()/2.);
+		g.drawImage(ic.getImage(), t, null);
+	}
+}
diff --git a/src/plm/universe/turtles/package-info.java b/src/plm/universe/turtles/package-info.java
new file mode 100644
index 0000000..6d3bf30
--- /dev/null
+++ b/src/plm/universe/turtles/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * Universe inspired from the LOGO language, mainly used to experiment with recursion. 
+ */
+
+package plm.universe.turtles;
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jlm.git



More information about the pkg-java-commits mailing list