[SCM] Lisaac compiler branch, master, updated. lisaac-0.12-417-g653c1fc

Damien Bouvarel dams.bouvarel at wanadoo.fr
Wed Aug 19 22:37:04 UTC 2009


The following commit has been merged in the master branch:
commit 653c1fc98ddcd2993046d7ebb9c2c75f2ab1f2ac
Author: Damien Bouvarel <dams.bouvarel at wanadoo.fr>
Date:   Thu Aug 20 00:35:45 2009 +0200

    add eclisaac sources

diff --git a/editor/eclipse/.classpath b/editor/eclipse/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/editor/eclipse/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/editor/eclipse/.project b/editor/eclipse/.project
new file mode 100644
index 0000000..35beef2
--- /dev/null
+++ b/editor/eclipse/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>eclipse</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/editor/eclipse/.settings/org.eclipse.jdt.core.prefs b/editor/eclipse/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5cab958
--- /dev/null
+++ b/editor/eclipse/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Tue Jun 16 14:27:35 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/editor/eclipse/META-INF/MANIFEST.MF b/editor/eclipse/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..982f333
--- /dev/null
+++ b/editor/eclipse/META-INF/MANIFEST.MF
@@ -0,0 +1,97 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.lisaac.ldt;singleton:=true
+Bundle-Version: 1.1.4
+Bundle-Activator: org.lisaac.ldt.LisaacPlugin
+Bundle-Vendor: %Bundle-Vendor.0
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.jface.text,
+ org.eclipse.ui.editors,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.console,
+ org.eclipse.debug.ui,
+ org.eclipse.ltk.core.refactoring
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: .,
+ bin/
+Import-Package: org.eclipse.debug.core,
+ org.eclipse.debug.core.model,
+ org.eclipse.debug.ui,
+ org.eclipse.ltk.ui.refactoring,
+ org.eclipse.ui.texteditor.templates,
+ org.eclipse.ui.views.contentoutline
+Export-Package: org.lisaac.ldt;
+  uses:="org.eclipse.core.runtime,
+   org.eclipse.jface.resource,
+   org.eclipse.ui.plugin,
+   org.eclipse.jface.text.templates.persistence,
+   org.osgi.framework,
+   org.eclipse.jface.text.templates",
+ org.lisaac.ldt.actions;
+  uses:="org.eclipse.jface.action,
+   org.eclipse.ui,
+   org.eclipse.jface.viewers,
+   org.eclipse.swt.widgets",
+ org.lisaac.ldt.builder;uses:="org.lisaac.ldt.model,org.eclipse.core.runtime,org.eclipse.core.resources",
+ org.lisaac.ldt.editors;
+  uses:="org.eclipse.jface.text,
+   org.eclipse.jface.text.hyperlink,
+   org.eclipse.core.runtime,
+   org.eclipse.jface.text.source,
+   org.eclipse.jface.text.rules,
+   org.eclipse.jface.text.contentassist,
+   org.lisaac.ldt.model,
+   org.eclipse.jface.preference,
+   org.eclipse.jface.text.presentation,
+   org.eclipse.core.resources,
+   org.eclipse.jface.viewers,
+   org.eclipse.swt.graphics,
+   org.eclipse.jface.util,
+   org.eclipse.swt.widgets,
+   org.eclipse.ui.editors.text",
+ org.lisaac.ldt.launch;
+  uses:="org.eclipse.debug.core,
+   org.eclipse.debug.ui,
+   org.eclipse.core.runtime,
+   org.eclipse.ui,
+   org.eclipse.debug.core.model,
+   org.eclipse.core.resources,
+   org.eclipse.jface.viewers,
+   org.eclipse.swt.graphics,
+   org.eclipse.swt.widgets",
+ org.lisaac.ldt.model;
+  uses:="org.lisaac.ldt.model.types,
+   org.lisaac.ldt.model.items,
+   org.lisaac.ldt.model.lip,
+   org.eclipse.core.resources,
+   org.lisaac.ldt.builder",
+ org.lisaac.ldt.model.items;uses:="org.lisaac.ldt.model,org.lisaac.ldt.model.types",
+ org.lisaac.ldt.model.lip,
+ org.lisaac.ldt.model.types,
+ org.lisaac.ldt.outline;uses:="org.lisaac.ldt.model.items,org.eclipse.jface.viewers,org.eclipse.swt.graphics",
+ org.lisaac.ldt.perspectives;uses:="org.eclipse.ui",
+ org.lisaac.ldt.preferences;
+  uses:="org.eclipse.ui.texteditor.templates,
+   org.eclipse.jface.preference,
+   org.eclipse.ui,
+   org.eclipse.core.runtime.preferences",
+ org.lisaac.ldt.properties;uses:="org.eclipse.core.resources,org.eclipse.ui.dialogs,org.eclipse.swt.widgets",
+ org.lisaac.ldt.templates;uses:="org.eclipse.jface.text,org.eclipse.swt.graphics,org.eclipse.jface.text.templates",
+ org.lisaac.ldt.views;
+  uses:="org.eclipse.jface.text,
+   org.eclipse.ui.texteditor,
+   org.eclipse.ui.console,
+   org.eclipse.ui.views.contentoutline,
+   org.eclipse.core.resources,
+   org.eclipse.jface.viewers,
+   org.eclipse.swt.widgets",
+ org.lisaac.ldt.wizards;
+  uses:="org.eclipse.jface.wizard,
+   org.eclipse.ui,
+   org.eclipse.core.resources,
+   org.eclipse.jface.viewers,
+   org.eclipse.swt.widgets"
+Bundle-Localization: plugin
+Bundle-Name: %Bundle-Name.0
diff --git a/editor/eclipse/build.properties b/editor/eclipse/build.properties
new file mode 100644
index 0000000..f67e7f3
--- /dev/null
+++ b/editor/eclipse/build.properties
@@ -0,0 +1,21 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               bin/,\
+               icons/,\
+               plugin.xml,\
+               plugin.properties,\
+               help/,\
+               build.properties
+bin.excludes = icons/Thumbs.db
+src.excludes = icons/Thumbs.db
+src.includes = META-INF/,\
+               README,\
+               bin/,\
+               build.properties,\
+               help/,\
+               icons/,\
+               plugin.properties,\
+               plugin.xml,\
+               src/
diff --git a/editor/eclipse/help/html/maintopic.html b/editor/eclipse/help/html/maintopic.html
new file mode 100644
index 0000000..a476078
--- /dev/null
+++ b/editor/eclipse/help/html/maintopic.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Main Topic</title>
+</head>
+
+<body>
+<h1>Main Topic</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/editor/eclipse/help/html/overview.html b/editor/eclipse/help/html/overview.html
new file mode 100644
index 0000000..a476078
--- /dev/null
+++ b/editor/eclipse/help/html/overview.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Main Topic</title>
+</head>
+
+<body>
+<h1>Main Topic</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/editor/eclipse/help/html/subtopic.html b/editor/eclipse/help/html/subtopic.html
new file mode 100644
index 0000000..8a61c50
--- /dev/null
+++ b/editor/eclipse/help/html/subtopic.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Sub Topic</title>
+</head>
+
+<body>
+<h1>Sub Topic</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/editor/eclipse/help/html/toc.html b/editor/eclipse/help/html/toc.html
new file mode 100644
index 0000000..326f0a9
--- /dev/null
+++ b/editor/eclipse/help/html/toc.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+	<title>Table of Contents</title>
+</head>
+
+<body>
+<h1>Table of Contents</h1>
+Please enter your text here.
+</body>
+</html>
\ No newline at end of file
diff --git a/editor/eclipse/help/sheet1_HelloWorld.xml b/editor/eclipse/help/sheet1_HelloWorld.xml
new file mode 100644
index 0000000..3324a79
--- /dev/null
+++ b/editor/eclipse/help/sheet1_HelloWorld.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<cheatsheet
+      title="Create a Hello World application">
+   <intro>
+      <description>
+         This cheat sheet shows you how to create a &quot;Hello World&quot; Lisaac application.
+
+ The application will print &quot;Hello World&quot; in the console when run.
+ Enter Lisaac World!
+      </description>
+   </intro>
+   <item
+         title="Open the Lisaac perspective">
+      <description>
+         If you&apos;re not already in a Lisaac perspective, in the main menu select <b>Window &gt; Open Perspective &gt; Lisaac</b>.
+         
+      </description>
+      <command
+            required="false"
+            serialization="org.eclipse.ui.perspectives.showPerspective"/>
+   </item>
+   <item
+         title="Create a Lisaac Project">
+      <description>
+         We need a project to create an application. Click on the <b>New Lisaac Project</b> button, or click on the link below. Enter <b>HelloWorld</b> for the project name, then click <b>Finish</b>.
+         
+      </description>
+      <command
+            required="false"
+            serialization="org.eclipse.ui.newWizard"/>
+   </item>
+  
+   <item
+         skip="false"
+         title="Create your HelloWorld Prototype">
+  	  <description>
+  	  The next step is to create a new prototype.
+If the project wizard has not created a main prototype, click on the <b>New Prototype</b> button, select the checkbox to create the <b>main</b> slot.
+  	  </description>
+   	  <command
+            required="false"
+            serialization="org.eclipse.ui.newWizard"/> 
+   </item>
+   <item
+         title="Add a print statement">
+      <description>
+         Now that you have your HelloWorld prototype, in the <b>main</b> slot, add the following statement:
+&quot;Hello World!&quot;.print;
+then <b>save</b> your changes, the prototype will automatically compile.
+      </description>
+   </item>
+   <item
+         title="Run your Lisaac application">
+      <description>
+         To run your application, select <b>Run-&gt; Run configurations</b> menu, select <b>Lisaac Application</b>.
+The <b>Console</b> view should appear at the bottom and display the &quot;Hello, world!&quot; output.
+
+Congratulations! You have successfully created a Lisaac Hello World application!
+      </description>
+   </item>
+   
+</cheatsheet>
diff --git a/editor/eclipse/help/testToc.xml b/editor/eclipse/help/testToc.xml
new file mode 100644
index 0000000..ca7402e
--- /dev/null
+++ b/editor/eclipse/help/testToc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Lisaac Development user Guide" topic="html/toc.html">
+	<link toc="toc.xml" />
+</toc>
diff --git a/editor/eclipse/help/toc.xml b/editor/eclipse/help/toc.xml
new file mode 100644
index 0000000..6ad67be
--- /dev/null
+++ b/editor/eclipse/help/toc.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?NLS TYPE="org.eclipse.help.toc"?>
+
+<toc label="Lisaac Table of Contents">
+	<topic label="Lisaac development overview"  href="html/overview.html"> 
+	</topic>
+	<topic href="html/maintopic.html" label="Getting Started">
+    <topic label="Topic">
+    </topic>
+ </topic>
+ <topic href="html/maintopic.html" label="Reference">
+    <topic label="Topic">
+    </topic>
+ </topic>
+ <topic label="Tips and Tricks">
+ </topic>
+ <topic label="Legal">
+ </topic>
+</toc>
diff --git a/editor/eclipse/icons/Thumbs.db b/editor/eclipse/icons/Thumbs.db
new file mode 100644
index 0000000..7571e9a
Binary files /dev/null and b/editor/eclipse/icons/Thumbs.db differ
diff --git a/editor/eclipse/icons/alphab_sort_co.gif b/editor/eclipse/icons/alphab_sort_co.gif
new file mode 100644
index 0000000..6d77244
Binary files /dev/null and b/editor/eclipse/icons/alphab_sort_co.gif differ
diff --git a/editor/eclipse/icons/blank.gif b/editor/eclipse/icons/blank.gif
new file mode 100644
index 0000000..ede75be
Binary files /dev/null and b/editor/eclipse/icons/blank.gif differ
diff --git a/editor/eclipse/icons/error_co.gif b/editor/eclipse/icons/error_co.gif
new file mode 100644
index 0000000..8612eaf
Binary files /dev/null and b/editor/eclipse/icons/error_co.gif differ
diff --git a/editor/eclipse/icons/keyword.gif b/editor/eclipse/icons/keyword.gif
new file mode 100644
index 0000000..435d62e
Binary files /dev/null and b/editor/eclipse/icons/keyword.gif differ
diff --git a/editor/eclipse/icons/library.gif b/editor/eclipse/icons/library.gif
new file mode 100644
index 0000000..cb55e33
Binary files /dev/null and b/editor/eclipse/icons/library.gif differ
diff --git a/editor/eclipse/icons/private-nonshared.gif b/editor/eclipse/icons/private-nonshared.gif
new file mode 100644
index 0000000..39891e1
Binary files /dev/null and b/editor/eclipse/icons/private-nonshared.gif differ
diff --git a/editor/eclipse/icons/private-shared.gif b/editor/eclipse/icons/private-shared.gif
new file mode 100644
index 0000000..e4c1859
Binary files /dev/null and b/editor/eclipse/icons/private-shared.gif differ
diff --git a/editor/eclipse/icons/prototype.gif b/editor/eclipse/icons/prototype.gif
new file mode 100644
index 0000000..eb6e0b6
Binary files /dev/null and b/editor/eclipse/icons/prototype.gif differ
diff --git a/editor/eclipse/icons/public-nonshared.gif b/editor/eclipse/icons/public-nonshared.gif
new file mode 100644
index 0000000..828590b
Binary files /dev/null and b/editor/eclipse/icons/public-nonshared.gif differ
diff --git a/editor/eclipse/icons/public-shared.gif b/editor/eclipse/icons/public-shared.gif
new file mode 100644
index 0000000..698f668
Binary files /dev/null and b/editor/eclipse/icons/public-shared.gif differ
diff --git a/editor/eclipse/icons/sample.gif b/editor/eclipse/icons/sample.gif
new file mode 100644
index 0000000..34fb3c9
Binary files /dev/null and b/editor/eclipse/icons/sample.gif differ
diff --git a/editor/eclipse/icons/sections_co.gif b/editor/eclipse/icons/sections_co.gif
new file mode 100644
index 0000000..82bc04e
Binary files /dev/null and b/editor/eclipse/icons/sections_co.gif differ
diff --git a/editor/eclipse/icons/source-folder.gif b/editor/eclipse/icons/source-folder.gif
new file mode 100644
index 0000000..fca9c53
Binary files /dev/null and b/editor/eclipse/icons/source-folder.gif differ
diff --git a/editor/eclipse/icons/template.gif b/editor/eclipse/icons/template.gif
new file mode 100644
index 0000000..fdde5fb
Binary files /dev/null and b/editor/eclipse/icons/template.gif differ
diff --git a/editor/eclipse/icons/warning_co.gif b/editor/eclipse/icons/warning_co.gif
new file mode 100644
index 0000000..3af228c
Binary files /dev/null and b/editor/eclipse/icons/warning_co.gif differ
diff --git a/editor/eclipse/plugin.properties b/editor/eclipse/plugin.properties
new file mode 100644
index 0000000..164a6d3
--- /dev/null
+++ b/editor/eclipse/plugin.properties
@@ -0,0 +1,43 @@
+#Properties file for eclipse
+Bundle-Name.0 = Lisaac Plug-in
+editor.name.0 = Lisaac Editor
+editor.name.1 = Lip Editor
+perspective.name.0 = Lisaac
+page.name.0 = Lisaac
+page.name.1 = Templates
+page.name.2 = Syntax Coloring
+page.name.3 = Editor
+page.name.5 = Lisaac Compiler
+category.name.0 = Lisaac
+wizard.name.0 = Lisaac Project
+wizard.name.1 = Lisaac Prototype
+consoleFactory.label.0 = Lisaac Console
+launchConfigurationType.name.0 = Lisaac Application
+actionSet.description.0 = Lisaac Source Tools
+actionSet.label.0 = Source
+menu.label.0 = Source
+action.label.0 = Correct Indentation
+action.label.1 = Generate Constructor
+menu.label.1 = New Prototype
+action.label.2 = New Prototype
+action.tooltip.0 = Create new prototype
+action.label.3 = Toggle Comment
+command.name.0 = Indentation
+category.name.1 = Lisaac Command
+command.name.1 = Generate Constructor
+command.name.2 = New Prototype
+command.name.3 = Toggle comment
+shortcut.label.0 = Lisaac Application
+
+perspective.description.0 = Perspective for Lisaac Development
+template.description.0 = While loop
+template.description.1 = Until Loop
+template.description.2 = If statement
+template.description.3 = If Else statement
+template.description.4 = If false statement
+template.description.5 = For loop
+Bundle-Vendor.0 = Damien Bouvarel
+wizard.name.2 = Source folder
+action.label.4 = Rename Prototype...
+menu.label.2 = Refactor
+command.name.4 = Rename Prototype
\ No newline at end of file
diff --git a/editor/eclipse/plugin.xml b/editor/eclipse/plugin.xml
new file mode 100644
index 0000000..cfadac6
--- /dev/null
+++ b/editor/eclipse/plugin.xml
@@ -0,0 +1,513 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+
+   <extension
+         id="lisaacProblem"
+         name="Lisaac Problem"
+         point="org.eclipse.core.resources.markers">
+      <persistent
+            value="true">
+      </persistent>
+      <super
+            type="org.eclipse.core.resources.problemmarker">
+      </super>
+      <super
+            type="org.eclipse.core.resources.textmarker">
+      </super>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            name="%editor.name.0"
+            extensions="li"
+            icon="$nl$/icons/prototype.gif"
+            contributorClass="org.eclipse.ui.texteditor.BasicTextEditorActionContributor"
+            class="org.lisaac.ldt.editors.LisaacEditor"
+            id="org.lisaac.ldt.editors.LisaacEditor">
+      </editor>
+      <editor
+            class="org.lisaac.ldt.editors.LipEditor"
+            contributorClass="org.eclipse.ui.texteditor.BasicTextEditorActionContributor"
+            default="false"
+            extensions="lip"
+            icon="$nl$/icons/releng_gears.gif"
+            id="org.lisaac.ldt.editors.LipEditor"
+            name="%editor.name.1">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.help.toc">
+      <toc
+            file="help/toc.xml">
+      </toc>
+      <toc
+            file="help/testToc.xml"
+            primary="true">
+      </toc>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            name="%perspective.name.0"
+            class="org.lisaac.ldt.perspectives.LisaacPerspective"
+            id="org.lisaac.ldt.perspectives.LisaacPerspective">
+         <description>
+            %perspective.description.0
+         </description>
+      </perspective>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            name="%page.name.0"
+            class="org.lisaac.ldt.preferences.LisaacPreferencePage"
+            id="org.lisaac.ldt.preferences.LisaacPreferencePage">
+      </page>
+      <page
+            category="org.lisaac.ldt.editorpreferences"
+            class="org.lisaac.ldt.preferences.LisaacTemplatePage"
+            id="org.lisaac.ldt.templatepreferences"
+            name="%page.name.1">
+      </page>
+      <page
+            category="org.lisaac.ldt.editorpreferences"
+            class="org.lisaac.ldt.preferences.LisaacColoringPage"
+            id="org.lisaac.ldt.editorcolorpreferences"
+            name="%page.name.2">
+      </page>
+      <page
+            category="org.lisaac.ldt.preferences.LisaacPreferencePage"
+            class="org.lisaac.ldt.preferences.LisaacEditorPage"
+            id="org.lisaac.ldt.editorpreferences"
+            name="%page.name.3">
+         <keywordReference
+               id="org.eclipse.ui.editors.general">
+         </keywordReference>
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer
+            class="org.lisaac.ldt.preferences.PreferenceInitializer">
+      </initializer>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            class="org.lisaac.ldt.properties.LisaacProjectPropertyPage"
+            id="org.lisaac.ldt.properties.projectPropertyPage"
+            name="%page.name.5"
+            objectClass="org.eclipse.core.resources.IProject">
+      </page>
+   </extension>
+   <extension
+         id="org.lisaac.ldt.newWizard"
+         name="Lisaac Project Wizard"
+         point="org.eclipse.ui.newWizards">
+      <category
+            id="Lisaac"
+            name="%category.name.0">
+      </category>
+      <wizard
+            canFinishEarly="true"
+            category="Lisaac"
+            class="org.lisaac.ldt.wizards.NewProjectWizard"
+            finalPerspective="org.lisaac.ldt.perspectives.LisaacPerspective"
+            hasPages="true"
+            icon="$nl$/icons/sample.gif"
+            id="org.lisaac.ldt.wizard"
+            name="%wizard.name.0"
+            preferredPerspectives="org.lisaac.ldt.perspectives.LisaacPerspective"
+            project="true">
+      </wizard>
+      <wizard
+            canFinishEarly="false"
+            category="Lisaac"
+            class="org.lisaac.ldt.wizards.NewPrototypeWizard"
+            finalPerspective="org.lisaac.ldt.perspectives.LisaacPerspective"
+            hasPages="true"
+            icon="$nl$/icons/prototype.gif"
+            id="org.lisaac.ldt.prototype"
+            name="%wizard.name.1"
+            preferredPerspectives="org.lisaac.ldt.perspectives.LisaacPerspective"
+            project="false">
+      </wizard>
+   </extension>
+   <extension
+         id="builder"
+         name="Lisaac Builder"
+         point="org.eclipse.core.resources.builders">
+      <builder
+            callOnEmptyDelta="false"
+            hasNature="true"
+            isConfigurable="false">
+         <run
+               class="org.lisaac.ldt.builder.LisaacBuilder">
+         </run>
+      </builder>
+   </extension>
+   <extension
+         id="lisaac"
+         name="Lisaac Nature"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run
+               class="org.lisaac.ldt.builder.LisaacNature">
+         </run>
+      </runtime>
+      <builder
+            id="org.lisaac.ldt.builder">
+      </builder>
+   </extension>
+   <extension
+         point="org.eclipse.ui.console.consoleFactories">
+      <consoleFactory
+            class="org.lisaac.ldt.views.ConsoleFactory"
+            label="%consoleFactory.label.0">
+      </consoleFactory>
+   </extension>
+   <extension
+         point="org.eclipse.debug.core.launchConfigurationTypes">
+      <launchConfigurationType
+            delegate="org.lisaac.ldt.launch.LaunchConfiguration"
+            id="org.lisaac.ldt.launchConfiguration"
+            modes="run,debug"
+            name="%launchConfigurationType.name.0"
+            public="true">
+      </launchConfigurationType>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+      <launchConfigurationTabGroup
+            class="org.lisaac.ldt.launch.LaunchConfigurationTabGroup"
+            id="org.lisaac.ldt.LaunchConfigurationTabGroup"
+            type="org.lisaac.ldt.launchConfiguration">
+      </launchConfigurationTabGroup>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            description="%actionSet.description.0"
+            id="org.lisaac.ldt.source"
+            label="%actionSet.label.0"
+            visible="true">
+         <menu
+               id="org.lisaac.ldt.sourcemenu"
+               label="%menu.label.0"
+               path="edit">
+            <groupMarker
+                  name="toggle">
+            </groupMarker>
+            <separator
+                  name="org.lisaac.ldt.separator1">
+            </separator>
+            <groupMarker
+                  name="indent">
+            </groupMarker>
+            <separator
+                  name="org.lisaac.ldt.separator2">
+            </separator>
+            <groupMarker
+                  name="generate">
+            </groupMarker>
+         </menu>
+         <action
+               class="org.lisaac.ldt.actions.IndentAction"
+               definitionId="org.lisaac.ldt.cmd1"
+               id="org.lisaac.ldt.indentaction"
+               label="%action.label.0"
+               menubarPath="org.lisaac.ldt.sourcemenu/indent">
+         </action>
+         <action
+               class="org.lisaac.ldt.actions.GenerateConstructor"
+               definitionId="org.lisaac.ldt.cmd2"
+               id="org.lisaac.ldt.generateconstructor"
+               label="%action.label.1"
+               menubarPath="org.lisaac.ldt.sourcemenu/generate">
+         </action>
+         <menu
+               id="org.lisaac.ldt.toolbar"
+               label="%menu.label.1">
+         </menu>
+         <action
+               class="org.lisaac.ldt.actions.CreatePrototype"
+               definitionId="org.lisaac.ldt.cmd3"
+               icon="$nl$/icons/prototype.gif"
+               id="org.lisaac.ldt.toolbar_action1"
+               label="%action.label.2"
+               style="push"
+               toolbarPath="org.lisaac.ldt.toolbar"
+               tooltip="%action.tooltip.0">
+         </action>
+         <action
+               class="org.lisaac.ldt.actions.ToggleComment"
+               definitionId="org.lisaac.ldt.cmd4"
+               id="org.lisaac.ldt.comment1"
+               label="%action.label.3"
+               menubarPath="org.lisaac.ldt.sourcemenu/toggle">
+         </action>
+         <action
+               class="org.lisaac.ldt.actions.RenamePrototype"
+               definitionId="org.lisaac.ldt.cmd5"
+               enablesFor="1"
+               id="org.lisaac.ldt.action.refactor1"
+               label="%action.label.4"
+               menubarPath="org.lisaac.ldt.refactor.menu/renameproto"
+               style="push">
+         </action>
+         <menu
+               id="org.lisaac.ldt.refactor.menu"
+               label="%menu.label.2"
+               path="org.lisaac.ldt.sourcemenu">
+         </menu>
+         <action
+               class="org.lisaac.ldt.actions.ChangeHeader"
+               definitionId="org.lisaac.ldt.cmd6"
+               id="org.lisaac.ldt.action.refactor2"
+               label="Change Project Headers"
+               menubarPath="org.lisaac.ldt.refactor.menu/changeheader"
+               style="push">
+         </action>
+      </actionSet>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd1"
+            name="%command.name.0">
+      </command>
+      <category
+            id="org.lisaac.ldt.commands"
+            name="%category.name.1">
+      </category>
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd2"
+            name="%command.name.1">
+      </command>
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd3"
+            name="%command.name.2">
+      </command>
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd4"
+            name="%command.name.3">
+      </command>
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd5"
+            name="%command.name.4">
+      </command>
+      <command
+            categoryId="org.lisaac.ldt.commands"
+            id="org.lisaac.ldt.cmd6"
+            name="Change Header">
+      </command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.bindings">
+      <key
+            commandId="org.lisaac.ldt.cmd1"
+            contextId="org.eclipse.ui.textEditorScope"
+            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+            sequence="F2">
+      </key>
+   </extension>
+   <extension
+         point="org.eclipse.ui.cheatsheets.cheatSheetContent">
+      <category
+            id="org.lisaac.ldt.cheatsheet"
+            name="Lisaac Development">
+      </category>
+      <cheatsheet
+            category="org.lisaac.ldt.cheatsheet"
+            composite="false"
+            contentFile="help/sheet1_HelloWorld.xml"
+            id="org.lisaac.ldt.cheatsheet1"
+            name="Lisaac HelloWorld">
+         <description>
+            Create a &quot;Hello World&quot; Lisaac application from scratch.
+         </description>
+      </cheatsheet>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.templates">
+      <contextType
+            class="org.lisaac.ldt.templates.LisaacContextType"
+            id="org.lisaac.ldt.contexttype"
+            name="Lisaac context type">
+      </contextType>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.0"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_whiledo"
+            name="while_do">
+         <pattern>
+            while_do {
+  ${cursor}
+};
+         </pattern>
+      </template>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.1"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_untildo"
+            name="until_do">
+         <pattern>
+            until_do {
+  ${cursor}
+};
+         </pattern>
+      </template>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.2"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_if"
+            name="if">
+         <pattern>
+            if {
+  ${cursor}
+};
+         </pattern>
+      </template>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.3"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_ifelse"
+            name="if__else">
+         <pattern>
+            if {
+  ${cursor}
+} else {
+};
+         </pattern>
+      </template>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.4"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_iffalse"
+            name="if_false">
+         <pattern>
+            if_false {
+  ${cursor}
+};
+         </pattern>
+      </template>
+      <template
+            autoinsert="true"
+            contextTypeId="org.lisaac.ldt.contexttype"
+            description="%template.description.5"
+            icon="$nl$/icons/template.gif"
+            id="org.lisaac.ldt.template_for"
+            name="to__do">
+         <pattern>
+            to ${cursor} do { i:INTEGER;
+};
+         </pattern>
+      </template>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchShortcuts">
+      <shortcut
+            class="org.lisaac.ldt.launch.LisaacApplicationShortcut"
+            icon="$nl$/icons/prototype.gif"
+            id="org.lisaac.ldt.launch.shortcut"
+            label="%shortcut.label.0"
+            modes="run,debug">
+         <perspective
+               id="org.lisaac.ldt.perspectives.LisaacPerspective">
+         </perspective>
+         <contextualLaunch>
+            <enablement>
+            <with variable="selection">
+			<count value="1"/>
+				<iterate>
+				<or><test property="org.eclipse.debug.ui.matchesPattern" value="*.li"/></or>
+				</iterate>
+			</with>
+            </enablement>
+         </contextualLaunch>
+      </shortcut>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.annotationTypes">
+      <type
+            markerSeverity="2"
+            markerType="org.lisaac.ldt.lisaacProblem"
+            name="org.lisaac.ldt.annotationtype"
+            super="org.eclipse.ui.workbench.texteditor.error">
+      </type>
+   </extension>
+   <extension
+         point="org.eclipse.ui.decorators">
+      <decorator
+            class="org.lisaac.ldt.editors.LisaacResourceDecorator"
+            id="org.lisaac.ldt.decorator"
+            label="%decorator.label.0"
+            lightweight="true"
+            location="BOTTOM_LEFT"
+            state="true">
+         <enablement>
+            <objectClass
+                  name="org.eclipse.core.resources.IResource">
+            </objectClass>
+         </enablement>
+      </decorator>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors.markerAnnotationSpecification">
+      <specification
+            annotationType="org.lisaac.ldt.annotationtype"
+            colorPreferenceKey="errorIndicationColor"
+            colorPreferenceValue="255,0,128"
+            contributesToHeader="true"
+            highlightPreferenceKey="errorIndicationHighlighting"
+            highlightPreferenceValue="false"
+            includeOnPreferencePage="true"
+            isGoToNextNavigationTarget="true"
+            isGoToNextNavigationTargetKey="isErrorGoToNextNavigationTarget"
+            isGoToPreviousNavigationTarget="true"
+            isGoToPreviousNavigationTargetKey="isErrorGoToPreviousNavigationTarget"
+            label="Lisaac Problem"
+            overviewRulerPreferenceKey="errorIndicationInOverviewRuler"
+            overviewRulerPreferenceValue="true"
+            presentationLayer="6"
+            showInNextPrevDropdownToolbarAction="true"
+            showInNextPrevDropdownToolbarActionKey="showErrorInNextPrevDropdownToolbarAction"
+            symbolicIcon="error"
+            textPreferenceKey="errorIndication"
+            textPreferenceValue="true"
+            textStylePreferenceKey="errorTextStyle"
+            textStylePreferenceValue="PROBLEM_UNDERLINE"
+            verticalRulerPreferenceKey="errorIndicationInVerticalRuler"
+            verticalRulerPreferenceValue="true">
+      </specification>
+   </extension>
+   <extension
+         point="org.eclipse.ui.popupMenus">
+      <viewerContribution
+            id="org.lisaac.ldt.editoraction"
+            targetID="#TextEditorContext">
+         <action
+               class="org.lisaac.ldt.actions.RefreshEditor"
+               id="org.lisaac.ldt.editoraction1"
+               label="Refresh Editor">
+         </action>
+      </viewerContribution>
+   </extension>
+
+</plugin>
diff --git a/editor/eclipse/src/org/lisaac/ldt/LisaacMessages.java b/editor/eclipse/src/org/lisaac/ldt/LisaacMessages.java
new file mode 100644
index 0000000..928e1dc
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/LisaacMessages.java
@@ -0,0 +1,22 @@
+package org.lisaac.ldt;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class LisaacMessages {
+	private static final String BUNDLE_NAME = "org.lisaac.ldt.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private LisaacMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/LisaacPlugin.java b/editor/eclipse/src/org/lisaac/ldt/LisaacPlugin.java
new file mode 100644
index 0000000..06acca3
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/LisaacPlugin.java
@@ -0,0 +1,153 @@
+package org.lisaac.ldt;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ISaveContext;
+import org.eclipse.core.resources.ISaveParticipant;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
+import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.lisaac.ldt.builder.LisaacChangeListener;
+import org.lisaac.ldt.builder.LisaacNature;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.templates.LisaacContextType;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class LisaacPlugin extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.lisaac.ldt"; //$NON-NLS-1$
+
+	// The shared instance
+	private static LisaacPlugin plugin;
+
+
+	/** The template store. */
+	private TemplateStore fStore;
+	/** The context type registry. */
+	private ContextTypeRegistry fRegistry;
+
+
+	private static final String TEMPLATES_KEY = "org.lisaac.ldt.templatepreferences"; //$NON-NLS-1$
+
+
+	public TemplateStore getTemplateStore() {
+		if (fStore == null) {
+			fStore = new ContributionTemplateStore (
+					getContextTypeRegistry(), LisaacPlugin
+					.getDefault().getPreferenceStore(),
+					TEMPLATES_KEY);
+			try {
+				fStore.load();
+			} catch (IOException e) {
+				LisaacPlugin
+				.getDefault()
+				.getLog()
+				.log(
+						new Status(
+								IStatus.ERROR,
+								PLUGIN_ID, IStatus.OK, "", e)); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		return fStore;
+	}
+
+	public ContextTypeRegistry getContextTypeRegistry() {
+		if (fRegistry == null) {
+			// create an configure the contexts available in the template editor
+			ContributionContextTypeRegistry registry= new ContributionContextTypeRegistry();
+			registry.addContextType(LisaacContextType.ID_CONTEXT_TYPE);
+
+			fRegistry= registry;
+		}
+		return fRegistry;
+	}
+
+	/**
+	 * The constructor
+	 */
+	public LisaacPlugin() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+		
+		// to notify project modifications
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(new LisaacChangeListener());
+	
+		// build all lisaac projects
+		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+		for (int i=0; i<projects.length; i++) {
+			try {
+				if (projects[i] != null && projects[i].isOpen()) {
+					if (projects[i].getNature(LisaacNature.NATURE_ID) != null) {
+						try {
+							// clean all lisaac projects to get started
+							projects[i].build(IncrementalProjectBuilder.FULL_BUILD, null);
+							
+						} catch (Exception e) {
+							log(new Status(IStatus.ERROR,
+									PLUGIN_ID, IStatus.OK, "Error loading "+projects[i].getName(), e)); //$NON-NLS-1$
+						}
+					}
+				}
+			} catch (Exception e) {
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static LisaacPlugin getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns an image descriptor for the image file at the given
+	 * plug-in relative path
+	 *
+	 * @param path the path
+	 * @return the image descriptor
+	 */
+	public static ImageDescriptor getImageDescriptor(String path) {
+		return imageDescriptorFromPlugin(PLUGIN_ID, path);
+	}
+
+	/**
+	 * Logs the specified status with this plug-in's log.
+	 *
+	 * @param status status to log.
+	 */
+	public static void log(final IStatus status) {
+		getDefault().getLog().log(status);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/ChangeHeader.java b/editor/eclipse/src/org/lisaac/ldt/actions/ChangeHeader.java
new file mode 100644
index 0000000..05296ef
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/ChangeHeader.java
@@ -0,0 +1,74 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.refactor.ChangeHeaderRefactor;
+import org.lisaac.ldt.refactor.ChangeHeaderWizard;
+
+public class ChangeHeader implements IWorkbenchWindowActionDelegate {
+
+	private IWorkbenchWindow fWindow = null;
+
+	private LisaacModel model;
+
+	public void dispose() { 
+	}
+
+	public void init(IWorkbenchWindow window) {
+		fWindow = window;
+	}
+
+	public void run(IAction action) {
+		if (fWindow != null&& model != null) {
+			ChangeHeaderRefactor refactoring = new ChangeHeaderRefactor(model);
+			String name = "Change Project Headers";
+			run(new ChangeHeaderWizard(refactoring, name),
+					fWindow.getShell(), name);
+		}
+	}
+	
+	public void run(RefactoringWizard wizard, Shell parent, String dialogTitle) {
+		try {
+			RefactoringWizardOpenOperation operation = new RefactoringWizardOpenOperation(wizard);
+			operation.run(parent, dialogTitle);
+		} catch (InterruptedException exception) {
+			// Do nothing
+		}
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+		model = null;
+		
+		if (selection instanceof ITextSelection) {
+			if (fWindow != null) {
+				// get surrounding word
+				IWorkbenchPart part = fWindow.getPartService().getActivePart();
+				if (part instanceof AbstractLisaacEditor) {
+					IProject project = ((AbstractLisaacEditor) part)
+							.getProject();
+					model = LisaacModel.getModel(project);
+				}
+			}
+		} else if (selection instanceof IStructuredSelection) {
+			if (((IStructuredSelection) selection).getFirstElement() instanceof IResource) {
+				IResource res = (IResource) ((IStructuredSelection) selection).getFirstElement();
+				if (res.getProject() != null) {
+					model = LisaacModel.getModel(res.getProject());
+				}
+			}
+		}
+		action.setEnabled(model != null);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/CreatePrototype.java b/editor/eclipse/src/org/lisaac/ldt/actions/CreatePrototype.java
new file mode 100644
index 0000000..eb7b5f2
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/CreatePrototype.java
@@ -0,0 +1,110 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.PlatformUI;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.wizards.NewPrototypeWizard;
+
+public class CreatePrototype extends Action implements IWorkbenchWindowActionDelegate {
+
+	private Shell fShell;
+	private IStructuredSelection fSelection;
+	
+	
+	public CreatePrototype() {
+	}
+	
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		Shell shell= getShell();
+
+		try {
+			INewWizard wizard= createWizard();
+			wizard.init(PlatformUI.getWorkbench(), getSelection());
+			
+			WizardDialog dialog= new WizardDialog(shell, wizard);
+			dialog.create();
+			int res= dialog.open();
+			if (res != Window.OK) {
+				// TODO log error
+			}
+		} catch (CoreException e) {
+			// TODO log error
+		}
+	}
+	
+	/**
+	 * Returns the configured selection. If no selection has been configured using {@link #setSelection(IStructuredSelection)},
+	 * the currently selected element of the active workbench is returned.
+	 * @return the configured selection
+	 */
+	protected IStructuredSelection getSelection() {
+		if (fSelection == null) {
+			return evaluateCurrentSelection();
+		}
+		return fSelection;
+	}
+	
+	private IStructuredSelection evaluateCurrentSelection() {
+		IWorkbenchWindow window = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+
+		if (window != null) {
+			ISelection selection= window.getSelectionService().getSelection();
+			if (selection instanceof IStructuredSelection) {
+				return (IStructuredSelection) selection;
+			}
+		}
+		return StructuredSelection.EMPTY;
+	}
+	
+	protected Shell getShell() {
+		return fShell;
+	}
+	
+	// make it an abstract method if more wizard shortcuts are created
+	protected final INewWizard createWizard() throws CoreException {
+		return new NewPrototypeWizard();
+	}
+	
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+	
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+	
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/GenerateConstructor.java b/editor/eclipse/src/org/lisaac/ldt/actions/GenerateConstructor.java
new file mode 100644
index 0000000..207ba42
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/GenerateConstructor.java
@@ -0,0 +1,80 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.LisaacEditor;
+
+public class GenerateConstructor implements IWorkbenchWindowActionDelegate {
+
+
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+
+		IWorkbenchPart part = w.getPartService().getActivePart();
+		if (part instanceof LisaacEditor) {
+			IDocument document = ((LisaacEditor)part).getDocument();
+			//
+			int caret = ((LisaacEditor)part).getViewer().getTextWidget().getCaretOffset();
+			String constructor = getConstructor();
+			try {
+				document.replace(caret, 0, constructor);
+			} catch (BadLocationException e) {
+			}
+			//
+		}
+	}
+	
+	public static String getConstructor() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("\n  //\n  // Creation.\n  //\n"); //$NON-NLS-1$
+		buffer.append("\n  - create:SELF <-"); //$NON-NLS-1$
+		buffer.append("\n  ( + result:SELF;"); //$NON-NLS-1$
+		buffer.append("\n    result := clone;"); //$NON-NLS-1$
+		buffer.append("\n    result.make;"); //$NON-NLS-1$
+		buffer.append("\n    result"); //$NON-NLS-1$
+		buffer.append("\n  );"); //$NON-NLS-1$
+		buffer.append("\n"); //$NON-NLS-1$
+		buffer.append("\n  - make <-"); //$NON-NLS-1$
+		buffer.append("\n  ("); //$NON-NLS-1$
+		buffer.append("\n  );\n\n"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+	
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+	
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/IndentAction.java b/editor/eclipse/src/org/lisaac/ldt/actions/IndentAction.java
new file mode 100644
index 0000000..96a09e0
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/IndentAction.java
@@ -0,0 +1,79 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+import org.lisaac.ldt.editors.LisaacAutoEditStrategy;
+
+/**
+ * Our sample action implements workbench action delegate.
+ * The action proxy will be created by the workbench and
+ * shown in the UI. When the user tries to use the action,
+ * this delegate will be created and execution will be 
+ * delegated to it.
+ * @see IWorkbenchWindowActionDelegate
+ */
+public class IndentAction implements IWorkbenchWindowActionDelegate {
+	/**
+	 * The constructor.
+	 */
+	public IndentAction() {
+	}
+
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+
+		IWorkbenchPart part = w.getPartService().getActivePart();
+		if (part instanceof AbstractLisaacEditor) {
+			IDocument document = ((AbstractLisaacEditor)part).getDocument();
+			//
+			LisaacAutoEditStrategy.fullIndentDocument(document);
+			//
+		}
+	}
+
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+		IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+
+		IWorkbenchPart part = w.getPartService().getActivePart();
+		if (part instanceof AbstractLisaacEditor) {
+			action.setEnabled(true);
+		} else {
+			action.setEnabled(false);
+		}
+	}
+
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/RefreshEditor.java b/editor/eclipse/src/org/lisaac/ldt/actions/RefreshEditor.java
new file mode 100644
index 0000000..7bf43a3
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/RefreshEditor.java
@@ -0,0 +1,28 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorActionDelegate;
+import org.eclipse.ui.IEditorPart;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+import org.lisaac.ldt.model.LisaacModel;
+
+public class RefreshEditor implements IEditorActionDelegate {
+
+	AbstractLisaacEditor targetEditor;
+	
+	public void setActiveEditor(IAction action, IEditorPart targetEditor) {
+		if (targetEditor instanceof AbstractLisaacEditor) {
+			this.targetEditor = (AbstractLisaacEditor) targetEditor;
+		} else {
+			this.targetEditor = null;
+		}
+		LisaacModel.currentEditor = this.targetEditor;
+	}
+
+	public void run(IAction action) {
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/RenamePrototype.java b/editor/eclipse/src/org/lisaac/ldt/actions/RenamePrototype.java
new file mode 100644
index 0000000..854c08a
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/RenamePrototype.java
@@ -0,0 +1,114 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+import org.lisaac.ldt.editors.LisaacScanner;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.refactor.RenamePrototypeRefactor;
+import org.lisaac.ldt.refactor.RenamePrototypeWizard;
+
+public class RenamePrototype implements IWorkbenchWindowActionDelegate {
+
+	private String prototypeName;
+
+	private LisaacModel model;
+
+	private IWorkbenchWindow fWindow = null;
+
+	public void dispose() {
+	}
+
+	public void init(IWorkbenchWindow window) {
+		fWindow = window;
+	}
+
+	public void run(IAction action) {
+		if (fWindow != null && prototypeName != null && model != null) {
+			RenamePrototypeRefactor refactoring = new RenamePrototypeRefactor(
+					prototypeName, model);
+			String name = LisaacMessages.getString("RenamePrototype.0"); //$NON-NLS-1$
+			run(new RenamePrototypeWizard(refactoring, prototypeName, name),
+					fWindow.getShell(), name);
+		}
+	}
+
+	public void run(RefactoringWizard wizard, Shell parent, String dialogTitle) {
+		try {
+			RefactoringWizardOpenOperation operation = new RefactoringWizardOpenOperation(
+					wizard);
+			operation.run(parent, dialogTitle);
+		} catch (InterruptedException exception) {
+			// Do nothing
+		}
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+		prototypeName = null;
+
+		if (selection instanceof ITextSelection) {
+			String text = ((ITextSelection) selection).getText();
+			if (/* text.length() == 0 && */fWindow != null) {
+				// get surrounding word
+				IWorkbenchPart part = fWindow.getPartService().getActivePart();
+				if (part instanceof AbstractLisaacEditor) {
+					IDocument document = ((AbstractLisaacEditor) part)
+							.getDocument();
+					IProject project = ((AbstractLisaacEditor) part)
+							.getProject();
+					model = LisaacModel.getModel(project);
+
+					try {
+						text = selectWord(document,
+								((ITextSelection) selection).getOffset());
+					} catch (BadLocationException e) {
+						action.setEnabled(false);
+						return;
+					}
+				}
+			}
+			if (LisaacScanner.isPrototypeIdentifier(text)) {
+				prototypeName = text;
+			}
+		}
+		action.setEnabled(prototypeName != null);
+	}
+
+	protected String selectWord(IDocument doc, int caretPos)
+			throws BadLocationException {
+		int startPos, endPos;
+
+		int pos = caretPos;
+		char c;
+
+		while (pos >= 0) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			--pos;
+		}
+		startPos = pos + 1;
+		pos = caretPos;
+		int length = doc.getLength();
+
+		while (pos < length) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			++pos;
+		}
+		endPos = pos;
+		return doc.get(startPos, endPos - startPos);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/actions/ToggleComment.java b/editor/eclipse/src/org/lisaac/ldt/actions/ToggleComment.java
new file mode 100644
index 0000000..f815259
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/actions/ToggleComment.java
@@ -0,0 +1,128 @@
+package org.lisaac.ldt.actions;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+
+public class ToggleComment implements IWorkbenchWindowActionDelegate {
+
+	/**
+	 * The action has been activated. The argument of the
+	 * method represents the 'real' action sitting
+	 * in the workbench UI.
+	 * @see IWorkbenchWindowActionDelegate#run
+	 */
+	public void run(IAction action) {
+		IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+
+		IWorkbenchPart part = w.getPartService().getActivePart();
+		if (part instanceof AbstractLisaacEditor) {
+			IDocument document = ((AbstractLisaacEditor)part).getDocument();
+			//
+			ITextSelection selection = (ITextSelection) ((AbstractLisaacEditor)part).getSelectionProvider().getSelection();
+
+			try {
+				if (selection.getStartLine() == selection.getEndLine()) {
+					// single line comment
+					
+					int startPos = document.getLineOffset(selection.getStartLine());
+					int pos = startPos;
+					char c;
+					do {
+						c = document.getChar(pos);
+						if (c != ICharacterScanner.EOF) {
+							if (c == '/') {
+								pos++;
+								c = document.getChar(pos);
+								if (c != ICharacterScanner.EOF && c == '/') {
+									document.replace(pos-1, 2, "");// delete comment //$NON-NLS-1$
+									return;
+								}
+							}
+						}
+						pos++;
+					} while (c != ICharacterScanner.EOF && pos <= startPos+selection.getLength());
+					
+					// add comment
+					document.replace(startPos, 0, "//"); //$NON-NLS-1$
+					
+				} else {
+					// multiline comment
+					int startPos = document.getLineOffset(selection.getStartLine());
+					int pos = startPos;
+					boolean deleteComment=false;
+					char c;
+					do {
+						c = document.getChar(pos);
+						if (c != ICharacterScanner.EOF) {
+							if (c == '/') {
+								pos++;
+								c = document.getChar(pos);
+								if (c != ICharacterScanner.EOF && c == '*') {
+									document.replace(pos-1, 2, "");// delete comment //$NON-NLS-1$
+									deleteComment = true;
+									pos++;
+								}
+							}
+							if (c == '*') {
+								pos++;
+								c = document.getChar(pos);
+								if (c != ICharacterScanner.EOF && c == '/') {
+									if (deleteComment) {
+										document.replace(pos-1, 2, "");// delete comment //$NON-NLS-1$
+									}
+								}
+							}
+						}
+						pos++;
+					} while (c != ICharacterScanner.EOF && pos <= startPos+selection.getLength());
+					
+					// add comment
+					if (! deleteComment) {
+						document.replace(startPos, 0, "/*"); //$NON-NLS-1$
+						int ofs = document.getLineOffset(selection.getEndLine());
+						ofs += document.getLineLength(selection.getEndLine());
+						document.replace(ofs, 0, "*/"); //$NON-NLS-1$
+					}
+				}
+				
+			} catch(BadLocationException e) {
+			}
+			//
+		}
+	}
+
+	/**
+	 * Selection in the workbench has been changed. We 
+	 * can change the state of the 'real' action here
+	 * if we want, but this can only happen after 
+	 * the delegate has been created.
+	 * @see IWorkbenchWindowActionDelegate#selectionChanged
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+
+	/**
+	 * We will cache window object in order to
+	 * be able to provide parent shell for the message dialog.
+	 * @see IWorkbenchWindowActionDelegate#init
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+
+	/**
+	 * We can use this method to dispose of any system
+	 * resources we previously allocated.
+	 * @see IWorkbenchWindowActionDelegate#dispose
+	 */
+	public void dispose() {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/builder/ILisaacErrorHandler.java b/editor/eclipse/src/org/lisaac/ldt/builder/ILisaacErrorHandler.java
new file mode 100644
index 0000000..9e43856
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/builder/ILisaacErrorHandler.java
@@ -0,0 +1,14 @@
+package org.lisaac.ldt.builder;
+
+import org.lisaac.ldt.model.Position;
+
+public interface ILisaacErrorHandler {
+
+	void syntaxError(String msg, Position position);
+	
+	void fatalError(String msg, Position position);
+
+	void warning(String msg, Position position);
+
+	void semanticError(String msg, Position position);
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/builder/LisaacBuilder.java b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacBuilder.java
new file mode 100644
index 0000000..e79b445
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacBuilder.java
@@ -0,0 +1,236 @@
+package org.lisaac.ldt.builder;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.Position;
+
+public class LisaacBuilder extends IncrementalProjectBuilder {
+
+	private LisaacModel model;
+
+
+	class LisaacDeltaVisitor implements IResourceDeltaVisitor {
+		
+		IProgressMonitor monitor;
+		
+		LisaacDeltaVisitor(IProgressMonitor monitor) {
+			this.monitor = monitor;
+		}
+		
+		public boolean visit(IResourceDelta delta) throws CoreException {
+			IResource resource = delta.getResource();
+			switch (delta.getKind()) {
+			case IResourceDelta.ADDED:
+				// handle added resource
+				buildLisaacFile(resource, monitor);
+				break;
+			case IResourceDelta.REMOVED:
+				// handle removed resource
+				removeLisaacFile(resource);
+				break;
+			case IResourceDelta.CHANGED:
+				// handle changed resource
+				buildLisaacFile(resource, monitor);
+				break;
+			}
+			//return true to continue visiting children.
+			return true;
+		}
+	}
+
+	class LisaacResourceVisitor implements IResourceVisitor {
+		IProgressMonitor monitor;
+		
+		LisaacResourceVisitor(IProgressMonitor monitor) {
+			this.monitor = monitor;
+		}
+		public boolean visit(IResource resource) {
+			buildLisaacFile(resource, monitor);
+			//return true to continue visiting children.
+			return true;
+		}
+	}
+
+	class LisaacErrorHandler implements ILisaacErrorHandler {
+
+		private IFile file;
+
+		public LisaacErrorHandler(IFile file) {
+			this.file = file;
+		}
+
+		public void syntaxError(String msg, Position position) {
+			addMarker(file, msg, position, IMarker.SEVERITY_ERROR);
+		}
+
+		public void semanticError(String msg, Position position) {
+			addMarker(file, msg, position, IMarker.SEVERITY_ERROR);
+		}
+
+		public void fatalError(String msg, Position position) {
+			addMarker(file, msg, position, IMarker.SEVERITY_ERROR);
+		}
+
+		public void warning(String msg, Position position) {
+			addMarker(file, msg, position, IMarker.SEVERITY_WARNING);
+		}
+	}
+
+	public static final String BUILDER_ID = "org.lisaac.ldt.builder"; //$NON-NLS-1$
+
+	private static final String MARKER_TYPE = "org.lisaac.ldt.lisaacProblem"; //$NON-NLS-1$
+
+	
+	public static void addMarker(IFile file, String msg, Position position, int severity) {
+		IMarker marker = LisaacBuilder.addMarker(file, msg, position.getLine(), severity);
+		if (marker != null && position.hasRange()) {
+			try {
+				marker.setAttribute(IMarker.CHAR_START, position.getCharStart());
+				marker.setAttribute(IMarker.CHAR_END, position.getCharEnd());
+		
+			} catch (CoreException e) {
+			}
+		}
+	}
+
+	public static IMarker addMarker(IFile file, String message, int lineNumber,
+			int severity) {
+		try {
+			IMarker marker = file.createMarker(MARKER_TYPE);
+			marker.setAttribute(IMarker.MESSAGE, message);
+			marker.setAttribute(IMarker.SEVERITY, severity);
+			if (lineNumber == -1) {
+				lineNumber = 1;
+			}
+			marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+			return marker;
+		} catch (CoreException e) {
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.internal.events.InternalBuilder#build(int,
+	 *      java.util.Map, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public IProject[] build(int kind, Map args, IProgressMonitor monitor)
+	throws CoreException {
+		
+		IProject project = getProject();
+		model = LisaacModel.getModel(project);
+		if (model == null) {
+			// create lisaac model
+			model = new LisaacModel(project);
+			
+		}
+		
+		monitor.beginTask(LisaacMessages.getString("LisaacBuilder.2"), 100); //$NON-NLS-1$
+		
+		model.refreshPresentation();
+		monitor.worked(1);
+		
+		if (kind == CLEAN_BUILD) {
+			model.refreshPath();
+			monitor.worked(10);
+		}
+		
+		if (kind == FULL_BUILD) {
+			fullBuild(monitor);
+		} else {
+			IResourceDelta delta = getDelta(model.getProject());
+			if (delta == null) {
+				fullBuild(monitor);
+			} else {
+				incrementalBuild(delta, monitor);
+			}
+		}
+		return null;
+	}
+
+	private void buildLisaacFile(IResource resource, IProgressMonitor monitor) {
+		if (resource instanceof IFile) {
+			IFile file = (IFile) resource;
+			
+			if (file.isHidden()) {
+				return;
+			}
+			
+			//System.out.println("VISITING => "+file.getName());
+			
+			if (resource.getName().endsWith(".li")) { //$NON-NLS-1$
+				deleteMarkers(file);
+				try {
+					LisaacErrorHandler reporter = new LisaacErrorHandler(file);
+					model.parsePrototype(file, file.getContents(), reporter);
+				} catch (Exception e) {
+				}
+			} else if (resource.getName().endsWith(".lip")) { //$NON-NLS-1$
+				deleteMarkers(file);
+				try {
+					LisaacErrorHandler reporter = new LisaacErrorHandler(file);
+					model.parseLip(file.getName(), file.getContents(), reporter);
+				} catch (Exception e) {
+				}
+			}
+			monitor.worked(1);
+		}
+	}
+
+	private void removeLisaacFile(IResource resource) {
+		if (resource instanceof IFile) {
+			IFile file = (IFile) resource;
+			if (resource.getName().endsWith(".li")) {				 //$NON-NLS-1$
+				deleteMarkers(file);
+				try {
+					model.removePrototype(file);
+				} catch (Exception e) {
+				}
+			} else if (resource.getName().endsWith(".lip")) { //$NON-NLS-1$
+				deleteMarkers(file);
+				try {
+					model.removeLip(file);
+				} catch (Exception e) {
+				}
+			}
+		}  
+	}
+
+	public static void deleteMarkers(IFile file) {
+		try {
+			file.deleteMarkers(MARKER_TYPE, false, IResource.DEPTH_ZERO);
+		} catch (CoreException ce) {
+		}
+	}
+
+	protected void fullBuild(final IProgressMonitor monitor)
+	throws CoreException {
+		try {
+			if (model.getProject() != null) {
+				model.getProject().accept(new LisaacResourceVisitor(monitor));
+				monitor.done();
+			}
+		} catch (CoreException e) {
+		}
+	}
+
+	protected void incrementalBuild(IResourceDelta delta,
+			IProgressMonitor monitor) throws CoreException {
+		// the visitor does the work.
+		delta.accept(new LisaacDeltaVisitor(monitor));
+		monitor.done();
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/builder/LisaacChangeListener.java b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacChangeListener.java
new file mode 100644
index 0000000..ddb9125
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacChangeListener.java
@@ -0,0 +1,32 @@
+package org.lisaac.ldt.builder;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.lisaac.ldt.model.LisaacModel;
+
+public class LisaacChangeListener implements IResourceChangeListener {
+
+	public void resourceChanged(IResourceChangeEvent event) {
+		IResourceDelta delta = event.getDelta();
+
+		IResource resource = delta.getResource(); 
+		if (resource != null) {
+			if (resource instanceof IWorkspaceRoot) {
+				delta = (IResourceDelta) (delta.getAffectedChildren())[0];// TODO go deeper in the delta
+				resource = delta.getResource(); 
+			}
+			if (resource != null) {
+				IProject project = (IProject) resource.getProject();
+				LisaacModel model = LisaacModel.getModel(project);
+
+				if (model != null) {
+					model.setCompiled(false);
+				}
+			}
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/builder/LisaacNature.java b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacNature.java
new file mode 100644
index 0000000..5b1faa9
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacNature.java
@@ -0,0 +1,80 @@
+package org.lisaac.ldt.builder;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+public class LisaacNature implements IProjectNature {
+
+	/**
+	 * ID of this project nature
+	 */
+	public static final String NATURE_ID = "org.lisaac.ldt.lisaac"; //$NON-NLS-1$
+
+	private IProject project;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.resources.IProjectNature#configure()
+	 */
+	public void configure() throws CoreException {
+		IProjectDescription desc = project.getDescription();
+		ICommand[] commands = desc.getBuildSpec();
+
+		for (int i = 0; i < commands.length; ++i) {
+			if (commands[i].getBuilderName().equals(LisaacBuilder.BUILDER_ID)) {
+				return;
+			}
+		}
+
+		ICommand[] newCommands = new ICommand[commands.length + 1];
+		System.arraycopy(commands, 0, newCommands, 0, commands.length);
+		ICommand command = desc.newCommand();
+		command.setBuilderName(LisaacBuilder.BUILDER_ID);
+		newCommands[newCommands.length - 1] = command;
+		desc.setBuildSpec(newCommands);
+		project.setDescription(desc, null);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+	 */
+	public void deconfigure() throws CoreException {
+		IProjectDescription description = getProject().getDescription();
+		ICommand[] commands = description.getBuildSpec();
+		for (int i = 0; i < commands.length; ++i) {
+			if (commands[i].getBuilderName().equals(LisaacBuilder.BUILDER_ID)) {
+				ICommand[] newCommands = new ICommand[commands.length - 1];
+				System.arraycopy(commands, 0, newCommands, 0, i);
+				System.arraycopy(commands, i + 1, newCommands, i,
+						commands.length - i - 1);
+				description.setBuildSpec(newCommands);
+				return;
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.resources.IProjectNature#getProject()
+	 */
+	public IProject getProject() {
+		return project;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
+	 */
+	public void setProject(IProject project) {
+		this.project = project;
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/builder/LisaacParseException.java b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacParseException.java
new file mode 100644
index 0000000..ab7c99e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/builder/LisaacParseException.java
@@ -0,0 +1,14 @@
+package org.lisaac.ldt.builder;
+
+public class LisaacParseException extends Exception {
+	
+	int line;
+	
+	LisaacParseException(String msg, int line) {
+		super(msg);
+	}
+
+	public int getLineNumber() {
+		return line;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/AbstractLisaacEditor.java b/editor/eclipse/src/org/lisaac/ldt/editors/AbstractLisaacEditor.java
new file mode 100644
index 0000000..b37056e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/AbstractLisaacEditor.java
@@ -0,0 +1,269 @@
+package org.lisaac.ldt.editors;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListResourceBundle;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionSupport;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.editors.text.EditorsUI;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
+import org.eclipse.ui.texteditor.ChainedPreferenceStore;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+import org.lisaac.ldt.views.LisaacOutlineView;
+
+/**
+ * Main class for the Lisaac editor
+ * @author Damien Bouvarel
+ */
+public class AbstractLisaacEditor extends TextEditor {
+
+	private ColorManager colorManager;
+
+	/** the outline view. */
+	private LisaacOutlineView outlineView;
+
+	private ProjectionSupport projectionSupport;
+	
+	
+	public AbstractLisaacEditor() {
+		super();
+		colorManager = new ColorManager(LisaacPlugin.getDefault().getPreferenceStore());
+
+		setSourceViewerConfiguration(new LisaacConfiguration(colorManager,this));
+		setDocumentProvider(new LisaacDocumentProvider());
+
+		IPreferenceStore store = LisaacPlugin.getDefault().getPreferenceStore();
+		
+		// wide caret
+		store.setDefault(PREFERENCE_USE_CUSTOM_CARETS, true);
+		store.setDefault(PREFERENCE_WIDE_CARET, true);
+		
+		store = getChainedPreferenceStore();
+		setPreferenceStore(store);
+	}
+	
+	 /**
+     * Returns the preference store to be used by this editor.
+     * @return the preference store to be used by this editor
+     */
+    private IPreferenceStore getChainedPreferenceStore() {
+        List<IPreferenceStore> stores = new ArrayList<IPreferenceStore>();
+
+        stores.add(LisaacPlugin.getDefault().getPreferenceStore());
+        stores.add(EditorsUI.getPreferenceStore());
+
+        return new ChainedPreferenceStore(stores.toArray(new IPreferenceStore[0]));
+    }
+
+    public void createPartControl(Composite parent) {
+       	super.createPartControl(parent);
+    	
+		ProjectionViewer viewer =(ProjectionViewer)getSourceViewer();
+       	
+        projectionSupport = new ProjectionSupport(viewer,getAnnotationAccess(),getSharedColors());
+		projectionSupport.install();
+		
+		//turn projection mode on
+		viewer.doOperation(ProjectionViewer.TOGGLE);		      
+		
+    	annotationModel = viewer.getProjectionAnnotationModel();  
+   
+    }
+    
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.texteditor.AbstractTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
+     */
+    protected ISourceViewer createSourceViewer(Composite parent,
+            IVerticalRuler ruler, int styles) {
+        ISourceViewer viewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
+
+    	// ensure decoration support has been created and configured.
+    	getSourceViewerDecorationSupport(viewer);
+    		
+    	return viewer;
+    }
+    
+    private Annotation[] oldAnnotations;
+	private ProjectionAnnotationModel annotationModel;
+	
+	public void updateFoldingStructure(ArrayList positions) {
+		
+		if (annotationModel == null) {
+			return;
+		}
+		
+		Annotation[] annotations = new Annotation[positions.size()];
+		
+		//this will hold the new annotations along
+		//with their corresponding positions
+		HashMap newAnnotations = new HashMap();
+		
+		for(int i =0;i<positions.size();i++)
+		{
+			ProjectionAnnotation annotation = new ProjectionAnnotation();	
+			newAnnotations.put(annotation,positions.get(i));		
+			annotations[i] = annotation;
+		}
+		annotationModel.modifyAnnotations(oldAnnotations,newAnnotations,null);
+		oldAnnotations=annotations;
+	}
+	
+	public void removeFoldingStructure() {
+		annotationModel.removeAllAnnotations();
+	}
+
+	public IDocument getDocument() {
+		if (getDocumentProvider() == null) {
+			return null;
+		}
+		return getDocumentProvider().getDocument(getEditorInput());
+	}
+
+	public void dispose() {
+		colorManager.dispose();
+		super.dispose();
+	}
+
+	public static class MyResources extends ListResourceBundle {
+		public Object[][] getContents() {
+			return contents;
+		}
+
+		static final Object[][] contents = { { "CorrectionAssist", "CorrectionAssist" }, { "ContentAssistProposal", "ContentAssistProposal" }, { "TemplateProposals", "TemplateProposals" }, };
+	}
+		
+	protected void createActions() {
+		super.createActions();
+
+		MyResources ressources = new MyResources();
+
+		Action action = new ContentAssistAction(ressources, "ContentAssistProposal.", this); //$NON-NLS-1$
+		String id = ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS;
+		action.setActionDefinitionId(id);
+		setAction("ContentAssistProposal", action);  //$NON-NLS-1$
+		markAsStateDependentAction("ContentAssistProposal", true); //$NON-NLS-1$
+	}
+
+	public void doSave(IProgressMonitor progressMonitor) {
+		super.doSave(progressMonitor);
+
+		/*LisaacModel model = LisaacModel.getModel(getProject());
+		if (model != null) {
+			model.incrementalBuild(); 
+		}*/
+	}
+
+	public ISourceViewer getViewer() {
+		return getSourceViewer();
+	}
+
+	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {	
+		colorManager.handlePreferenceStoreChanged(event);
+		super.handlePreferenceStoreChanged(event);
+		
+		String prop = event.getProperty();
+		if (prop.equals(PreferenceConstants.P_LISAAC_COMPLETION_DELAY)) {
+			IContentAssistant assistant = getSourceViewerConfiguration().getContentAssistant(getSourceViewer());
+			
+			Integer delay;
+			try {
+				delay = Integer.valueOf(((String)event.getNewValue()));
+			} catch (Exception e) {
+				delay = 500;
+			}
+			((ContentAssistant) assistant).setAutoActivationDelay(delay);
+		}
+	}
+
+	protected boolean affectsTextPresentation(PropertyChangeEvent event) {
+		return super.affectsTextPresentation(event)
+		|| colorManager.affectsTextPresentation(event);
+	}
+
+
+	/**
+	 * Redraw whole text presentation of the editor
+	 */
+	public void refreshPresentation() {
+		IDocument document = getDocument();
+		if (document != null) {
+			refreshPresentation(0, document.getLength());
+		}
+	}
+	/**
+	 * Redraw region of text presentation of the editor
+	 * @param offset redraw region offset
+	 * @param length redraw region length
+	 */
+	public void refreshPresentation(int offset, int length) {
+		ISourceViewer viewer = getSourceViewer();
+		if (viewer instanceof ITextViewerExtension2) {
+			ITextViewerExtension2 ext = (ITextViewerExtension2) viewer;
+			ext.invalidateTextPresentation(offset, length);
+		}
+	}
+
+	/**
+	 * @return the project for the file that's being edited (or null if not available)
+	 */
+	public IProject getProject() {
+		IEditorInput editorInput = this.getEditorInput();
+		if (editorInput instanceof FileEditorInput) {
+			IFile file = (IFile) ((FileEditorInput) editorInput).getAdapter(IFile.class);
+			return file.getProject();
+		}
+		return null;
+	}
+
+	/**
+	 * @return the file name for the file that's being edited (or null if not available)
+	 */
+	public String getFileName() {
+		IEditorInput editorInput = this.getEditorInput();
+		if (editorInput instanceof FileEditorInput) {
+			IFile file = (IFile) ((FileEditorInput) editorInput).getAdapter(IFile.class);
+			return file.getName();
+		}
+		return null;
+	}
+
+	/**
+	 * @see AbstractTextEditor#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class required) {
+
+		if (IContentOutlinePage.class.equals(required)) {
+			if (outlineView == null) {
+				outlineView = new LisaacOutlineView(getDocumentProvider(), this);
+			}
+			return outlineView;
+		} else {	
+			return super.getAdapter(required);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/ColorManager.java b/editor/eclipse/src/org/lisaac/ldt/editors/ColorManager.java
new file mode 100644
index 0000000..cef19a8
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/ColorManager.java
@@ -0,0 +1,126 @@
+package org.lisaac.ldt.editors;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.StringConverter;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorManager {
+
+	protected Map<RGB,Color> fColorTable = new HashMap<RGB,Color>(10);
+	private Map<String,IToken> tokenTable = new HashMap<String,IToken>(10);
+	private Map<String,String> styleTable = new HashMap<String,String>(10);
+
+	private final IPreferenceStore preferenceStore;
+
+	public ColorManager(IPreferenceStore preferenceStore) {
+		this.preferenceStore = preferenceStore;
+	}
+
+	public void dispose() {
+		Iterator<Color> e = fColorTable.values().iterator();
+		while (e.hasNext())
+			((Color) e.next()).dispose();
+	}
+	public Color getColor(RGB rgb) {
+		Color color = (Color) fColorTable.get(rgb);
+		if (color == null) {
+			color = new Color(Display.getCurrent(), rgb);
+			fColorTable.put(rgb, color);
+		}
+		return color;
+	}
+
+	public IToken getToken(String prefKey, String styleKey) {
+		Token token = (Token) tokenTable.get(prefKey);
+		int style = convertToStyle(styleKey);
+
+		if (token == null) {
+			String colorName = preferenceStore.getString(prefKey);
+			RGB rgb = StringConverter.asRGB(colorName);
+
+			token = new Token(new TextAttribute(getColor(rgb), null, style));
+			tokenTable.put(prefKey, token);
+			styleTable.put(styleKey, prefKey);
+		} else {
+			TextAttribute attrib = (TextAttribute) token.getData();
+			if (attrib.getStyle() != style) {
+				token = new Token(new TextAttribute(attrib.getForeground(), null, style));
+				tokenTable.put(prefKey, token);
+			}
+		}
+		return token;
+	}
+
+	public IToken getToken2(String prefKey, String prefKey2) {
+		Token token = (Token) tokenTable.get(prefKey);
+		if (token == null) {
+			String colorName = preferenceStore.getString(prefKey);
+			RGB rgb = StringConverter.asRGB(colorName);
+			String colorName2 = preferenceStore.getString(prefKey2);
+			RGB rgb2 = StringConverter.asRGB(colorName2);
+			token = new Token(new TextAttribute(getColor(rgb2), getColor(rgb), SWT.NORMAL));
+			tokenTable.put(prefKey, token);
+		}
+		return token;
+	}
+
+	public boolean affectsTextPresentation(PropertyChangeEvent event) {
+		Token token = (Token) tokenTable.get(event.getProperty());
+		return (token != null) || styleTable.get(event.getProperty()) != null;
+	}
+
+	public void handlePreferenceStoreChanged (PropertyChangeEvent event) {
+		String prefKey = event.getProperty();
+		Token token = (Token) tokenTable.get(prefKey);
+		if (token != null) {      	
+			String colorName = preferenceStore.getString(prefKey);
+			RGB rgb = StringConverter.asRGB(colorName);
+
+			if (prefKey.equals(ILisaacColor.PREF_EXTERNAL)) {
+				String colorName2 = preferenceStore.getString(ILisaacColor.PREF_LOCAL_SLOT);
+				RGB rgb2 = StringConverter.asRGB(colorName2);
+				token.setData(new TextAttribute(getColor(rgb2), getColor(rgb), SWT.NORMAL));
+			} else {
+				token.setData(new TextAttribute(getColor(rgb)));
+			}
+		} else { // update style
+			String key = (String) styleTable.get(prefKey);
+			if (key != null) {
+				token = (Token) tokenTable.get(key);
+				if (token != null) {      	
+					int style = convertToStyle(prefKey);
+					TextAttribute attrib = (TextAttribute) token.getData();
+					token.setData(new TextAttribute(attrib.getForeground(), null, style));
+				}
+			}
+		}
+	}
+	
+	public int convertToStyle(String prefKey) {
+		String pref = preferenceStore.getString(prefKey);
+		if (pref.equals(ILisaacColor.PREF_NORMAL)) {
+			return SWT.NORMAL;
+		}
+		if (pref.equals(ILisaacColor.PREF_BOLD)) {
+			return SWT.BOLD;
+		}
+		if (pref.equals(ILisaacColor.PREF_ITALICS)) {
+			return SWT.ITALIC;
+		}
+		if (pref.equals(ILisaacColor.PREF_UNDERLINE)) {
+			return TextAttribute.UNDERLINE;
+		}
+		return SWT.NORMAL; 
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/HoverPresenter.java b/editor/eclipse/src/org/lisaac/ldt/editors/HoverPresenter.java
new file mode 100644
index 0000000..d30d9aa
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/HoverPresenter.java
@@ -0,0 +1,136 @@
+package org.lisaac.ldt.editors;
+
+import java.util.Stack;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Drawable;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.TextPresentation;
+
+
+/**
+ * Format Lisaac hover text.
+ */
+public class HoverPresenter implements DefaultInformationControl.IInformationPresenter, DefaultInformationControl.IInformationPresenterExtension {
+
+	private static final int NONE = 0;
+	private static final int BOLD = 1;
+	private static final int ITALIC = 2;
+	private static final int GRAY = 3;
+	
+	protected ColorManager colorManager;
+	
+	public HoverPresenter(ColorManager colorManager) {
+		this.colorManager = colorManager;
+	}
+	
+	/*
+	 * @see IHoverInformationPresenterExtension#updatePresentation(Drawable drawable, String, TextPresentation, int, int)
+	 * @since 3.2
+	 */
+	public String updatePresentation(Drawable drawable, String hoverInfo,
+			TextPresentation presentation, int maxWidth, int maxHeight) {
+
+		if (hoverInfo == null)
+			return null;
+
+		StringBuffer buffer= new StringBuffer();
+
+		int style = NONE;
+		Stack<Integer> styles = new Stack<Integer>();
+		int startOffset = 0;
+
+		int len = hoverInfo.length();
+		int i = 0;
+		int derive = 0;
+
+		while (i < len) {
+			char c = hoverInfo.charAt(i);
+
+			if (c == '<' && i < len-3) {
+				if (hoverInfo.charAt(i+1) == '/') {
+					// end of style
+
+					c = Character.toLowerCase(hoverInfo.charAt(i+2));
+					if (hoverInfo.charAt(i+3) == '>') {
+						style = styles.pop();
+						startOffset = styles.pop();
+						int styleDerive = styles.pop();
+						
+						int lengthDerive = derive - styleDerive;
+						
+						if (lengthDerive > 0) {
+							// FIXME ranges cannot overlap...
+							style = NONE;
+						}
+						
+						switch(style) {
+						case BOLD:
+							presentation.addStyleRange(new StyleRange(
+									startOffset - styleDerive, i - startOffset - lengthDerive, null, null, SWT.BOLD));
+							break;
+						case ITALIC:
+							presentation.addStyleRange(new StyleRange(
+									startOffset - styleDerive, i - startOffset - lengthDerive, null, null, SWT.ITALIC));
+							break;
+						case GRAY:
+							Color gray = colorManager.getColor(ILisaacColor.GRAY);
+							presentation.addStyleRange(new StyleRange(
+									startOffset - styleDerive, i - startOffset - lengthDerive, gray, null, SWT.NONE));
+							break;
+						}
+						i += 3;
+						derive += 4;
+					}
+					style = NONE;
+				} else {
+					c = Character.toLowerCase(hoverInfo.charAt(i+1));
+					startOffset = i+3;
+					switch(c) {
+					case 'b':
+						style = BOLD;
+						break;
+					case 'i':
+						style = ITALIC;
+						break;
+					case 'g':
+						style = GRAY;
+						break;
+					}
+					c = hoverInfo.charAt(i+2);
+					if (c != '>') {
+						buffer.append(c);
+						style = NONE;
+					} else {
+						i += 2;
+						derive += 3;
+						
+						styles.push(derive);
+						styles.push(startOffset);
+						styles.push(style);
+					}
+				}
+			} else {
+				buffer.append(c);
+			}
+			i++;
+		}
+		
+		return buffer.toString();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter#updatePresentation(org.eclipse.swt.widgets.Display, java.lang.String, org.eclipse.jface.text.TextPresentation, int, int)
+	 * @deprecated
+	 */
+	public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
+		return updatePresentation((Drawable)display, hoverInfo, presentation, maxWidth, maxHeight);
+	}
+}
+
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/ILisaacColor.java b/editor/eclipse/src/org/lisaac/ldt/editors/ILisaacColor.java
new file mode 100644
index 0000000..662de00
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/ILisaacColor.java
@@ -0,0 +1,50 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Associate a color to each token lexical class.
+ * @author Damien Bouvarel
+ */
+public interface ILisaacColor {
+	RGB COMMENT = new RGB(200, 50, 0);
+	RGB PROTOTYPE = new RGB(0, 128, 0);
+	RGB PROTOTYPE_STYLE = new RGB(255, 0, 0);
+	RGB KEYWORD = new RGB(128, 0, 255);
+	RGB CHARACTER = new RGB(128, 128, 255);
+	RGB STRING = new RGB(210, 150, 150);
+	RGB NUMBER = new RGB(128, 0, 255);
+	RGB OPERATOR = new RGB(200, 130, 0);
+	RGB EXTERNAL = new RGB(128, 255, 128);
+	RGB UNDEFINED = new RGB(0, 0, 255);
+	RGB DEFAULT = new RGB(0, 0, 0);
+	
+	RGB GRAY = new RGB(128, 128, 128);
+	
+	String PREF_NORMAL = "normal";
+	String PREF_BOLD = "bold";
+	String PREF_ITALICS = "italic";
+	String PREF_UNDERLINE = "underline";
+	
+	String PREF_COMMENT = "comment_color";
+	String PREF_PROTOTYPE = "prototype_color";
+	String PREF_PROTOTYPE_STYLE = "prototype_style_color";
+	String PREF_KEYWORD = "keyword_color";
+	String PREF_SLOT = "slot_color";
+	String PREF_LOCAL_SLOT = "local_slot_color";
+	String PREF_CHARACTER = "character_color";
+	String PREF_STRING  = "string_color";
+	String PREF_NUMBER = "number_color";
+	String PREF_OPERATOR = "operator_color";
+	String PREF_EXTERNAL = "external_color";
+
+	String STYLE_PROTOTYPE = "prototype_style";
+	String STYLE_PROTOTYPE_STYLE = "prototype_style_style";
+	String STYLE_KEYWORD = "keyword_style";
+	String STYLE_SLOT = "slot_style";
+	String STYLE_LOCAL_SLOT = "local_slot_style";
+	String STYLE_CHARACTER = "character_style";
+	String STYLE_STRING  = "string_style";
+	String STYLE_NUMBER = "number_style";
+	String STYLE_OPERATOR = "operator_style";
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LipEditor.java b/editor/eclipse/src/org/lisaac/ldt/editors/LipEditor.java
new file mode 100644
index 0000000..61457a2
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LipEditor.java
@@ -0,0 +1,25 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+
+/**
+ * Main class for the Lip editor
+ * @author Damien Bouvarel
+ */
+public class LipEditor extends AbstractLisaacEditor {
+
+	public LipEditor() {
+		super();
+	}
+	
+	/**
+     * @see AbstractTextEditor#getAdapter(java.lang.Class)
+     */
+	public Object getAdapter(Class required) {
+        if (IContentOutlinePage.class.equals(required)) {
+            return null; // no outline
+         } else {
+             return super.getAdapter(required);
+         }
+    }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacAutoEditStrategy.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacAutoEditStrategy.java
new file mode 100644
index 0000000..08adc58
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacAutoEditStrategy.java
@@ -0,0 +1,352 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.DocumentCommand;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextUtilities;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+
+
+public class LisaacAutoEditStrategy extends DefaultIndentLineAutoEditStrategy {
+
+	/**
+	 * @see DefaultIndentLineAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
+	 */
+	public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+		editDocumentCommand(d, c);
+	}
+
+	/**
+	 * Customizes the given document command to edit the given document. 
+	 * @param document the document
+	 * @param command the command
+	 * @see DefaultIndentLineAutoEditStrategy#customizeDocumentCommand(IDocument, DocumentCommand)
+	 */
+	protected void editDocumentCommand(IDocument document, DocumentCommand command) {
+		String textCommand = command.text;
+
+		if (textCommand != null) {
+			
+			boolean enableIndent = LisaacPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_LISAAC_INDENT);
+			if (! enableIndent) {
+				return;
+			}
+			String[] lineDelimiters = document.getLegalLineDelimiters();
+			int endOfLineIndex = TextUtilities.endsWith(lineDelimiters, textCommand);
+
+			if (endOfLineIndex > -1) {
+				// this is an end of line
+				indentOnNewLine(document, command);
+			} else if (textCommand.equals("\t")) {
+				// this is a tab
+				indentOnTab(document, command);
+			} else {
+				// this is another character or string
+				indentOnSpecificChar(document, command);
+			}
+		}
+	}
+
+	/**
+	 * Indent One line.
+	 * @param indentLine line to be indented
+	 * @param document 
+	 * @param command
+	 * @return last indentation for the next line
+	 */
+	private static void doIndentLine(int indentLine, IDocument document, DocumentCommand command) {
+		try {
+			//
+			// find last line indent
+			//
+
+			int lastIndent = getIndentWithPreviousLine(indentLine, document);
+
+			//
+			// current line indent
+			//
+			IRegion currentLineInfo = document.getLineInformation(indentLine);
+
+			int lineStart = currentLineInfo.getOffset();
+			int lineEnd = currentLineInfo.getOffset() + currentLineInfo.getLength();
+
+			IRegion originalBlankRegion = getBlankAfterOffset(document, lineStart);
+			int currentIndent = originalBlankRegion.getLength();
+
+			// special case
+			if (lineEnd - originalBlankRegion.getOffset()+currentIndent > 8) {
+				String instr = document.get(originalBlankRegion.getOffset()+currentIndent,8);
+				if (instr.startsWith("Section ")) {
+					lastIndent = 2;
+
+					// insertion in current line
+					if (command != null) {
+						command.text = "";
+						command.offset = lineStart;
+						command.length = currentIndent;
+					} else {
+						document.replace(lineStart, currentIndent, "");
+					}
+					return;
+				}
+			}
+			int i = lineEnd-1;
+			int indent2 = 0;
+			while (i >= lineStart) {
+				char c = document.getChar(i);
+				switch (c) {
+				case '{':
+				case '(':
+				case '[':
+					if (indent2 != 0) {
+						indent2 -= 2;
+					}
+					break;
+				case '}':
+				case ')':
+				case ']':
+					indent2 += 2;
+					break;
+				case '\"'://  string " "
+					do {
+						i--;
+						if (i >= lineStart) {
+							c = document.getChar(i);
+						}
+					} while (i >= lineStart && c != '\"');
+					break;
+				case '\'':// string ' '
+					do {
+						i--;
+						if (i >= lineStart) {
+							c = document.getChar(i);
+						}
+					} while (i >= lineStart && c != '\'');
+					break;
+				}
+				i--;
+			}
+			//
+			// insertion in current line
+			//
+			lastIndent -= indent2;
+
+			if (command != null) {
+				command.text = createString(lastIndent);
+				command.offset = lineStart;
+				command.length = currentIndent;
+			} else {
+				document.replace(lineStart, currentIndent, createString(lastIndent));
+			}
+
+		} catch (BadLocationException excp) {
+			// stop work
+		}
+	}
+
+	/**
+	 * Get line indentation using previous line.
+	 */
+	private static int getIndentWithPreviousLine(int line, IDocument document) {
+		int result = 0;
+		try {
+			//
+			// find last line indent
+			//
+			while (line > 0) {
+				line--;
+				IRegion lineRegion = document.getLineInformation(line);
+
+				int lineStart = lineRegion.getOffset();
+				int lineEnd = lineRegion.getOffset() + lineRegion.getLength();
+
+				IRegion originalBlankRegion = getBlankAfterOffset(document, document.getLineOffset(line));
+				result = originalBlankRegion.getLength();
+
+				// special case
+				if (lineEnd - originalBlankRegion.getOffset()+result > 8) {
+					String instr = document.get(originalBlankRegion.getOffset()+result,8);
+					if (instr.startsWith("Section ")) {
+						result = 2;
+						break;
+					}
+				}
+				int i = lineStart;
+				int deltaIndent = 0;
+				while (i < lineEnd) {
+					char c = document.getChar(i);
+					switch (c) {
+					case '{':
+					case '(':
+					case '[':
+						deltaIndent += 2;
+						break;
+					case '}':
+					case ')':
+					case ']':
+						if (deltaIndent != 0) {
+							deltaIndent -= 2;
+						}
+						break;
+					case '\"'://  string " "
+						do {
+							i++;
+							if (i < lineEnd) {
+								c = document.getChar(i);
+							}
+						} while (i < lineEnd && c != '\"');
+						break;
+					case '\'':// string ' '
+						do {
+							i++;
+							if (i < lineEnd) {
+								c = document.getChar(i);
+							}
+						} while (i < lineEnd && c != '\'');
+						break;
+					}
+					i++;
+				}
+				result += deltaIndent;
+
+				if (getBlankEnd(document,lineStart) != lineEnd) {
+					// not empty line
+					break;
+				} 
+			}
+		} catch (BadLocationException excp) {
+			// stop work
+		}
+		return result;
+	}
+
+	/**
+	 * Get the blank region of given line after offset
+	 */
+	private static int getBlankEnd(IDocument document, int offset) throws BadLocationException {
+		IRegion lineRegion = document.getLineInformationOfOffset(offset);
+		int blankEnd = offset;
+		int maxBlankEnd = lineRegion.getOffset() + lineRegion.getLength();
+
+		while (blankEnd < maxBlankEnd) {
+			char c = document.getChar(blankEnd);
+			if (c != ' ' && c != '\t') {
+				break;
+			}
+			blankEnd++;
+		}
+		return blankEnd;
+	}
+
+	/**
+	 * Customizes the given command to edit the given document when a newline is pressed.
+	 * @param document the document
+	 * @param command the command
+	 */
+	protected void indentOnNewLine(IDocument document, DocumentCommand command) {
+		try {
+			int p = (command.offset == document.getLength() ? command.offset  - 1 : command.offset);
+			int line = document.getLineOfOffset(p);
+
+			// indent previous line
+			doIndentLine(line, document, command);
+
+			// get indent for new line
+			int indent = getIndentWithPreviousLine(line+1, document);
+
+			//
+			// indent new line
+			//
+			//IRegion info = document.getLineInformation(line);
+			command.addCommand(p/*info.getOffset() + info.getLength()*/, 0, "\n"+createString(indent), null);
+			command.shiftsCaret = true;
+			command.caretOffset = p /*info.getOffset() + info.getLength()*/;
+
+		} catch (BadLocationException e) {
+			// stop work
+		}
+	}
+
+	/**
+	 * Get the blank region of given line after offset
+	 */
+	private static IRegion getBlankAfterOffset(IDocument document, int offset) throws BadLocationException {
+		IRegion lineRegion = document.getLineInformationOfOffset(offset);
+		int blankEnd = offset;
+		int maxBlankEnd = lineRegion.getOffset() + lineRegion.getLength();
+
+		while (blankEnd < maxBlankEnd) {
+			char c = document.getChar(blankEnd);
+			if (c != ' ' && c != '\t') {
+				break;
+			}
+			blankEnd++;
+		}
+		return new Region(offset, blankEnd - offset);
+	}
+
+	/**
+	 * Returns a blank string of the given length.
+	 * @param length the length of the string to create
+	 * @return a blank string of the given length
+	 */
+	public static String createString(int length) {
+		StringBuffer buffer = new StringBuffer(length);
+
+		for (int index = 0 ; index < length ; index++) {
+			buffer.append(' ');
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * Customizes the given command to edit the given document when a tabulation is pressed.
+	 * @param document the document
+	 * @param command the command
+	 */
+	protected void indentOnTab(IDocument document, DocumentCommand command) {
+
+		//fullIndentDocument(document);
+
+		try {
+			int p = (command.offset == document.getLength() ? command.offset  - 1 : command.offset);
+			int line = document.getLineOfOffset(p);
+
+			doIndentLine(line, document, command);
+
+		} catch (BadLocationException excp) {
+			// stop work
+		}
+	}
+
+	/**
+	 * Customizes the given command to edit the given document when a specific character is pressed.
+	 * @param document the document
+	 * @param command the command
+	 */
+	protected void indentOnSpecificChar(IDocument document, DocumentCommand command) {
+		// TODO code templates!!!
+	}
+
+	/** 
+	 * Indent correctly the whole document
+	 * @param document the document
+	 */
+	public static void fullIndentDocument(IDocument document) {
+		int line = 0;
+		int maxLine = document.getNumberOfLines();
+
+		while (line < maxLine) {
+			doIndentLine(line, document, null);
+			line++;
+		}
+	}
+	
+	public static void indentLine(int line, IDocument document) {
+		doIndentLine(line, document, null);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacCompletionProcessor.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacCompletionProcessor.java
new file mode 100644
index 0000000..935351c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacCompletionProcessor.java
@@ -0,0 +1,148 @@
+package org.lisaac.ldt.editors;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+import org.eclipse.jface.text.templates.TemplateProposal;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.LisaacCompletionParser;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+import org.lisaac.ldt.templates.LisaacTemplateProcessor;
+
+
+public class LisaacCompletionProcessor implements IContentAssistProcessor {
+
+	private final IContextInformation[] NO_CONTEXTS = new IContextInformation[0];
+	private final char[] PROPOSAL_ACTIVATION_CHARS = new char[] { '.' };
+	private ICompletionProposal[] NO_COMPLETIONS = new ICompletionProposal[0];
+
+	private LisaacTemplateProcessor templates;
+
+
+	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+		try {
+			boolean enableCompletion = LisaacPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_LISAAC_COMPLETION);
+			if (! enableCompletion) {
+				return null;
+			}
+
+			IDocument document = viewer.getDocument();
+			ArrayList<ICompletionProposal> result = new ArrayList<ICompletionProposal>();
+
+			//
+			computeLisaacCompletion(document, offset, result);
+			//
+
+			String prefix= extractPrefix(document, offset);
+
+			if (prefix != null && prefix.length() > 0) {
+				templates = new LisaacTemplateProcessor();
+				ICompletionProposal[] props = templates.computeCompletionProposals(viewer, offset);
+				for (int t=0; t<props.length; t++) {
+					TemplateProposal tp = (TemplateProposal) props[t];
+					if (tp.getDisplayString().startsWith(prefix)) {
+						result.add(props[t]);
+					}
+				}
+			}
+
+			return (ICompletionProposal[]) result.toArray(new ICompletionProposal[result.size()]);
+		} catch (Exception e) {
+			// ... log the exception ...
+			return NO_COMPLETIONS;
+		}
+
+	}
+
+	private void computeLisaacCompletion(IDocument document, int baseOffset, 
+			ArrayList<ICompletionProposal> proposals) {
+		int bracketLevel=0;
+		//
+		// Rewind to '(' '{' ';' '[' ':' '<-'
+		//
+		try {
+			int pos = baseOffset-1;
+			while (pos > 0) {
+				char c = document.getChar(pos);
+				if (c == ';' || c == ':') {
+					break;
+				}
+				if (c == '-' && pos-1 > 0 && document.getChar(pos-1) == '<') {
+					break;
+				}
+				if (c == '(' || c == '{' || c == '[') {
+					if (bracketLevel == 0) {
+						break;
+					}
+					bracketLevel--;
+				}
+				if (c == ')' || c == '}' || c == ']') {
+					bracketLevel++;
+				}
+				pos--;
+			}
+			if (pos > 0) {
+				//
+				// compute lisaac expression type
+				//
+				String contents = document.get(pos+1, baseOffset-1 - pos);
+
+				LisaacCompletionParser parser = new LisaacCompletionParser(contents, null);
+				parser.parseCompletions(pos+1, baseOffset, proposals);
+			}
+		} catch (BadLocationException e) {
+		} catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	protected String extractPrefix(IDocument document, int offset) {
+		int i= offset;
+		if (i > document.getLength())
+			return ""; //$NON-NLS-1$
+
+		try {
+			while (i > 0) {
+				char ch= document.getChar(i - 1);
+				if (!Character.isJavaIdentifierPart(ch))
+					break;
+				i--;
+			}
+
+			return document.get(i, offset - i);
+		} catch (BadLocationException e) {
+			return ""; //$NON-NLS-1$
+		}
+	}
+
+	public IContextInformation[] computeContextInformation(ITextViewer viewer,
+			int offset) {
+		return NO_CONTEXTS;
+	}
+
+
+	public char[] getCompletionProposalAutoActivationCharacters() {
+		return PROPOSAL_ACTIVATION_CHARS;
+	}
+
+
+	public char[] getContextInformationAutoActivationCharacters() {
+		return null;
+	}
+
+	public IContextInformationValidator getContextInformationValidator() {
+		return null;
+	}
+
+	public String getErrorMessage() {
+		return "Lisaac Completion error";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacConfiguration.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacConfiguration.java
new file mode 100644
index 0000000..4af210f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacConfiguration.java
@@ -0,0 +1,195 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.text.DefaultIndentLineAutoEditStrategy;
+import org.eclipse.jface.text.IAutoEditStrategy;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.URLHyperlinkDetector;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+
+/**
+ * Manage the configuration of syntax coloration for lisaac documents.
+ */
+public class LisaacConfiguration extends SourceViewerConfiguration {
+	private LisaacDoubleClickStrategy doubleClickStrategy;
+	private LisaacScanner scanner;
+	private ColorManager colorManager;
+
+	private ContentAssistant contentAssistant = null;
+	private ITextHover textHover = null;
+	
+	private AbstractLisaacEditor editor;
+	
+	public LisaacConfiguration(ColorManager colorManager, AbstractLisaacEditor editor) {
+		this.colorManager = colorManager;
+		this.editor = editor;
+	}
+	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+		return new String[] {
+			IDocument.DEFAULT_CONTENT_TYPE,
+			LisaacPartitionScanner.LISAAC_COMMENT
+		};
+	}
+	
+	public ITextDoubleClickStrategy getDoubleClickStrategy(
+		ISourceViewer sourceViewer,
+		String contentType) {
+		if (doubleClickStrategy == null)
+			doubleClickStrategy = new LisaacDoubleClickStrategy();
+		return doubleClickStrategy;
+	}
+
+	/**
+	 * Returns the content assistant ready to be used with the given source viewer.
+	 * This implementation always returns <code>null</code>.
+	 *
+	 * @param sourceViewer the source viewer to be configured by this configuration
+	 * @return a content assistant or <code>null</code> if content assist should not be supported
+	 */
+	public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+		if (contentAssistant == null) {	
+			contentAssistant = new ContentAssistant();
+			IContentAssistProcessor cap = new LisaacCompletionProcessor();
+			contentAssistant.setContentAssistProcessor(cap, IDocument.DEFAULT_CONTENT_TYPE);
+			//
+			contentAssistant.setRepeatedInvocationMode(true);
+			contentAssistant.setStatusLineVisible(true);
+			contentAssistant.setStatusMessage(LisaacMessages.getString("LisaacConfiguration_0")); //$NON-NLS-1$
+			//
+			
+			int delay;
+			try {
+				delay = LisaacPlugin.getDefault().getPreferenceStore().getInt(PreferenceConstants.P_LISAAC_COMPLETION_DELAY);
+			} catch (Exception e) {
+				delay = 500;
+			}
+			contentAssistant.enableAutoActivation(true);
+			contentAssistant.setAutoActivationDelay(delay);
+			contentAssistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
+		}
+        return contentAssistant;
+	}
+
+	
+	public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+		if (textHover != null) {
+			return textHover;
+		}
+		if (editor != null) {
+			IProject project = editor.getProject();
+	
+			LisaacModel model = LisaacModel.getModel(project);
+			textHover = new LisaacTextHover(model, editor.getFileName(), colorManager);
+		}
+		return textHover;
+	}
+	
+	/**
+     * @see SourceViewerConfiguration#getAutoEditStrategies(ISourceViewer, String)
+     */
+    public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
+    	
+        if (contentType.equals(LisaacPartitionScanner.LISAAC_COMMENT)) {
+            return new IAutoEditStrategy[] { new DefaultIndentLineAutoEditStrategy() };
+
+        } else if (contentType.equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+            return new IAutoEditStrategy[] { new LisaacAutoEditStrategy() };
+            
+        } else {
+            return super.getAutoEditStrategies(sourceViewer, contentType);
+        }
+    }
+	
+    /**
+     * @see SourceViewerConfiguration#getIndentPrefixes(ISourceViewer, String)
+     */
+    public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+        return new String[]{ new String("  "), new String() }; //$NON-NLS-1$
+    }
+    
+    /**
+	 * Returns the hyperlink detectors which be used to detect hyperlinks
+	 * in the given source viewer. 
+	 * @param sourceViewer the source viewer to be configured by this configuration
+	 * @return an array with hyperlink detectors or <code>null</code> if no hyperlink support should be installed
+	 * @since 3.1
+	 */
+	public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+		if (sourceViewer == null)
+			return null;
+
+		return new IHyperlinkDetector[] { new LisaacHyperLinkDetector(), new URLHyperlinkDetector() };
+	}
+    
+	protected LisaacScanner getLisaacScanner() {
+		if (scanner == null) {
+			scanner = new LisaacScanner(colorManager);
+			scanner.setDefaultReturnToken(
+				new Token(
+					new TextAttribute(
+						colorManager.getColor(ILisaacColor.DEFAULT))));
+		}
+		return scanner;
+	}
+	
+	public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+		PresentationReconciler reconciler = new PresentationReconciler();
+			
+		LisaacDamagerRepairer dr = new LisaacDamagerRepairer(getLisaacScanner());
+		reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+		reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+		NonRuleBasedDamagerRepairer ndr =
+			new NonRuleBasedDamagerRepairer(
+				new TextAttribute(
+					colorManager.getColor(ILisaacColor.COMMENT)));
+		reconciler.setDamager(ndr, LisaacPartitionScanner.LISAAC_COMMENT);
+		reconciler.setRepairer(ndr, LisaacPartitionScanner.LISAAC_COMMENT);
+		
+		return reconciler;
+	}
+	
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getQuickAssistAssistant(org.eclipse.jface.text.source.ISourceViewer)
+     */
+  /*  public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
+        // create a content assistant:
+    	
+    	 QuickAssistAssistant assistant = new QuickAssistAssistant();
+    	 assistant.setQuickAssistProcessor(new LisaacQuickAssistProcessor());
+    	 assistant.setStatusLineVisible(true);
+    	 assistant.setStatusMessage("Lisaac QuickFix");
+    	 
+    	 
+        assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
+
+        
+        return assistant;
+    }
+*/
+	/*
+	public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer){
+        QuickAssistAssistant qaa = new QuickAssistAssistant();
+        qaa.setQuickAssistProcessor(new LisaacQuickAssistProcessor());
+        qaa.setStatusLineVisible(true);
+        qaa.setStatusMessage("Lisaac QuickFix");
+        return qaa;
+    }*/
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDamagerRepairer.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDamagerRepairer.java
new file mode 100644
index 0000000..6589696
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDamagerRepairer.java
@@ -0,0 +1,60 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.ITokenScanner;
+import org.eclipse.jface.text.rules.Token;
+
+public class LisaacDamagerRepairer extends DefaultDamagerRepairer{
+
+	public LisaacDamagerRepairer(ITokenScanner scanner) {
+		super(scanner);
+	}
+	
+	/*
+	 * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+	 */
+	public void createPresentation(TextPresentation presentation, ITypedRegion region) {
+
+		if (fScanner == null) {
+			// will be removed if deprecated constructor will be removed
+			addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute);
+			return;
+		}
+
+		int lastStart= region.getOffset();
+		int length= 0;
+		boolean firstToken= true;
+		IToken lastToken= Token.UNDEFINED;
+		TextAttribute lastAttribute= getTokenTextAttribute(lastToken);
+
+		fScanner.setRange(fDocument, lastStart, region.getLength());
+
+		while (true) {
+			IToken token= fScanner.nextToken();
+			if (token.isEOF())
+				break;
+
+			// define text attribute for this token
+			TextAttribute attribute= getTokenTextAttribute(token);
+			if (lastAttribute != null && lastAttribute.equals(attribute)) {
+				length += fScanner.getTokenLength();
+				firstToken= false;
+			} else {
+				if (!firstToken)
+					addRange(presentation, lastStart, length, lastAttribute);
+				firstToken= false;
+				lastToken= token;
+				lastAttribute= attribute;
+				lastStart= fScanner.getTokenOffset();
+				length= fScanner.getTokenLength();
+			}			
+		}
+		
+		// process last token
+		addRange(presentation, lastStart, length, lastAttribute);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDocumentProvider.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDocumentProvider.java
new file mode 100644
index 0000000..af20e26
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDocumentProvider.java
@@ -0,0 +1,29 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.FastPartitioner;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+
+/**
+ * Handle the creation of lisaac document.<br>
+ * Attach lisaac partitioning to this documents. 
+ */
+public class LisaacDocumentProvider extends FileDocumentProvider {
+	
+	protected IDocument createDocument(Object element) throws CoreException {
+		IDocument document = super.createDocument(element);
+		if (document != null) {
+			IDocumentPartitioner partitioner =
+				new FastPartitioner(
+					new LisaacPartitionScanner(),
+					new String[] {
+						LisaacPartitionScanner.LISAAC_DEFAULT,
+						LisaacPartitionScanner.LISAAC_COMMENT });
+			partitioner.connect(document);
+			document.setDocumentPartitioner(partitioner);
+		}
+		return document;
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDoubleClickStrategy.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDoubleClickStrategy.java
new file mode 100644
index 0000000..7aa3ea7
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacDoubleClickStrategy.java
@@ -0,0 +1,56 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.*;
+
+public class LisaacDoubleClickStrategy implements ITextDoubleClickStrategy {
+	protected ITextViewer fText;
+
+	public void doubleClicked(ITextViewer part) {
+		int pos = part.getSelectedRange().x;
+
+		if (pos < 0)
+			return;
+
+		fText = part;
+		selectWord(pos);
+	}
+	
+	protected boolean selectWord(int caretPos) {
+		IDocument doc = fText.getDocument();
+		int startPos, endPos;
+
+		try {
+			int pos = caretPos;
+			char c;
+
+			while (pos >= 0) {
+				c = doc.getChar(pos);
+				if (!Character.isJavaIdentifierPart(c))
+					break;
+				--pos;
+			}
+			startPos = pos;
+			pos = caretPos;
+			int length = doc.getLength();
+
+			while (pos < length) {
+				c = doc.getChar(pos);
+				if (!Character.isJavaIdentifierPart(c))
+					break;
+				++pos;
+			}
+			endPos = pos;
+			selectRange(startPos, endPos);
+			return true;
+
+		} catch (BadLocationException x) {
+		}
+		return false;
+	}
+
+	private void selectRange(int startPos, int stopPos) {
+		int offset = startPos + 1;
+		int length = stopPos - offset;
+		fText.setSelectedRange(offset, length);
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacEditor.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacEditor.java
new file mode 100644
index 0000000..e11fb81
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacEditor.java
@@ -0,0 +1,41 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+
+/**
+ * Main class for the Lisaac editor
+ * @author Damien Bouvarel
+ */
+public class LisaacEditor extends AbstractLisaacEditor {
+
+	public LisaacEditor() {
+		super();
+	}
+
+	public void refreshPresentation() {
+		super.refreshPresentation();
+
+		// refresh folding
+		boolean doFold = LisaacPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_LISAAC_FOLD);
+		if (! doFold) {
+			removeFoldingStructure();
+			return;
+		}
+		LisaacModel model = LisaacModel.getModel(getProject());
+		if (model != null) {
+			Prototype p;
+			try {
+				p = model.getPrototype(LisaacModel.extractPrototypeName(getFileName()));
+				if (p != null) {
+					updateFoldingStructure(p.getPositions());
+				}
+			} catch (CoreException e) {
+			}
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacHyperLinkDetector.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacHyperLinkDetector.java
new file mode 100644
index 0000000..5bfa51e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacHyperLinkDetector.java
@@ -0,0 +1,62 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+
+
+public class LisaacHyperLinkDetector extends AbstractHyperlinkDetector {
+
+	public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
+			IRegion region, boolean canShowMultipleHyperlinks) {
+
+		if (region == null || textViewer == null)
+			return null;
+
+		IDocument document= textViewer.getDocument();
+		if (document == null)
+			return null;
+
+		try {
+			int offset= region.getOffset();
+			
+			IRegion wordRegion = selectWord(document, offset);
+			String prototypeString = document.get(wordRegion.getOffset(), wordRegion.getLength());
+			
+			return new IHyperlink[] {new PrototypeHyperLink(wordRegion, prototypeString)};
+
+		} catch (BadLocationException e) {
+			return null;
+		}
+	}
+
+	protected IRegion selectWord(IDocument doc, int caretPos) throws BadLocationException {
+		int startPos, endPos;
+
+		int pos = caretPos;
+		char c;
+
+		while (pos >= 0) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			--pos;
+		}
+		startPos = pos+1;
+		pos = caretPos;
+		int length = doc.getLength();
+		
+		while (pos < length) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			++pos;
+		}
+		endPos = pos;
+		return new Region(startPos, endPos - startPos);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacPartitionScanner.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacPartitionScanner.java
new file mode 100644
index 0000000..0ef3916
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacPartitionScanner.java
@@ -0,0 +1,30 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.rules.*;
+
+/**
+ * Define rules to allow document partitioning.<br>
+ * We have two types of partition: lisaac code and lisaac comments.
+ */
+public class LisaacPartitionScanner extends RuleBasedPartitionScanner {
+	public final static String LISAAC_COMMENT = "__lisaac_comment";
+	public final static String LISAAC_DEFAULT = "__lisaac_default";
+
+	public LisaacPartitionScanner() {
+		/*
+		 * Define rules to identify comment partition, the rest of documents is default partition
+		 */
+		IToken comment = new Token(LISAAC_COMMENT);
+		
+		IPredicateRule[] rules = new IPredicateRule[4];
+
+		rules[0] = new MultiLineRule("/*", "*/", comment);
+		rules[1] = new EndOfLineRule("//", comment);
+
+		// avoid processing comment inside lisaac strings
+		rules[2] = new MultiLineRule("\"", "\"", Token.UNDEFINED, '\0', true);
+		rules[3] = new SingleLineRule("`", "`", Token.UNDEFINED, '\0', true);
+		
+		setPredicateRules(rules);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacResourceDecorator.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacResourceDecorator.java
new file mode 100644
index 0000000..8e9babe
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacResourceDecorator.java
@@ -0,0 +1,94 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.lisaac.ldt.LisaacPlugin;
+
+/**
+ * Handle image decoration in Navigator View
+ */
+public class LisaacResourceDecorator implements ILightweightLabelDecorator {
+
+	private static ImageDescriptor OVERLAY_ERROR = LisaacPlugin.getImageDescriptor("/icons/error_co.gif");
+	private static ImageDescriptor OVERLAY_WARNING = LisaacPlugin.getImageDescriptor("/icons/warning_co.gif");
+
+	private static ImageDescriptor OVERLAY_SOURCE_FOLDER = LisaacPlugin.getImageDescriptor("/icons/source-folder.gif");
+	private static ImageDescriptor OVERLAY_LIB = LisaacPlugin.getImageDescriptor("/icons/library.gif");
+
+	public static String SOURCE_FOLDER_PROPERTY = "source_folder";
+	public static String LIB_PROPERTY = "lib";
+	
+	public void decorate(Object element, IDecoration decoration) {
+		if (element instanceof IResource) {
+			int type;
+			try {
+				type = getTypeFromMarkers((IResource) element);
+				if (type == 1) {
+					decoration.addOverlay(OVERLAY_WARNING);
+				} else if (type == 2) {
+					decoration.addOverlay(OVERLAY_ERROR);
+				}
+				if (element instanceof IFolder) {
+					String sourceFolder = ((IResource) element).getPersistentProperty(
+							new QualifiedName("", SOURCE_FOLDER_PROPERTY));
+					if (sourceFolder != null && sourceFolder != "") {
+						decoration.addOverlay(OVERLAY_SOURCE_FOLDER);
+					} else {
+						String lib = ((IResource) element).getPersistentProperty(
+								new QualifiedName("", LIB_PROPERTY));
+						if (lib != null && lib != "") {
+							decoration.addOverlay(OVERLAY_LIB);
+						}
+					}
+				}
+			} catch (CoreException e) {
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private int getTypeFromMarkers(IResource res) throws CoreException {
+		if (res == null || !res.isAccessible()) {
+			return 0;
+		}
+		int markerType = 0;
+
+		IMarker[] markers = res.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+		if (markers != null) {
+			for (int i = 0; i < markers.length && (markerType != 2); i++) {
+				IMarker curr = markers[i];
+
+				int priority = curr.getAttribute(IMarker.SEVERITY, -1);
+				if (priority == IMarker.SEVERITY_WARNING) {
+					markerType = 1;
+				} else if (priority == IMarker.SEVERITY_ERROR) {
+					markerType = 2;
+				}
+			}
+		}
+		return markerType;
+	}
+
+	public void dispose() {
+	}
+
+	public boolean isLabelProperty(Object element, String property) {
+		return true;
+	}
+
+	// TODO refresh decorator on marker update
+	public void addListener(ILabelProviderListener listener) {
+	}
+
+	
+	public void removeListener(ILabelProviderListener listener) {		
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacScanner.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacScanner.java
new file mode 100644
index 0000000..1690eb1
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacScanner.java
@@ -0,0 +1,336 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.rules.*;
+import org.lisaac.ldt.model.ILisaacModel;
+
+class LisaacWhitespaceDetector implements IWhitespaceDetector {
+	public boolean isWhitespace(char c) {
+		return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+		// return c.isWhitespace();
+	}
+}
+
+class LisaacPrototypeDetector implements IWordDetector {
+	public boolean isWordPart(char c) {
+		return (Character.isLetter(c) && Character.isUpperCase(c))
+		|| Character.isDigit(c) || c == '_';
+	}
+
+	public boolean isWordStart(char c) {
+		return (Character.isLetter(c) && Character.isUpperCase(c)) || c == '_';
+	}
+}
+
+class LisaacNumberDetector implements IWordDetector {
+	public boolean isWordPart(char c) {
+		return Character.isLetterOrDigit(c);
+	}
+
+	public boolean isWordStart(char c) {
+		return Character.isDigit(c);
+	}
+}
+
+class LisaacKeywordDetector implements IWordDetector {
+	public boolean isWordPart(char c) {
+		return Character.isLetter(c) && Character.isLowerCase(c);
+	}
+
+	public boolean isWordStart(char c) {
+		return Character.isLetter(c) && Character.isUpperCase(c);
+	}
+}
+
+class LisaacWordDetector implements IWordDetector {
+	public boolean isWordPart(char c) {
+		return (Character.isLetter(c) && Character.isLowerCase(c))
+		|| Character.isDigit(c) || c == '_';
+	}
+
+	public boolean isWordStart(char c) {
+		return (Character.isLetter(c) && Character.isLowerCase(c)) || c == '_';
+	}
+}
+
+/**
+ * Lisaac code scanner.<br>
+ * Scan a range of a document into tokens, the scanner is used by the repairer
+ * to create the text presentation.
+ */
+public class LisaacScanner extends RuleBasedScanner {
+
+	// Lisaac tokens
+	private IToken stringToken;
+	private IToken characterToken;
+	private IToken numberToken;
+	private IToken prototypeToken;
+	private IToken prototypeStyleToken;
+	private IToken keywordToken;
+	private IToken localVariableToken;
+	private IToken operatorToken;
+	private IToken externalToken;
+	private IToken undefinedToken;
+
+	/**
+	 * Creates a new Lisaac scanner.
+	 */
+	public LisaacScanner(ColorManager manager) {
+		/*
+		 * Create lisaac tokens.
+		 */
+
+		stringToken = manager.getToken(ILisaacColor.PREF_STRING, ILisaacColor.STYLE_STRING);
+		characterToken = manager.getToken(ILisaacColor.PREF_CHARACTER, ILisaacColor.STYLE_CHARACTER);
+		numberToken = manager.getToken(ILisaacColor.PREF_NUMBER, ILisaacColor.STYLE_NUMBER);
+		prototypeToken = manager.getToken(ILisaacColor.PREF_PROTOTYPE, ILisaacColor.STYLE_PROTOTYPE);
+		prototypeStyleToken = manager.getToken(ILisaacColor.PREF_PROTOTYPE_STYLE, ILisaacColor.STYLE_PROTOTYPE_STYLE);
+		keywordToken = manager.getToken(ILisaacColor.PREF_KEYWORD, ILisaacColor.STYLE_KEYWORD);
+		localVariableToken = manager.getToken(ILisaacColor.PREF_LOCAL_SLOT, ILisaacColor.STYLE_LOCAL_SLOT);
+		operatorToken = manager.getToken(ILisaacColor.PREF_OPERATOR, ILisaacColor.STYLE_OPERATOR);
+		externalToken = manager.getToken2(ILisaacColor.PREF_EXTERNAL, ILisaacColor.PREF_LOCAL_SLOT);
+		
+		undefinedToken = manager.getToken(ILisaacColor.PREF_SLOT, ILisaacColor.STYLE_SLOT);
+			//new Token(getAttribute(ILisaacColor.UNDEFINED));
+
+		/*
+		 * Create basic lisaac rules.
+		 */
+		IRule[] rules = new IRule[8];
+
+		// Add rule for processing strings
+		rules[0] = new MultiLineRule("\"", "\"", stringToken, '\0', true);// double
+		// quotes
+		rules[1] = new SingleLineRule("'", "'", characterToken, '\0', true);// simple
+		// quotes
+
+		// Add generic whitespace rule.
+		rules[2] = new WhitespaceRule(new LisaacWhitespaceDetector());
+
+		// keywords rule
+		WordRule wr = new WordRule(new LisaacKeywordDetector(), Token.UNDEFINED);
+		String[] keywords = ILisaacModel.keywords;
+		for (int i = 0; i < keywords.length; i++) {
+			wr.addWord(keywords[i], keywordToken);
+		}
+		rules[3] = wr;
+
+		// prototype rule
+		rules[4] = new WordRule(new LisaacPrototypeDetector(), prototypeToken);
+
+		// simple lisaac word rule
+		//rules[5] = new WordRule(new LisaacWordDetector(), undefinedToken);
+		rules[5] = new LisaacWordRule(new LisaacWordDetector(), undefinedToken, localVariableToken);
+
+		// lisaac external
+		rules[6] = new SingleLineRule("`", "`", externalToken, '\0', true);// back
+		// quotes
+
+		// number rule
+		rules[7] = new WordRule(new LisaacNumberDetector(), numberToken);
+
+		// add basic rules
+		setRules(rules);
+	}
+
+	/*
+	 * @see ITokenScanner#nextToken()
+	 */
+	public IToken nextToken() {
+
+		fTokenOffset = fOffset;
+		fColumn = UNDEFINED;
+
+		//
+		// Lisaac scan
+		//
+
+		// start processing basic rules first
+		if (fRules != null) {
+			for (int i = 0; i < fRules.length; i++) {
+				IToken token = (fRules[i].evaluate(this));
+				if (!token.isUndefined())
+					return token;
+			}
+		}
+
+		// none of the basic rules fired
+		char c = (char) read();
+		if (c != ICharacterScanner.EOF) {
+			if (c == '+' || c == '-') {
+				if (getColumn() == 3) {// slot style
+					return prototypeStyleToken;
+				}
+				if (detectLocalSlot()) { // local slot style
+					return prototypeStyleToken;
+				}
+				return operatorToken;// arithmetic + or -
+			}
+			if (c == '<') {// list affect
+				c = (char) read();
+				if (c == '-') {
+					return fDefaultReturnToken;
+				} else {
+					unread();
+					return operatorToken;
+				}
+			}
+			if (c == ':') {// slot affect
+				c = (char) read();
+				if (c != '=') {
+					unread();
+					if (detectBlockType()) {
+						return prototypeToken;
+					}
+				}
+				return fDefaultReturnToken;
+			}
+			if (c == '?') {// ?= affect
+				c = (char) read();
+				if (c == '=') {
+					return fDefaultReturnToken;
+				}
+				unread();
+				return operatorToken;
+			}
+			if (c == '*' || c == '/' || c == '&' || c == '$' || c == '|'
+				|| c == '>' || c == '=' || c == '!' || c == '~' || c == '@'
+					|| c == '#' || c == '^') {
+				return operatorToken;
+			}
+			if (c == '{' || c == '}') {
+				return operatorToken;
+			}
+		}
+
+		unread();
+		//
+		// End of Lisaac scan
+		//
+
+		if (read() == EOF)
+			return Token.EOF;
+		return fDefaultReturnToken;
+	}
+
+	private boolean readIndentifier() {
+		char c;
+		int i = 0;
+
+		do {
+			c = (char) read();
+			i++;
+		} while (c != ICharacterScanner.EOF
+				&& (Character.isLetterOrDigit(c) || c == '_'));
+		unread();
+
+		return i > 1;
+	}
+
+	private void readSpace() {
+		char c;
+
+		do {
+			c = (char) read();
+		} while (c != ICharacterScanner.EOF && Character.isWhitespace(c));
+		unread();
+	}
+
+	private boolean detectLocalSlot() {
+		int oldOffset = fOffset;
+		boolean result = false;
+
+		readSpace();
+		while (readIndentifier()) {
+			readSpace();
+			char c = (char) read();
+			if (c == ICharacterScanner.EOF)
+				break;
+
+			if (c == ':') {
+				result = true;
+				break;
+			}
+			if (c != ',')
+				break;
+
+			readSpace();
+		}
+		fOffset = oldOffset;// unread all
+		fColumn = UNDEFINED;
+		return result;
+	}
+
+	private boolean detectBlockType() {
+		int oldOffset = fOffset;
+		boolean result = false;
+
+		readSpace();
+		char c = (char) read();
+		if (c != ICharacterScanner.EOF && c == '{') {
+			int level = 1;
+			do {
+				c = (char) read();
+				if (c != ICharacterScanner.EOF) {
+					if (c == '{') {
+						level++;
+					} else if (c == '}') {
+						level--;
+
+					} else if (c == '\n' || c == '\r') {
+						break; // no multiline type
+
+					} else if (((int)c) == 65535) {
+						break;  // bug!
+					}
+				}
+			} while (c != ICharacterScanner.EOF && level != 0);
+
+			if (level == 0) {
+				result = true;
+			}
+		} 
+		if (! result) {
+			fOffset = oldOffset;// unread all
+			fColumn = UNDEFINED;
+		}
+		return result;
+	}
+
+	public int getOffset() {
+		return fOffset;
+	}
+
+	public static boolean isPrototypeIdentifier(String word) {
+		return detectKeyword(word, new LisaacPrototypeDetector());
+	}
+	
+	public static boolean isIdentifier(String word) {
+		return detectKeyword(word, new LisaacWordDetector());
+	}
+
+	public static boolean isKeywordIdentifier(String word) {
+		return detectKeyword(word, new LisaacKeywordDetector());
+	}
+	
+	private static boolean detectKeyword(String word, IWordDetector detector) {
+		int i = 0;
+		char c;
+		boolean b = true;
+		
+		if (word.length() > 0 && detector.isWordStart(word.charAt(0))) {
+			if (word.length() == 1) {
+				return true;
+			}
+			i = 1;
+			do {
+				c = word.charAt(i);
+				b = detector.isWordPart(c);
+				i++;
+			} while (i < word.length() && b);
+			if (! b) {
+				return false;
+			}
+		}
+		return i == word.length();
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacTextHover.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacTextHover.java
new file mode 100644
index 0000000..1ffb8dc
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacTextHover.java
@@ -0,0 +1,119 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextHoverExtension;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.swt.widgets.Shell;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.IVariable;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Slot;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+
+public class LisaacTextHover implements ITextHover, ITextHoverExtension {
+
+	protected LisaacModel model;
+	protected String filename;
+	protected ColorManager colorManager;
+
+	public LisaacTextHover(LisaacModel model, String filename, ColorManager colorManager) {
+		super();
+		this.model = model;
+		this.filename = filename;
+		this.colorManager = colorManager;
+	}
+
+	public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+		try {
+			boolean enableHover = LisaacPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.P_LISAAC_HOVER);
+			if (! enableHover) {
+				return null;
+			}
+			
+			String text = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
+			if (LisaacScanner.isPrototypeIdentifier(text)) {
+				// get prototype info
+
+				Prototype prototype = model.getPrototype(text);
+				if (prototype != null) {
+					return "<I>Prototype</I> : "+prototype.getHoverInformation();
+				}
+			} else if (LisaacScanner.isIdentifier(text)) {
+				// get slot info
+
+				Prototype prototype = model.getPrototype(LisaacModel.extractPrototypeName(filename));
+				if (prototype != null) {
+					Slot slot = prototype.getSlotFromKeyword(text, prototype.openParser(), hoverRegion.getOffset());
+					if (slot != null) {
+						return "<I>Slot</I> : "+slot.getHoverInformation();
+					} else {
+						slot = prototype.getSlot(hoverRegion.getOffset());
+						IVariable variable = slot.getVariable(text, hoverRegion.getOffset());
+						if (variable != null) {
+							return variable.getHoverInformation();
+						}
+					}
+				}
+			}
+		} catch (BadLocationException e) {
+		} catch (CoreException e) {
+		}		
+		return null;
+	}
+
+
+	public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+		try {
+			return selectWord(textViewer.getDocument(), offset);
+		} catch (BadLocationException e) {
+		}
+		return new Region(offset, 0);
+	}
+
+
+	/*
+	 * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
+	 */
+	public IInformationControlCreator getHoverControlCreator() {
+		return new IInformationControlCreator() {
+			public IInformationControl createInformationControl(Shell parent) {
+				return new DefaultInformationControl(parent, "Lisaac", new HoverPresenter(colorManager));
+			}
+		};
+	}
+
+	protected IRegion selectWord(IDocument doc, int caretPos) throws BadLocationException {
+		int startPos, endPos;
+
+		int pos = caretPos;
+		char c;
+
+		while (pos >= 0) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			--pos;
+		}
+		startPos = pos+1;
+		pos = caretPos;
+		int length = doc.getLength();
+
+		while (pos < length) {
+			c = doc.getChar(pos);
+			if (!Character.isJavaIdentifierPart(c))
+				break;
+			++pos;
+		}
+		endPos = pos;
+		return new Region(startPos, endPos - startPos);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/LisaacWordRule.java b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacWordRule.java
new file mode 100644
index 0000000..17839ed
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/LisaacWordRule.java
@@ -0,0 +1,99 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.rules.ICharacterScanner;
+import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Slot;
+
+public class LisaacWordRule extends WordRule {
+
+	private IToken localVariableToken;
+	
+	private StringBuffer fBuffer= new StringBuffer();
+	
+	
+	public LisaacWordRule(IWordDetector detector, IToken defaultToken, IToken localVariableToken) {
+		super(detector, defaultToken);
+		this.localVariableToken = localVariableToken;
+	}
+
+	/*
+	 * @see IRule#evaluate(ICharacterScanner)
+	 */
+	public IToken evaluate(ICharacterScanner scanner) {
+		IToken result = doEvaluate(scanner);
+		
+		if (result == fDefaultToken) {	
+			//
+			Prototype prototype = null;
+			try {
+				prototype = LisaacModel.getCurrentPrototype();
+			} catch (CoreException e1) {
+			}
+			if (prototype == null) {
+				return result;
+			}
+			//
+			int offset = ((LisaacScanner) scanner).getOffset();
+			String word = fBuffer.toString();
+			
+			Slot slot = prototype.getSlot(offset);
+			if (slot != null) {
+				
+				// is current word a slot argument?
+				if (slot.hasArgument(word)) {
+					return localVariableToken;
+				}
+				// is current word a slot variable?
+				if (slot.hasVariableDefinition(word, offset)) {
+					return localVariableToken;
+				}
+			}
+			try {
+				slot = prototype.getSlotFromKeyword(word, prototype.openParser(), offset-word.length());
+				if (slot != null) {
+					return result;
+				}
+			} catch (CoreException e) {
+				e.printStackTrace();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		return result;
+	}
+	
+
+	public IToken doEvaluate(ICharacterScanner scanner) {
+		int c= scanner.read();
+		if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c)) {
+			if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
+
+				fBuffer.setLength(0);
+				do {
+					fBuffer.append((char) c);
+					c= scanner.read();
+				} while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
+				scanner.unread();
+
+				String buffer= fBuffer.toString();
+				IToken token= (IToken)fWords.get(buffer);
+								
+				if (token != null)
+					return token;
+
+				if (fDefaultToken.isUndefined())
+					unreadBuffer(scanner);
+
+				return fDefaultToken;
+			}
+		}
+		scanner.unread();
+		return Token.UNDEFINED;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/NonRuleBasedDamagerRepairer.java b/editor/eclipse/src/org/lisaac/ldt/editors/NonRuleBasedDamagerRepairer.java
new file mode 100644
index 0000000..f176cb3
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/NonRuleBasedDamagerRepairer.java
@@ -0,0 +1,138 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.custom.StyleRange;
+
+public class NonRuleBasedDamagerRepairer
+	implements IPresentationDamager, IPresentationRepairer {
+
+	/** The document this object works on */
+	protected IDocument fDocument;
+	/** The default text attribute if non is returned as data by the current token */
+	protected TextAttribute fDefaultTextAttribute;
+	
+	/**
+	 * Constructor for NonRuleBasedDamagerRepairer.
+	 */
+	public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
+		Assert.isNotNull(defaultTextAttribute);
+
+		fDefaultTextAttribute = defaultTextAttribute;
+	}
+
+	/**
+	 * @see IPresentationRepairer#setDocument(IDocument)
+	 */
+	public void setDocument(IDocument document) {
+		fDocument = document;
+	}
+
+	/**
+	 * Returns the end offset of the line that contains the specified offset or
+	 * if the offset is inside a line delimiter, the end offset of the next line.
+	 *
+	 * @param offset the offset whose line end offset must be computed
+	 * @return the line end offset for the given offset
+	 * @exception BadLocationException if offset is invalid in the current document
+	 */
+	protected int endOfLineOf(int offset) throws BadLocationException {
+
+		IRegion info = fDocument.getLineInformationOfOffset(offset);
+		if (offset <= info.getOffset() + info.getLength())
+			return info.getOffset() + info.getLength();
+
+		int line = fDocument.getLineOfOffset(offset);
+		try {
+			info = fDocument.getLineInformation(line + 1);
+			return info.getOffset() + info.getLength();
+		} catch (BadLocationException x) {
+			return fDocument.getLength();
+		}
+	}
+
+	/**
+	 * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+	 */
+	public IRegion getDamageRegion(
+		ITypedRegion partition,
+		DocumentEvent event,
+		boolean documentPartitioningChanged) {
+		if (!documentPartitioningChanged) {
+			try {
+
+				IRegion info =
+					fDocument.getLineInformationOfOffset(event.getOffset());
+				int start = Math.max(partition.getOffset(), info.getOffset());
+
+				int end =
+					event.getOffset()
+						+ (event.getText() == null
+							? event.getLength()
+							: event.getText().length());
+
+				if (info.getOffset() <= end
+					&& end <= info.getOffset() + info.getLength()) {
+					// optimize the case of the same line
+					end = info.getOffset() + info.getLength();
+				} else
+					end = endOfLineOf(end);
+
+				end =
+					Math.min(
+						partition.getOffset() + partition.getLength(),
+						end);
+				return new Region(start, end - start);
+
+			} catch (BadLocationException x) {
+			}
+		}
+
+		return partition;
+	}
+
+	/**
+	 * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+	 */
+	public void createPresentation(
+		TextPresentation presentation,
+		ITypedRegion region) {
+		addRange(
+			presentation,
+			region.getOffset(),
+			region.getLength(),
+			fDefaultTextAttribute);
+	}
+
+	/**
+	 * Adds style information to the given text presentation.
+	 *
+	 * @param presentation the text presentation to be extended
+	 * @param offset the offset of the range to be styled
+	 * @param length the length of the range to be styled
+	 * @param attr the attribute describing the style of the range to be styled
+	 */
+	protected void addRange(
+		TextPresentation presentation,
+		int offset,
+		int length,
+		TextAttribute attr) {
+		if (attr != null)
+			presentation.addStyleRange(
+				new StyleRange(
+					offset,
+					length,
+					attr.getForeground(),
+					attr.getBackground(),
+					attr.getStyle()));
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/editors/PrototypeHyperLink.java b/editor/eclipse/src/org/lisaac/ldt/editors/PrototypeHyperLink.java
new file mode 100644
index 0000000..48a45ae
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/editors/PrototypeHyperLink.java
@@ -0,0 +1,168 @@
+package org.lisaac.ldt.editors;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.ide.IDE;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.items.IVariable;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Slot;
+
+
+
+public class PrototypeHyperLink implements IHyperlink {
+
+	private String fPrototypeString;
+	private IRegion fRegion;
+
+	/**
+	 * Creates a new Prototype hyperlink.
+	 * @param region
+	 * @param urlString
+	 */
+	public PrototypeHyperLink(IRegion region, String string) {
+		fRegion= region;
+		fPrototypeString= string;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkRegion()
+	 */
+	public IRegion getHyperlinkRegion() {
+		return fRegion;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.javaeditor.IHyperlink#open()
+	 */
+	public void open() {
+		if (fPrototypeString != null) {
+			IProject project = null;
+			final IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+			IWorkbenchPart part = w.getPartService().getActivePart();
+			if (part instanceof LisaacEditor) {
+				project = ((LisaacEditor)part).getProject();
+			}
+			if (part instanceof LipEditor) {
+				return;
+			}
+
+			if (project != null) {// open 'prototype' in editor, select 'slot' at 'position'
+				Prototype prototype = null;
+				Slot slot = null;
+				Position position = null;
+
+				LisaacModel model = LisaacModel.getModel(project);
+
+				if (LisaacScanner.isPrototypeIdentifier(fPrototypeString)) {
+					// prototype hyperlink
+					try {
+						prototype = model.getPrototype(fPrototypeString);
+					} catch (CoreException e) {
+						return;
+					}
+				} else {
+
+					// Slot Hyperlink
+					try {
+						prototype = LisaacModel.getCurrentPrototype();
+						slot = prototype.getSlotFromKeyword(fPrototypeString, prototype.openParser(), fRegion.getOffset());
+
+					} catch (CoreException e) {
+						return;
+					}
+					if (slot != null) {
+						// slot hyperlink
+						prototype = slot.getPrototype();
+						position = slot.getPosition();
+					} else {
+
+						// variable hyperlink
+						IVariable variable = null;
+						slot = prototype.getSlot(fRegion.getOffset());
+						if (slot != null) {
+							variable = slot.getVariable(fPrototypeString, fRegion.getOffset());
+						}
+						if (variable != null) {
+							Position p = variable.getPosition();
+							int len = fPrototypeString.length();
+							if (p.length > 0) {
+								len = p.length;
+							}
+							position = new Position(0, 0, p.offset-len, len);
+						} else {
+							prototype = null;
+						}					
+					}
+				}
+				if (prototype != null) {
+					final IProject p = project;
+					final String filename = prototype.getFileName();
+					final Position selectPosition = position;
+
+					part.getSite().getShell().getDisplay().asyncExec(new Runnable() {
+						public void run() {
+							IWorkbenchPage page = w.getActivePage();
+							if (page == null) {
+								return;
+							}
+							IFile file=null;
+							IPath location = new Path(filename);
+
+							IContainer src = p.getFolder("src");
+							if (src == null) {
+								src = p;
+							}
+							file = src.getFile(location);
+							if (!file.isAccessible()) {
+								IContainer lib = p.getFolder("lib");
+								if (lib == null) {
+									lib = p;
+								}
+								file = lib.getFile(location);
+							}
+							try {
+								IDE.openEditor(page, file);
+								if (selectPosition != null) {
+									IWorkbenchPart part = w.getPartService().getActivePart();
+									if (part instanceof LisaacEditor) {
+										((LisaacEditor)part).selectAndReveal(selectPosition.offset, selectPosition.length);
+									}
+								}
+							} catch (CoreException e) {
+								// TODO open editor error
+								e.printStackTrace();
+							}
+						}
+					});
+				}
+			}
+			fPrototypeString = null;
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkText()
+	 */
+	public String getHyperlinkText() {
+		return fPrototypeString;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.javaeditor.IHyperlink#getTypeLabel()
+	 */
+	public String getTypeLabel() {
+		return null;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfiguration.java b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfiguration.java
new file mode 100644
index 0000000..d7705b0
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfiguration.java
@@ -0,0 +1,109 @@
+package org.lisaac.ldt.launch;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+
+
+public class LaunchConfiguration implements ILaunchConfigurationDelegate {
+
+	public static final String TYPE_ID = "org.lisaac.ldt.launchConfiguration";
+
+	protected LisaacCompiler compiler;
+
+	public void launch(ILaunchConfiguration configuration, String mode,
+			ILaunch launch, IProgressMonitor monitor) throws CoreException {
+
+		// get project to run
+		String projectName = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROJECT, "");
+		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+
+		// get run informations
+		String mainPrototype = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROTOTYPE, "main.li");
+		String programArguments = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_ARGUMENTS, "");
+
+		boolean doAlwaysCompile = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_COMPILER, true);
+		boolean doRun = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROGRAM, true);
+		boolean hasCompiled = false;
+		
+		int index = mainPrototype.lastIndexOf('/');
+		if (index != -1) {
+			mainPrototype = mainPrototype.substring(index+1);
+		}
+
+		LisaacModel model = LisaacModel.getModel(project);
+		if (model != null) {
+			Prototype main = model.getPrototype(LisaacModel.extractPrototypeName(mainPrototype));
+			if (main == null || main.getSlot("main") == null) {
+				MessageDialog.openInformation(
+						null,
+						"Lisaac Plug-in",
+						mainPrototype+ " : Slot 'main' is missing.");
+				monitor.done();
+				return;
+			}
+			String outputName = main.getName().toLowerCase();
+			monitor.worked(5);
+
+			// 1. Compile project
+			if ((!doAlwaysCompile && model.needCompilation()) || doAlwaysCompile) {
+				compiler = new LisaacCompiler(model, mainPrototype, outputName, "make.lip");
+
+				// options
+				int count = 0;
+				String option;
+				do {
+					option = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_OPTION+count, "");
+					if (option != null && ! option.equals("")) {
+						compiler.addOption("-"+option);
+
+						String optionArg = configuration.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_OPTION_ARG+count, "");
+						if (! optionArg.equals("")) {
+							compiler.addOption(optionArg);
+						}
+					}
+					count++;
+				} while (option != null && ! option.equals(""));
+
+				// compile & launch project;
+				IContainer output = compiler.launchInConsole(launch, project, monitor);
+				if (output == null) {
+					MessageDialog.openInformation(
+							null,
+							"Lisaac Plug-in",
+					"Compilation Error!");
+				}
+				monitor.worked(50);
+				
+				//
+				hasCompiled = true;
+				model.setCompiled(true);
+				monitor.worked(1);
+			}
+
+			// 2. Run program
+			if (doRun && !hasCompiled) {
+				IContainer bin = project.getFolder("bin");
+				if (bin == null) {
+					bin = project;
+				}
+				IFile executable = bin.getFile(new Path(outputName));
+				String[] commandLine = {executable.getLocation().toString(), programArguments};
+				LisaacLauncher.executeCommandInConsole(launch, monitor, bin, commandLine, null);
+			}
+		}
+		monitor.done();
+	}
+	
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTab.java b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTab.java
new file mode 100644
index 0000000..b426bbf
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTab.java
@@ -0,0 +1,486 @@
+package org.lisaac.ldt.launch;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.TableEditor;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+import org.eclipse.ui.dialogs.ResourceSelectionDialog;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.lip.LIP;
+import org.lisaac.ldt.model.lip.LIPSlotCode;
+
+
+public class LaunchConfigurationTab extends AbstractLaunchConfigurationTab {
+
+	public static final String LISAAC_LAUNCH_PROJECT = "launchProject"; //$NON-NLS-1$
+
+	public static final String LISAAC_LAUNCH_PROTOTYPE = "mainPrototype"; //$NON-NLS-1$
+	public static final String LISAAC_LAUNCH_COMPILER = "launchCompiler"; //$NON-NLS-1$
+
+	public static final String LISAAC_LAUNCH_PROGRAM = "launchProgram"; //$NON-NLS-1$
+	public static final String LISAAC_LAUNCH_ARGUMENTS = "programArguments"; //$NON-NLS-1$
+
+	public static final String LISAAC_LAUNCH_OPTION = "lipOption"; //$NON-NLS-1$
+	public static final String LISAAC_LAUNCH_OPTION_ARG = "lipOptionARG"; //$NON-NLS-1$
+
+	// Project UI widget.
+	private Text projectText;
+	private Text mainPrototypeText;
+	private Table lipTable;
+
+	// associated lip
+	private LIP lipCode;
+
+	private Button doLaunchCompiler;
+
+	private Button doLaunchProgram;
+	private Text argumentsText;
+
+	/**
+	 * @see ILaunchConfigurationTab#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {		
+		Font font = parent.getFont();
+
+		Composite comp = new Composite(parent, SWT.NONE);
+		setControl(comp);		
+		GridLayout topLayout = new GridLayout();
+		topLayout.numColumns = 1;
+		comp.setLayout(topLayout);		
+
+		// Project Options
+		Group projComp = new Group(comp, SWT.SHADOW_IN);
+		projComp.setText(LisaacMessages.getString("LaunchConfigurationTab.6")); //$NON-NLS-1$
+		GridLayout projLayout = new GridLayout();
+		projLayout.numColumns = 3;
+		projLayout.marginHeight = 0;
+		projLayout.marginWidth = 0;
+		projComp.setLayout(projLayout);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		projComp.setLayoutData(gd);
+		projComp.setFont(font);
+
+		Label fProjLabel = new Label(projComp, SWT.NONE);
+		fProjLabel.setText(LisaacMessages.getString("LaunchConfigurationTab.7")); //$NON-NLS-1$
+		gd = new GridData();
+		gd.horizontalSpan = 1;
+		fProjLabel.setLayoutData(gd);
+		fProjLabel.setFont(font);
+
+		projectText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 1;
+		projectText.setLayoutData(gd);
+		projectText.setFont(font);
+		this.projectText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+		Button browseButton = new Button(projComp, SWT.PUSH);
+		browseButton.setText(LisaacMessages.getString("LaunchConfigurationTab.9")); //$NON-NLS-1$
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+		gd.horizontalSpan = 1;
+		browseButton.setLayoutData(gd);
+		browseButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleBrowseContainer(projectText);
+			}
+		});
+
+		Label label = new Label(projComp, SWT.NONE);
+		label.setText(LisaacMessages.getString("LaunchConfigurationTab.8")); //$NON-NLS-1$
+		gd = new GridData();
+		label.setLayoutData(gd);
+		label.setFont(font);
+
+		mainPrototypeText = new Text(projComp, SWT.SINGLE | SWT.BORDER);
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		mainPrototypeText.setLayoutData(gd);
+		mainPrototypeText.setFont(font);
+		mainPrototypeText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+		browseButton = new Button(projComp, SWT.PUSH);
+		browseButton.setText(LisaacMessages.getString("LaunchConfigurationTab.9")); //$NON-NLS-1$
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+		browseButton.setLayoutData(gd);
+		browseButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleBrowseFile(mainPrototypeText);
+			}
+		});
+
+		Label separator = new Label (comp, SWT.SEPARATOR | SWT.HORIZONTAL);
+		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// compiler options
+		Group compilerOptions = new Group(comp, SWT.SHADOW_IN);
+		compilerOptions.setText(LisaacMessages.getString("LaunchConfigurationTab.12")); //$NON-NLS-1$
+		GridLayout gl = new GridLayout();
+		gl.numColumns = 3;
+		compilerOptions.setLayout(gl);
+		gd = new GridData(GridData.FILL_BOTH);
+		compilerOptions.setLayoutData(gd);
+
+		doLaunchCompiler = new Button(compilerOptions, SWT.CHECK);
+		doLaunchCompiler.setText("Always Compile (cannot run program)");
+		doLaunchCompiler.setSelection(false);
+		gd = new GridData();
+		gd.horizontalSpan = 3;
+		doLaunchCompiler.setLayoutData(gd);
+		doLaunchCompiler.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+			public void widgetSelected(SelectionEvent e) {
+				doLaunchProgram.setEnabled(! doLaunchCompiler.getSelection());
+				argumentsText.setEnabled(! doLaunchCompiler.getSelection());
+				updateLaunchConfigurationDialog();
+			}
+		});
+
+		// lip options
+		Composite tableGroup = new Composite(compilerOptions, SWT.NONE);
+		tableGroup.setLayout(new GridLayout(1, false));
+		gd = new GridData(GridData.FILL_BOTH);
+		gd.horizontalSpan = 1;
+		gd.verticalSpan = 3;
+		tableGroup.setLayoutData(gd);
+
+		lipTable = new Table(tableGroup, SWT.BORDER | SWT.SINGLE |
+				SWT.H_SCROLL | SWT.FULL_SELECTION | SWT.CHECK);
+		final TableColumn c1  = new TableColumn(lipTable, SWT.LEFT);
+		c1.setText(LisaacMessages.getString("LaunchConfigurationTab.15")); //$NON-NLS-1$
+		c1.setWidth(130);
+		final TableColumn c2  = new TableColumn(lipTable, SWT.LEFT);
+		c2.setText(LisaacMessages.getString("LaunchConfigurationTab.16")); //$NON-NLS-1$
+		c2.setWidth(80);
+		final TableColumn c3  = new TableColumn(lipTable, SWT.LEFT);
+		c3.setText(LisaacMessages.getString("LaunchConfigurationTab.17")); //$NON-NLS-1$
+		c3.setWidth(100);
+		lipTable.setHeaderVisible(true);
+		lipTable.setLinesVisible(true);
+		lipTable.setItemCount(4);
+		lipTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		final TableEditor editor = new TableEditor(lipTable);
+		// The editor must have the same size as the cell and must
+		// not be any smaller than 50 pixels.
+		editor.horizontalAlignment = SWT.LEFT;
+		editor.grabHorizontal = true;
+		editor.minimumWidth = 50;
+
+		lipTable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				//
+				// Clean up any previous editor control
+				Control oldEditor = editor.getEditor();
+				if (oldEditor != null)
+					oldEditor.dispose();
+
+				// Identify the selected row
+				TableItem item = (TableItem) e.item;
+				if (item == null)
+					return;
+
+				// The control that will be the editor must be a child of the
+				// Table
+				Text newEditor = new Text(lipTable, SWT.NONE);
+				newEditor.setText(item.getText(1));
+				newEditor.addModifyListener(new ModifyListener() {
+					public void modifyText(ModifyEvent me) {
+						Text text = (Text) editor.getEditor();
+						editor.getItem().setText(1, text.getText());
+					}
+				});
+				newEditor.selectAll();
+				newEditor.setFocus();
+				editor.setEditor(newEditor, item, 1);
+				//
+				updateLaunchConfigurationDialog();
+			}
+		});
+
+		GridData gridData = new GridData(GridData.FILL_BOTH);
+		gridData.horizontalSpan = 2;
+		tableGroup.setLayoutData(gridData);
+
+		separator = new Label (comp, SWT.SEPARATOR | SWT.HORIZONTAL);
+		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		// program options
+		Group programOptions = new Group(comp, SWT.SHADOW_IN);
+		programOptions.setText("Program Options"); //$NON-NLS-1$
+		gl = new GridLayout();
+		gl.numColumns = 2;
+		programOptions.setLayout(gl);
+		programOptions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		doLaunchProgram = new Button(programOptions, SWT.CHECK);
+		doLaunchProgram.setText("Run the program");
+		gd = new GridData(GridData.FILL_HORIZONTAL);
+		gd.horizontalSpan = 2;
+		doLaunchProgram.setLayoutData(gd);
+		doLaunchProgram.setSelection(true);
+		doLaunchProgram.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				if (argumentsText != null) {
+					argumentsText.setEnabled(doLaunchProgram.getSelection());
+				}
+				updateLaunchConfigurationDialog();
+			}
+		});
+
+		label = new Label(programOptions, SWT.NONE);
+		label.setText("Command-Line:");
+		label.setLayoutData(new GridData(GridData.BEGINNING));
+
+		argumentsText = new Text(programOptions, SWT.SINGLE | SWT.BORDER);
+		argumentsText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		argumentsText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent evt) {
+				updateLaunchConfigurationDialog();
+			}
+		});
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+	 */
+	public String getName() {
+		return LisaacMessages.getString("LaunchConfigurationTab.18"); //$NON-NLS-1$
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+	 */
+	public void initializeFrom(ILaunchConfiguration configuration) {
+		try {
+			String projectName = configuration.getAttribute(LISAAC_LAUNCH_PROJECT, ""); //$NON-NLS-1$
+			projectText.setText(projectName);	
+
+			String mainPrototypeName = configuration.getAttribute(LISAAC_LAUNCH_PROTOTYPE, ""); //$NON-NLS-1$
+			mainPrototypeText.setText(mainPrototypeName);	
+
+			boolean check = configuration.getAttribute(LISAAC_LAUNCH_COMPILER, false);
+			doLaunchCompiler.setSelection(check);	
+
+			check = configuration.getAttribute(LISAAC_LAUNCH_PROGRAM, true);
+			doLaunchProgram.setSelection(check);	
+
+			String commandLine = configuration.getAttribute(LISAAC_LAUNCH_ARGUMENTS, ""); //$NON-NLS-1$
+			argumentsText.setText(commandLine);	
+
+			IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+			LisaacModel model = LisaacModel.getModel(project);
+			if (model != null) {
+				lipCode = model.getLipCode();
+				if (lipCode != null) {
+					// update table
+					lipTable.setItemCount(0);
+					for (int i=0; i<lipCode.getMethodCount(); i++) {
+						LIPSlotCode method = lipCode.getMethod(i);
+						if (method.isPublic()) {	
+							String methodComment = method.getComment();
+							if (methodComment == null) {
+								methodComment = LisaacMessages.getString("LaunchConfigurationTab.23"); //$NON-NLS-1$
+							}
+							methodComment = methodComment.replaceAll("\t", ""); //$NON-NLS-1$ //$NON-NLS-2$
+							methodComment = methodComment.replaceAll("\n", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+							if (! lipTable.isDisposed()) {
+								TableItem item = new TableItem (lipTable, SWT.NONE);
+								item.setText(0, method.getName());
+								item.setText(2, methodComment);
+
+								if (method.getName().compareTo(ILisaacModel.slot_debug_mode) == 0) {
+									if (getLaunchConfigurationDialog().getMode().compareTo("debug") == 0) {
+										item.setChecked(true);
+									} else {
+										item.setChecked(false);
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		} catch (CoreException ce) {
+			// Log the error to the Eclipse log.
+			IStatus status = new Status(IStatus.ERROR,
+					LisaacPlugin.PLUGIN_ID, 0,
+					"Error in Lisaac launch: " + //$NON-NLS-1$
+					ce.getMessage(), ce);
+			LisaacPlugin.log(status);	   
+		}
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+		configuration.setAttribute(LISAAC_LAUNCH_PROJECT, projectText.getText());
+		configuration.setAttribute(LISAAC_LAUNCH_PROTOTYPE, mainPrototypeText.getText());
+
+		configuration.setAttribute(LISAAC_LAUNCH_COMPILER, doLaunchCompiler.getSelection());
+		configuration.setAttribute(LISAAC_LAUNCH_PROGRAM, doLaunchProgram.getSelection());
+		configuration.setAttribute(LISAAC_LAUNCH_ARGUMENTS, argumentsText.getText());
+
+		TableItem[] options = lipTable.getItems();
+		if (options != null && options.length > 0) {
+			for (int i=0; i<options.length; i++) {
+				configuration.removeAttribute(LISAAC_LAUNCH_OPTION+i);// remove options
+				configuration.removeAttribute(LISAAC_LAUNCH_OPTION_ARG+i);// remove options
+			}			
+			int count = 0;
+			for (int i=0; i<options.length; i++) {
+				TableItem item = options[i];
+				if (item.getChecked()) {
+					configuration.setAttribute(LISAAC_LAUNCH_OPTION+count, item.getText(0));
+					configuration.setAttribute(LISAAC_LAUNCH_OPTION_ARG+count, item.getText(1));
+					count++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+	 */
+	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+		IProject project = getSelectedProject();	
+		String projectName = "";	 //$NON-NLS-1$
+		String mainPrototypeName = ""; //$NON-NLS-1$
+
+		if (project != null) {			
+			projectName = project.getName();
+			mainPrototypeName = projectName + ".li"; //$NON-NLS-1$
+		}
+		configuration.setAttribute(LISAAC_LAUNCH_PROJECT, projectName);
+		configuration.setAttribute(LISAAC_LAUNCH_PROTOTYPE, mainPrototypeName);
+
+		configuration.setAttribute(LISAAC_LAUNCH_COMPILER, false);
+		configuration.setAttribute(LISAAC_LAUNCH_PROGRAM, true);
+		configuration.setAttribute(LISAAC_LAUNCH_ARGUMENTS, ""); //$NON-NLS-1$
+
+		if (lipTable != null) {
+			TableItem[] options = lipTable.getItems();
+			if (options != null && options.length > 0) {
+				for (int i=0; i<options.length; i++) {
+					configuration.removeAttribute(LISAAC_LAUNCH_OPTION+i);// remove options
+					configuration.removeAttribute(LISAAC_LAUNCH_OPTION_ARG+i);// remove options
+				}
+			}
+		}
+	}
+
+	/** 
+	 * Gets the current project selected in the workbench.
+	 * @return the current project selected in the workbench.
+	 */
+	private IProject getSelectedProject() {
+		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+		if (window != null) {
+			IWorkbenchPage page = window.getActivePage();
+			if (page != null) {
+				ISelection selection = page.getSelection();
+				if (selection instanceof IStructuredSelection) {
+					IStructuredSelection ss = (IStructuredSelection)selection;
+					if (!ss.isEmpty()) {
+						Object obj = ss.getFirstElement();
+						if (obj instanceof IResource) {
+							IResource i = (IResource) obj;
+							IProject pro = i.getProject();
+							return pro;														
+						}
+					}
+				}
+				// If the editor has the focus...
+				IEditorPart part = page.getActiveEditor();
+				if (part != null) {
+					IEditorInput input = part.getEditorInput();
+					IFile file = (IFile) input.getAdapter(IFile.class);
+					return file.getProject();
+				}				
+			}
+		}
+		return null;							
+	}
+
+
+	/**
+	 * Uses the standard container selection dialog to choose the new value for
+	 * the container field.
+	 */
+	private void handleBrowseContainer(Text text) {
+		ContainerSelectionDialog dialog = new ContainerSelectionDialog(
+				getShell(), null, false,
+		"Select Folder"); //$NON-NLS-1$
+		if (dialog.open() == ContainerSelectionDialog.OK) {
+			Object[] results = dialog.getResult();
+			if (results.length == 1) {
+				Object result = results[0];
+				if (result instanceof IPath) {
+					IPath ipath = (IPath) result;
+					text.setText(ipath.toString());
+				}
+			}
+		}
+	}
+
+	private void handleBrowseFile(Text text) {
+		ResourceSelectionDialog dialog = new ResourceSelectionDialog(
+				getShell(), ResourcesPlugin.getWorkspace().getRoot(), "Select File"); //$NON-NLS-1$
+		dialog.setInitialSelections(new Object[0]);
+		if (dialog.open() == ResourceSelectionDialog.OK) {
+			Object[] results = dialog.getResult();
+			if (results.length == 1) {
+				Object result = results[0];
+				if (result instanceof IResource) {
+					text.setText(((IResource) result).getName());
+				}
+			}
+		}
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTabGroup.java b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTabGroup.java
new file mode 100644
index 0000000..58e2e8d
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LaunchConfigurationTabGroup.java
@@ -0,0 +1,20 @@
+package org.lisaac.ldt.launch;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+
+public class LaunchConfigurationTabGroup  extends AbstractLaunchConfigurationTabGroup {
+
+	 /**
+     * @see ILaunchConfigurationTabGroup#createTabs(ILaunchConfigurationDialog, String)
+     */
+    public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+        ILaunchConfigurationTab[] tabs = {
+                new LaunchConfigurationTab(),
+                new CommonTab()	
+            };
+        setTabs(tabs);
+    }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LisaacApplicationShortcut.java b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacApplicationShortcut.java
new file mode 100644
index 0000000..1168a0f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacApplicationShortcut.java
@@ -0,0 +1,98 @@
+package org.lisaac.ldt.launch;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Handle the 'Lisaac Application' run shortcut.
+ */
+public class LisaacApplicationShortcut implements ILaunchShortcut {
+
+    public LisaacApplicationShortcut() {
+    }
+ 
+    public void launch(ISelection selection, String mode) {
+        if(selection instanceof IStructuredSelection) {
+            Object firstSelection = ((IStructuredSelection)selection).getFirstElement();
+            if (firstSelection instanceof IFile) {
+                ILaunchConfiguration config = findLaunchConfiguration((IFile)firstSelection, mode);
+                try {
+                    if(config != null)
+                        config.launch(mode, null);
+                }
+                catch(CoreException coreexception) { }
+            }
+        }
+    }
+
+    public void launch(IEditorPart editor, String mode)
+    {
+		// make sure the file is saved
+		editor.getEditorSite().getPage().saveEditor(editor,true);
+        org.eclipse.ui.IEditorInput input = editor.getEditorInput();
+        ISelection selection = new StructuredSelection(input.getAdapter(org.eclipse.core.resources.IFile.class));
+        launch(selection, mode);
+    }
+
+    protected ILaunchConfiguration findLaunchConfiguration(IFile file, String mode) {
+        ILaunchConfigurationType configType = getLaunchConfigType();
+        List<ILaunchConfiguration> candidateConfigs = null;
+        try {
+            ILaunchConfiguration configs[] = getLaunchManager().getLaunchConfigurations(configType);
+            candidateConfigs = new ArrayList<ILaunchConfiguration>(configs.length);
+            for(int i = 0; i < configs.length; i++) {
+                ILaunchConfiguration config = configs[i];
+                
+                if(config.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROTOTYPE, "").equals(file.getFullPath().lastSegment()) &&
+                		config.getAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROJECT, "").equals(file.getProject().getFullPath().lastSegment()))
+                    candidateConfigs.add(config);
+            }
+        }
+        catch(CoreException coreexception) { }
+        switch(candidateConfigs.size())
+        {
+        case 0: // '\0'
+            return createConfiguration(file);
+
+        case 1: // '\001'
+        default:
+            return (ILaunchConfiguration)candidateConfigs.get(0);
+        }
+    }
+
+    protected ILaunchConfiguration createConfiguration(IFile file)
+    {
+        ILaunchConfiguration config = null;
+        try
+        {
+            ILaunchConfigurationType configType = getLaunchConfigType();
+            ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(file.getName()));
+            wc.setAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROJECT, file.getProject().getName());
+            wc.setAttribute(LaunchConfigurationTab.LISAAC_LAUNCH_PROTOTYPE, file.getName());
+            config = wc.doSave();
+        }
+        catch(CoreException coreexception) { }
+        return config;
+    }
+
+    protected ILaunchConfigurationType getLaunchConfigType() {
+        return getLaunchManager().getLaunchConfigurationType(LaunchConfiguration.TYPE_ID);
+    }
+
+    protected ILaunchManager getLaunchManager() {
+        return DebugPlugin.getDefault().getLaunchManager();
+    }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LisaacCompiler.java b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacCompiler.java
new file mode 100644
index 0000000..4e2e470
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacCompiler.java
@@ -0,0 +1,243 @@
+package org.lisaac.ldt.launch;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.jface.text.IRegion;
+import org.lisaac.ldt.builder.LisaacBuilder;
+import org.lisaac.ldt.model.AbstractLisaacParser;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.items.Prototype;
+
+public class LisaacCompiler {
+
+	protected String inputFile;
+	protected String lipFile;
+
+	protected ArrayList<String> options;
+
+	protected LisaacModel model;
+
+	protected String outputName;
+
+	// for lisaac <input_file> <lip_file> [options]
+	public LisaacCompiler(LisaacModel model, String inputFile, String outputName, String lipFile) {
+		this.inputFile = inputFile;
+		this.lipFile = lipFile;
+		this.outputName = outputName;
+		this.model = model;
+	}
+
+	// for lisaac <lip_file> --p
+	public LisaacCompiler(String lipFile) {
+		this.lipFile = lipFile;
+	}
+
+	public IContainer launchInConsole(final ILaunch launch, IProject project, IProgressMonitor monitor) throws CoreException {
+		IContainer src = project.getFolder("src");
+
+		if (src != null) {
+			if (LisaacLauncher.executeCommandInConsole(launch, monitor, src, this.toCommandLineArray(),this)) {
+				return src;
+			}
+		}
+		else if (LisaacLauncher.executeCommandInConsole(launch, monitor, project, this.toCommandLineArray(),this)) {
+			return project;
+		}
+		return null;
+	}
+
+	public Process launch(IProject project, IProgressMonitor monitor) throws CoreException {
+		return LisaacLauncher.executeCommand(monitor, project, this.toCommandLineArray());
+	}
+
+	public String[] toCommandLineArray() {
+		ArrayList<String> cmd = new ArrayList<String>();
+
+		cmd.add("lisaac ");
+		if (lipFile != null) {
+			cmd.add(lipFile);
+		}
+		if (inputFile != null) {
+			cmd.add(inputFile);
+		}
+		if (options != null) {
+			cmd.addAll(options);
+		}
+		return cmd.toArray(new String[cmd.size()]);
+	}
+
+	public String toCommandLine() {
+		StringBuffer result = new StringBuffer();
+
+		result.append("lisaac ");
+		if (lipFile != null) {
+			result.append(lipFile);
+		}
+		if (inputFile != null) {
+			result.append(" "+inputFile);
+		}
+		if (options != null) {
+			for (int i=0; i<options.size(); i++) {
+				result.append(" "+options.get(i));
+			}
+		}
+		return result.toString();
+	}
+
+	public void addOption(String option) {
+		if (options == null) {
+			options = new ArrayList<String>();
+		}
+		options.add(option);
+	}
+
+	public void moveFiles(IContainer output) throws CoreException {
+		IProject project = model.getProject();
+
+		// refresh the generated files
+		output.refreshLocal(IResource.DEPTH_INFINITE, null);
+
+		// move the generated files to bin/
+		IContainer bin = project.getFolder("bin");
+		IPath generatedPath = new Path(outputName);
+		IFile executable = output.getFile(generatedPath);
+		if (! executable.exists()) {
+			generatedPath = new Path(outputName+".exe");// FIXME platform-dependant
+			executable = output.getFile(generatedPath);
+		}
+		if (executable.exists()) {
+			IFile destFile = bin.getFile(generatedPath);
+			if (destFile.exists()) {
+				destFile.delete(true, null);
+			}
+			executable.move(bin.getFullPath().append(generatedPath), true, null);
+		}
+		moveFile(outputName+".o", output, bin);// FIXME .java, etc..
+		moveFile(outputName+".c", output, bin);
+
+		//
+		project.refreshLocal(IResource.DEPTH_INFINITE, null); // TODO usefull? try to remove
+		//
+
+		model.setCompiled(true);
+	}
+
+	private void moveFile(String filename, IContainer origin, IContainer destination) throws CoreException {
+		IPath path = new Path(filename);
+		IFile originFile = origin.getFile(path);
+
+		if (originFile.exists()) {
+			IFile destFile = destination.getFile(path);
+			if (destFile.exists()) {
+				destFile.delete(true, null);
+			}
+			originFile.move(destination.getFullPath().append(path), true, null);
+		}
+	}
+
+	public void cleanFiles() throws CoreException {
+		IContainer bin = model.getProject().getFolder("bin");
+
+		IFile executable = bin.getFile(new Path(outputName));
+		if (executable.exists()) {
+			executable.delete(true, null);
+		}
+		executable = bin.getFile(new Path(outputName+".exe"));// FIXME platform-dependant
+		if (executable.exists()) {
+			executable.delete(true, null);	
+		}
+		IFile file = bin.getFile(new Path(outputName+".o"));
+		if (file.exists()) {
+			file.delete(true, null);	
+		}
+		file = bin.getFile(new Path(outputName+".c")); // FIXME .java, etc..
+		if (file.exists()) {
+			file.delete(true, null);	
+		}
+	}
+
+	public void showErrors(String output) throws CoreException {
+		new CompilerOutputParser(output).run(model);
+	}
+}
+
+class CompilerOutputParser extends AbstractLisaacParser {
+	public CompilerOutputParser(String contents) {
+		super(contents);
+	}
+
+	public void run(LisaacModel model) throws CoreException {
+		int startOffset = source.indexOf("--");
+		while (startOffset != -1) {
+			setPosition(startOffset+2);
+
+			if (! readCapIdentifier()) {
+				break;
+			}
+			int line, column;
+			String prototypeName;
+			String msg;
+			int severity = 0;
+
+			if (lastString.compareTo("WARNING") == 0) {
+				readWord("----------");
+				severity = 1;
+			} else if (lastString.compareTo("SYNTAX") == 0) {
+				readWord("-----------");
+				severity = 2;
+			} else if (lastString.compareTo("SEMANTIC") == 0) {
+				readWord("---------");
+				severity = 2;
+			}
+			readLine();
+			msg = new String(lastString);
+			msg = msg.replace('\r', ' ');
+			readWord("Line");
+			readInteger();
+			line = (int) lastInteger;
+			readWord("column");
+			readInteger();
+			column = (int) lastInteger;
+			readWord("in");
+			readCapIdentifier();
+			prototypeName = new String(lastString);
+			
+			// add marker to file
+			Prototype prototype = model.getPrototype(prototypeName);
+			if (prototype != null) {
+				IFile file = prototype.getFile();
+				IRegion region = prototype.getRegionAt(line, column);
+				
+				Position position = new Position(line, column, region.getOffset(), region.getLength());
+				LisaacBuilder.addMarker(file, msg, position, severity);
+			}
+			startOffset = source.indexOf("--", position);
+		}
+	}
+	private void readLine() {
+		if (readSpace()) {
+			string_tmp = "";
+			while (lastCharacter() != 0 && lastCharacter() != '\n') {
+				string_tmp += lastCharacter();
+				if (lastCharacter() == '\\') {
+					position = position+1;
+					readEscapeCharacter();
+				} else {
+					position = position+1;
+				}
+			}
+			position = position+1;
+			lastString = string_tmp;
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/launch/LisaacLauncher.java b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacLauncher.java
new file mode 100644
index 0000000..bb55953
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/launch/LisaacLauncher.java
@@ -0,0 +1,142 @@
+package org.lisaac.ldt.launch;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.IStreamListener;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStreamMonitor;
+import org.eclipse.swt.widgets.Display;
+import org.lisaac.ldt.views.ConsoleFactory;
+import org.lisaac.ldt.views.LisaacConsole;
+
+
+public class LisaacLauncher {
+
+	public static boolean executeCommandInConsole(final ILaunch launch, final IProgressMonitor monitor,
+			final IContainer container, final String[] commandLine, final LisaacCompiler compiler) throws CoreException {
+		// get & clear lisaac console
+		final LisaacConsole console = ConsoleFactory.getConsole();
+		console.clearConsole();
+		
+		if (compiler == null) {
+			console.activate();// show console		
+		}
+		Runnable getStandardOutput = new Runnable() {
+			public void run() {
+				monitor.beginTask("Executing... ", 100);
+
+				// 1. Clean existing files
+				if (compiler != null) {
+					try {
+						compiler.cleanFiles();
+					} catch (CoreException e) {
+					}
+					monitor.worked(10);
+				}
+				
+				// 2. Launch process
+				Process process = null;
+				try {
+					process = launchProcess(commandLine, container);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+
+				monitor.worked(20);
+				if (monitor.isCanceled()) {        
+					return;
+				}
+				if (process != null) {
+					monitor.setTaskName("Reading output...");
+					monitor.worked(20);
+
+					// attach process stream to Lisaac console
+					IProcess eclipseProcess = DebugPlugin.newProcess(launch,
+							process,"Lisaac Session");
+		
+					// get the process output
+					final StringBuffer buffer = new StringBuffer();
+					
+					IStreamListener listener = new IStreamListener() {	
+						public void streamAppended(String text,
+								IStreamMonitor monitor) {
+							buffer.append(text);
+						}
+					};
+					eclipseProcess.getStreamsProxy().getOutputStreamMonitor().addListener(listener);
+					eclipseProcess.getStreamsProxy().getErrorStreamMonitor().addListener(listener);
+					
+					// 3. clean files after process execution
+					if (compiler != null) {
+						try {
+							process.waitFor();
+						} catch (InterruptedException e) {
+						}
+						try {
+							compiler.moveFiles(container);
+							
+							while (! eclipseProcess.isTerminated()) {}
+							compiler.showErrors(buffer.toString());
+							
+						} catch (CoreException e) {
+						}
+					}
+				}
+				monitor.done();
+			}
+		};
+		// execute action in a new thread UI safe
+		Display.getDefault().asyncExec(getStandardOutput);
+		return true;
+	}
+
+	public static Process executeCommand(IProgressMonitor monitor, IContainer container, String[] commandLine) throws CoreException {
+		monitor.beginTask("Executing...", 100);
+
+		Process process = null;
+		try {
+			process = launchProcess(commandLine, container);
+		} catch (IOException e) {
+			e.printStackTrace();
+			return null;
+		}
+		monitor.worked(20);
+		if (monitor.isCanceled()) {        
+			return null;
+		}
+		return process;
+	}
+
+	/**
+	 * Executes the command line at the given project location, and returns the 
+	 * corresponding process.
+	 * @param commandLine the command line
+	 * @param project the project in which the command line is executed
+	 * @return the corresponding process
+	 * @throws IOException if the command line can't be executed
+	 */
+	public static Process launchProcess(String[] commandLine, IContainer directory) throws IOException {
+		File projectDirectory = 
+			(directory != null) ? new File(directory.getLocationURI()) : null;
+
+			String cmd = concatCommandLine(commandLine);
+			
+			Process process = Runtime.getRuntime().exec(cmd, null, projectDirectory);
+			return process;
+	}
+	
+	private static String concatCommandLine(String[] commandLine) {
+		StringBuffer buf = new StringBuffer();
+		for (int i=0; i<commandLine.length; i++) {
+			buf.append(commandLine[i]);
+			buf.append(' ');
+		}
+		return buf.toString();
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/messages.properties b/editor/eclipse/src/org/lisaac/ldt/messages.properties
new file mode 100644
index 0000000..58c617b
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/messages.properties
@@ -0,0 +1,75 @@
+AbstractNewFileWizardPage_1=Source folder : 
+AbstractNewFileWizardPage_2=Browse...
+AbstractNewFileWizardPage_3=File name : 
+AbstractNewFileWizardPage_4=Select container.
+AbstractNewFileWizardPage_5=Source folder must be specified.
+AbstractNewFileWizardPage_6=File name must be specified.
+AbstractNewFileWizardPage_7=File already exists.
+LaunchConfigurationTab.10=Program Arguments
+LaunchConfigurationTab.12=Compiler Options
+LaunchConfigurationTab.13=Lisaac Path File (default : make.lip): 
+LaunchConfigurationTab.14=Browse...
+LaunchConfigurationTab.15=Option
+LaunchConfigurationTab.16=Argument
+LaunchConfigurationTab.17=Description
+LaunchConfigurationTab.18=Main
+LaunchConfigurationTab.23=No comment
+LaunchConfigurationTab.6=Project Options
+LaunchConfigurationTab.7=Project: 
+LaunchConfigurationTab.8=Main Prototype to run :
+LaunchConfigurationTab.9=Browse...
+LisaacBuilder.2=Build workpace...
+LisaacColoringPage.0=Lisaac Editor Syntax Coloring preferences :
+LisaacColoringPage.10=\ \ \ \ &Externals:       
+LisaacColoringPage.11=\ \ \ \ &Slots:           
+LisaacColoringPage.12=\ \ \ \ &Local variable: 
+LisaacColoringPage.2=\ \ \ \ &Comments:        
+LisaacColoringPage.3=\ \ \ \ &Prototype:       
+LisaacColoringPage.4=\ \ \ \ &Slot style: 
+LisaacColoringPage.5=\ \ \ \ &Keywords:        
+LisaacColoringPage.6=\ \ \ \ &Characters:      
+LisaacColoringPage.7=\ \ \ \ &Strings:         
+LisaacColoringPage.8=\ \ \ \ &Numbers:         
+LisaacColoringPage.9=\ \ \ \ &Operators:       
+LisaacColoringPage.20=Bold
+LisaacColoringPage.21=Italics
+LisaacColoringPage.22=Normal
+LisaacColoringPage.23=Underline
+LisaacConfiguration_0=Lisaac Completion
+LisaacConsole.1=Lisaac Console
+LisaacEditorPage.0=&Enable Auto-Indentation
+LisaacEditorPage.1=&Enable Hovering
+LisaacEditorPage.2=Content Assist preferences
+LisaacEditorPage.3=&Enable Completion
+LisaacEditorPage.4=Auto-Activation Delay
+LisaacEditorPage.5=Enable folding
+LisaacPreferencePage.0=General settings for Lisaac Development
+LisaacPreferencePage.1=&Your name :
+LisaacPreferencePage.2=&Support for Lisaac 0.13
+LisaacProjectPropertyPage.0=Lisaac Environment Path
+LisaacProjectPropertyPage.1=Use default Lisaac Environment
+LisaacProjectPropertyPage.2=Use a project specific Lisaac Environment : 
+LisaacProjectPropertyPage.3=Browse...
+LisaacProjectPropertyPage.8=Select Lisaac Environment Directory.
+NewProjectWizard_46=New Lisaac Project Wizard
+NewProjectWizard_47=New Lisaac Project
+NewProjectWizard_48=Create a lisaac project
+NewProjectWizard_49=Use default Lisaac Environment
+NewProjectWizard_50=Use a project specific Lisaac Environment : 
+NewProjectWizard_51=Browse...
+NewPrototypeWizard_0=New Prototype
+NewPrototypeWizard_2=Prototype File
+NewPrototypeWizard_25=Prototype Style : 
+NewPrototypeWizard_26=None
+NewPrototypeWizard_27=Expanded
+NewPrototypeWizard_28=Strict
+NewPrototypeWizard_29=Description : 
+NewPrototypeWizard_3=Creates a new source file into a project
+NewPrototypeWizard_30=Inheritance : 
+NewPrototypeWizard_32=Inheritance Type
+NewPrototypeWizard_34=Add...
+NewPrototypeWizard_35=Remove
+NewPrototypeWizard_36=Which slots would you like to create?
+NewPrototypeWizard_37=Main slot
+NewPrototypeWizard_38=Constructor slot
+RenamePrototype.0=Rename Prototype...
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/AbstractLisaacParser.java b/editor/eclipse/src/org/lisaac/ldt/model/AbstractLisaacParser.java
new file mode 100644
index 0000000..45af489
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/AbstractLisaacParser.java
@@ -0,0 +1,886 @@
+package org.lisaac.ldt.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+
+import org.lisaac.ldt.builder.ILisaacErrorHandler;
+
+
+public class AbstractLisaacParser {
+	
+	protected ILisaacErrorHandler reporter;
+
+	protected ILisaacModel model;
+	
+	protected String source;
+
+	protected int position;
+
+	protected int pos_cur, pos_line, pos_col;
+	protected int begin_position;
+
+	protected String string_tmp="";
+
+	
+	public Position getPosition() {
+		return getPosition(0);
+	}
+	
+	public Position getPosition(int len) {
+		Position result=null;
+
+		while (pos_cur < position) {
+			if (source.charAt(pos_cur) == '\n') {
+				pos_col = 0;
+				pos_line++;
+			} else {
+				pos_col++;
+			}
+			pos_cur++;
+		}
+		if (pos_line > 32767) {
+			result = new Position(32767, pos_col, pos_cur);
+			reporter.syntaxError ("Line counter overflow.",result);
+		}
+		if (pos_col > 255) {
+			result = new Position(pos_line, 255, pos_cur);
+			reporter.syntaxError ("Column counter overflow (line too long).",result);
+		};
+		result = new Position(pos_line, pos_col, pos_cur, len);
+		return result;
+	}
+	
+	public Position getLine() {
+		Position result=null;
+		int startLine = pos_cur;
+		int endLine = position+1;
+		
+		while (pos_cur < position && !isEOF()) {
+			if (source.charAt(pos_cur) == '\n') {
+				pos_col = 0;
+				pos_line++;
+				startLine = pos_cur+1;
+			} else {
+				pos_col++;
+			}
+			pos_cur++;
+		}
+		if (pos_line > 32767) {
+			result = new Position(32767, pos_col, pos_cur);
+			reporter.syntaxError ("Line counter overflow.",result);
+		}
+		if (pos_col > 255) {
+			result = new Position(pos_line, 255, pos_cur);
+			reporter.syntaxError ("Column counter overflow (line too long).",result);
+		};
+		while (endLine <= source.length()-1) {
+			if (source.charAt(endLine) == '\n') {
+				break;
+			}
+			endLine++;
+		}
+		result = new Position(pos_line, pos_col, endLine, endLine - startLine);
+		return result;
+	}
+	
+	public void updateLine() {
+		while (pos_cur < position) {
+			if (source.charAt(pos_cur) == '\n') {
+				pos_col = 0;
+				pos_line++;
+			} else {
+				pos_col++;
+			}
+			pos_cur++;
+		}
+	}
+	
+	public int getOffset() {
+		return position;
+	}
+	
+	public String getSource() {
+		return source;
+	}
+
+	public boolean isEOF() {
+		return position > source.length()-1;
+	}
+
+	public void setPosition(int pos) {
+		initialize();
+		position = pos;
+	}
+
+	protected long lastInteger;
+	protected String lastReal;
+	protected String lastString;
+
+	protected static String lastComment;
+	protected boolean isCatchComment;
+	
+	protected boolean isParameterType;
+	
+	protected void setCatchComment() {
+		isCatchComment = true;
+		lastComment = "";
+	}
+	protected void setCatchCommentOff() {
+		isCatchComment = false;
+	}
+	
+	public String getLastString() {
+		return lastString;
+	}
+	
+	public char lastCharacter() {
+		if (position > source.length()-1) {
+			return 0;
+		} 
+		return source.charAt(position);
+	}
+
+	//
+	// AMBIGU Manager.
+	//
+
+	protected int old_position;
+	protected int old_pos_cur;
+	protected int old_pos_line;
+	protected int old_pos_col;
+
+	protected void saveContext() {
+		old_position = position;
+		old_pos_cur  = pos_cur;
+		old_pos_line = pos_line;
+		old_pos_col  = pos_col;
+	}
+	protected void restoreContext() {
+		position = old_position;
+		pos_cur  = old_pos_cur;
+		pos_line = old_pos_line;
+		pos_col  = old_pos_col;
+	}
+	
+	public AbstractLisaacParser(InputStream contents, ILisaacModel model) {
+		this.model = model;
+		this.reporter = model.getReporter();
+		
+		// convert the input stream into string
+		try {
+			InputStreamReader reader = new InputStreamReader (contents);
+			BufferedReader buffer = new BufferedReader(reader);
+
+			StringWriter writer = new StringWriter();
+
+			String line="";
+			do {
+				line = buffer.readLine();
+				if (line != null) {
+					writer.write(line+"\n"); 
+				}
+			} while (line != null);
+			//
+			source = writer.toString();
+			//
+		} catch (IOException e) {
+			return; // ERROR
+		}
+		initialize();
+	}
+	
+	public AbstractLisaacParser(String contents) {
+		// null reporter
+		this.reporter = new ILisaacErrorHandler() {
+			public void fatalError(String msg, Position position) {
+			}
+			public void semanticError(String msg, Position position) {
+			}
+			public void syntaxError(String msg, Position position) {
+			}
+			public void warning(String msg, Position position) {
+			}
+		};
+		source = contents;
+		initialize();
+	}
+	
+	public void initialize() {
+		position = 0;
+		pos_cur = 0;
+		pos_line = 1;
+		pos_col = 0;
+	}
+	
+	//
+	// Lisaac Parser
+	//
+
+	public boolean readSpace() {
+		int pos,posold;
+		int level_comment = 0;
+
+		pos = position;
+		posold = -1;
+		while (posold != position) {
+			posold = position;
+
+			// skip spaces
+			while ((lastCharacter() != 0) && (lastCharacter() <= ' ')) {
+				position++;
+			}
+			if (position < source.length()-1) {
+				// Skip C++ comment style :
+				if (lastCharacter() == '/' && source.charAt(position+1) == '/') {
+					position += 2;
+
+					if (isCatchComment) 
+						lastComment += "\t";
+
+					while ((lastCharacter() != 0) && (lastCharacter() != '\n')) {
+						if (isCatchComment) 
+							lastComment += lastCharacter();
+
+						lastCharacter();
+						position++;
+					}
+					if (isCatchComment) 
+						lastComment += "\n";
+				}
+			}
+			if (position < source.length()-1) {
+				// Skip C comment style :
+				if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
+					position += 2;
+					level_comment++;
+
+					while (lastCharacter() != 0 && level_comment != 0) {
+						if (lastCharacter() == '/' && source.charAt(position+1) == '*') {
+							position += 2;
+							level_comment++;
+						} else if (lastCharacter() == '*' && source.charAt(position+1) == '/') {
+							position += 2;
+							level_comment--;
+						} else {
+							position++;
+						}
+					}
+					if (level_comment != 0) {
+						reporter.syntaxError("End of comment not found !", getPosition());
+					}
+				}
+			}
+		}
+		// FALSE : Last character.
+		begin_position = position;
+		return (position != pos) || (lastCharacter() != 0);
+	}
+
+	public boolean readSymbol(String st) {
+		int posold,j;
+		boolean result=false;
+
+		if (! readSpace()) {
+			result = false;
+		} else {
+			posold = position;
+			j = 0;
+			while (lastCharacter() != 0 && (j <= st.length()-1 && lastCharacter() == st.charAt(j))) {
+				position++;
+				j++;
+			}
+			if (j > st.length()-1) {
+				result = true;
+				lastString = st;
+			} else {
+				position = posold;
+				result = false;
+			}
+		}
+		return result;
+	}
+
+	public boolean readCharacter (char ch) {
+		boolean result=false;
+
+		if (! readSpace()) {
+			result = false;
+		} else {
+			if (lastCharacter() == ch) {
+				position++;
+				result = true;
+			}
+		}
+		return result;
+	}
+
+	//-- affect -> ":=" | "<-" | "?="
+	public boolean readAffect() {
+		return readSymbol(ILisaacModel.symbol_affect_immediate) ||
+		readSymbol(ILisaacModel.symbol_affect_cast) ||
+		readSymbol(ILisaacModel.symbol_affect_code);
+	}
+
+	//-- style         -> '-' | '+'
+	public char readStyle() {
+		char result;
+
+		if (readCharacter('-')) {
+			result = '-';
+		} else if (readCharacter('+')) {
+			result = '+';
+		} else {
+			result = ' ';
+		}
+		return result;
+	}
+
+	//-- identifier    -> 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
+	public boolean readIdentifier() {
+		boolean result=false;
+		int posold,idx;
+
+		if (! readSpace() || !Character.isLowerCase(lastCharacter())) {
+			result = false;
+		} else {
+			posold = position;
+			string_tmp = "";
+
+			while (lastCharacter() != 0 && 
+					(Character.isLowerCase(lastCharacter()) ||
+							Character.isDigit(lastCharacter()) ||
+							lastCharacter() == '_')) {
+				string_tmp += lastCharacter();
+				position++;
+			}
+			if (string_tmp.length() > 0) {
+				idx = string_tmp.lastIndexOf("__");
+				if (idx != -1) {
+					position = posold+idx;
+					reporter.syntaxError("Identifier is incorrect.", getPosition());
+				}
+				lastString = getString(string_tmp);
+				result = true;
+			}
+		}
+		return result;
+	}
+
+	public boolean readWord(String st) {
+		int posold,idx;
+		boolean result=false;
+
+		if (! readSpace()) {
+			result = false;
+		} else {
+			posold = position;
+			idx = 0;
+
+			while (idx <= st.length()-1 && lastCharacter() == st.charAt(idx)) {
+				position++;
+				idx++;
+			}
+			if (idx > st.length()-1) {
+				lastString = st;
+				result = true;
+			} else {
+				position = posold;
+			}
+		}
+		return result;
+	}
+
+	public boolean readThisKeyword(String st) {
+		return readWord(st);
+	}
+
+	//-- keyword -> 'A'-'Z' 'a'-'z' {'a'-'z' | '0'-'9' | '_'}
+	public boolean readKeyword() {
+		boolean result=false;
+
+		if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
+			result = false;
+		} else {
+			string_tmp = "";
+			string_tmp += lastCharacter();
+			position++;
+
+			if (Character.isLowerCase(lastCharacter())) {
+				string_tmp += lastCharacter();
+				position++;				
+				while (lastCharacter() != 0 &&
+						(Character.isLowerCase(lastCharacter()) ||
+								Character.isDigit(lastCharacter()) ||
+								lastCharacter() == '_')) {
+					string_tmp += lastCharacter();
+					position++;
+				}
+				lastString = getString(string_tmp);
+				result = true;
+			} else {
+				position--;
+				result = false;
+			}
+		}
+		return result;
+	}
+
+	//-- cap_identifier -> 'A'-'Z' {'A'-'Z' | '0'-'9' | '_'}
+	public boolean readCapIdentifier() {
+		int posold,idx;
+		boolean result=false;
+		char car;
+
+		if (! readSpace() || ! Character.isUpperCase(lastCharacter())) {
+			result = false;
+		} else {
+			posold = position;
+			string_tmp = ""+lastCharacter();
+			position++;
+			isParameterType = true;
+			while (lastCharacter() != 0 && 
+					(Character.isUpperCase(lastCharacter()) ||
+							Character.isDigit(lastCharacter()) ||
+							lastCharacter() == '_')) {
+				car = lastCharacter();
+				isParameterType = isParameterType && (Character.isDigit(car));
+
+				string_tmp += car;
+				position++;
+			}
+			if (Character.isLetter(lastCharacter()) ||
+					Character.isDigit(lastCharacter()) ||
+					lastCharacter() == '_') {
+				reporter.syntaxError("Identifier is incorrect.", getPosition());
+				return false;
+			} 
+			idx = string_tmp.lastIndexOf("__");
+			if (idx != -1) {
+				position = posold + idx;
+				reporter.syntaxError("Identifier is incorrect.", getPosition());
+				return false;
+			}
+			lastString = getString(string_tmp);
+			result = true;
+		}
+		return result;
+	}
+
+	//-- integer -> number 
+	//-- number  -> {'0'-'9'} ['d'] 
+	//--          | '0'-'9' {'0'-'9' | 'A'-'F' | 'a'-'f'} 'h'
+	//--          | {'0'-'7'} 'o'
+	//--          | {'0' | '1'} 'b'
+	public boolean readInteger() {
+		boolean result=false;
+		//int pos_old;
+
+		if (readSpace() && Character.isDigit(lastCharacter())) {
+			result = true;
+			string_tmp = ""+lastCharacter();
+			//pos_old = position;
+			position++;
+
+			while (isHexadecimalDigit(lastCharacter()) || lastCharacter() == '_') {
+				if (lastCharacter() != '_') {
+					string_tmp += lastCharacter();
+				}
+				position++;
+			}
+			if (lastCharacter() == 'h') {
+				try {
+					Integer integer = Integer.valueOf(string_tmp, 16);
+					lastInteger = integer.intValue();
+				} catch (Exception e) {
+					System.out.println("Warning readInteger : "+e);// FIXME hex string
+					lastInteger = 0;
+				}
+				position++;
+			} else {
+				if (string_tmp.charAt(string_tmp.length()-1) > '9') {
+					string_tmp = string_tmp.substring(0, string_tmp.length()-1);// remove last
+					position--;
+				}
+				if (lastCharacter() == 'o') {
+					if (!isOctal(string_tmp)) {
+						reporter.syntaxError("Incorrect octal number.", getPosition());
+					}
+					lastInteger = Integer.valueOf(string_tmp, 8).intValue();
+					position++;
+				} else if (lastCharacter() == 'b') {
+					if (!isBinary(string_tmp)) {
+						reporter.syntaxError("Incorrect binary number.", getPosition());
+					}
+					lastInteger = Integer.valueOf(string_tmp, 2).intValue();
+					position++;
+				} else {
+					if (lastCharacter() == 'd') {
+						position++;
+					}
+					if (! isInteger(string_tmp)) {
+						reporter.syntaxError("Incorrect decimal number.", getPosition());
+					}
+					lastInteger = Integer.valueOf(string_tmp);
+				}
+			}
+		}
+		return result;
+	}
+
+	private boolean isInteger(String s) {
+		try {
+			Integer.parseInt(s);
+		} catch (NumberFormatException e) {
+			return false;
+		}
+		return true;
+	}
+
+	// True when the contents is a sequence of bits (i.e., mixed
+	// characters `0' and characters `1').
+	private boolean isBinary(String s) {
+		boolean result;
+		int i;
+
+		i = s.length()-1;
+		result = true;
+		while (result && i != 0) {
+			result = s.charAt(i) == '0' || s.charAt(i) == '1';
+			i--;
+		}
+		return result;
+	}
+
+	private boolean isOctal(String s) {
+		try {
+			Integer.parseInt(s, 8);
+		} catch (NumberFormatException e) {
+			return false;
+		}
+		return true;
+	}
+
+	private boolean isHexadecimalDigit(char c) {
+		boolean result=false;
+
+		if (Character.isDigit(c)) {
+			result = true;
+		} else if (c >= 'a') {
+			result = c <= 'f';
+		} else if (c >= 'A') {
+			result = c <= 'F';
+		}
+		return result;
+	}
+
+	//-- real -> '0'-'9' {'0'-'9'_} [ '.' {'0'-'9'} ] [ 'E' ['+'|'-'] '0'-'9' {'0'-'9'}
+	public boolean readReal() {
+		boolean result=false;
+		int pos_old;
+
+		if (readSpace() && Character.isDigit(lastCharacter())) {
+			string_tmp = ""+lastCharacter();
+			pos_old = position;
+			position++;
+
+			while (Character.isDigit(lastCharacter()) || lastCharacter() == '_') {
+				if (lastCharacter() != '_') {
+					string_tmp += lastCharacter();
+				}
+				position++;
+			}
+			if (lastCharacter() == '.') {
+				string_tmp += '.';
+				position++;
+
+				if (Character.isDigit(lastCharacter())) {
+					result = true;
+					string_tmp += lastCharacter();
+					position++;
+
+					while (Character.isDigit(lastCharacter())) {
+						string_tmp += lastCharacter();
+						position++;
+					}
+				}
+				if (lastCharacter() == 'E') {
+					result = true;
+					string_tmp += 'E';
+					position++;
+
+					if (lastCharacter() == '+' || lastCharacter() == '-') {
+						string_tmp += lastCharacter();
+						position++;
+					}
+					if (Character.isDigit(lastCharacter())) {
+						string_tmp += lastCharacter();
+						position++;
+						while (Character.isDigit(lastCharacter())) {
+							string_tmp += lastCharacter();
+							position++;
+						}
+					} else {
+						reporter.syntaxError("Incorrect real number.", getPosition());
+					}
+				}
+			}
+			if (result) {
+				lastReal = getString(string_tmp);
+			} else {
+				position = pos_old;
+			}
+		}
+		return result;
+	}
+
+	public void readEscapeCharacter() {
+		int val;
+
+		if (isSeparator(lastCharacter())) {
+			position++;
+			while (lastCharacter() != 0 && isSeparator(lastCharacter())) {
+				position++;
+			}
+			if (lastCharacter() == '\\') {
+				string_tmp.substring(0, string_tmp.length()-2); // remove last
+				position++;
+			} else if (lastCharacter() != 0) {
+				reporter.syntaxError("Unknown escape sequence.", getPosition());
+			}
+		} else if (lastCharacter() != 0) {
+			char c = lastCharacter();
+
+			if (c == 'a' ||
+					c == 'b' ||
+					c == 'f' ||
+					c == 'n' ||
+					c == 'r' ||
+					c == 't' ||
+					c == 'v' ||
+					c == '\\' ||
+					c == '?' ||
+					c == '\'' ||
+					c == '\"') {
+				string_tmp += c;
+				position++;
+			} else if (lastCharacter() >= '0' && lastCharacter() <= '9') {
+				if (lastCharacter() == '0' && 
+						position < source.length() &&
+						! isHexadecimalDigit(source.charAt(position+1))) {
+
+					string_tmp += lastCharacter();
+					position++;
+				} else {
+					String string_tmp2 = new String(string_tmp);
+					readInteger(); // result is Always TRUE.
+					string_tmp = string_tmp2;
+
+					if (lastInteger > 255) {
+						reporter.syntaxError("Invalid range character number [0,255].", getPosition());
+					}
+					val = (int) lastInteger;
+					string_tmp += (val / 64);
+					string_tmp += ((val % 64) / 8);
+					string_tmp += (val % 8);
+					if (lastCharacter() == '\\') {
+						position++;
+					} else {
+						reporter.syntaxError("Character '\' is needed.", getPosition());
+					}
+				}
+			} else {
+				reporter.syntaxError("Unknown escape sequence.", getPosition());
+			}
+		}
+	}
+
+	//-- character  -> '\'' ascii '\''
+	public boolean readCharacters() {
+		boolean result=false;
+		int count=0;
+
+		if (readSpace() && lastCharacter() == '\'') {
+			//old_pos = position;
+			position++;
+			string_tmp = "";
+			while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\'') {
+				string_tmp += lastCharacter();
+				if (lastCharacter() == '\\') {
+					position++;
+					readEscapeCharacter();
+					count++;
+				} else {
+					position++;
+					count++;
+				}
+			}
+			if (lastCharacter() == '\'') {
+				position++;
+				lastString = getString(string_tmp);
+				if (count != 1) {
+					position = begin_position;
+					reporter.syntaxError("Character constant too long.", getPosition());
+				}
+				result = true;
+			} else {
+				position = begin_position;
+				reporter.syntaxError("Unterminated character constant.", getPosition());
+			}
+		}
+		return result;
+	}
+
+	//-- string -> '\"' ascii_string '\"'
+	public boolean readString() {
+		boolean result=false;
+		//	int old_pos;
+
+		if (readSpace() && lastCharacter() == '\"') {
+			//	old_pos = position;
+			position = position+1;
+			string_tmp = "";
+			while (lastCharacter() != 0 && lastCharacter() != '\n' && lastCharacter() != '\"') {
+				string_tmp += lastCharacter();
+				if (lastCharacter() == '\\') {
+					position = position+1;
+					readEscapeCharacter();
+				} else {
+					position = position+1;
+				}
+			}
+			if (lastCharacter() == '\"') {
+				position = position+1;
+				lastString = getString(string_tmp);
+				result = true;
+			} else {
+				position = begin_position;
+				reporter.syntaxError("Unterminated string constant.", getPosition());
+			}
+		}
+		return result;
+	}
+
+	//-- external -> '`' ascii_c_code '`'
+	public boolean readExternal() {
+		boolean result=false;
+		//	int pos_old;
+
+		if ((! readSpace()) || lastCharacter() != '`') {
+			result = false;
+		} else {
+			//	pos_old=position;
+			position = position+1;
+			string_tmp = "";
+			while (lastCharacter() != 0 && lastCharacter() != '`') {
+				string_tmp += lastCharacter();
+				if (lastCharacter() == '\\') {
+					position = position+1;
+					string_tmp += lastCharacter();
+					if (lastCharacter() != 0) {
+						position = position+1;
+					}
+				} else {
+					position = position+1;
+				}
+			}
+			if (lastCharacter() != 0) {
+				position = position+1;
+				lastString = getString(string_tmp);
+				result = true;
+			} else {
+				result = false;
+			}
+		}
+		return result;
+	}
+
+	private final String operators = "!@#$%^&<|*-+=~/?\\>";
+
+	public boolean isOperatorSymbol(char c) {
+		return operators.indexOf(c) != -1;
+	}
+	
+	//-- operator -> '!' | '@' | '#' | '$' | '%' | '^' | '&' | '<' | '|'  
+	//--           | '*' | '-' | '+' | '=' | '~' | '/' | '?' | '\' | '>'
+	public boolean readOperator() {
+		boolean result=false;
+		//		int old_pos;
+
+		readSpace();
+		//	old_pos = position;
+		string_tmp = "";
+		while (lastCharacter() != 0 &&
+				operators.indexOf(lastCharacter()) != -1) {
+			string_tmp += lastCharacter();
+			position = position+1;
+		}
+		if (string_tmp.length() > 0) {
+			lastString = getString(string_tmp);
+			if (lastString.equals(ILisaacModel.symbol_affect_immediate) ||
+					lastString.equals(ILisaacModel.symbol_affect_code) ||
+					lastString.equals(ILisaacModel.symbol_affect_cast)) {
+				reporter.syntaxError("Incorrect operator.", getPosition());
+			}
+			result = true;
+		}
+		return result;
+	}
+
+	// True when character is a separator.
+	private boolean isSeparator(char c) {
+		return c == ' ' || c == '\t' || c == '\n' ||
+		c == '\r' || c == '\0' || c == '\f'; // || c == '\v';
+	}
+	
+	public String getString(String str) {
+		if (model == null) {
+			return str;
+		}
+		return model.getAliasString().get(str);
+	}
+
+	
+	public ILisaacErrorHandler getReporter() {
+		return reporter;
+	}
+	
+	public void readTokenAt(int line, int column) {
+		// goto (line,column) position
+		while (! isEOF()) {
+			if (source.charAt(pos_cur) == '\n') {
+				pos_col = 0;
+				pos_line++;
+			} else {
+				pos_col++;
+			}
+			if (pos_line == line && pos_col == column) {
+				position = pos_cur;
+				break;
+			}
+			pos_cur++;
+		}
+		// goto token begining
+		while (position >= 0) {
+			char c = lastCharacter();
+			if (isSeparator(c)) {
+				break;
+			}
+			position--;
+		}
+		// read token
+		position++;
+		string_tmp = "";
+		while (! isEOF()) {
+			char c = lastCharacter();
+			if (isSeparator(c)) {
+				break;
+			}
+			string_tmp += c;
+			position++;
+		}
+		lastString = string_tmp;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/AliasString.java b/editor/eclipse/src/org/lisaac/ldt/model/AliasString.java
new file mode 100644
index 0000000..c3e214c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/AliasString.java
@@ -0,0 +1,84 @@
+package org.lisaac.ldt.model;
+
+import java.util.HashSet;
+
+public class AliasString {
+	private HashSet<String> list;
+	
+	public AliasString() {
+		list = new HashSet<String>();
+		
+		// add model string constants
+		list.add(ILisaacModel.section_header); 
+		list.add(ILisaacModel.section_inherit);
+		list.add(ILisaacModel.section_insert);
+		list.add(ILisaacModel.section_public);
+		list.add(ILisaacModel.section_private);
+		list.add(ILisaacModel.section_interrupt);
+		list.add(ILisaacModel.section_mapping);
+		list.add(ILisaacModel.section_directory);
+		list.add(ILisaacModel.section_external);
+		
+		list.add(ILisaacModel.keyword_section);
+		list.add(ILisaacModel.keyword_right);
+		list.add(ILisaacModel.keyword_left);
+		list.add(ILisaacModel.keyword_ldots);
+		list.add(ILisaacModel.keyword_old);
+		list.add(ILisaacModel.keyword_expanded);  
+		list.add(ILisaacModel.keyword_strict);  
+		list.add(ILisaacModel.keyword_result);
+		
+		list.add(ILisaacModel.symbol_affect_immediate);
+		list.add(ILisaacModel.symbol_affect_cast);
+		list.add(ILisaacModel.symbol_affect_code);
+		list.add(ILisaacModel.symbol_auto_export);
+		list.add(ILisaacModel.symbol_equal);
+		list.add(ILisaacModel.symbol_not_equal);
+		list.add(ILisaacModel.symbol_great);
+		list.add(ILisaacModel.symbol_great_equal);
+		list.add(ILisaacModel.symbol_less);
+		list.add(ILisaacModel.symbol_less_equal);
+		
+		list.add(ILisaacModel.slot_name);
+		list.add(ILisaacModel.slot_export);
+		list.add(ILisaacModel.slot_import);
+		list.add(ILisaacModel.slot_external);
+		list.add(ILisaacModel.slot_default);
+		list.add(ILisaacModel.slot_type);
+		list.add(ILisaacModel.slot_version);
+		list.add(ILisaacModel.slot_date);
+		list.add(ILisaacModel.slot_comment);
+		list.add(ILisaacModel.slot_author);
+		list.add(ILisaacModel.slot_bibliography);
+		list.add(ILisaacModel.slot_language);
+		list.add(ILisaacModel.slot_copyright);
+		list.add(ILisaacModel.slot_bug_report);
+		
+		list.add(ILisaacModel.prototype_true);
+		list.add(ILisaacModel.prototype_false);
+		list.add(ILisaacModel.prototype_self);
+		list.add(ILisaacModel.prototype_string);
+		list.add(ILisaacModel.prototype_integer);
+		list.add(ILisaacModel.prototype_real);
+		list.add(ILisaacModel.prototype_boolean);
+		list.add(ILisaacModel.prototype_character);
+		list.add(ILisaacModel.prototype_block);
+		
+		list.add(ILisaacModel.variable_null);
+		list.add(ILisaacModel.variable_void);
+		list.add(ILisaacModel.variable_self);
+		
+		// lip
+		list.add(ILisaacModel.slot_lip);
+		list.add(ILisaacModel.slot_if);
+		list.add(ILisaacModel.slot_else);
+		list.add(ILisaacModel.slot_print);
+	}
+	
+	public String get (String str) {
+		if (! list.contains(str)) {
+			list.add(str);
+		}
+		return str;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/ILisaacContext.java b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacContext.java
new file mode 100644
index 0000000..168cb32
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacContext.java
@@ -0,0 +1,20 @@
+package org.lisaac.ldt.model;
+
+import org.lisaac.ldt.model.items.Prototype;
+
+public interface ILisaacContext {
+	/**
+	 * Parse the definition of the context. Returns true if the
+	 * context is correctly parsed. <br>
+	 * Automatically report parse errors.
+	 * @param prototype The model to fill
+	 * @return false if the definition of context contains at least one error
+	 */
+	boolean parseDefinition(Prototype prototype);
+
+	/**
+	 * Get the following context of same category in the lisaac code.
+	 * @return next context in current prototype
+	 */
+	ILisaacContext getNextContext();
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/ILisaacFileVisitor.java b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacFileVisitor.java
new file mode 100644
index 0000000..9c16926
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacFileVisitor.java
@@ -0,0 +1,8 @@
+package org.lisaac.ldt.model;
+
+import org.lisaac.ldt.model.items.Prototype;
+
+public interface ILisaacFileVisitor {
+	
+	void visit(Prototype prototype);
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/ILisaacModel.java b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacModel.java
new file mode 100644
index 0000000..6ce8e63
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/ILisaacModel.java
@@ -0,0 +1,96 @@
+package org.lisaac.ldt.model;
+
+import org.eclipse.core.resources.IProject;
+import org.lisaac.ldt.builder.ILisaacErrorHandler;
+import org.lisaac.ldt.model.lip.LIP;
+
+public interface ILisaacModel {
+
+	final String[] keywords = new String[] { "Section", "Public",
+		"Private", "Inherit", "Header", "Insert", "Mapping", "Interrupt",
+		"External", "Directory", 
+		"Expanded", "Strict",
+		"Left", "Right",
+		"Self",};
+	
+	final String inherit_shared             = "Shared";
+	final String inherit_shared_expanded    = "Shared Expanded";
+	final String inherit_nonshared          = "Non Shared";
+	final String inherit_nonshared_expanded = "Non Shared Expanded";
+	
+	//
+	final String keyword_section  = "Section";
+	final String keyword_right    = "Right";
+	final String keyword_left     = "Left";
+	final String keyword_ldots    = "...";
+	final String keyword_old      = "Old";
+	final String keyword_expanded = "Expanded";  
+	final String keyword_strict   = "Strict";  
+	final String keyword_result   = "Result";
+	
+	final String symbol_affect_immediate = ":=";
+	final String symbol_affect_cast      = "?=";
+	final String symbol_affect_code      = "<-";
+	final String symbol_auto_export      = "->";
+	final String symbol_auto_import      = symbol_affect_code;
+	final String symbol_equal            = "=";
+	final String symbol_not_equal        = "!=";
+	final String symbol_great            = ">";
+	final String symbol_great_equal      = ">=";
+	final String symbol_less             = "<";
+	final String symbol_less_equal       = "<=";
+	
+	final String section_header     = "Header";
+	final String section_inherit    = "Inherit";
+	final String section_insert     = "Insert";
+	final String section_public     = "Public";
+	final String section_private    = "Private";
+	final String section_interrupt  = "Interrupt";
+	final String section_mapping    = "Mapping";
+	final String section_directory  = "Directory";
+	final String section_external   = "External";
+	
+	final String slot_name         = "name";
+	final String slot_export       = "export";
+	final String slot_import       = "import";
+	final String slot_external     = "external";
+	final String slot_default      = "default";
+	final String slot_type         = "type";
+	final String slot_version      = "version";
+	final String slot_date         = "date";
+	final String slot_comment      = "comment";
+	final String slot_author       = "author";
+	final String slot_bibliography = "bibliography";
+	final String slot_language     = "language";
+	final String slot_copyright    = "copyright";
+	final String slot_bug_report   = "bug_report";
+	
+	final String  prototype_true            = "TRUE";
+	final String  prototype_false           = "FALSE";
+	final String  prototype_self            = "SELF";
+	final String  prototype_string          = "STRING";
+	final String  prototype_integer         = "INTEGER";
+	final String  prototype_real            = "REAL";
+	final String  prototype_boolean         = "BOOLEAN";
+	final String  prototype_character       = "CHARACTER";
+	final String  prototype_block           = "BLOCK";
+	
+	final String variable_null          = "NULL";
+	final String variable_void          = "VOID";
+	final String variable_self          = "Self";
+	
+	// lip
+	final String slot_lip    = "lip";
+	final String slot_if    = "if";
+	final String slot_else  = "else";
+	final String slot_print = "print";
+	
+	final String slot_debug_mode = "debug_mode";
+	
+	ILisaacErrorHandler getReporter();
+	AliasString getAliasString();
+	LisaacParser getParser();
+	LIP getLipCode();
+	IProject getProject(); 
+	LisaacPath getPathManager();
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/LipParser.java b/editor/eclipse/src/org/lisaac/ldt/model/LipParser.java
new file mode 100644
index 0000000..fe22d7d
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/LipParser.java
@@ -0,0 +1,465 @@
+package org.lisaac.ldt.model;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import org.lisaac.ldt.model.lip.*;
+
+
+public class LipParser extends AbstractLisaacParser {
+
+	public LIP lipFile;
+
+	public LipParser(InputStream contents, ILisaacModel model) {
+		super(contents, model);
+		this.lipFile = model.getLipCode();
+	}
+
+	public LipParser(String contents, int offset) {
+		super(contents);
+		setPosition(offset);
+	}
+	
+	//
+	// Parser for LIP file.
+	// 
+
+	////PROGRAM      -> { 'Section' ('Inherit' | 'Public' | 'Private') { SLOT ';' } } 
+	public boolean parse() {
+		boolean result=false;
+
+		while (readThisKeyword(ILisaacModel.keyword_section)) {
+			if (readThisKeyword(ILisaacModel.section_inherit)) {
+				// { '+' string ':' STRING [ ':=' string ] ';' }
+				while (readCharacter('+')) {
+					if (! readIdentifier()) {
+						reporter.syntaxError("Identifier needed.", getLine());
+						return false;
+					}
+					if (! readCharacter(':')) {
+						reporter.syntaxError("Added ':' is needed.", getLine());
+						return false;
+					}
+					if (! readWord(ILisaacModel.prototype_string)) {
+						reporter.warning("`STRING' type needed.", getLine());
+					}
+					if (readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						if (! readString()) {
+							reporter.syntaxError("String needed.", getLine());
+							return false;
+						}
+						string_tmp = new String(lipFile.getFileName());
+						while (string_tmp.length() > 0) {
+							char c = string_tmp.charAt(string_tmp.length()-1);
+							if (c == '/' || c == '\\') {
+								break;
+							}// FIXME use index
+							string_tmp = string_tmp.substring(0, string_tmp.length()-1);
+						}
+						string_tmp += lastString;
+					} else {
+						string_tmp = "";
+					}
+					// add parent slot
+					lipFile.addParent(getString(string_tmp));
+					//
+					if (! readCharacter(';')) {
+						reporter.syntaxError("Added ';' is needed.", getLine());
+						return false;
+					}
+					result = true;
+				}
+			} else if (readThisKeyword(ILisaacModel.section_public) ||
+					readThisKeyword(ILisaacModel.section_private)) {
+				String section = new String(lastString);
+				while (readSlot(section)) {
+					if (! readCharacter(';')) {
+						reporter.syntaxError("Added ';' is needed.", getLine());
+						return false;
+					}
+					result = true;
+				}
+			} else {
+				reporter.syntaxError("`Public' or `Private' or `Inherit' needed.", getLine());
+				return false;	
+			}
+		}
+		if (position < source.length()-2) {
+			result = false;
+		}
+		
+		// TODO recursive parsing !!!
+		return result;
+	} 
+
+	//// SLOT         -> '+' identifier ':' TYPE [ ':=' EXPR_CONSTANT ]
+	////               | '-' identifier [ identifier ':' TYPE ] '<-' '(' { EXPR ';' } ')' 
+	private boolean readSlot(String sec) {
+		boolean result=false;
+		LIPSlotData data=null;
+
+		if (readCharacter('+')) {
+			// Data.
+			result = true;
+			if (sec.equals(ILisaacModel.section_public)) {
+				reporter.syntaxError("No data in Public section.", getPosition(1));
+			}
+			if (! readIdentifier()) {
+				reporter.syntaxError("Identifier is incorrect.", getLine());
+				return false;
+			}
+			String n = new String(lastString);
+			if (! readCharacter(':')) {
+				reporter.syntaxError("Added ':' is needed.", getLine());
+				return false;
+			}
+			LIPConstant t = readType();
+			if (t == null) {
+				reporter.syntaxError("type is incorrect.", getLine());
+				return false;
+			}
+			data = new LIPSlotData(n, t);
+			//
+			lipFile.addData(data);
+			//
+			if (readSymbol(LisaacModel.symbol_affect_immediate)) {
+				LIPConstant cst = readExprConstant();
+				if (cst == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return false;
+				}
+				data.setValue(cst);
+				cst.free();
+			}
+		} else if (readCharacter('-')) {
+			// Function.
+			result = true;
+			if (! readIdentifier()) {
+				reporter.syntaxError("Identifier is incorrect.", getLine());
+				return false;
+			}
+			//Position pos = getPosition();
+			setCatchComment();
+
+			String n = new String(lastString);
+			if (readIdentifier()) {
+				String na = new String(lastString);
+				if (! readCharacter(':')) {
+					reporter.syntaxError("Added ':' is needed.", getLine());
+					return false;
+				}
+				LIPConstant t = readType();
+				if (t == null) {
+					reporter.syntaxError("Incorrect type.", getLine());
+					return false;
+				}
+				data = new LIPSlotData(na, t);// do not add argument do lipFile
+			}
+			//
+			if (! readSymbol(ILisaacModel.symbol_affect_code)) {
+				reporter.syntaxError("Added '<-' is needed.", getLine());
+				return false;
+			}
+			if (! readCharacter('(')) {
+				reporter.syntaxError("Added '(' is needed.", getLine());
+				return false;
+			}
+			setCatchCommentOff();
+			ArrayList<LIPCode> code = new ArrayList<LIPCode>();
+			LIPCode instr;
+			while ((instr = readExpr()) != null) {
+				code.add(instr);
+				if (! readCharacter(';')) {
+					reporter.syntaxError("Added ';' is needed.", getLine());
+					return false;
+				}
+			}
+			if (! readCharacter(')')) {
+				reporter.syntaxError("Added ')' is needed.", getLine());
+				return false;
+			}
+			LIPSlotCode slotCode = new LIPSlotCode(sec, n, data, code.toArray(new LIPCode[code.size()]));
+			lipFile.addMethod(slotCode);
+			if (sec.equals(ILisaacModel.section_public)) {
+				if (lastComment == null || lastComment.length() == 0) {
+					reporter.syntaxError("Comment needed.", getPosition());
+				} else {
+					slotCode.setComment(lastComment);
+				}
+			}
+		}
+		return result;
+	}
+
+	////TYPE         -> 'BOOLEAN' | 'STRING' | 'INTEGER'
+	private LIPConstant readType() {
+		LIPConstant result=null;
+
+		if (readCapIdentifier()) {
+			if (lastString.equals(ILisaacModel.prototype_integer)) {
+				result = LIPInteger.get(0);
+			} else if (lastString.equals(ILisaacModel.prototype_string)) {
+				result = LIPString.get(getString(""));
+			} else if (lastString.equals(ILisaacModel.prototype_boolean)) {
+				result = LIPBoolean.get(false);
+			} else {
+				reporter.syntaxError("Incorrect type.", getLine());
+			}
+		}
+		return result;
+	}
+
+	//// EXPR         -> [ identifier !!AMBIGU!! ':=' ] EXPR_OPERATOR [ '.' FUNCTION ]
+	public LIPCode readExpr() {
+		LIPCode result=null;
+
+		saveContext(); // !! SAVE CONTEXT !!
+
+		if (readIdentifier()) {
+			String name = new String(lastString);
+			if (readSymbol(ILisaacModel.symbol_affect_immediate)) {
+				LIPCode val = readExprOperator();
+				if (val == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				result = new LIPAffect(name, val);
+			} else {
+				restoreContext(); // !! RESTORE CONTEXT !!
+			}
+		}
+		if (result == null) {
+			result = readExprOperator();
+			if (result != null && readCharacter('.')) {
+				result = readFunction(result);
+				if (result == null) {
+					reporter.syntaxError("Incorrect slot.", getLine());
+					return null;
+				}
+			}
+		}
+		return result;
+	}
+
+	//// FUNCTION     -> 'if' '{' { EXPR ';' }  '}' [ 'else' '{' { EXPR ';' } '}' ]
+	////               | 'print'
+	private LIPCode readFunction(LIPCode rec) {
+		LIPCode result=null;
+		ArrayList<LIPCode> thenArray=null, elseArray=null;
+
+		if (readWord(ILisaacModel.slot_if)) {
+			thenArray = new ArrayList<LIPCode>();
+			if (! readCharacter('{')) {
+				reporter.syntaxError("Added '{' is needed.", getLine());
+				return null;
+			}
+			LIPCode val;
+			while ((val = readExpr()) != null) {
+				thenArray.add(val);
+				if (! readCharacter(';')) {
+					reporter.syntaxError("Added ';' is needed.", getLine());
+					return null;
+				}
+			}
+			if (! readCharacter('}')) {
+				reporter.syntaxError("Added '}' is needed.", getLine());
+				return null;
+			}
+			if (readWord(ILisaacModel.slot_else)) {
+				elseArray = new ArrayList<LIPCode>();
+				if (! readCharacter('{')) {
+					reporter.syntaxError("Added '{' is needed.", getLine());
+					return null;
+				}
+				while ((val = readExpr()) != null) {
+					elseArray.add(val);
+					if (! readCharacter(';')) {
+						reporter.syntaxError("Added ';' is needed.", getLine());
+						return null;
+					}
+				}
+				if (! readCharacter('}')) {
+					reporter.syntaxError("Added '}' is needed.", getLine());
+					return null;
+				}
+			}
+			result = new LIPIf(rec, thenArray.toArray(new LIPCode[thenArray.size()]),
+					elseArray.toArray(new LIPCode[elseArray.size()]));
+		} else if (readWord(ILisaacModel.slot_print)) {
+			result = new LIPPrint(rec);
+		}
+		return result;
+	}
+
+	////EXPR_OPERATOR-> EXPR_CMP { ('|' | '&') EXPR_CMP }   
+	private LIPCode readExprOperator() {
+		LIPCode result=null;
+		boolean isOr=false;
+
+		result = readExprCmp();
+		if (result != null) {
+			while ((isOr = readCharacter('|')) || readCharacter('&')) {
+				LIPCode right = readExprCmp();
+				if (right == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				if (isOr) {
+					result = new LIPBinary(result, '|', right);
+				} else {
+					result = new LIPBinary(result, '&', right);
+				}
+			}
+		}
+		return result;
+	}
+
+	////EXPR_CMP     -> EXPR_BINARY { ('='|'!='|'>'|'<'|'>='|'<=') EXPR_BINARY }
+	private LIPCode readExprCmp() {
+
+		LIPCode result = readExprBinary();
+		if (result != null) {
+			while (readSymbol(ILisaacModel.symbol_great_equal) ||
+					readSymbol(ILisaacModel.symbol_less_equal) ||
+					readSymbol(ILisaacModel.symbol_not_equal) ||
+					readSymbol(ILisaacModel.symbol_equal) ||
+					readSymbol(ILisaacModel.symbol_great) ||
+					readSymbol(ILisaacModel.symbol_less)) {
+				String op = new String(lastString);
+				LIPCode right = readExprBinary();
+				if (right == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				char type = 0;
+				if (op.equals(">=")) {
+					type = 'S';
+				} else if (op.equals("<=")) {
+					type = 'I';
+				} else if (op.equals("!=")) {
+					type = 'E';
+				} else if (op.equals("=")) {
+					type = '=';
+				} else if (op.equals(">")) {
+					type = '>';
+				} else if (op.equals("<")) {
+					type = '<';
+				}
+				result = new LIPBinary(result, type, right);	
+			}
+		}
+		return result;
+	}
+
+	////EXPR_BINARY  -> EXPR_UNARY { ('-'|'+') EXPR_UNARY }
+	private LIPCode readExprBinary() {
+		boolean isSub;
+
+		LIPCode result = readExprUnary();
+		if (result != null) {
+			while ((isSub = readCharacter('-')) || readCharacter('+')) {
+				LIPCode right = readExprUnary();
+				if (right == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				if (isSub) {
+					result = new LIPBinary(result, '-', right);
+				} else {
+					result = new LIPBinary(result, '+', right);
+				}
+			}
+		}
+		return result;
+	}
+
+	//// EXPR_UNARY   -> ( '-' | '!' ) EXPR_UNARY
+	////               | EXPR_BASE
+	////               | identifier [ EXPR_ARGUMENT ]
+	private LIPCode readExprUnary() {
+		LIPCode result=null;
+		boolean isNeg;
+
+		if ((isNeg = readCharacter('-')) || readCharacter('!')) {
+			result = readExprUnary();
+			if (result == null) {
+				reporter.syntaxError("Incorrect expression.", getLine());
+				return null;
+			}
+			char type;
+			if (isNeg) {
+				type = '-';
+			} else {
+				type = '+';
+			}
+			result = new LIPUnary(type, result);
+		} else if (readIdentifier()) {
+			String name = new String(lastString);
+			LIPCode arg = readExprArgument();
+			result = new LIPCall(name, arg);
+		} else {
+			result = readExprBase();
+		}
+		return result;
+	}
+
+	//// EXPR_BASE    -> '(' EXPR_OPERATOR ')'
+	////               | EXPR_CONSTANT
+	private LIPCode readExprBase() {
+		LIPCode result=null;
+
+		if (readCharacter('(')) {
+			result = readExprOperator();
+			if (result == null) {
+				reporter.syntaxError("Incorrect expression.", getLine());
+				return null;
+			}
+			if (! readCharacter(')')) {
+				reporter.syntaxError("Added ')' is needed.", getLine());
+				return null;
+			}
+		} else {
+			LIPConstant v = readExprConstant();
+			if (v != null) {
+				result = new LIPValue(v);
+			}
+		}
+		return result;
+	}
+
+	////EXPR_CONSTANT-> integer              
+	////               | string
+	////               | TRUE
+	////               | FALSE
+	private LIPConstant readExprConstant() {
+		LIPConstant result=null;
+
+		if (readInteger()) {
+			result = LIPInteger.get((int)lastInteger);
+		} else if (readString()) {
+			result = LIPString.get(lastString);
+		} else if (readCapIdentifier()) {
+			if (lastString.equals(ILisaacModel.prototype_true)) {
+				result = LIPBoolean.get(true);
+			} else if (lastString.equals(ILisaacModel.prototype_false)){
+				result = LIPBoolean.get(false);	
+			} else {
+				reporter.syntaxError("Type incorrect.", getLine());
+			}
+		}
+		return result;
+	}
+
+	//// EXPR_ARGUMENT-> identifier 
+	////               | EXPR_BASE
+	private LIPCode readExprArgument() {
+		LIPCode result=null;
+
+		if (readIdentifier()) {
+			result = new LIPCall(lastString, null);
+		} else {
+			result = readExprBase();
+		}
+		return result;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/LisaacCompletionParser.java b/editor/eclipse/src/org/lisaac/ldt/model/LisaacCompletionParser.java
new file mode 100644
index 0000000..d539280
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/LisaacCompletionParser.java
@@ -0,0 +1,193 @@
+package org.lisaac.ldt.model;
+
+
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.LisaacEditor;
+import org.lisaac.ldt.model.items.ICode;
+import org.lisaac.ldt.model.items.ITMRead;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Slot;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSelf;
+import org.lisaac.ldt.outline.OutlineImages;
+
+public class LisaacCompletionParser extends LisaacParser {
+	protected static LisaacModel model;
+
+	protected Prototype currentPrototype;
+	protected Slot currentSlot;
+
+	protected int endOffset;
+
+
+
+	public LisaacCompletionParser(String contents, LisaacModel model) {
+		super(null,contents);
+		LisaacCompletionParser.model = model;
+	} 
+
+	/**
+	 * Get the lisaac completions at baseOffset
+	 * @param startOffset start offset for completion parsing
+	 * @param baseOffset completion offset 
+	 * @param proposals list of proposals to be filled  
+	 * @throws CoreException
+	 */
+	public void parseCompletions(int startOffset, int baseOffset, ArrayList<ICompletionProposal> proposals)
+	throws CoreException {
+		IType type;
+
+		currentPrototype = LisaacModel.getCurrentPrototype();
+		currentSlot = currentPrototype.getSlot(startOffset);
+		endOffset = -1;
+
+		// keyword match
+		while (readKeyword()) {
+			if (baseOffset != (startOffset+position)) {
+				continue;// not last keyword
+			}
+			String[] keywords = ILisaacModel.keywords;
+			for (int i = 0; i < keywords.length; i++) {
+				if (keywords[i].startsWith(lastString)) {// length(keyword[i]) >= length(lastString)
+					String keywordCompletion = keywords[i].substring(lastString.length());
+					proposals.add(new CompletionProposal(keywordCompletion,
+							baseOffset, 0, keywordCompletion.length(),
+							OutlineImages.KEYWORD, keywords[i], null, ""));
+				}
+			}
+			return;
+		}
+		
+		// slot match
+		ICode code = readExpr();
+		if (code != null && currentPrototype != null) {
+			type = code.getType(currentSlot, currentPrototype);
+			if (type != null) {
+				//if (! type.equals(TypeSimple.getTypeSelf())) {
+				//if ("SELF".compareTo(type.toString()) != 0) {
+				if (type instanceof TypeSelf) {
+					currentPrototype = findPrototype(((TypeSelf) type).getStaticType());
+				} else {
+					currentPrototype = findPrototype(type.toString());
+				}
+				if (currentPrototype != null) {
+					currentPrototype.getSlotProposals(proposals, baseOffset, 0);
+					proposals.add(new CompletionProposal(""+type,baseOffset,0,0));
+				} else {
+					// partial prototype name
+					String prefix = type.toString();
+					model.getPathManager().getPathMatch(prefix, proposals, baseOffset);
+				}
+			} else {
+				// partial slot name (first keyword)
+				if (code instanceof ITMRead) {
+					String prefix = ((ITMRead) code).getName();
+					currentPrototype.lookupSlotMatch(prefix, proposals, baseOffset, 0);
+				}
+			}
+		}
+	}
+
+	//++ EXPR_MESSAGE -> EXPR_BASE { '.' SEND_MSG }
+	protected ICode readExprMessage() {
+
+		ICode result = readExprBase();
+		if (result != null) {
+			while (readCharacter('.')) {
+				if (endOffset != -1 && position == endOffset+1) {
+					break;
+				}
+				ICode lastResult = result;
+				result = readSendMsg(result);
+				if (result == null) {
+					return lastResult;
+				}
+				// update source of completion
+				IType type = lastResult.getType(currentSlot, currentPrototype);
+				//if (type != null && ! type.equals(TypeSimple.getTypeSelf())) {
+				if (type != null && "SELF".compareTo(type.toString()) != 0) {
+					try {
+						currentPrototype = findPrototype(type.toString());
+					} catch(CoreException e) {
+						return null;
+					}
+					if (currentPrototype == null) {
+						return null;
+					}
+					if (result instanceof ITMRead) {
+						currentSlot = currentPrototype.lookupSlot(((ITMRead) result).getName());
+					} else {
+						currentSlot = null;
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+
+	public Prototype readReceiver(int startOffset, int endOffset, Prototype currentPrototype) throws CoreException {
+		Prototype result=null;
+		IType type;
+
+		this.currentPrototype = currentPrototype;//LisaacModel.getCurrentPrototype();
+		currentSlot = currentPrototype.getSlot(startOffset);
+		this.endOffset = endOffset;
+
+		setPosition(startOffset);
+		readSpace();
+
+		ICode code = readExpr();
+		if (code != null && currentPrototype != null) {
+			type = code.getType(currentSlot, currentPrototype);
+			if (type != null) {
+				//if (! type.equals(TypeSimple.getTypeSelf())) {
+				if (type.toString() != null && "SELF".compareTo(type.toString()) != 0) {
+					Prototype save = currentPrototype;
+					currentPrototype = findPrototype(type.toString());
+					if (currentPrototype == null) {
+						currentPrototype = save;
+					}
+				}
+				result = currentPrototype;	
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Find and parse a lisaac prototype according to its name.
+	 */
+	public static Prototype findPrototype(String prototypeName) throws CoreException {
+		IProject project = null;
+
+		if (model == null) {
+			IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+			if (w == null) {
+				return null;
+			} 
+			IWorkbenchPart part = w.getPartService().getActivePart();
+			if (part instanceof LisaacEditor) {
+				project = ((LisaacEditor)part).getProject();
+			}
+			if (project != null) {
+				model = LisaacModel.getModel(project);
+			}
+		}
+		if (model == null) {
+			return null;
+		}
+		if (project == null) {
+			project = model.getProject();
+		}
+		return model.getPrototype(prototypeName);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/LisaacModel.java b/editor/eclipse/src/org/lisaac/ldt/model/LisaacModel.java
new file mode 100644
index 0000000..e0913ae
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/LisaacModel.java
@@ -0,0 +1,309 @@
+package org.lisaac.ldt.model;
+
+import java.io.InputStream;
+import java.util.HashMap;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.builder.ILisaacErrorHandler;
+import org.lisaac.ldt.editors.AbstractLisaacEditor;
+import org.lisaac.ldt.editors.LisaacEditor;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.lip.LIP;
+
+/**
+ * Represents Lisaac model of a project
+ * @author Damien Bouvarel
+ */
+public class LisaacModel implements ILisaacModel{
+
+	/** list of all encoutered models */
+	private static HashMap<IProject,LisaacModel> modelList;
+
+	/** list of all legal prototypes path */
+	private LisaacPath modelPath;
+
+	/** list of all encountered prototypes */
+	private HashMap<String,Prototype> prototypes;
+
+	/** lip makefile of this model */
+	private LIP lipCode;
+
+	/** project associated with this model */
+	private IProject project;
+
+	/** error handler */
+	private ILisaacErrorHandler reporter;
+
+	/** lisaac parser */
+	private LisaacParser parser;
+
+	/** string aliaser */
+	private AliasString aliasString;
+
+	/** modification flag */
+	private boolean isProjectCompiled;
+	
+	public static AbstractLisaacEditor currentEditor = null;
+
+
+	public LisaacModel(IProject project) {
+		this.project = project;
+		prototypes = new HashMap<String,Prototype>();
+		aliasString = new AliasString();
+
+		// add this model to the model list
+		if (modelList == null) {
+			modelList = new HashMap<IProject,LisaacModel>();
+		}
+		modelList.put(project, this);
+
+		// create lisaac path
+		modelPath = new LisaacPath(project, "make.lip"); // TODO get lip from property page
+		isProjectCompiled = false;
+	}
+
+	public IProject getProject() {
+		return project;
+	}
+	public void setProject(IProject project) {
+		this.project = project;
+	}
+
+	public AliasString getAliasString() {
+		return aliasString;
+	}
+	public LisaacParser getParser() {
+		return parser;
+	}
+	public LisaacPath getPathManager() {
+		return modelPath;
+	}
+	public LIP getLipCode() {
+		return lipCode;
+	}
+
+	public Prototype getPrototype(String name) throws CoreException {
+		Prototype result=null;
+
+		if (prototypes != null) {
+			result = prototypes.get(name); // prototype is already cached
+
+			if (result == null) {
+				// cache new prototype
+				String prototypePath = modelPath.getFullPath(name);
+				if (prototypePath != null) {
+					IPath location = new Path(prototypePath);
+					IPath projectLocation = project.getLocation();
+					IFile file = null;
+
+					if (projectLocation.isPrefixOf(location)) {
+						// the file is inside the workspace
+						location = location.removeFirstSegments(projectLocation.segmentCount());
+						file = project.getFile(location);
+					} else {
+						// file is outside workspace : create link in /lib
+						IContainer lib = project.getFolder("lib");
+						if (lib == null) {
+							lib = project;
+						}
+						file = lib.getFile(new Path(location.lastSegment()));
+						if (! file.isAccessible() && ! file.exists()) {
+							file.createLink(location, IResource.NONE, null);
+							//
+							ResourceAttributes attrib = new ResourceAttributes();
+							attrib.setReadOnly(true);
+							file.setResourceAttributes(attrib);
+							//
+						}
+					}
+					result = parsePrototype(file, file.getContents(), new ILisaacErrorHandler() {
+						public void fatalError(String msg, Position position) {				
+						}
+						public void semanticError(String msg, Position position) {					
+						}
+						public void syntaxError(String msg, Position position) {			
+						}
+						public void warning(String msg, Position position) {
+						}
+					});
+				}
+			}
+		}
+		return result;
+	}
+
+	public void refreshPresentation() {		
+		final IWorkbenchPart part = currentEditor;			
+		Display display = PlatformUI.getWorkbench().getDisplay();
+
+		if (currentEditor != null) {
+			display.asyncExec(new Runnable() {
+				public void run() {
+					((AbstractLisaacEditor)part).refreshPresentation();
+				}
+			});
+		}
+	}
+
+	public void accept(final ILisaacFileVisitor visitor) {
+		try {
+			project.accept(new IResourceVisitor() {
+				public boolean visit(IResource resource) throws CoreException {
+					if (resource instanceof IFile) {
+						if (resource.getName().endsWith(".li")) {
+							String name = extractPrototypeName(resource.getName());
+							visitor.visit(getPrototype(name));
+						}
+					}
+					return true;
+				}		
+			});
+		} catch (CoreException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/** parse and create part of current model */
+	public Prototype parsePrototype(IFile file, InputStream contents, ILisaacErrorHandler reporter) {
+		this.reporter = reporter;
+
+		String name = file.getName();
+		String prototypeName = extractPrototypeName(name);
+
+		modelPath.addPath(prototypeName, file.getLocation());
+
+		parser = new LisaacParser(prototypeName, contents, this);
+		Prototype prototype = new Prototype(file, prototypeName, this);
+
+		ILisaacContext context = parser.readContext();
+		while (context != null) {
+			if (context.parseDefinition(prototype)) { 
+				context = parser.readContext();
+			} else {
+				context = context.getNextContext();
+			}
+		}
+		parser.setLastSection(null);// close last section
+
+		// add new prototype to current model
+		prototypes.put(prototype.getName(), prototype);
+		return prototype;
+	}
+
+	/** remove part of current model */
+	public void removePrototype(IResource resource) {
+		prototypes.remove(extractPrototypeName(resource.getName()));
+	}
+
+	/** parse and create part of current model 
+	 * @throws CoreException */
+	public void parseLip(String name, InputStream contents, ILisaacErrorHandler reporter) throws CoreException {
+		this.reporter = reporter;
+
+		lipCode = new LIP(name);
+		LipParser lipParser = new LipParser(contents, this);
+		if (! lipParser.parse()) {
+			reporter.syntaxError("Syntax error.", lipParser.getPosition());
+			return;
+		}
+
+	/*	// parse lip parents
+		for (int i=0; i<lipCode.getParentCount(); i++) {
+			String parent = lipCode.getParent(i);
+			IFile file=null;
+			if (parent.equals("")) { // lisaac make.lip
+				// TODO get lisaac directory
+				return;
+			} else {
+				file = project.getFile(parent);
+			}
+			lipParser = new LipParser(file.getContents(), this);
+			if (! lipParser.parse()) {
+				reporter.syntaxError("Syntax error.", lipParser.getPosition());
+			}
+		}*/
+	}
+
+	/** remove part of current model */
+	public void removeLip(IResource resource) {
+		// TODO remove lip
+	}
+
+	/** get little name of prototype instead of full path */
+	public static String extractPrototypeName(String s) {
+		int idx = s.indexOf('.');
+		if (idx != -1) {
+			return (s.substring(0, idx)).toUpperCase();
+		}
+		return s.toUpperCase();
+	}
+
+	public ILisaacErrorHandler getReporter() {
+		return reporter;
+	}
+
+	/**
+	 * Get the lisaac model associated with the given project.
+	 * @param p A lisaac project
+	 * @return The associated lisaac model
+	 */
+	public static LisaacModel getModel(IProject p) {
+		if (modelList != null) {
+			return modelList.get(p);
+		}
+		return null;
+	}
+
+	public static Prototype getCurrentPrototype() throws CoreException {
+		IWorkbenchWindow w = LisaacPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow();
+		if (w == null) {
+			return null;
+		}
+		IPartService service = w.getPartService(); 
+		if (service == null) {
+			return null;
+		}
+		IWorkbenchPart part = service.getActivePart();
+		if (part == null ||  !(part instanceof LisaacEditor)) {
+			part = currentEditor; 
+		}
+		if (part instanceof LisaacEditor) {
+			IProject project = ((LisaacEditor)part).getProject();
+			String filename = ((LisaacEditor)part).getFileName();
+
+			LisaacModel model = LisaacModel.getModel(project);
+			if (model != null) {
+				return model.getPrototype(extractPrototypeName(filename));
+			}
+		}
+		return null;
+	}
+
+	public void refreshPath() {
+		// create lisaac path
+		modelPath = new LisaacPath(project, "make.lip"); // TODO get lip from property page
+	}
+
+	public boolean needCompilation() {
+		return !isProjectCompiled;
+	} 
+	
+	public void setCompiled(boolean done) {
+		isProjectCompiled = done;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/LisaacParser.java b/editor/eclipse/src/org/lisaac/ldt/model/LisaacParser.java
new file mode 100644
index 0000000..994bd3f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/LisaacParser.java
@@ -0,0 +1,1554 @@
+package org.lisaac.ldt.model;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.lisaac.ldt.model.items.IArgument;
+import org.lisaac.ldt.model.items.ICode;
+import org.lisaac.ldt.model.items.IConstant;
+import org.lisaac.ldt.model.items.ITMArgs;
+import org.lisaac.ldt.model.items.ITMArgument;
+import org.lisaac.ldt.model.items.ITMBlock;
+import org.lisaac.ldt.model.items.ITMCharacter;
+import org.lisaac.ldt.model.items.ITMExpression;
+import org.lisaac.ldt.model.items.ITMExternal;
+import org.lisaac.ldt.model.items.ITMExternalType;
+import org.lisaac.ldt.model.items.ITMLDots;
+import org.lisaac.ldt.model.items.ITMList;
+import org.lisaac.ldt.model.items.ITMListIdf;
+import org.lisaac.ldt.model.items.ITMLocal;
+import org.lisaac.ldt.model.items.ITMNumber;
+import org.lisaac.ldt.model.items.ITMOld;
+import org.lisaac.ldt.model.items.ITMOperator;
+import org.lisaac.ldt.model.items.ITMPrototype;
+import org.lisaac.ldt.model.items.ITMRead;
+import org.lisaac.ldt.model.items.ITMReadArg1;
+import org.lisaac.ldt.model.items.ITMReadArg2;
+import org.lisaac.ldt.model.items.ITMReadArgs;
+import org.lisaac.ldt.model.items.ITMReal;
+import org.lisaac.ldt.model.items.ITMResult;
+import org.lisaac.ldt.model.items.ITMString;
+import org.lisaac.ldt.model.items.ITMWrite;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Section;
+import org.lisaac.ldt.model.items.Slot;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.ITypeMono;
+import org.lisaac.ldt.model.types.TypeBlock;
+import org.lisaac.ldt.model.types.TypeGeneric;
+import org.lisaac.ldt.model.types.TypeMulti;
+import org.lisaac.ldt.model.types.TypeParameter;
+import org.lisaac.ldt.model.types.TypeSelf;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+/**
+ *  Lisaac Prototype Parser
+ */
+
+
+public class LisaacParser extends AbstractLisaacParser {
+
+	private String selfType;
+
+	private ILisaacContext sectionContext;
+	private ILisaacContext slotContext;
+
+	//
+	private Slot lastSlot;
+	private ITMList lastGroup;
+	private Section lastSection;
+	//
+
+	public LisaacParser(String selfType, InputStream contents, ILisaacModel model) {
+		super(contents, model);
+		this.model = model;
+		this.selfType = selfType;
+		sectionContext = new SectionContext(this);
+		slotContext = new SlotContext(this);
+
+		initialize();
+	}
+
+	public LisaacParser(String selfType, String contents) {
+		super(contents);
+		this.selfType = selfType;
+		initialize();
+	}
+
+	public void initialize() {
+		//
+		// initialisations
+		//
+		super.initialize();
+		TypeSimple.init();
+	}
+
+	public ILisaacContext getSectionContext() {
+		return sectionContext;
+	}
+
+	public Slot getLastSlot() {
+		return lastSlot;
+	}
+
+	public void setLastSection(Section section) {
+		if (lastSection != null) {
+			// update last section length
+			Position pos = lastSection.getPosition();
+			pos.setLength(position - pos.offset);
+
+			// update link
+			lastSection.setNext(section);
+		}
+		lastSection = section;
+	}
+
+	//
+	// Lisaac Prototype Parser
+	//
+
+	//++ TYPE_LIST    -> TYPE { ',' TYPE }
+	public ITypeMono[] readTypeList(boolean isSection) {
+		ArrayList<ITypeMono> lst=null;
+		ITypeMono t;
+
+		t = readType(false);
+		if (t != null) {
+			if (isSection) {
+				if (! (t instanceof TypeSimple) && ! (t instanceof TypeSelf)) {
+					reporter.syntaxError("For a section, the prototype name only (without '('...')').", getLine());
+					return null;
+				}
+			}
+			lst = new ArrayList<ITypeMono>();
+			lst.add(t);
+			while (readCharacter(',')) {
+				t = readType(false);
+				if (t == null) {
+					reporter.syntaxError("Incorrect type list.", getLine());
+					return null;
+				}
+				if (isSection) {
+					if (! (t instanceof TypeSimple)) {
+						reporter.syntaxError("For a section, the prototype name only (without '('...')').", getLine());
+						return null;
+					}
+				}
+				lst.add(t);
+			}
+			// TODO alias lst
+		}
+		if (lst != null) {
+			return lst.toArray(new ITypeMono[lst.size()]);
+		}
+		return null;
+	}
+
+	//++ TYPE         -> '{' [ (TYPE | '(' TYPE_LIST ')') ';' ] [ TYPE_LIST ] '}'
+	//++               | [type] PROTOTYPE [ CONTRACT ]
+	public ITypeMono readType (boolean isLocal) {
+		ITypeMono result=null;
+		ITypeMono[] lst=null;
+		IType typ_arg=null,typ_res=null;
+		String style=null;
+
+		if (readCharacter('{')) {
+			// '{' [ (TYPE | '(' TYPE_LIST ')') ';' ] [ TYPE_LIST ] '}' 
+			if (readCharacter('(')) {
+				// Read vector argument.
+				lst = readTypeList(false);
+				if (lst == null) {
+					reporter.syntaxError("Incorrect type list.", getLine());
+					return null;
+				}
+				if (lst.length == 1) {
+					typ_arg = lst[0];
+				} else {
+					typ_arg = TypeMulti.get(lst);
+				}
+				if (! readCharacter(')')) {
+					reporter.syntaxError("Added ')'.", getLine());
+					return null;
+				}
+				if (! readCharacter(';')) {
+					reporter.syntaxError("Added ';'.", getLine());
+				}
+				// Read result type.
+				lst = readTypeList(false);
+			} else {
+
+				lst = readTypeList(false);
+				if (lst != null) {
+					if (readCharacter(';')) {
+						if (lst.length == 1) {
+							typ_arg = lst[0];
+						} else {
+							typ_arg = TypeMulti.get(lst);
+							// TODO warning "Added 'typ_arg'."
+						}
+						// Read result type.
+						lst = readTypeList(false);
+					}
+				}
+			}
+			if (lst != null) {
+				if (lst.length == 1) {
+					typ_res = lst[0];
+				} else {
+					typ_res = TypeMulti.get(lst);
+				}
+			}
+			if (! readCharacter('}')) {
+				reporter.syntaxError("Added '}'.", getLine());
+				return null;
+			}
+			result = TypeBlock.get(typ_arg, typ_res);
+		} else {
+			// Expanded | Strict 
+			if (readThisKeyword(ILisaacModel.keyword_expanded) ||
+					readThisKeyword(ILisaacModel.keyword_strict)) {
+
+				style = getLastString();
+				if (isLocal && (style.equals(ILisaacModel.keyword_expanded))) {
+					int len = ILisaacModel.keyword_expanded.length();
+					reporter.syntaxError("`Expanded' is not possible.", getPosition(len));
+				}
+			}
+			// PROTOTYPE
+			result = readPrototype(style);
+
+			// TODO read contract
+		}
+		return result;
+	}
+
+	//++ PROTOTYPE    -> cap_identifier{('.'|'...')cap_identifier}['('PARAM_TYPE{','PARAM_TYPE}')']
+	public ITypeMono readPrototype(String style) {
+		ITypeMono result=null;
+		String name=null;
+
+		if (readCapIdentifier()) {
+			// TODO syntax {('.'|'...')cap_identifier}
+			name = getString(lastString);
+			if (readCharacter('(')) {
+				//
+				// Genericity.
+				//
+				ArrayList<ITypeMono> genericity = new ArrayList<ITypeMono>();
+				do {
+					ITypeMono t = readParamType();
+					if (t == null) {
+						reporter.syntaxError("Type needed.", getLine());
+						return null;
+					}
+					genericity.add(t);
+				} while (readCharacter(','));
+				// alias genericity array...
+				result = new TypeGeneric(name, style, genericity.toArray(new ITypeMono[genericity.size()]));
+
+				if (! readCharacter(')')) {
+					reporter.syntaxError("Added ')'.", getLine());
+					return result;
+				}
+			} else {
+				// Simple type.	 
+				if (isParameterType) {
+					if (style != null) {
+						reporter.warning("Style `"+style+"' for parameter type is ignored.", getPosition(name.length()));
+					}
+					result = TypeParameter.get(name);
+				} else if (style == null) {
+					if (name.equals(ILisaacModel.prototype_self)) {
+						result = TypeSelf.get(selfType);
+					} else {
+						result = TypeSimple.get(name);
+					}
+				} else {
+					if (name.equals(ILisaacModel.prototype_self)) {
+						reporter.warning("Style `"+style+"' ignored.", getPosition(name.length()));
+						result = TypeSelf.get(selfType);
+					} else {
+						if (name.equals(ILisaacModel.prototype_self)) {
+							result = TypeSelf.get(selfType);
+						} else {
+							result = TypeSimple.get(name);
+						}
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	//++ PARAM_TYPE   -> TYPE
+	//++               | CONSTANT
+	//++               | identifier
+	private ITypeMono readParamType() {
+		ITypeMono result = readType(false);
+		if (result == null) {
+			IConstant cst = readConstant();
+			if (cst != null) {
+				// TODO compiler not yet implemented
+			} else if (readIdentifier()) {
+				// TODO compiler not yet implemented
+			}
+		}
+		return result;
+	}
+
+	//++ SLOT         -> style TYPE_SLOT [':' (TYPE|'('TYPE_LIST')') ][ affect DEF_SLOT ]';'
+	public boolean readSlot(Prototype prototype) {
+		char affect;
+		boolean result=false;
+		IType t;
+
+		char style = readStyle();
+		if (style != ' ') {
+			//
+			// Classic slot.
+			//
+			result = true;
+			lastSlot = readTypeSlot();
+			if (lastSlot == null) {
+				reporter.syntaxError("Incorrect slot declaration.", getLine());
+				return false;
+			}
+			lastSlot.setStyle(style);
+
+			if (readAffect()) {
+				affect = lastString.charAt(0);
+			} else {
+				affect = ' ';
+			}
+			// ':' (TYPE|'('TYPE_LIST')'
+			if (affect == ' ' && readCharacter(':')) {
+				if (readCharacter('(')) {
+					ITypeMono[] lt = readTypeList(false);
+					if (lt == null) {
+						reporter.syntaxError("Incorrect result type.", getLine());
+						return false;
+					}
+					if (! readCharacter(')')) {
+						reporter.warning("Added ')' is needed.", getLine());
+					}
+					t = TypeMulti.get(lt);
+				} else {
+					t = readType(false);
+					if (t == null) {
+						reporter.syntaxError("Incorrect result type.", getLine());
+						return false;
+					}
+				}
+				if (readAffect()) {
+					affect = lastString.charAt(0);
+				}
+			} else {
+				t = TypeSimple.getTypeVoid();
+			}
+			lastSlot.setResultType(t);
+			lastSlot.setAffect(affect);
+
+			setCatchComment();
+
+			if (affect != ' ') {
+				readSpace();
+
+				setCatchCommentOff();
+
+				//
+				readDefSlot();
+				//
+			}
+			if (! readCharacter(';')) {
+				reporter.syntaxError("Added ';'.", getLine());
+				return false;
+			}
+			// update slot body position
+			updateLine();
+			Position body = lastSlot.getPositionBody();
+			if (body.line != pos_line) {
+				body.setLength(position - body.offset);
+			} else {
+				// one line slot - delete position
+				lastSlot.setBody(null);
+			}
+
+			if (lastComment != null && lastComment.length() > 0) {
+				lastSlot.setComment(lastComment);
+			}
+			if (lastSection.isInheritOrInsert()) {
+				// Add parent slot
+				Slot s = prototype.getParentSlot(lastSlot.getName());
+				if (s != null) {
+					reporter.semanticError("Double slot declaration.", getPosition());
+				} else {
+					prototype.addParentSlot(lastSlot);
+				}
+			} else {
+				// Added slot in prototype :
+				Slot s = prototype.getSlot(lastSlot.getName());
+				if (s != null) {
+					reporter.semanticError("Double slot declaration.", getPosition());
+				} else {
+					prototype.addSlot(lastSlot);
+					lastSection.addSlot(lastSlot);
+				}
+			}
+		}
+		return result;
+	}
+
+	//++ DEF_SLOT     -> [CONTRACT] EXPR [CONTRACT]
+	private void readDefSlot() {
+
+		readRequire();
+		ICode expr = readExpr();
+		if (expr == null) {
+			reporter.syntaxError("Incorrect expression.", getLine());
+		}
+		lastSlot.setValue(expr);
+		readEnsure();
+	}
+
+	//++ TYPE_SLOT    -> [ LOC_ARG '.' ] identifier [ LOC_ARG { identifier LOC_ARG } ]
+	//++               | [ LOC_ARG ] '\'' operator '\'' [("Left"|"Right") [integer]] [LOC_ARG]
+	public Slot readTypeSlot() {
+		Slot result=null;
+		IArgument arg=null;
+
+		ArrayList<IArgument> list_arg = new ArrayList<IArgument>();
+
+		arg = readLocArg(false,true);
+		if (arg == null) {
+			if (readCharacter('\'')) {
+				result = readSlotOperator(list_arg);
+			} else {
+				//arg = new ITMArgument(ILisaacModel.variable_self, TypeSimple.getTypeSelf());
+				//list_arg.add(arg); no use here? 
+
+				result = readSlotKeyword(list_arg);
+			}
+		} else {
+			list_arg.add(arg);
+			if (readCharacter('.')) {
+				result = readSlotKeyword(list_arg);
+			} else if (readCharacter('\'')) {
+				result = readSlotOperator(list_arg);
+			}
+		}
+		if (result != null) {
+			result.setArgumentList(list_arg.toArray(new IArgument[list_arg.size()]));
+		}
+		return result;
+	}
+
+	private Slot readSlotKeyword(ArrayList<IArgument> list_arg) {
+		Slot result=null;
+		Position slotPosition = getPosition();
+		Position slotBody = getPosition();
+		int start_pos = position;
+
+		if (readIdentifier()) {
+			String n = new String(lastString);
+
+			ArrayList<String> keywords = new ArrayList<String>();
+			keywords.add(n);
+
+			IArgument arg = readLocArg(false,false);
+			if (arg != null) {
+				list_arg.add(arg);
+				if (readIdentifier()) {
+					// TODO section external -> syntax error
+					do {
+						n += "__" + lastString;
+						keywords.add(new String(lastString));
+
+						arg = readLocArg(false,false);
+						if (arg == null) {
+							reporter.syntaxError("Incorrect symbol.", getLine());
+							return null;
+						}
+						list_arg.add(arg);
+					} while (readIdentifier());
+				}
+			}
+			slotPosition.setLength(position - start_pos);
+			result = new Slot(slotPosition, getString(n), lastSection);
+			//
+			result.setKeywordList(keywords.toArray(new String[keywords.size()]));
+			result.setBody(slotBody);
+			//
+		}
+		return result;
+	}  
+
+	//++ LOC_ARG      -> identifier ':' TYPE
+	//++               | '(' LOCAL ')'
+	public IArgument readLocArg(boolean mute, boolean selfFirst) {
+		IArgument result=null;
+
+		if ((selfFirst && readThisKeyword(ILisaacModel.variable_self)) ||
+				(! selfFirst && readIdentifier())) {
+
+			int startPos = position;
+
+			//Position pos = getPosition(); 
+			String n = new String(lastString);
+			if (readCharacter(':') && lastCharacter() != '=') {
+				ITypeMono t = readType(true);
+				if (t == null) {
+					reporter.syntaxError("Incorrect type.", getLine());
+					return null;
+				}
+
+				// TODO SELF
+				/*if (selfFirst && (t != TypeSimple.getTypeSelf()) &&
+						((object.name != ALIAS_STR.prototype_block) || 
+					            {tb ?= t; tb = NULL})) {
+					reporter.syntaxError("Type `SELF' is needed.", getPosition());
+				}*/
+				Position p = getPosition();
+				p.offset = startPos;
+				result = new ITMArgument(n, t, p);
+			} else {
+				if (! mute) {
+					reporter.warning("Added ':' is needed.", getLine());
+				}
+			}
+		} else if (readCharacter('(')) {
+			result = readLocalArg(mute, selfFirst);
+			if (result == null) {
+				if (! mute) {
+					reporter.syntaxError("Incorrect argument definition.", getLine());
+					return null;
+				}
+			} else {
+				if (! readCharacter(')')) {
+					reporter.warning("Added ')'.", getPosition());
+				}
+			}
+		}	
+		return result;
+	}
+
+	private IArgument readLocalArg(boolean m, boolean s) {
+		IArgument result=null;
+		boolean mute = m;
+		int startPos;
+
+		int firstPos = position;
+
+		if ((s && readThisKeyword(ILisaacModel.variable_self)) ||
+				readIdentifier()) {
+			List<String> name = new ArrayList<String>();
+			List<ITypeMono> type = new ArrayList<ITypeMono>();
+			int beg = 0;
+
+
+			do {
+				if (name.size() != 0 && !readIdentifier() && !mute) {
+					reporter.syntaxError("Incorrect argument identifier.", getLine());
+					return null;
+				}
+
+				startPos = position;
+
+				name.add(lastString);
+				if (readCharacter(':') && lastCharacter() != '=') {
+					mute = false;
+					ITypeMono t = readType(true);
+
+					if (t == null) {
+						reporter.syntaxError("Incorrect argument type.", getLine());
+						return null;
+					}
+					for (int i=beg; i<name.size(); i++) {
+						type.add(t);
+					}
+					beg = name.size();
+				}
+			} while (readCharacter(','));
+
+			if (beg != name.size()) {
+				if (! mute) {
+					reporter.syntaxError("Incorrect argument type.", getLine());
+					return null;
+				}
+				// free arrays..
+			} else {
+				/*if (s && (
+						type.get(0) != TypeSimple.getTypeSelf() ||
+						)) {
+					// TODO  syntax_error (current_position,"Type `SELF' is needed.");
+				}*/
+
+				if (name.size() == 1) {
+					// Single Argument.
+					Position p = new Position(0,0,startPos, 0);
+
+					result = new ITMArgument(name.get(0), type.get(0), p);
+
+					// free arrays
+				} else {
+					// Vector Arguments.
+					// alias arrays...
+					TypeMulti tm = new TypeMulti(type.toArray(new ITypeMono[type.size()]));
+					result = new ITMArgs(name.toArray(new String[name.size()]), tm, getPosition(position - firstPos));
+				}
+			}
+		}
+		return result;
+	}
+
+	private Slot readSlotOperator(ArrayList<IArgument> list_arg) { 
+		Slot result=null;
+		String associativity=null;
+		int priority=0;
+		Position slotPosition = getPosition();
+		Position slotBody = getPosition();
+
+		if (! readOperator()) {
+			reporter.syntaxError("Operator is needed.", getLine());
+			return null;
+		}
+		if (lastString.equals(ILisaacModel.symbol_equal) ||
+				lastString.equals(ILisaacModel.symbol_not_equal)) {
+			reporter.syntaxError("Incorrect operator.", getLine());
+			return null;
+		}
+		String name = new String(lastString);
+		slotPosition.setLength(name.length());
+
+		if (! readCharacter('\'')) {
+			reporter.warning("Added `''.", getLine());
+		}
+		if (readThisKeyword(ILisaacModel.keyword_left) ||
+				readThisKeyword(ILisaacModel.keyword_right)) {
+			associativity = new String(lastString);
+			if (readInteger()) {
+				priority = (int) lastInteger;
+			}
+		}
+		if (list_arg.isEmpty()) {
+			// Prefix operator.
+			IArgument arg = readLocArg(false, true);
+			if (arg == null) {
+				reporter.syntaxError("Operator declaration invalid.", getLine());
+				return null;
+			}
+			if (arg != null) {
+				list_arg.add(arg);
+			}
+			name = getOperator("__prefix", name);
+			if (associativity != null) {
+				reporter.syntaxError("No associativity for postfix operator.", getLine());
+			}
+		} else {
+			IArgument arg = readLocArg(false,false);
+			if (arg != null) {
+				// Infix operator.
+				list_arg.add(arg);
+				name = getOperator("__infix", name);
+				if (associativity == null) {
+					associativity = ILisaacModel.keyword_left;
+				}
+			} else {
+				// Postfix operator.
+				name = getOperator("__postfix", name);
+				if (associativity != null) {
+					reporter.syntaxError("No associativity for prefix operator.", getLine());
+				}
+			}
+		}
+		result = new Slot(slotPosition, name, lastSection);
+		result.setAssociativity(associativity, priority);
+		result.setBody(slotBody);
+
+		return result;
+	} 
+
+	private String getOperator(String typ, String op) {
+		String s = new String(typ);
+
+		for (int i=0; i<op.length(); i++) {
+			char c = op.charAt(i);
+			switch (c) {
+			case '+': s += "_add"; break;
+			case '-': s += "_sub"; break;
+			case '~': s += "_logicnot"; break;
+			case '!': s += "_not"; break;
+			case '/': s += "_div"; break;
+			case '*': s += "_mul"; break;
+			case '^': s += "_xor"; break;
+			case '%': s += "_mod"; break;
+			case '>': s += "_greater"; break;
+			case '<': s += "_less"; break;
+			case '=': s += "_equal"; break;
+			case '\\': s += "_notdiv"; break;
+			case '|': s += "_or"; break;
+			case '&': s += "_and"; break;
+			case '$': s += "_dollar"; break;
+			case '#': s += "_diese"; break;
+			case '@': s += "_at"; break;
+			case '?': s += "_ask"; break;
+			}
+		}
+		return getString(s); // alias string
+	}
+
+	//++ EXPR         -> { ASSIGN !!AMBIGU!! affect } EXPR_OPERATOR
+	//++ ASSIGN       -> '(' IDF_ASSIGN { ',' IDF_ASSIGN } ')'
+	//++               | IDF_ASSIGN
+	//++ IDF_ASSIGN   -> identifier { identifier }
+	public ICode readExpr() {
+		ICode result=null;
+		boolean again;
+		String string_tmp2="";
+
+		// !! AMBIGU resolution !!    
+		saveContext();
+
+		if (readCharacter('(')) {
+			ArrayList<String> l_assignment = new ArrayList<String>();
+			do {
+				again = false;
+				if (readIdentifier()) {
+					//p = position - lastString.length();
+
+					string_tmp2 = new String(lastString);
+					while (readIdentifier()) {
+						string_tmp2 += "__" + lastString;
+					}
+					String name = getString(string_tmp2);
+					l_assignment.add(name);
+
+					if (readCharacter(',')) {
+						again = true;
+					}
+				}
+			} while(again);
+
+			if (!l_assignment.isEmpty() && readCharacter(')') && readAffect()) {
+				result = new ITMListIdf(l_assignment);
+
+				char affect = lastString.charAt(0);
+				ICode value = readExpr();
+				if (value == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				if (affect == '<') {
+					reporter.syntaxError("Impossible '<-' style assignment with vector.", getPosition(lastString.length()));
+					return null;
+				}
+				result = new ITMWrite(result, value, affect);
+			} else {
+				// FREE l_assignment
+			}
+		} else if (readIdentifier()) {
+			//p = position - lastString.length();
+			string_tmp2 = new String(lastString);
+			while (readIdentifier()) {
+				string_tmp2 += "__" + lastString;
+			}
+			String name = getString(string_tmp2);
+
+			if (readAffect()) {
+				result = new ITMRead(name);
+
+				char affect = lastString.charAt(0);
+				ICode value = readExpr();
+				if (value == null) {
+					reporter.syntaxError("Incorrect expression.", getLine());
+					return null;
+				}
+				result = new ITMWrite(result, value, affect);
+			}
+		}
+		if (result == null) {
+			restoreContext();
+			result = readExprOperator();
+		}
+		return result;
+	}
+
+	//++ EXPR_OPERATOR-> { operator } EXPR_MESSAGE { operator {operator} EXPR_MESSAGE } {operator}
+	private ICode readExprOperator() {
+		ICode result=null;
+		int first_msg,last_msg;
+
+		ArrayList<ICode> l_expr = new ArrayList<ICode>();
+		while (readOperator()) {
+			ICode expr = new ITMOperator(new String(lastString));
+			l_expr.add(expr);
+		}
+		ICode expr = readExprMessage();
+		if (expr == null) {
+			// Error.
+			if (l_expr.size() > 0) {
+				reporter.syntaxError("Incorrect expression.", getLine());
+			}
+			// free l_expr
+		} else {
+			// { operator {operator} EXPR_MESSAGE } {operator}
+			first_msg = l_expr.size();
+			do {
+				last_msg = l_expr.size();
+				l_expr.add(expr);
+				if (readOperator()) {
+					do {
+						expr = new ITMOperator(new String(lastString));
+						l_expr.add(expr);
+					} while (readOperator());
+
+					expr = readExprMessage();
+				} else {
+					expr = null;
+				}
+			} while (expr != null);
+
+			// Last Post-fix operator.
+			while (last_msg < l_expr.size()-1) {
+				ITMOperator itm_op = (ITMOperator) l_expr.get(last_msg+1);
+				expr = new ITMReadArg1(getOperator("__postfix", itm_op.getName()), l_expr.get(last_msg));
+
+				l_expr.add(last_msg, expr);
+				l_expr.remove(last_msg+1);
+			}
+			if (last_msg - first_msg < 3) {
+				// First Pre-fix operator.
+				while (first_msg != 0) {
+					ITMOperator itm_op = (ITMOperator) l_expr.get(first_msg - 1);
+					expr = new ITMReadArg1(getOperator("__prefix", itm_op.getName()), l_expr.get(first_msg));
+
+					l_expr.add(first_msg, expr);
+					first_msg = first_msg - 1;
+					l_expr.remove(first_msg);
+				}
+			}
+			if (l_expr.size() == 1) {
+				result = l_expr.get(0);// first
+				// free l_expr
+			} else if (l_expr.size() == 3) {
+				// Simple binary message.
+				ITMOperator itm_op = (ITMOperator) l_expr.get(1);// second
+				result = new ITMReadArg2(getOperator("__infix", itm_op.getName()),
+						l_expr.get(0),
+						l_expr.get(2));
+				// free l_expr
+			} else {
+				// Complex expression.
+				result = new ITMExpression(l_expr.toArray(new ICode[l_expr.size()]));
+			}
+		}
+		return result;
+	}
+
+	//++ EXPR_MESSAGE -> EXPR_BASE { '.' SEND_MSG }
+	protected ICode readExprMessage() {
+
+		ICode result = readExprBase();
+		if (result != null) {
+			while (readCharacter('.')) {
+				result = readSendMsg(result);
+				if (result == null) {
+					reporter.syntaxError("Incorrect message.", getLine());
+					return null;
+				}
+			}
+		}
+		return result;
+	}
+
+	//++ EXPR_BASE    -> "Old" EXPR
+	//++               | EXPR_PRIMARY
+	//++               | SEND_MSG
+	public ICode readExprBase() {
+		ICode result=null;
+
+		if (readThisKeyword(ILisaacModel.keyword_old)) {
+			ICode old_value = readExpr();
+			if (old_value == null) {
+				reporter.syntaxError("Incorrect `Old' expression.", getLine());
+				return null;
+			}
+			result = new ITMOld(old_value);
+		} else {
+			result = readExprPrimary();
+			if (result == null) {
+				result = readSendMsg(null);
+			}
+		}
+		return result;
+	}
+
+	//++ EXPR_PRIMARY -> "Self"
+	//++               | result
+	//++               | PROTOTYPE
+	//++               | CONSTANT
+	//++               | '(' GROUP ')'
+	//++               | '{' [ LOC_ARG ';' !! AMBIGU!! ] GROUP '}'
+	//++               | external [ ':' ['('] TYPE ['{' TYPE_LIST '}'] [')'] ]
+	public ICode readExprPrimary() {
+		ICode result=null;
+		String result_id=null;
+		ITypeMono type=null;
+		ITMList group_sav=null;
+
+		readSpace();
+		Position pos = getPosition();
+
+		if (readThisKeyword(ILisaacModel.variable_self)) {
+			result = new ITMRead(new String(lastString));
+		} else if (readThisKeyword(ILisaacModel.keyword_result)) {
+			if (lastCharacter() == '_') {
+				position = position + 1;
+				string_tmp = "" + ILisaacModel.keyword_result + "_";
+
+				while (Character.isDigit(lastCharacter())) {
+					string_tmp += lastCharacter();
+					position = position + 1;
+				}
+				if (string_tmp.length() <= 0) {
+					reporter.syntaxError("Incorrect Result number.", getLine());
+				}
+				result_id = getString(string_tmp);
+			} else {
+				result_id = ILisaacModel.keyword_result;
+			}
+			result = new ITMRead(result_id);
+
+		} else if ((type = readPrototype(null)) != null) {
+			result = new ITMPrototype(type, pos);
+
+		} else if ((result = readConstant()) != null) {
+		} else if (readCharacter('(')) {
+			group_sav = lastGroup;
+			lastGroup = new ITMList(lastSlot, position);
+			result = lastGroup;
+
+			lastGroup.setCode(readGroup());
+			if (! readCharacter(')')) {
+				reporter.syntaxError("Added ')'.", getLine());
+				return null;
+			}
+			lastGroup.setEndOffset(position);
+			lastGroup = group_sav;
+		} else if (readCharacter('{')) {
+			group_sav = lastGroup;  
+			lastGroup = new ITMList(lastSlot, position);
+
+			saveContext(); // !! SAVE CONTEXT !!
+
+			//
+			IArgument arg = readLocArg(true,false);
+			//
+			if (arg != null) {
+				if (! readCharacter(';')) {
+					reporter.syntaxError("Added ';'.", getLine());
+					return null;
+				}
+			} else {
+				restoreContext(); // !! RESTORE CONTEXT !!
+			}
+			result = new ITMBlock(lastGroup, arg, lastSlot);
+
+			lastGroup.setCode(readGroup());
+			if (! readCharacter('}')) {
+				reporter.syntaxError("Added '}'.", getLine());
+				return null;
+			}
+			lastGroup.setEndOffset(position);
+			lastGroup = group_sav; 
+		} else if (readExternal()) {
+			if (! readCharacter(':')) {
+				result = new ITMExternal(new String(lastString));
+			} else {
+				boolean persistant = readCharacter('(');
+				ITMExternalType ext = new ITMExternalType(new String(lastString), persistant);
+				type = readType(false);
+				if (type == null) {
+					reporter.syntaxError("Incorrect type.", getLine());
+					return null;
+				}
+				ext.setType(type);
+				if (readCharacter('{')) {
+					ITypeMono[] ltype = readTypeList(false);
+					if (ltype == null) {
+						reporter.syntaxError("Incorrect live type list.", getLine());
+						return null;
+					}
+					if (! readCharacter('}')) {
+						reporter.syntaxError("Added '}'.", getLine());
+						return null;
+					}
+					ext.setTypeList(ltype);
+				}
+				if (ext.isPersistant() && (! readCharacter(')'))) {
+					reporter.syntaxError("Added '}'.", getLine());
+					return null;
+				}
+				result = ext;
+			}
+		}
+		return result;
+	}
+
+	//++ CONSTANT     -> integer
+	//++               | real
+	//++               | characters
+	//++               | string
+	private IConstant readConstant() {
+		IConstant result=null;
+
+		if (readReal()) {
+			result = new ITMReal(new String(lastReal));
+		} else if (readInteger()) {
+			result = new ITMNumber(lastInteger);
+		} else if (readCharacters()) {
+			result = new ITMCharacter(new String(lastString));
+		} else if (readString()) {
+			result = new ITMString(new String(lastString));
+		}
+		return result;
+	}
+
+	//++ GROUP        -> DEF_LOCAL {EXPR ';'} [ EXPR {',' {EXPR ';'} EXPR } ]
+	private ICode[] readGroup() {		
+		readDefLocal();
+
+		ArrayList<ICode> result = new ArrayList<ICode>();
+		ICode e = readExpr();
+		while (e != null && readCharacter(';')) {
+			result.add(e);
+			e = readExpr();
+		}
+		if (e != null) {
+			if (readCharacter(',')) {
+				do {
+					e = new ITMResult(e);
+					result.add(e);
+					e = readExpr();
+					while (e != null && readCharacter(';')) {
+						result.add(e);
+						e = readExpr();
+					}
+					if (e == null) {
+						reporter.syntaxError("Incorrect multiple result expression.", getLine());
+						return null;
+					}
+				} while (readCharacter(','));
+			}
+			e = new ITMResult(e);
+			result.add(e);
+		}
+		return result.toArray(new ICode[result.size()]);
+	}
+
+	//++ DEF_LOCAL    -> { style LOCAL ';' } !! AMBIGU !!
+	private void readDefLocal() {
+		List<ITMLocal> loc_lst;
+
+		saveContext(); // !! SAVE CONTEXT !!
+
+		char style = readStyle();
+		ArrayList<ITMLocal> local_list = new ArrayList<ITMLocal>();
+		ArrayList<ITMLocal> static_list = new ArrayList<ITMLocal>();
+
+		while (style != ' ') {
+			loc_lst = readLocal(true);
+			if (loc_lst != null) {
+				if (style == '+') {
+					local_list.addAll(loc_lst);
+				} else {
+					static_list.addAll(loc_lst);
+				}
+				if (! readCharacter(';')) {
+					reporter.syntaxError("Added ';'.", getLine());
+				}
+				saveContext(); // !! SAVE CONTEXT !!
+
+				style = readStyle();
+			} else {
+				restoreContext(); // !! RESTORE CONTEXT !!
+				style = ' ';
+			}
+		}
+		if (local_list.isEmpty()) {
+			// free local_list
+		} else {
+			lastGroup.setLocalList(local_list.toArray(new ITMLocal[local_list.size()]));
+		}
+		if (static_list.isEmpty()) {
+			// free static_list
+		} else {
+			lastGroup.setStaticList(static_list.toArray(new ITMLocal[static_list.size()]));
+		}
+	}
+
+	//++ SEND_MSG     -> identifier [ ARGUMENT { identifier ARGUMENT } ]
+	public ICode readSendMsg(ICode firstArg) {
+		ICode result=null;
+
+		if (readIdentifier()) {
+			//
+			// Classic Message.
+			//
+			String n = getString(lastString);// create alias
+
+			// Argument list.
+			LinkedList<ICode> l_arg = new LinkedList<ICode>();
+			ICode arg = readArgument();
+			if (arg != null) {
+				l_arg.addLast(arg);
+				while (readIdentifier()) {
+					n += "__" + lastString; // FIXME: alias pb
+					arg = readArgument();
+					if (arg == null) {
+						reporter.syntaxError("Incorrect argument.", getLine());
+						return null;
+					}
+					l_arg.addLast(arg);
+				}
+			}
+			String name = getString(n); // FIXME alias pb
+			if (l_arg.isEmpty()) {
+				if (firstArg == null) {
+					// Local ou Implicite Slot without argument.
+					result = new ITMRead(name);
+				} else {
+					result = new ITMReadArg1(name, firstArg);
+				}
+				// free l_arg
+			} else if (l_arg.size() == 1) {
+				result = new ITMReadArg2(name, firstArg, l_arg.get(0));
+				// free l_arg
+			} else {
+				l_arg.addFirst(firstArg);
+				result = new ITMReadArgs(name, l_arg.toArray(new ICode[l_arg.size()]));
+			}
+		}	
+		return result;
+	}
+
+	//++ ARGUMENT     -> EXPR_PRIMARY
+	//++               | identifier
+	private ICode readArgument() {
+		ICode result = readExprPrimary();
+		if (result == null && readIdentifier()) {
+			result = new ITMRead(new String(lastString));
+		}
+		return result;
+	}
+
+	//++ LOCAL        -> { identifier [ ':' TYPE ] ',' } identifier ':' TYPE
+	private List<ITMLocal> readLocal(boolean m) {
+		List<ITMLocal> result=null;
+		int beg = 0;
+
+		boolean mute = m;
+		if (readIdentifier()) {
+			result = new LinkedList<ITMLocal>();			
+			do {
+				if (result.size() != 0 && !readIdentifier() && !mute) {
+					reporter.syntaxError("Incorrect identifier.", getLine());
+					return null;
+				}
+				ITMLocal loc = new ITMLocal(new String(lastString), getPosition());
+				result.add(loc);
+				if (readCharacter(':') && lastCharacter() != '=') {
+					mute = false;
+					ITypeMono t = readType(false);
+					if (t == null) {
+						reporter.syntaxError("Incorrect local type.", getLine());
+						return null;
+					}
+					for (int j=beg; j<result.size(); j++) {
+						result.get(j).setType(t);
+					}
+					beg = result.size(); // upper+1
+				}
+			} while(readCharacter(','));
+			if (beg != result.size()) {
+				if (mute) {
+					// free result
+					result = null;
+				} else {
+					reporter.syntaxError("Incorrect local type.", getLine());
+					return null;
+				}
+			} else {
+			}
+		}	
+		return result;
+	}
+
+	public boolean readRequire() {
+		boolean result=false;
+
+		ITMList lst = readContract();
+		if (lst != null) {
+			// lastSlot.setRequire lst
+			result = true;
+		}
+		return result;
+	}
+
+	public boolean readEnsure() {
+		boolean result=false;
+
+		ITMList lst = readContract();
+		if (lst != null) {
+			// lastSlot.setEnsure lst
+			result = true;
+		}
+		return result;
+	}
+
+	//++ CONTRACT     -> '[' DEF_LOCAL { ( EXPR ';' | "..." ) } ']'
+	private ITMList readContract() {
+		ITMList result = null;
+
+		if (readCharacter('[')) {
+			result = new ITMList(lastSlot, position);
+			lastGroup = result;
+
+			readDefLocal();
+
+			ArrayList<ICode> lst = new ArrayList<ICode>();
+			boolean doContinue = false;
+			do {
+				ICode e = readExpr();
+				if (e == null) {
+					doContinue = readWord(ILisaacModel.keyword_ldots);
+					if (doContinue) {
+						lst.add(new ITMLDots());
+					}
+				} else {
+					lst.add(e);
+					if (! readCharacter(';')) {
+						reporter.syntaxError("Added ';'.", getLine());
+						return null;
+					}
+					doContinue = true;
+				}
+			} while (doContinue);
+
+			if (! readCharacter(']')) {
+				reporter.syntaxError("Added ']'.", getLine());
+				return null;
+			}
+			// TODO lst add prototype void
+			result.setCode(lst.toArray(new ICode[lst.size()]));
+			result.setEndOffset(position);
+		}
+		return result;
+	}	   
+
+	public boolean skipUntilThisKeyword(String st) {
+		int idx;
+		int posold;
+		boolean result=false;
+
+		while (! isEOF() && ! result) {
+			idx = 0;
+			while ((readSpace() || lastCharacter() == '\n') && lastCharacter() != st.charAt(idx)) {
+				position++;
+			}
+			posold = position;
+			position++;
+			idx++;
+			if (! isEOF()) {
+				while (idx <= st.length()-1 && lastCharacter() == st.charAt(idx)) {
+					position++;
+					idx++;
+				}
+				if (idx > st.length()-1) {
+					lastString = st;
+					position = posold;
+					result = true;
+				}
+			}
+		}
+		return result;
+	}
+
+	public String readSlotNameFromOffset(int offset, boolean modifyCurrentOffset) {
+		String result=null;
+		int oldPosition = position;
+		position = offset;
+
+		//++ TYPE_SLOT    -> [ LOC_ARG '.' ] identifier [ LOC_ARG { identifier LOC_ARG } ]
+		//++               | [ LOC_ARG ] '\'' operator '\'' [("Left"|"Right") [integer]] [LOC_ARG]
+		if (! skipLocalArg(true)) {
+			if (readCharacter('\'')) {
+				result = readSlotNameOperator();
+			} else {
+				result = readSlotNameKeyword();
+			}
+		} else {
+			if (readCharacter('.')) {
+				result = readSlotNameKeyword();
+			} else if (readCharacter('\'')) {
+				result = readSlotNameOperator();
+			}
+		}
+		if (! modifyCurrentOffset) {
+			position = oldPosition;
+		}
+		return result;
+	}
+
+	//++ LOC_ARG      -> identifier ':' TYPE
+	//++               | '(' LOCAL ')'
+	public boolean skipLocalArg(boolean selfFirst) {
+		boolean result=false;
+		if ((selfFirst && readThisKeyword(ILisaacModel.variable_self)) ||
+				(! selfFirst && readIdentifier())) {
+			if (readCharacter(':') && lastCharacter() != '=') {
+				return skipType();
+			}
+		} else if (readCharacter('(')) {
+			result = skipLocal(selfFirst);
+			if (! result) {
+				return false;
+			} else {
+				if (! readCharacter(')')) {
+					return false;
+				}
+				result = true;
+			}
+		}	
+		return result;
+	}
+
+	private boolean skipLocal(boolean s) {
+		boolean result = false;
+
+		if ((s && readThisKeyword(ILisaacModel.variable_self)) ||
+				readIdentifier()) {
+			int size = 0;
+			do {
+				if (size != 0 && !readIdentifier()) {
+					return false;
+				}
+				size++;
+				if (readCharacter(':') && lastCharacter() != '=') {
+					if (!skipType()) {
+						return false;
+					}
+					result = true;
+				}
+			} while (readCharacter(','));
+		}
+		return result;
+	}
+
+	private String readSlotNameKeyword() {
+		String result=null;
+
+		if (readIdentifier()) {
+			result = new String(lastString);
+
+			if (skipLocalArg(false)) {
+				if (readIdentifier()) {
+					do {
+						result += "__" + lastString;
+						if (! skipLocalArg(false)) {
+							return null;
+						}
+					} while (readIdentifier());
+				}
+			}
+		}
+		return result;
+	}  
+
+	private String readSlotNameOperator() { 
+		String result=null;
+
+		if (! readOperator()) {
+			return null;
+		}
+		result = new String(lastString);
+		result = getOperator("__infix", result);// TODO fix!! prefix postfix
+
+		return result;
+	} 
+
+	//++ TYPE         -> '{' [ (TYPE | '(' TYPE_LIST ')') ';' ] [ TYPE_LIST ] '}'
+	//++               | [type] PROTOTYPE [ CONTRACT ]
+	public boolean skipType () {
+		boolean result=false;
+
+		if (readCharacter('{')) {
+			// '{' [ (TYPE | '(' TYPE_LIST ')') ';' ] [ TYPE_LIST ] '}' 
+			if (readCharacter('(')) {
+				// Read vector argument.
+				result = skipTypeList();
+				if (! result) {
+					return false;
+				}
+				if (! readCharacter(')')) {
+					return false;
+				}
+				if (! readCharacter(';')) {
+					return false;
+				}
+				// Read result type.
+				result = skipTypeList();
+			} else {
+
+				result = skipTypeList();
+				if (result) {
+					if (readCharacter(';')) {
+						// Read result type.
+						result = skipTypeList();
+					}
+				}
+			}
+			if (! readCharacter('}')) {
+				return false;
+			}
+			result = true;
+		} else {
+			// Expanded | Strict 
+			if (readThisKeyword(ILisaacModel.keyword_expanded) ||
+					readThisKeyword(ILisaacModel.keyword_strict)) {
+			}
+			// PROTOTYPE
+			result = skipPrototype();
+			// TODO read contract
+		}
+		return result;
+	}
+
+	//++ TYPE_LIST    -> TYPE { ',' TYPE }
+	public boolean skipTypeList() {
+		boolean result=false;
+
+		result = skipType();
+		if (result) {
+			while (readCharacter(',')) {
+				result = skipType();
+				if (! result) {
+					return false;
+				}
+			}
+		}
+		return result;
+	}
+
+	//++ PROTOTYPE    -> cap_identifier{('.'|'...')cap_identifier}['('PARAM_TYPE{','PARAM_TYPE}')']
+	public boolean skipPrototype() {
+		boolean result=false;
+
+		if (readCapIdentifier()) {
+			// TODO syntax {('.'|'...')cap_identifier}
+			if (readCharacter('(')) {
+				//
+				// Genericity.
+				//
+				do {
+					if (! skipParamType()) {
+						return false;
+					}
+				} while (readCharacter(','));
+				if (! readCharacter(')')) {
+					return false;
+				}
+				result = true;
+			} else {
+				// Simple type.	 
+				result = true;
+			}
+		}
+		return result;
+	}
+
+	//++ PARAM_TYPE   -> TYPE
+	//++               | CONSTANT
+	//++               | identifier
+	private boolean skipParamType() {
+		if (! skipType()) {
+			// TODO compiler not yet implemented
+			return false;
+		}
+		return true;
+	}
+
+	//++ SEND_MSG     -> identifier [ ARGUMENT { identifier ARGUMENT } ]
+	public String readKeywordInSendMsg(String keyword, int keywordOffset) {
+		String result=null;
+		boolean keywordFound=false;
+
+		if (readIdentifier()) {
+			//
+			// Classic Message.
+			//
+			String n = getString(lastString);// create alias
+			if (n.compareTo(keyword) == 0 && position == keywordOffset+keyword.length()) {
+				keywordFound = true;
+			}
+			// Argument list.
+			ICode arg = readArgument();
+			if (arg != null) {
+				while (readIdentifier()) {
+					if (lastString.compareTo(keyword) == 0 && position == keywordOffset+keyword.length()) {
+						keywordFound = true;
+					}
+					n += "__" + lastString; // FIXME: alias pb
+					arg = readArgument();
+					if (arg == null) {
+						reporter.syntaxError("Incorrect argument.", getPosition());
+						return null;
+					}
+				}
+			}
+			// return slot full name
+			result = getString(n); // FIXME alias pb
+		}	
+		if (! keywordFound) {
+			result = null;
+		}
+		return result;
+	}
+
+	/**
+	 * Read the next context in lisaac code.
+	 * @return Context at parser position
+	 */
+	public ILisaacContext readContext() {
+		readSpace();
+
+		int old_pos = position;
+
+		//
+		// Try read Section Context.
+		//    
+		if (readThisKeyword (ILisaacModel.keyword_section)) {
+			position = old_pos;
+			return sectionContext;
+		}
+
+		//
+		// Try read Slot Context.
+		//
+		if (readCharacter('-') || readCharacter('+')) {
+			position = old_pos;
+			return slotContext;
+		}
+		// restore old position (unread)
+		position = old_pos;
+
+		if (position >= source.length()-1) {
+			return null;
+		} else {
+			// error
+			reporter.syntaxError("Syntax error", getLine());
+			return sectionContext.getNextContext(); // go to next section
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/LisaacPath.java b/editor/eclipse/src/org/lisaac/ldt/model/LisaacPath.java
new file mode 100644
index 0000000..0872307
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/LisaacPath.java
@@ -0,0 +1,124 @@
+package org.lisaac.ldt.model;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.lisaac.ldt.launch.LisaacCompiler;
+import org.lisaac.ldt.outline.OutlineImages;
+
+
+public class LisaacPath {
+
+	private HashMap<String,String> prototypesPath;
+
+	private LisaacCompiler compiler;
+
+	private String lipFile;
+
+
+	public LisaacPath(final IProject project, String lipFile) {
+		prototypesPath = new HashMap<String,String>();
+		this.lipFile = lipFile;
+
+		refreshPath(project);
+	}
+
+	public void refreshPath(final IProject project) {
+		try {
+			compiler = new LisaacCompiler(lipFile);
+			compiler.addOption("--p");
+
+			System.out.println("===> "+compiler.toCommandLine());
+
+			try {
+				final Process process = compiler.launch(project, new NullProgressMonitor());
+				
+				if (process != null) {
+					try {
+						// wait for end of process
+						process.waitFor();
+					} catch(InterruptedException e) {
+					}
+				}
+				BufferedReader bufferIn = new BufferedReader(
+						new InputStreamReader( 
+								new FileInputStream(project.getLocation()+"/current_path.txt")));
+
+				String line;
+				while ((line = bufferIn.readLine()) != null) {
+					createPath(line);
+				}
+				bufferIn.close();
+			} catch (FileNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		} catch (CoreException e) {
+			//LisaacPlugin.log(status) // TODO log error
+			e.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public String getFullPath(String prototypeName) {
+		if (prototypesPath.containsKey(prototypeName)) {
+			return prototypesPath.get(prototypeName);
+		}
+		return null;
+	}
+
+
+	private void createPath(String fullPath) {
+		int index = fullPath.lastIndexOf("/");
+		String prototypeName = fullPath.substring(index+1);
+		index = prototypeName.lastIndexOf(".");
+		prototypeName = prototypeName.substring(0, index).toUpperCase();
+		prototypesPath.put(prototypeName, fullPath);
+	}
+
+
+	public void getPathMatch(String prefix,
+			ArrayList<ICompletionProposal> proposals, int baseOffset) {
+
+		Collection<String> values = prototypesPath.keySet();
+		Iterator<String> it = values.iterator() ;
+		while (it.hasNext()) {
+			String name = it.next();
+			if (name.startsWith(prefix)) {
+				int lenPrefix = prefix.length();
+				int lenName = name.length();
+				proposals.add(new CompletionProposal(name, baseOffset-lenPrefix, lenPrefix, lenName,
+						OutlineImages.PROTOTYPE, name, null, null));
+			}
+		}
+	}
+
+	public void addPath(String prototypeName, IPath location) {
+		prototypesPath.put(prototypeName, location.toString());
+	}
+
+	public int getSize() {
+		return prototypesPath.size();
+	}
+
+	public Iterator<String> getPathIterator() {
+		return prototypesPath.values().iterator();
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/Position.java b/editor/eclipse/src/org/lisaac/ldt/model/Position.java
new file mode 100644
index 0000000..3c2b8fa
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/Position.java
@@ -0,0 +1,52 @@
+package org.lisaac.ldt.model;
+
+public class Position {
+	public int line;
+	//public int column;
+	public int offset;
+	public int length;
+	
+	public Position(int line, int column, int offset) {
+		super();
+		this.line = line;
+		//this.column = column;
+		this.offset = offset;
+		length = 0;
+	}
+	public Position(int line, int column, int offset, int len) {
+		super();
+		this.line = line;
+		//this.column = column;
+		this.offset = offset;
+		length = len;
+	}
+
+	public int getLine() {
+		return line;
+	}
+	//public int getColumn() {
+		//return column;
+	//}
+	
+	public boolean hasRange() {
+		return length != 0;
+	}
+	
+	public int getCharStart() {
+		return offset-length;
+	}
+	public int getCharEnd() {
+		return offset;
+	}
+	
+	public int getStartOffset() {
+		return offset;
+	}
+	
+	public int length() {
+		return length;
+	}
+	public void setLength(int l) {
+		length = l;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/SectionContext.java b/editor/eclipse/src/org/lisaac/ldt/model/SectionContext.java
new file mode 100644
index 0000000..3596bdf
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/SectionContext.java
@@ -0,0 +1,306 @@
+package org.lisaac.ldt.model;
+
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.model.items.Section;
+import org.lisaac.ldt.model.types.ITypeMono;
+
+public class SectionContext implements ILisaacContext {
+
+	private LisaacParser parser;
+	private boolean firstSection;
+
+	public SectionContext(LisaacParser parser) {
+		this.parser = parser;
+		firstSection = true;
+	}
+
+	public boolean parseDefinition(Prototype prototype) {
+		Position sectionPosition;
+
+		parser.readSpace();
+
+		// read Section
+		if (! parser.readThisKeyword (ILisaacModel.keyword_section)) {
+			parser.getReporter().syntaxError("`Section' is needed.", parser.getLine());
+			return false;
+		}
+		sectionPosition = parser.getPosition();
+
+		if (firstSection) {
+			//
+			// Read Section Header.
+			// 
+			if (! parser.readThisKeyword (ILisaacModel.section_header)) {
+				parser.getReporter().syntaxError("Section `Header' is needed.", parser.getLine());
+				return false;
+			}    
+			firstSection = false;
+
+			if (! readSectionHeaderContent(prototype)) {
+				return false;
+			}
+		} else {
+			//
+			// Read Other Section.
+			//
+			if (parser.readKeyword()) {
+				String section = parser.getLastString();
+				if (section.equals(ILisaacModel.section_inherit) ||
+						section.equals(ILisaacModel.section_insert) ||
+						section.equals(ILisaacModel.section_interrupt) ||
+						section.equals(ILisaacModel.section_private) ||
+						section.equals(ILisaacModel.section_public) ||
+						section.equals(ILisaacModel.section_mapping) ||
+						section.equals(ILisaacModel.section_directory) ||
+						section.equals(ILisaacModel.section_external)) {
+
+					Section lastSection = new Section(prototype, section, sectionPosition);
+					parser.setLastSection(lastSection);
+
+					if (prototype.getFirstSection() == null) {// section list head
+						prototype.setFirstSection(lastSection);
+					}
+
+					if (lastSection.isInheritOrInsert() &&
+							parser.getLastSlot() != null &&
+							! parser.getLastSlot().getSectionId().isInheritOrInsert()) {
+						parser.getReporter().syntaxError("`Section Inherit/Insert' must to be first section.", parser.getLine());
+						return false;
+
+					} else if (prototype.isExpanded() && section.equals(ILisaacModel.section_inherit)) {
+						parser.getReporter().warning("`Section Inherit' is not possible with Expanded object (Use `Section Insert').", parser.getLine());
+					}
+				} else {
+					parser.getReporter().syntaxError("Incorrect type section.", parser.getLine());
+					return false;
+				}
+			} else {
+				// TYPE_LIST.
+				ITypeMono[] t = parser.readTypeList(true);
+				if (t == null) {
+					parser.getReporter().syntaxError("Incorrect type section.", parser.getLine());
+					return false;
+				} 
+				parser.setLastSection(new Section(prototype, t, sectionPosition));
+			}
+			// content of section is out of this context
+		}
+		return true;
+	}
+
+	private boolean readSectionHeaderContent(Prototype prototype) {
+		boolean result;
+		boolean first=true;
+
+		//
+		// Read Slots of Section Header.
+		//
+		do {
+			result = false;
+
+			char style = parser.readStyle();
+			if (style != ' ') {
+				result = true;
+
+				if (!first && style == '+') {
+					parser.getReporter().warning("Incorrect style slot ('-').", parser.getPosition(1));
+				}
+				if (first) {
+					first = false;
+
+					if (parser.readWord(ILisaacModel.slot_name)) {
+						//
+						// Read `name' slot.
+						//
+						if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+							parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+							return false;
+						}
+						if (parser.readThisKeyword(ILisaacModel.keyword_expanded) ||
+								parser.readThisKeyword(ILisaacModel.keyword_strict)) {
+							prototype.setTypeStyle(parser.getLastString());
+						}
+						prototype.setNameOffset(parser.getOffset());// for refactor
+
+						if (! parser.readCapIdentifier()) {
+							parser.getReporter().syntaxError("Prototype identifier is needed.", parser.getLine());
+							return false;
+						}
+						if (parser.getLastString().compareTo(prototype.getName()) != 0) {
+							int len = parser.getLastString().length();
+							parser.getReporter().syntaxError("Incorrect name (filename != name).", parser.getPosition(len));
+						}
+
+						if (parser.readCharacter('(')) {
+							//
+							// Generic loader.
+							//
+							// TODO error for non generic object
+							if (parser.readIdentifier()) {
+								return false;
+								// TODO syntax identifier : PROTO
+							} else if (parser.readCapIdentifier()) {
+								// TODO error Identifier parameter type is needed.
+
+								while (parser.readCharacter(',')) {
+									// TODO error Identifier parameter type is needed.
+									if (! parser.readCapIdentifier()) {
+										parser.getReporter().syntaxError("Identifier parameter type is needed.", parser.getLine());
+										return false;
+									}
+								}
+								if (! parser.readCharacter(')')) {
+									parser.getReporter().syntaxError("Added ')'.", parser.getLine());
+									return false;
+								}
+							} else {
+								parser.getReporter().syntaxError("Identifier parameter type is needed.", parser.getLine());
+								return false;
+							}
+						}
+					} else {
+						parser.getReporter().syntaxError("Slot `name' must to be first slot.", parser.getLine());
+					}
+				} else if (parser.readWord(ILisaacModel.slot_export) ||
+						parser.readWord(ILisaacModel.slot_import)) {
+
+					// - ("export"|"import") ':=' TYPE_LIST 
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					if (parser.readTypeList(false) == null) {
+						parser.getReporter().syntaxError("Incorrect type list.", parser.getLine());
+						return false;
+					}
+					//  TODO store export / import
+
+				} else if (parser.readWord(ILisaacModel.slot_external)) {	
+					// - "external" ':=' `<code_c>`
+
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					if (! parser.readExternal()) {
+						parser.getReporter().syntaxError("Incorrect external.", parser.getLine());
+						return false;
+					}
+				} else if (parser.readWord(ILisaacModel.slot_default)) {
+					// '-' "default" ':=' EXPR_PRIMARY
+
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					if (parser.readExprPrimary() == null) {
+						parser.getReporter().syntaxError("Incorrect expr.", parser.getLine());
+						return false;
+					}
+					// TODO check double default slot
+					// TODO set prototyp default value
+				} else if (parser.readWord(ILisaacModel.slot_type)) {
+					// '-' "type" ':=' `<type C>`
+
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					if (! parser.readExternal()) {
+						parser.getReporter().syntaxError("Incorrect external.", parser.getLine());
+						return false;
+					}
+					// TODO check double type declaration
+
+				} else if (parser.readWord(ILisaacModel.slot_version)) {
+					//
+					// Read `version' slot.
+					//
+
+					// '-' "version" ':=' integer
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					if (! parser.readInteger()) {
+						parser.getReporter().syntaxError("Incorrect number.", parser.getLine());
+						return false;
+					}
+				} else if (parser.readWord(ILisaacModel.slot_lip)) {
+
+					// '-' lip <- ( { LIP_EXPR ';' } )
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_code)) {
+						parser.getReporter().warning("Added '<-' is needed.", parser.getLine());
+					}
+					if (! parser.readCharacter('(')) {
+						parser.getReporter().warning("Added '(' is needed.", parser.getLine());
+					}
+					//
+					// LIP interpreter
+					//
+					LipParser lipParser = new LipParser(parser.getSource(), parser.getOffset());
+
+					while (lipParser.readExpr() != null) {
+						// instr.run(); // TODO interpret lip code if needed
+						if (! lipParser.readCharacter(';')) {
+							parser.getReporter().warning("Added ';' is needed.", parser.getLine());
+						}
+					}
+					if (! lipParser.readCharacter(')')) {
+						parser.getReporter().warning("Added ')' is needed.", parser.getLine());
+					}
+					parser.setPosition(lipParser.getOffset());
+
+				} else if (parser.readWord(ILisaacModel.slot_date) ||
+						parser.readWord(ILisaacModel.slot_comment) ||
+						parser.readWord(ILisaacModel.slot_author) ||
+						parser.readWord(ILisaacModel.slot_bibliography) ||
+						parser.readWord(ILisaacModel.slot_language) ||
+						parser.readWord(ILisaacModel.slot_copyright) ||
+						parser.readWord(ILisaacModel.slot_bug_report)) {
+					//						  
+					// Read `date', `comment', `author', `bibliography', 
+					// `language', `copyright' or `bug_report' slots.
+					//
+
+					String headerSlot = new String(parser.getLastString());
+
+					// '-' ("date"|"comment"|"author"|"bibliography"|"language"|"copyright"|"bug_report") 
+					// ':=' string
+					if (! parser.readSymbol(ILisaacModel.symbol_affect_immediate)) {
+						parser.getReporter().syntaxError("Added ':='.", parser.getLine());
+						return false;
+					}
+					parser.readSpace();
+					Position slotPosition = parser.getPosition();
+					if (! parser.readString()) {
+						parser.getReporter().syntaxError("Incorrect string.", parser.getLine());
+						return false;
+					}
+					if (headerSlot.equals(ILisaacModel.slot_comment)) {
+						prototype.setHeaderComment(new String(parser.getLastString()));
+					} else {
+						slotPosition.setLength(parser.getOffset() - slotPosition.offset);
+						prototype.addHeaderData(headerSlot,new String(parser.getLastString()), slotPosition);
+					}
+
+				} else {
+					parser.getReporter().syntaxError("Incorrect slot.", parser.getPosition());
+					return false;
+				}
+				if (! parser.readCharacter(';')) {
+					parser.getReporter().warning("Added ';'.", parser.getPosition());
+				}
+			}
+		} while (! parser.isEOF() && result);
+
+		return true;
+	}
+
+	public ILisaacContext getNextContext() {
+		if (parser.skipUntilThisKeyword(ILisaacModel.keyword_section)) {
+			return this;
+		}
+		return null;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/SlotContext.java b/editor/eclipse/src/org/lisaac/ldt/model/SlotContext.java
new file mode 100644
index 0000000..c58a267
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/SlotContext.java
@@ -0,0 +1,29 @@
+package org.lisaac.ldt.model;
+
+import org.lisaac.ldt.model.items.Prototype;
+
+public class SlotContext implements ILisaacContext {
+	private LisaacParser parser;
+	
+	public SlotContext(LisaacParser parser) {
+		this.parser = parser;
+	}
+	
+	//++ SLOT         -> style TYPE_SLOT [':' (TYPE|'('TYPE_LIST')') ][ affect DEF_SLOT ]';'
+	public boolean parseDefinition(Prototype prototype) {
+		boolean result=false;
+		
+		result = parser.readSlot(prototype);
+		
+		return result;
+	}
+	
+	public ILisaacContext getNextContext() {
+		// FIXME skip until next slot !!!!
+		if (parser.skipUntilThisKeyword(ILisaacModel.keyword_section)) {
+			return parser.getSectionContext();
+		}
+		return null;
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/IArgument.java b/editor/eclipse/src/org/lisaac/ldt/model/items/IArgument.java
new file mode 100644
index 0000000..8a464f5
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/IArgument.java
@@ -0,0 +1,14 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.types.IType;
+
+public interface IArgument extends IVariable {
+
+	String getName();
+
+	IType getType();
+
+	boolean hasName(String word);
+	
+	void printIn(StringBuffer buffer);
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ICode.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ICode.java
new file mode 100644
index 0000000..9ba6c20
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ICode.java
@@ -0,0 +1,13 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public interface ICode {
+
+	IType getType(Slot slot, Prototype prototype);
+
+	void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits);
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/IConstant.java b/editor/eclipse/src/org/lisaac/ldt/model/items/IConstant.java
new file mode 100644
index 0000000..797c218
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/IConstant.java
@@ -0,0 +1,5 @@
+package org.lisaac.ldt.model.items;
+
+public interface IConstant extends ICode {
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgs.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgs.java
new file mode 100644
index 0000000..d053c6e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgs.java
@@ -0,0 +1,96 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeMulti;
+
+public class ITMArgs implements IArgument {
+
+	protected String[] name;
+	protected TypeMulti type;
+
+	protected Position position;
+	
+	public ITMArgs(String[] name, TypeMulti type, Position position) {
+		this.name = name;
+		this.type = type;
+		this.position = position;
+	}
+
+	public String getName() {
+		StringBuffer buffer = new StringBuffer("(");
+		for (int i=0; i<name.length; i++) {
+			buffer.append(name[i]);
+			
+			if (i != name.length-1) {
+				buffer.append(", ");
+			}
+		}
+		buffer.append(")");
+		return buffer.toString();
+	}
+
+	private int lastIndexOf(String word) {
+		for (int i=0; i<name.length; i++) {
+			if (name[i].compareTo(word) == 0) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	public boolean hasName(String word) {
+		return lastIndexOf(word) != -1;
+	}
+	
+	public IType getType() {
+		return null;// FIXME list arg type
+	}
+	
+	public IType getArgType(String name) {
+		int index = lastIndexOf(name);
+		if (index != -1) {
+			return type.getSubType(index);
+		}
+		return null;
+	}
+	
+	public void printIn(StringBuffer buffer) {
+		buffer.append("(");
+		for (int i=0; i<name.length; i++) {
+			IType subType = type.getSubType(i);
+			buffer.append(name[i]);
+			buffer.append(" : ");
+			buffer.append(subType);
+			
+			if (i != name.length-1) {
+				buffer.append(", ");
+			}
+		}
+		buffer.append(")");
+	}
+
+	public String getHoverInformation() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("<I>Arguments</I> : ");
+		buffer.append("(");
+		for (int i=0; i<name.length; i++) {
+			IType subType = type.getSubType(i);
+			buffer.append("<b>"+name[i]+"</b>");
+			buffer.append(" : ");
+			buffer.append("<g>"+subType+"</g>");
+			
+			if (i != name.length-1) {
+				buffer.append(", ");
+			}
+		}
+		buffer.append(")");
+		
+		return buffer.toString();
+	}
+
+	public Position getPosition() {
+		return position;
+	}
+}
+	
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgument.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgument.java
new file mode 100644
index 0000000..ae1abdc
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMArgument.java
@@ -0,0 +1,52 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.ITypeMono;
+
+public class ITMArgument implements IArgument {
+	
+	protected String name;
+	protected ITypeMono type;
+	
+	protected Position position;
+	
+	public ITMArgument(String name, ITypeMono type, Position position) {
+		this.name = name;
+		this.type = type;
+		this.position = position;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public IType getType() {
+		return type;
+	}
+	
+	public boolean hasName(String word) {
+		return name.compareTo(word) == 0;
+	}
+	
+	public void printIn(StringBuffer buffer) {
+		buffer.append(name);
+		buffer.append(':');
+		buffer.append(type);
+	}
+	
+	public String getHoverInformation() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("<I>Argument</I> : <b>");
+		buffer.append(name);
+		buffer.append("</b> <g> : ");
+		buffer.append(type.toString());
+		buffer.append("</g>");
+		
+		return buffer.toString();
+	}
+
+	public Position getPosition() {
+		return position;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMBlock.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMBlock.java
new file mode 100644
index 0000000..831171c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMBlock.java
@@ -0,0 +1,51 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.LisaacParser;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeBlock;
+
+public class ITMBlock implements ICode {
+	protected ITMList list;
+	protected IArgument argument;
+
+	public ITMBlock(ITMList list, IArgument argument, Slot slot) {
+		this.list = list;
+		this.argument = argument;
+
+		if (slot != null) {
+			slot.addSubList(this);
+		}
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return TypeBlock.get(null, null); // FIXME empty block
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {
+		if (argument != null && list != null) {
+			IType type = argument.getType();
+			Position p = argument.getPosition();
+
+			if (p != null && type.toString().compareTo(oldName) == 0) {
+				LisaacParser parser = list.getOwner().getPrototype().openParser();
+				parser.setPosition(p.offset+p.length);
+				parser.readCharacter(':');
+				parser.readSpace();
+
+				int startOffset = parser.getOffset();
+
+				edits.add(new DeleteEdit(startOffset, oldName.length()));
+				edits.add(new InsertEdit(startOffset, newName));
+			}
+		}
+		if (list != null) {
+			list.refactorRenamePrototype(oldName, newName, edits);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMCharacter.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMCharacter.java
new file mode 100644
index 0000000..0656c92
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMCharacter.java
@@ -0,0 +1,21 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMCharacter implements IConstant {
+
+	public ITMCharacter(String string) {
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return TypeSimple.get(ILisaacModel.prototype_character);
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExpression.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExpression.java
new file mode 100644
index 0000000..06cf4ae
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExpression.java
@@ -0,0 +1,30 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+/**
+ * operator list message
+ */
+public class ITMExpression implements ICode {
+	protected ICode[] valueList;
+	
+	public ITMExpression(ICode[] list) {
+		valueList = list;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		if (valueList != null && valueList.length > 0) {
+			return valueList[valueList.length-1].getType(slot, prototype); // FIXME expr type
+		}
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {	
+		for (int i=0; i<valueList.length; i++) {
+			valueList[i].refactorRenamePrototype(oldName, newName, edits);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternal.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternal.java
new file mode 100644
index 0000000..dbbeed5
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternal.java
@@ -0,0 +1,21 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMExternal implements ICode {
+	protected String extern;
+
+	public ITMExternal(String extern) {
+		this.extern = extern;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternalType.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternalType.java
new file mode 100644
index 0000000..782e001
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMExternalType.java
@@ -0,0 +1,36 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.types.ITypeMono;
+
+public class ITMExternalType extends ITMExternal {
+
+	protected ITypeMono type;
+	protected ITypeMono[] typeList;
+	protected boolean persistant;
+	
+	public ITMExternalType(String extern, boolean persistant) {
+		super(extern);
+		this.persistant = persistant;
+	}
+
+	public boolean isPersistant() {
+		return persistant;
+	}
+	
+	public ITypeMono getType(Prototype prototype) {
+		return type;
+	}
+
+	public void setType(ITypeMono type) {
+		this.type = type;
+	}
+
+	public ITypeMono[] getTypeList() {
+		return typeList;
+	}
+
+	public void setTypeList(ITypeMono[] typeList) {
+		this.typeList = typeList;
+	}
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLDots.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLDots.java
new file mode 100644
index 0000000..5b39c71
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLDots.java
@@ -0,0 +1,16 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMLDots implements ICode {
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMList.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMList.java
new file mode 100644
index 0000000..be09219
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMList.java
@@ -0,0 +1,116 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.LisaacParser;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMList implements ICode {
+	protected ICode[] code;
+	protected ITMLocal[] localList;
+	protected ITMLocal[] staticList;
+
+	protected int startOffset, endOffset;
+	
+	private Slot owner;
+	
+	public ITMList(Slot slot, int start) {
+		startOffset = start;
+		endOffset = startOffset;
+		owner = slot;
+		if (slot != null) {
+			slot.addSubList(this);
+		}
+	}
+	
+	public Slot getOwner() {
+		return owner;
+	}
+	
+	public void setEndOffset(int end) {
+		endOffset = end;
+	}
+
+	public void setCode(ICode[] code) {
+		this.code = code;
+	}
+
+	public void setLocalList(ITMLocal[] list) {
+		localList = list;
+	}
+	public void setStaticList(ITMLocal[] list) {
+		staticList = list;
+	}
+
+	public boolean hasVariableDefinition(String word) {		
+		return getLocal(word) != null;
+	}
+
+	public ITMLocal getLocal(String word) {		
+		if (localList != null) {
+			for (int i=0; i<localList.length; i++) {
+				if (localList[i].name.compareTo(word) == 0) {
+					return localList[i];
+				}
+			}
+		}
+		if (staticList != null) {
+			for (int i=0; i<staticList.length; i++) {
+				if (staticList[i].name.compareTo(word) == 0) {
+					return staticList[i];
+				}
+			}
+		}
+		return null;
+	}
+	
+	public IType getType(Slot slot, Prototype prototype) {
+		if (code != null && code.length > 0) {
+			return code[code.length-1].getType(slot, prototype); // FIXME list type
+		}
+		return null;
+	}
+	
+	public boolean isInside(int offset) {
+		return offset >= startOffset && offset <= endOffset;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName, List<TextEdit> edits) {
+		if (localList != null && owner != null) {
+			for (int i=0; i<localList.length; i++) {
+				createEdit(localList[i], oldName, newName, edits);
+			}
+		}
+		if (staticList != null && owner != null) {
+			for (int i=0; i<staticList.length; i++) {
+				createEdit(staticList[i], oldName, newName, edits);
+			}
+		}
+		if (code != null) {
+			for (int i=0; i<code.length; i++) { 
+				code[i].refactorRenamePrototype(oldName, newName, edits);
+			}
+		}
+	}
+	
+	private void createEdit(ITMLocal local, String oldName, String newName, List<TextEdit> edits) {
+		IType type = local.getType();
+		Position p = local.getPosition();
+		
+		if (p != null && type.toString().compareTo(oldName) == 0) {
+			LisaacParser parser = owner.getPrototype().openParser();
+			parser.setPosition(p.offset+p.length);
+			parser.readCharacter(':');
+			parser.readSpace();
+			
+			int startOffset = parser.getOffset();
+			
+			edits.add(new DeleteEdit(startOffset, oldName.length()));
+			edits.add(new InsertEdit(startOffset, newName));
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMListIdf.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMListIdf.java
new file mode 100644
index 0000000..20ad159
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMListIdf.java
@@ -0,0 +1,28 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMListIdf implements ICode {
+
+	ArrayList<String> list;
+	
+
+	public ITMListIdf(ArrayList<String> list) {
+		this.list = list;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		// TODO Auto-generated method stub
+
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLocal.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLocal.java
new file mode 100644
index 0000000..626afe7
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMLocal.java
@@ -0,0 +1,48 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.ITypeMono;
+
+/**
+ * Local declaration slot
+ */
+public class ITMLocal implements IVariable {
+	protected ITypeMono type;
+	protected String name;
+	
+	protected Position position;
+	
+	public ITMLocal(String name, Position position) {
+		this.position = position;
+		this.name = name;
+	}
+	
+	public ITMLocal(ITypeMono type, String name) {
+		this.type = type;
+		this.name = name;
+	}
+
+	public IType getType() {
+		return type;
+	}
+	
+	public void setType(ITypeMono type) {
+		this.type = type;
+	}
+	
+	public String getHoverInformation() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("<I>Local</I> : <b>");
+		buffer.append(name);
+		buffer.append("</b> <g> : ");
+		buffer.append(type.toString());
+		buffer.append("</g>");
+		
+		return buffer.toString();
+	}
+
+	public Position getPosition() {
+		return position;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMNumber.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMNumber.java
new file mode 100644
index 0000000..9785e18
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMNumber.java
@@ -0,0 +1,22 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMNumber implements IConstant {
+
+	public ITMNumber(long lastInteger) {
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return TypeSimple.get(ILisaacModel.prototype_integer);
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOld.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOld.java
new file mode 100644
index 0000000..0ea0cb6
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOld.java
@@ -0,0 +1,25 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMOld implements ICode {
+	protected ICode value;
+
+	public ITMOld(ICode value) {
+		this.value = value;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		if (value != null) {
+			return value.getType(slot, prototype);
+		}
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOperator.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOperator.java
new file mode 100644
index 0000000..c99d6ec
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMOperator.java
@@ -0,0 +1,27 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMOperator implements ICode {
+	protected String name;
+
+	public ITMOperator(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMPrototype.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMPrototype.java
new file mode 100644
index 0000000..7f0de2b
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMPrototype.java
@@ -0,0 +1,34 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.ITypeMono;
+
+public class ITMPrototype implements ICode {
+	protected ITypeMono type;
+
+	protected Position position;
+	
+	public ITMPrototype(ITypeMono type, Position position) {
+		this.type = type;
+		this.position = position;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return type;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		
+		if (type.toString().compareTo(oldName) == 0) {
+			edits.add(new DeleteEdit(position.offset, oldName.length()));
+			edits.add(new InsertEdit(position.offset, newName));
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMRead.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMRead.java
new file mode 100644
index 0000000..a9898e6
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMRead.java
@@ -0,0 +1,55 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMRead implements ICode {
+	protected String name;
+
+	public ITMRead(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		
+		if (slot != null) {
+			if (name.equals(ILisaacModel.variable_self)) {// type simple?
+				return TypeSimple.get(slot.getPrototype().getName());
+			}
+			IArgument arg = slot.getArgument(name);
+			if (arg != null) {
+				if (arg instanceof ITMArgs) {
+					return ((ITMArgs) arg).getArgType(name);
+				}
+				return arg.getType();
+			}
+			if (slot.getValue() instanceof ITMList) {
+				ITMList list = (ITMList) slot.getValue();
+				ITMLocal local = list.getLocal(name);
+				if (local != null) {
+					return local.getType();
+				}
+			}
+		}
+		if (prototype != null) {
+			Slot s = prototype.lookupSlot(name);
+			if (s != null) {
+				return s.getResultType();
+			}
+		}
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		// TODO Auto-generated method stub
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg1.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg1.java
new file mode 100644
index 0000000..6b08c01
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg1.java
@@ -0,0 +1,20 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+
+public class ITMReadArg1 extends ITMRead {
+
+	protected ICode arg;
+	
+	public ITMReadArg1(String name, ICode arg) {
+		super(name);
+		this.arg = arg;
+	}
+	
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		arg.refactorRenamePrototype(oldName, newName, edits);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg2.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg2.java
new file mode 100644
index 0000000..7b220ef
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArg2.java
@@ -0,0 +1,76 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.LisaacCompletionParser;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMReadArg2 extends ITMRead {
+
+	protected ICode argFirst;
+	protected ICode argSecond;
+
+	public ITMReadArg2(String name, ICode a1, ICode a2) {
+		super(name);
+		this.argFirst = a1;
+		this.argSecond = a2;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		//
+		// operator expression.
+		//
+		if (name.startsWith("__")) { // FIXME __infix __prefix __postfix??
+
+			// Get type of left part of operator.
+			IType type = argFirst.getType(slot, prototype);
+			if (type != null) {
+				try {
+					Prototype operatorPrototype = LisaacCompletionParser.findPrototype(""+type);
+					if (operatorPrototype != null) {
+						Slot operatorSlot = operatorPrototype.lookupSlot(name);
+						if (operatorSlot != null) {
+							// return result type of operator.
+							return operatorSlot.getResultType();
+						} else {
+							if (name.compareTo("__infix_equal") == 0) {
+								// special case for '=' operator (can't be a slot)
+								return TypeSimple.getTypeBoolean();
+							}
+						}
+					}
+				} catch (CoreException e) {
+				}
+			}
+			// second chance with second argument  FIXME use __postfix?
+			type = argSecond.getType(slot, prototype);
+			if (type != null) {
+				try {
+					Prototype operatorPrototype = LisaacCompletionParser.findPrototype(""+type);
+					if (operatorPrototype != null) {
+						Slot operatorSlot = operatorPrototype.lookupSlot(name);
+						if (operatorSlot != null) {
+							// return result type of operator.
+							return operatorSlot.getResultType();
+						}
+					}
+				} catch (CoreException e) {
+				}
+			}
+		}
+		//
+		// classic slot
+		//
+		return super.getType(slot, prototype);
+	}
+	
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		
+		argFirst.refactorRenamePrototype(oldName, newName, edits);
+		argSecond.refactorRenamePrototype(oldName, newName, edits);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArgs.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArgs.java
new file mode 100644
index 0000000..4d819c5
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReadArgs.java
@@ -0,0 +1,21 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+
+public class ITMReadArgs extends ITMRead {
+	protected ICode[] args;
+
+	public ITMReadArgs(String name, ICode[] args) {
+		super(name);
+		this.args = args;
+	}
+	
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		for (int i=0; i<args.length; i++) {
+			args[i].refactorRenamePrototype(oldName, newName, edits);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReal.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReal.java
new file mode 100644
index 0000000..3aa345f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMReal.java
@@ -0,0 +1,22 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMReal implements IConstant {
+
+	public ITMReal(String string) {
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return TypeSimple.get(ILisaacModel.prototype_real);
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMResult.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMResult.java
new file mode 100644
index 0000000..7cfe175
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMResult.java
@@ -0,0 +1,26 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMResult implements ICode {
+	protected ICode value;
+
+	public ITMResult(ICode value) {
+		this.value = value;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		if (value != null) {
+			return value.getType(slot, prototype);
+		}
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		value.refactorRenamePrototype(oldName, newName, edits);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMString.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMString.java
new file mode 100644
index 0000000..229c20f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMString.java
@@ -0,0 +1,25 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.TypeSimple;
+
+public class ITMString implements IConstant {
+
+	protected String string;
+	
+	public ITMString(String string) {
+		this.string = string;
+	}
+
+	public IType getType(Slot slot, Prototype prototype) {
+		return TypeSimple.get(ILisaacModel.prototype_string);
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/ITMWrite.java b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMWrite.java
new file mode 100644
index 0000000..8f8746f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/ITMWrite.java
@@ -0,0 +1,33 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.List;
+
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.types.IType;
+
+public class ITMWrite implements ICode {
+
+	protected ICode assign;
+	protected ICode value;
+	
+	protected char type;
+	
+	public ITMWrite(ICode assign, ICode value, char type) {
+		super();
+		this.assign = assign;
+		this.value = value;
+		this.type = type;
+	}
+	
+	public IType getType(Slot slot, Prototype prototype) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refactorRenamePrototype(String oldName, String newName,
+			List<TextEdit> edits) {
+		assign.refactorRenamePrototype(oldName, newName, edits);
+		value.refactorRenamePrototype(oldName, newName, edits);
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/IVariable.java b/editor/eclipse/src/org/lisaac/ldt/model/items/IVariable.java
new file mode 100644
index 0000000..4060773
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/IVariable.java
@@ -0,0 +1,9 @@
+package org.lisaac.ldt.model.items;
+
+import org.lisaac.ldt.model.Position;
+
+public interface IVariable {
+	String getHoverInformation();
+
+	Position getPosition();
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/Prototype.java b/editor/eclipse/src/org/lisaac/ldt/model/items/Prototype.java
new file mode 100644
index 0000000..adc9b70
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/Prototype.java
@@ -0,0 +1,679 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.TextFileChange;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MultiTextEdit;
+import org.eclipse.text.edits.TextEdit;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.LisaacCompletionParser;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.LisaacParser;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.model.types.ITypeMono;
+import org.lisaac.ldt.outline.OutlineItem;
+import org.lisaac.ldt.outline.OutlinePrototype;
+import org.lisaac.ldt.outline.OutlineSection;
+
+public class Prototype {
+	protected IFile file;
+
+	protected ILisaacModel parent;
+	protected LisaacParser parser;
+
+	protected String name;
+	protected String typeStyle;
+
+	protected HashMap<String, Slot> parentList;
+	protected HashMap<String, Slot> slotList;
+
+	// hover informations
+	protected String headerData;
+	protected String headerComment;
+
+	protected Section firstSection;
+
+	// refactor information
+	protected int nameOffset;
+	protected Position authorOffset;
+	protected Position bibliographyOffset;
+	protected Position copyrightOffset;
+
+	public Prototype(IFile file, String name, ILisaacModel model) {
+		this.file = file;
+		this.name = name;
+		this.parent = model;
+		this.parser = model.getParser();
+
+		slotList = new HashMap<String, Slot>();
+		parentList = new HashMap<String, Slot>();
+	}
+
+	public ILisaacModel getModel() {
+		return parent;
+	}
+
+	public boolean setName(String n) {
+		if (name != null && name.equals(n)) {
+			return false;
+		}
+		name = n;
+		return true;
+	}
+
+	public IFile getFile() {
+		return file;
+	}
+	
+	public String getFileName() {
+		return file.getName();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setHeaderComment(String comment) {
+		this.headerComment = comment;
+	}
+
+	public void addHeaderData(String slotName, String data, Position position) {
+		String info = "\n<g>" + slotName + "</g> " + data;
+		if (headerData == null) {
+			headerData = info;
+		} else {
+			this.headerData += info;
+		}
+		if (slotName.equals(ILisaacModel.slot_author)) {
+			authorOffset = position;
+		} else if (slotName.equals(ILisaacModel.slot_bibliography)) {
+			bibliographyOffset = position;
+		} else if (slotName.equals(ILisaacModel.slot_copyright)) {
+			copyrightOffset = position;
+		}
+	}
+	
+
+	public LisaacParser openParser() {
+		parser.initialize();
+		return parser;
+	}
+
+	public void setTypeStyle(String s) {
+		typeStyle = s;
+	}
+
+	public String getTypeStyle() {
+		return typeStyle;
+	}
+
+	public Section getFirstSection() {
+		return firstSection;
+	}
+
+	public void setFirstSection(Section s) {
+		firstSection = s;
+	}
+
+	public boolean isExpanded() {
+		if (typeStyle != null) {
+			return typeStyle.equals(ILisaacModel.keyword_expanded)
+			|| name.equals(ILisaacModel.prototype_true)
+			|| name.equals(ILisaacModel.prototype_false);
+		}
+		return false;
+	}
+
+	public Slot lookupSlot(String n) {
+		Slot result = null;
+
+		//
+		// Search in 'Self'.
+		//
+		result = getSlot(n);
+		if (result == null) {
+			result = getParentSlot(n);
+		}
+
+		if (result == null) {
+			//
+			// Search in parents.
+			//
+			Collection<Slot> values = parentList.values();
+			Iterator<Slot> it = values.iterator();
+			while (it.hasNext()) {
+				Slot slotParent = it.next();
+				IType typeParent = slotParent.getResultType();
+				try {
+					Prototype parent = LisaacCompletionParser
+					.findPrototype("" + typeParent);
+					if (parent != null) {
+						result = parent.lookupSlot(n);
+						if (result != null) {
+							return result;
+						}
+					}
+				} catch (CoreException e) {
+					return null;
+				}
+			}
+		}
+		return result;
+	}
+
+	public Slot getSlot(String n) {
+		//
+		// Search in 'Self' only.
+		//
+		if (slotList.containsKey(n)) {
+			return slotList.get(n);
+		}
+		return null;
+	}
+
+	public Slot getParentSlot(String n) {
+		// Search in 'Self' parent.
+		if (parentList.containsKey(n)) {
+			return parentList.get(n);
+		}
+		return null;
+	}
+
+	public Slot getSlot(int offset) {
+		return getSlot(openParser(), offset);
+	}
+
+	public Slot getSlot(String s, int offset) {
+		return getSlot(new LisaacParser(null, s), offset);
+	}
+
+	public Slot getSlot(LisaacParser parser, int offset) {
+		//
+		// Use indentation to get slot
+		//
+		String source = parser.getSource();
+		boolean again;
+
+		if (offset >= source.length() - 1) {
+			return null;
+		}
+
+		do {
+			again = false;
+
+			// find beginning of line
+			while (offset > 0 && source.charAt(offset) != '\n') {
+				offset--;
+			}
+			// look at indentation
+			if (offset > 0 && source.length() > 4) {
+				if (source.charAt(offset + 1) == ' '
+					&& source.charAt(offset + 2) == ' '
+						&& (source.charAt(offset + 3) == '+' || source
+								.charAt(offset + 3) == '-')) {
+					String slotName = parser
+					.readSlotNameFromOffset(offset + 4, false);
+					if (slotName != null) {
+						return getSlot(slotName);
+					}
+				} else {
+					again = true;
+					offset--;
+				}
+			}
+		} while (again);
+
+		return null;
+	}
+
+	public void lookupSlotMatch(String n,
+			ArrayList<ICompletionProposal> matchList, int offset, int length) {
+		//
+		// Search in 'Self'.
+		//
+		getSlotMatch(n, matchList, offset, length);
+		getParentSlotMatch(n, matchList, offset, length);
+
+		//
+		// Search in parents.
+		//
+		Collection<Slot> values = parentList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slotParent = it.next();
+			IType typeParent = slotParent.getResultType();
+			try {
+				Prototype parent = LisaacCompletionParser.findPrototype(""
+						+ typeParent);
+				if (parent != null) {
+					parent.lookupSlotMatch(n, matchList, offset, length);
+				}
+			} catch (CoreException e) {
+			}
+		}
+	}
+
+	public void getSlotMatch(String n,
+			ArrayList<ICompletionProposal> matchList, int offset, int length) {
+		//
+		// // Search in 'Self' only.
+		//
+		Collection<Slot> values = slotList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slot = it.next();
+			if (slot.match(n)) {
+				slot.getSlotMatchProposals(matchList, offset, length, n
+						.length());
+			}
+		}
+	}
+
+	public void getParentSlotMatch(String n,
+			ArrayList<ICompletionProposal> matchList, int offset, int length) {
+		// Search in 'Self' parent.
+		Collection<Slot> values = parentList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slot = it.next();
+			if (slot.match(n)) {
+				slot.getSlotMatchProposals(matchList, offset, length, n
+						.length());
+			}
+		}
+	}
+
+	public Slot getSlotFromKeyword(String keyword, LisaacParser parser,
+			int baseOffset) throws CoreException {
+		String source = parser.getSource();
+		int bracketLevel = 0, invBracketLevel = 0;
+		Prototype receiver = null;
+		Slot result = null;
+		char c = 0;
+
+		int offset = baseOffset;
+		if (offset >= source.length() - 1) {
+			return null;
+		}
+
+		while (offset > 0) {
+			//
+			// find beginning of SEND_MSG grammar rule
+			//
+
+			// Rewind to '(' '{' ';' '[' '.' '<-' 'operator'
+			c = source.charAt(offset);
+
+			if (c == '(' || c == '{' || c == '[') {
+				if (bracketLevel == 0) {
+					break;
+				}
+				bracketLevel--;
+				invBracketLevel++;
+			}
+			if (c == ')' || c == '}' || c == ']') {
+				bracketLevel++;
+				invBracketLevel--;
+			}
+
+			// ok, we're not in nested statements
+			if (bracketLevel == 0 && invBracketLevel == 0) {
+				if (c == ';' || c == '.') {
+					break;
+				}
+
+				// affectation
+				if (c == '=' && source.length() - offset > 2) {
+					if (source.charAt(offset - 1) == ':'
+						|| source.charAt(offset - 1) == '?') {
+						break;
+					}
+				} else if (c == '-' && source.length() - offset > 2) {
+					if (source.charAt(offset - 1) == '<') {
+						break;
+					}
+				}
+				if (parser.isOperatorSymbol(c)) {
+					if (c == '+' || c == '-') {
+						// ambiguity with slot definition
+						if (offset - 3 > 0 && source.charAt(offset - 1) == ' ' &&
+								source.charAt(offset - 2) == ' ' && 
+								source.charAt(offset - 3) == '\n') {
+							offset = offset - 3;
+							continue;
+						}
+					}
+					break;
+				}
+			}
+
+			// look at indentation
+			if (c == '\n' && source.length() - offset > 4) {
+				if (source.charAt(offset + 1) == ' '
+					&& source.charAt(offset + 2) == ' '
+						&& (source.charAt(offset + 3) == '+' || source
+								.charAt(offset + 3) == '-')) {
+					String slotName = parser
+					.readSlotNameFromOffset(offset + 4, false);
+					if (slotName != null) {
+						result = lookupSlot(slotName);
+						if (result == null) {
+							return null;
+						}
+						if (result.keywordCount() == 1) {
+							if (result.getName().compareTo(keyword) == 0) {
+								return result;
+							}
+						} else {
+							// find keyword next token
+							offset = baseOffset;
+							while (offset < source.length() - 1
+									&& Character
+									.isJavaIdentifierPart(source
+											.charAt(offset))) {
+								offset++;
+							}
+							// read space
+							while (offset < source.length() - 1
+									&& Character.isWhitespace(source
+											.charAt(offset))) {
+								offset++;
+							}
+							if (source.charAt(offset) != ':') {
+								return result;// 'keyword' is a slot keyword
+							}
+							return null;
+						}
+					}
+				}
+			}
+			offset--;
+		}
+		if (result == null) {
+			// Slot Call.
+
+			if (c == '.') {
+				int pointOffset = offset;
+				offset--;
+				bracketLevel = 0;
+
+				// rewind until ';' '(' '{' '['
+				while (offset > 0) {
+					c = source.charAt(offset);
+					if (c == ';') {
+						break;
+					}
+					if (c == '(' || c == '{' || c == '[') {
+						if (bracketLevel == 0) {
+							break;
+						}
+						bracketLevel--;
+					}
+					if (c == ')' || c == '}' || c == ']') {
+						bracketLevel++;
+					}
+					offset--;
+				}
+				if (offset > 0) {
+					LisaacCompletionParser p = new LisaacCompletionParser(
+							source, (LisaacModel) getModel());
+					receiver = p
+					.readReceiver(offset + 1, pointOffset, this);
+
+					offset = pointOffset;
+				}
+			} else {
+				receiver = this;
+			}
+			parser.setPosition(offset + 1);
+			parser.readSpace();
+			String slotName = parser.readKeywordInSendMsg(keyword,
+					baseOffset);
+
+			if (slotName != null && receiver != null) {
+				result = receiver.lookupSlot(slotName);
+			}
+		}
+		return result;
+	}
+
+	public void addSlot(Slot s) {
+		slotList.put(s.getName(), s);
+	}
+
+	public void addParentSlot(Slot s) {
+		parentList.put(s.getName(), s);
+	}
+
+	public String getHoverInformation() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("<b>");
+		buffer.append(name);
+		buffer.append("</b>");
+		if (headerComment != null) {
+			buffer.append("\n" + headerComment);
+		}
+		if (headerData != null) {
+			buffer.append("\n\n" + headerData);
+		}
+		return buffer.toString();
+	}
+
+	public List<OutlineItem> getOutlineItems() {
+		List<OutlineItem> sections = new ArrayList<OutlineItem>();
+
+		Section current = firstSection;
+		while (current != null) {
+			sections.add(new OutlineSection(current));
+			current = current.getNext();
+		}
+
+		List<OutlineItem> result = new ArrayList<OutlineItem>();
+		result.add(new OutlinePrototype(this, sections));
+		return result;
+	}
+
+	public void getSlotProposals(ArrayList<ICompletionProposal> proposals,
+			int offset, int length) {
+		Collection<Slot> values = slotList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slot = it.next();
+			slot.getSlotProposals(proposals, offset, length);
+		}
+
+		values = parentList.values();
+		it = values.iterator();
+		while (it.hasNext()) {
+			Slot slotParent = it.next();
+			IType typeParent = slotParent.getResultType();
+			try {
+				Prototype parent = LisaacCompletionParser.findPrototype(""
+						+ typeParent);
+				if (parent != null) {
+					parent.getSlotProposals(proposals, offset, length);
+				}
+			} catch (CoreException e) {
+			}
+		}
+	}
+
+	public ArrayList<org.eclipse.jface.text.Position> getPositions() {
+		ArrayList<org.eclipse.jface.text.Position> result = new ArrayList<org.eclipse.jface.text.Position>();
+
+		// section positions
+		Section current = firstSection;
+		while (current != null) {
+			Position p = current.getPosition();
+			result.add(new org.eclipse.jface.text.Position(p.offset, p.length));
+
+			current = current.getNext();
+		}
+
+		// slot positions
+		Collection<Slot> values = slotList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slot = it.next();
+			Position p = slot.getPositionBody();
+			if (p != null) {
+				result.add(new org.eclipse.jface.text.Position(p.offset, p.length));
+			}
+		}
+		return result;
+	}
+
+	public IPath getWorkspacePath() {
+		return file.getFullPath();
+	}
+
+	public Change refactorRenameSelf(String newName) {
+		TextFileChange change = new TextFileChange("Change 'name' slot in section header", file);
+
+		// rename 'name' slot
+		MultiTextEdit edit= new MultiTextEdit();
+		edit.addChild(new DeleteEdit(nameOffset, name.length()));
+		edit.addChild(new InsertEdit(nameOffset, newName));
+
+		change.setEdit(edit);
+		return change;
+	}
+
+	public Change refactorRenamePrototype(String oldName, String newName) {
+		MultiTextEdit edit= new MultiTextEdit();
+
+		// 1. refactor sections
+		Section current = firstSection;
+		while (current != null) {
+			Position p = current.getPosition();	
+			ITypeMono[] typeList = current.getTypeList();
+			if (typeList != null) {
+				for (int i=0; i<typeList.length; i++) {
+					if (typeList[i].toString().compareTo(oldName) == 0) {
+						typeList[i].rename(oldName, newName);
+
+						// rename section 
+						edit.addChild(new DeleteEdit(p.offset+1, p.length-1));
+						edit.addChild(new InsertEdit(p.offset+1, current.getName()+"\n\n  "));
+
+						// for model invariance (other changes in refactor)
+						typeList[i].rename(newName, oldName);
+					}
+				}
+			}
+			current = current.getNext();
+		}
+
+		// 2. refactor slots
+		Collection<Slot> values = slotList.values();
+		Iterator<Slot> it = values.iterator();
+		while (it.hasNext()) {
+			Slot slot = it.next();
+			TextEdit[] slotEdits = slot.refactorRenamePrototype(oldName, newName);
+			if (slotEdits != null) {
+				edit.addChildren(slotEdits);
+			}
+		}
+		// create change
+		if (edit.getChildrenSize() > 0) {
+			TextFileChange change = new TextFileChange("Rename prototype occurences", file);
+			change.setEdit(edit);
+			return change;
+		}
+		return null;
+	}
+
+	public Change refactorHeader(String author, String bibliography,
+			String copyright, String license) {
+		MultiTextEdit edit= new MultiTextEdit();
+		
+		// update header slots.
+		refactorHeaderSlot(ILisaacModel.slot_author, authorOffset, author, edit);
+		refactorHeaderSlot(ILisaacModel.slot_bibliography, bibliographyOffset, bibliography, edit);
+		refactorHeaderSlot(ILisaacModel.slot_copyright, copyrightOffset, copyright, edit);
+		
+		// update license.
+		if (license != null) {
+			int offset = getOffsetBeforeSection();
+			edit.addChild(new DeleteEdit(0, offset-1));
+			edit.addChild(new InsertEdit(0, license));
+		}
+		
+		// create change
+		if (edit.getChildrenSize() > 0) {
+			TextFileChange change = new TextFileChange("Update Section Header", file);
+			change.setEdit(edit);
+			return change;
+		}
+		return null;
+	}
+	
+	private void refactorHeaderSlot(String name, Position pos, String newValue, MultiTextEdit edit) {
+		if (newValue != null) {
+			if (pos != null) {
+				// slot already exist
+				edit.addChild(new DeleteEdit(pos.offset, pos.length));
+				edit.addChild(new InsertEdit(pos.offset, "\"" + newValue + "\""));
+			} else {
+				// create slot
+				String slot = "\n  - " + name + " := \"" + newValue + "\";";
+				edit.addChild(new InsertEdit(getOffsetAfterName(), slot));
+			}
+		}
+	}
+	
+	private int getOffsetAfterName() {
+		LisaacParser parser = openParser();
+		parser.setPosition(nameOffset);
+		parser.readCapIdentifier();
+		parser.readCharacter(';');
+	
+		return parser.getOffset();
+	}
+	
+	private int getOffsetBeforeSection() {
+		LisaacParser parser = openParser();
+		parser.setPosition(0);
+		if (parser.readThisKeyword (ILisaacModel.keyword_section)) {
+			return parser.getOffset() - 7;
+		}
+		return 0;
+	}
+	
+	public void setNameOffset(int offset) {
+		nameOffset = offset;
+	}
+	
+	public void setAuthorOffset(Position p) {
+		authorOffset = p;
+	}
+	
+	public void setBibliographyOffset(Position p) {
+		bibliographyOffset = p;
+	}
+	
+	public void setCopyrightOffset(Position p) {
+		copyrightOffset = p;
+	}
+
+	public IRegion getRegionAt(int line, int column) {
+		LisaacParser parser = openParser();
+		parser.readTokenAt(line, column);
+		
+		return new Region(parser.getOffset(), parser.getLastString().length());
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/Section.java b/editor/eclipse/src/org/lisaac/ldt/model/items/Section.java
new file mode 100644
index 0000000..f08234e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/Section.java
@@ -0,0 +1,166 @@
+package org.lisaac.ldt.model.items;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.types.ITypeMono;
+import org.lisaac.ldt.outline.OutlineItem;
+import org.lisaac.ldt.outline.OutlineSlot;
+
+public class Section {
+	protected Prototype prototype;
+
+	protected String name;
+	protected ITypeMono[] typeList;
+
+	protected Section next;
+
+	protected Position position;
+
+	protected LinkedList<Slot> slots;
+
+
+	public Section(Prototype prototype, String name, Position position) {
+		this.name = name;
+		this.prototype = prototype;
+		this.position = position;
+		this.next = null;
+	}
+
+	public Section(Prototype prototype, ITypeMono[] typeList, Position position) {
+		this.typeList = typeList;
+		this.prototype = prototype;
+		this.position = position;
+		this.next = null;
+	}
+
+	public String getName() {
+		if (name == null) {
+			StringBuffer buffer = new StringBuffer();
+			for (int i=0; i<typeList.length; i++) {
+				buffer.append(typeList[i].toString());
+				if (i != typeList.length-1) {
+					buffer.append(", ");
+				}
+			}
+			return buffer.toString();
+		}
+		return name;
+	}
+
+	public ITypeMono[] getTypeList() {
+		return typeList;
+	}
+
+	public Section getNext() {
+		return next;
+	}
+
+	public void setNext(Section next) {
+		this.next = next;
+	}
+
+	public Position getPosition() {
+		return position;
+	}
+
+	public void addSlot(Slot slot) {
+		if (slots == null) {
+			slots = new LinkedList<Slot>();
+		}
+		slots.add(slot);
+	}
+
+	//
+	// Consultation
+	//
+
+	public boolean isMapping() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_mapping);
+	}
+
+	public boolean isPrivate() {
+		if (name == null) {
+			return true;
+		}
+		return name.equals(ILisaacModel.section_private);
+	}
+
+	public boolean isPublic() {
+		if (name != null) {
+			return name.equals(ILisaacModel.section_public);
+		}
+		return false;
+	}
+
+	public boolean isHeader() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_header);
+	}
+
+	public boolean isInherit() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_inherit);
+	}
+
+	public boolean isInsert() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_insert);
+	}
+
+	public boolean isInheritOrInsert() {
+		return isInherit() || isInsert();
+	}
+
+	public boolean isInterrupt() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_interrupt);
+	}
+
+	public boolean isDirectory() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_directory);
+	}
+
+	public boolean isExternal() {
+		if (name == null) {
+			return false;
+		}
+		return name.equals(ILisaacModel.section_external);
+	}
+
+	public boolean isPrivateStyle() {
+		return !isPublic() && typeList == null;
+	}
+
+	public Prototype getPrototype() {
+		return prototype;
+	}
+
+	public List<OutlineItem> getOutlineItems() {
+		List<OutlineItem> items = new ArrayList<OutlineItem>();
+
+		if (slots != null) {
+			for (int i=0; i<slots.size(); i++) {
+				items.add(new OutlineSlot(slots.get(i)));
+			}
+		}
+		return items;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/items/Slot.java b/editor/eclipse/src/org/lisaac/ldt/model/items/Slot.java
new file mode 100644
index 0000000..90d2b16
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/items/Slot.java
@@ -0,0 +1,417 @@
+	package org.lisaac.ldt.model.items;
+
+	import java.util.ArrayList;
+	import org.eclipse.jface.text.contentassist.CompletionProposal;
+	import org.eclipse.jface.text.contentassist.ICompletionProposal;
+	import org.eclipse.swt.graphics.Image;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.TextEdit;
+	import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.model.LisaacParser;
+	import org.lisaac.ldt.model.Position;
+	import org.lisaac.ldt.model.types.IType;
+import org.lisaac.ldt.outline.OutlineSlot;
+
+	public class Slot {
+
+		protected Section sectionId;
+		protected Position position;
+
+		protected String name;
+		protected char style;
+		protected char affect; // ':', '?', '<'
+
+		protected IArgument[] argumentList;
+		protected IType resultType;
+
+		protected String[] keywordList;
+
+		protected ICode value;
+
+		protected ArrayList<ICode> subLists;
+
+		protected String comment;
+
+		protected Position body;
+		
+		public Slot(Position position, String name, Section sectionId) {
+			this.name = name;
+			this.position = position;
+			this.sectionId = sectionId;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public char getStyle() {
+			return style;
+		}
+
+		public char getAffect() {
+			return affect;
+		}
+
+		public IArgument getArgument(int i) {
+			return argumentList[i];
+		}
+
+		public Section getSectionId() {
+			return sectionId;
+		}
+
+		public IType getResultType() {
+			return resultType;
+		}
+
+		public void setArgumentList(IArgument[] argumentList) {
+			this.argumentList = argumentList;
+		}
+
+		public void setResultType(IType resultType) {
+			this.resultType = resultType;
+		}
+
+		public void setKeywordList(String[] keywordList) {
+			this.keywordList = keywordList;
+		}
+
+		public void setComment(String comment) {
+			this.comment = comment;
+		}
+
+		public void setAffect(char affect) {
+			this.affect = affect;
+		}
+
+		public Position getPosition() {
+			return position;
+		}
+		
+		public Position getPositionBody() {
+			return body;
+		}
+
+		public void setBody(Position p) {
+			body = p;
+		}
+		
+		public int keywordCount() {
+			if (keywordList == null) {
+				return 0;
+			}
+			return keywordList.length;
+		}
+
+		//
+		// Value.
+		//
+
+		public void setValue(ICode v) {
+			if (affect == '<') {
+				value = v;
+			} else {
+				// TODO not yet implemented
+			}
+		}
+
+		public ICode getValue() {
+			return value;
+		}
+
+		public void addSubList(ICode list) {
+			if (subLists == null) {
+				subLists = new ArrayList<ICode>();
+			}
+			subLists.add(list);
+		}
+
+		//
+		// Access associativity & priority level.
+		//
+		protected int priorityAndLevel;
+
+		public void setAssociativity(String p, int l) {
+			if (p == null || p.equals(ILisaacModel.keyword_left)) {
+				priorityAndLevel = l;
+			} else {
+				priorityAndLevel = -l;
+			}
+		}
+
+		public String getAssociativity() {
+			String result;
+
+			if (priorityAndLevel >= 0) {
+				result = ILisaacModel.keyword_left;
+			} else {
+				result = ILisaacModel.keyword_right;
+			}
+			return result;
+		}
+
+		public int getPriority() {
+			if (priorityAndLevel < 0) {
+				return -priorityAndLevel;
+			}
+			return priorityAndLevel;
+		}
+
+		public void setStyle(char style) {
+			this.style = style;
+		}
+
+		public boolean hasArgument(String word) {
+			return getArgument(word) != null;
+		}
+
+		public IArgument getArgument(String word) {
+			if (argumentList != null) {
+				for (int i = 0; i < argumentList.length; i++) {
+					if (argumentList[i].hasName(word)) {
+						return argumentList[i];
+					}
+				}
+			}
+			return null;
+		}
+
+		public boolean hasVariableDefinition(String word, int offset) {
+			return getVariableDefinition(word, offset) != null;
+		}
+
+		public IVariable getVariableDefinition(String word, int offset) {
+			ITMList list;
+
+			if (subLists != null) {
+				for (int i = 0; i < subLists.size(); i++) {
+					ICode c = subLists.get(i);
+
+					if (c instanceof ITMList) {
+						list = (ITMList) c;
+						if (list != null && list.isInside(offset)) {
+							// list variable
+							IVariable var = list.getLocal(word);
+							if (var != null) {
+								return var;
+							}
+						}
+					} else if (c instanceof ITMBlock) {
+						list = ((ITMBlock) c).list;
+						IArgument arg = ((ITMBlock) c).argument;
+
+						if (list != null && arg != null
+								&& list.isInside(offset) && arg.hasName(word)) {
+							// block argument
+							return arg;
+						}
+					}
+				}
+			}
+			return null;
+		}
+
+		public IVariable getVariable(String word, int offset) {
+			IVariable result = getArgument(word);
+			if (result == null) {
+				result = getVariableDefinition(word, offset);
+			}
+			return result;
+		}
+
+		public Prototype getPrototype() {
+			return sectionId.getPrototype();
+		}
+
+		private String getOperatorName() {
+			String s = name.substring(2);
+			StringBuffer result = new StringBuffer("'");
+			int index;
+			do {
+				index = s.indexOf("_");
+				s = s.substring(index + 1);
+				if (index != -1) {
+					if (s.startsWith("add")) {
+						result.append('+');
+					} else if (s.startsWith("sub")) {
+						result.append('-');
+					} else if (s.startsWith("logicnot")) {
+						result.append('~');
+					} else if (s.startsWith("not")) {
+						result.append('!');
+					} else if (s.startsWith("div")) {
+						result.append('/');
+					} else if (s.startsWith("mul")) {
+						result.append('*');
+					} else if (s.startsWith("xor")) {
+						result.append('^');
+					} else if (s.startsWith("mod")) {
+						result.append('%');
+					} else if (s.startsWith("greater")) {
+						result.append('>');
+					} else if (s.startsWith("less")) {
+						result.append('<');
+					} else if (s.startsWith("equal")) {
+						result.append('=');
+					} else if (s.startsWith("notdiv")) {
+						result.append('\\');
+					} else if (s.startsWith("or")) {
+						result.append('|');
+					} else if (s.startsWith("and")) {
+						result.append('&');
+					} else if (s.startsWith("dollar")) {
+						result.append('$');
+					} else if (s.startsWith("diese")) {
+						result.append('#');
+					} else if (s.startsWith("at")) {
+						result.append('@');
+					} else if (s.startsWith("ask")) {
+						result.append('?');
+					}
+				}
+			} while (index != -1);
+
+			result.append('\'');
+			return result.toString();
+		}
+
+		public String getSignature(boolean isCall) {
+
+			if (name.startsWith("__")) {
+				return getOperatorName();
+			}
+
+			if (keywordList == null || keywordList.length < 1) {
+				return name;
+			}
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(keywordList[0]);
+			buffer.append(" ");
+
+			int keywordIndex = 1;
+			for (int argIndex = 0; argIndex < argumentList.length; argIndex++) {
+				if (isCall) {
+					buffer.append(argumentList[argIndex].getName());
+				} else {
+					argumentList[argIndex].printIn(buffer);
+				}
+				buffer.append(" ");
+
+				if (keywordIndex < keywordList.length) {
+					buffer.append(keywordList[keywordIndex]);
+					buffer.append(" ");
+					keywordIndex++;
+				}
+			}
+			if (!isCall && resultType.toString() != null) {
+				buffer.append(" : " + resultType);
+			}
+			return buffer.toString();
+		}
+
+		public void getSlotProposals(ArrayList<ICompletionProposal> proposals,
+				int offset, int length) {
+
+			Image image = new OutlineSlot(this).getImage();
+			String displayString = getSignature(true);
+
+			
+			
+			if (checkUnicity(proposals,displayString)) {
+				proposals.add(new CompletionProposal(displayString, offset, length,
+					displayString.length() - 1, image, getSignature(false),
+					null, null));
+			}
+		}
+
+		public void getSlotMatchProposals(
+				ArrayList<ICompletionProposal> proposals, int offset,
+				int length, int matchLength) {
+
+			Image image = new OutlineSlot(this).getImage();
+			String displayString = getSignature(true);
+
+			if (checkUnicity(proposals,displayString)) {
+				displayString = displayString.substring(matchLength);
+				proposals.add(new CompletionProposal(displayString, offset, length,
+					displayString.length(), image, getSignature(false), null,
+					null));
+			}
+		}
+
+		private boolean checkUnicity(ArrayList<ICompletionProposal> proposals, String str) {
+			for (int i=0; i<proposals.size(); i++) {
+				if (proposals.get(i).getDisplayString().compareTo(str) == 0) {
+					return false;
+				}
+			}
+			return true;
+		}
+		
+		public boolean match(String n) {
+			return name.startsWith(n);
+		}
+
+		public String getHoverInformation() {
+			StringBuffer buffer = new StringBuffer("<b>");
+			buffer.append(getSignature(false));
+			buffer.append("</b> <I>- ");
+			buffer.append(getPrototype().getName());
+			buffer.append("</I>");
+			if (comment != null) {
+				buffer.append("\n\n<g>");
+				buffer.append(comment);
+				buffer.append("</g>");
+			}
+			return buffer.toString();
+		}
+
+		public TextEdit[] refactorRenamePrototype(String oldName, String newName) {
+			ArrayList<TextEdit> result = new ArrayList<TextEdit>();
+			
+			// 1. rename arguments
+			for (int i=0; i<argumentList.length; i++) {
+				IType type = argumentList[i].getType();
+				Position p = argumentList[i].getPosition();
+				
+				if (p != null && type.toString().compareTo(oldName) == 0) {
+					LisaacParser parser = getPrototype().openParser();
+					parser.setPosition(p.offset+p.length);
+					parser.readCharacter(':');
+					parser.readSpace();
+					
+					int startOffset = parser.getOffset();
+					
+					result.add(new DeleteEdit(startOffset, oldName.length()));
+					result.add(new InsertEdit(startOffset, newName));
+				}
+			}
+			
+			// 2. rename result type
+			if (resultType != null && resultType.toString() != null) {
+				if (resultType.toString().compareTo(oldName) == 0) {
+					LisaacParser parser = getPrototype().openParser();
+					parser.setPosition(position.offset);
+					parser.readSlotNameFromOffset(position.offset, true);
+					parser.readCharacter(':');
+					parser.readSpace();
+					
+					int startOffset = parser.getOffset();
+					
+					result.add(new DeleteEdit(startOffset, oldName.length()));
+					result.add(new InsertEdit(startOffset, newName));
+				}
+			}
+			
+			// 3. rename code
+			if (value != null) {
+				value.refactorRenamePrototype(oldName, newName, result);
+			}
+			
+			if (result.size() > 0) {
+				return result.toArray(new TextEdit[result.size()]);
+			}
+			return null;
+		}
+	}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIP.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIP.java
new file mode 100644
index 0000000..03971e9
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIP.java
@@ -0,0 +1,93 @@
+package org.lisaac.ldt.model.lip;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class LIP {
+	
+	private static final String PROJECT_PATH_SLOT = "project_path";
+	private static final String LISAAC_PATH_SLOT = "path";
+
+	private String filename;
+	
+	/** parent lip files */
+	protected ArrayList<String> listParent = new ArrayList<String>();
+	
+	/** lip method list */
+	protected ArrayList<LIPSlotCode> listMethod = new ArrayList<LIPSlotCode>();
+	
+	/** lip data */
+	protected HashMap<String,LIPSlotData> listData = new HashMap<String,LIPSlotData>();
+
+	
+	public LIP(String filename) {
+		this.filename = filename;
+	}
+	
+	public String getFileName() {
+		return filename;
+	}
+	
+	public void addParent(String string) {
+		listParent.add(string);
+	}
+	public void addMethod(LIPSlotCode m) {
+		listMethod.add(m);
+	}
+	public void addData(LIPSlotData data) {
+		listData.put(data.getName(),data);
+	}
+	
+	public ArrayList<String> getParentList() {
+		return listParent;
+	}
+	
+	public void clearParents() {
+		listParent = null;
+	}
+	
+	public LIPSlotCode getMethod(int i) {
+		return listMethod.get(i);
+	}
+	public int getMethodCount() {
+		return listMethod.size();
+	}
+	
+	public LIPSlotCode getPublicMethod(int index) {
+		int count = 0;
+		for (int i=0; i<getMethodCount(); i++) {
+			LIPSlotCode method = getMethod(i);
+			if (method.isPublic()) {
+				if (index == count) {
+					return method;
+				}
+				count++;
+			}
+		}
+		return null;
+	}
+	
+	public int getPublicMethodCount() {
+		int count = 0;
+		for (int i=0; i<getMethodCount(); i++) {
+			LIPSlotCode method = getMethod(i);
+			if (method.isPublic()) {
+				count++;
+			}
+		}
+		return count;
+	}
+
+	public void addProjectPath(String projectPath) {
+		for (int i=0; i<getMethodCount(); i++) {
+			LIPSlotCode method = getMethod(i);
+			if (method.getName().compareTo(PROJECT_PATH_SLOT) == 0) {
+				
+				// lip code: path (projectPath);
+				method.addLastCode(new LIPCall(LISAAC_PATH_SLOT, new LIPValue(new LIPString(projectPath))));
+				break;
+			}
+		}
+	}
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPAffect.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPAffect.java
new file mode 100644
index 0000000..aa7ca69
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPAffect.java
@@ -0,0 +1,12 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPAffect extends LIPCode {
+
+	protected String name;
+	protected LIPCode value;
+	
+	public LIPAffect(String name, LIPCode value) {
+		this.name = name;
+		this.value = value;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBinary.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBinary.java
new file mode 100644
index 0000000..2c8b920
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBinary.java
@@ -0,0 +1,13 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPBinary extends LIPCode {
+
+	protected LIPCode left, right;
+	protected char operator;
+	
+	public LIPBinary(LIPCode left, char operator, LIPCode right) {
+		this.left = left;
+		this.right = right;
+		this.operator = operator;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBoolean.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBoolean.java
new file mode 100644
index 0000000..9d07d51
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPBoolean.java
@@ -0,0 +1,28 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPBoolean extends LIPConstant {
+
+	private static LIPBoolean lipTrue = new LIPBoolean(true);
+	private static LIPBoolean lipFalse = new LIPBoolean(false);
+	
+	protected boolean value;
+
+	LIPBoolean(boolean i) {
+		value = i;
+	}
+
+	public static LIPBoolean get(boolean b) {
+		if (b) {
+			return lipTrue;
+		} else {
+			return lipFalse;
+		}
+	}
+
+	public void free() {;
+	}
+
+	public String getName() {
+		return "BOOLEAN";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCall.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCall.java
new file mode 100644
index 0000000..2cd28f4
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCall.java
@@ -0,0 +1,13 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPCall extends LIPCode {
+
+	protected String name;
+	protected LIPCode argument;
+	
+	public LIPCall(String name, LIPCode argument) {
+		this.name = name;
+		this.argument = argument;
+	}
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCode.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCode.java
new file mode 100644
index 0000000..716d535
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPCode.java
@@ -0,0 +1,4 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPCode {
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPConstant.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPConstant.java
new file mode 100644
index 0000000..1e4a1f8
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPConstant.java
@@ -0,0 +1,8 @@
+package org.lisaac.ldt.model.lip;
+
+public abstract class LIPConstant {
+
+	public abstract String getName();
+	
+	public abstract void free();
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPIf.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPIf.java
new file mode 100644
index 0000000..3b378af
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPIf.java
@@ -0,0 +1,15 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPIf extends LIPCode {
+	
+	protected LIPCode condition;
+	protected LIPCode[] thenCode;
+	protected LIPCode[] elseCode;
+	
+	public LIPIf(LIPCode condition, LIPCode[] thenCode, LIPCode[] elseCode) {
+		this.condition = condition;
+		this.thenCode = thenCode;
+		this.elseCode = elseCode;
+	}
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPInteger.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPInteger.java
new file mode 100644
index 0000000..a494883
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPInteger.java
@@ -0,0 +1,23 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPInteger extends LIPConstant {
+	
+	protected int value;
+
+	LIPInteger(int i) {
+		value = i;
+	}
+
+	public static LIPInteger get(int i) {
+		// TODO storage..
+		return new LIPInteger(i);
+	}
+	
+	public void free() {
+		// TODO storage.add_last Self;
+	}
+
+	public String getName() {
+		return "INTEGER";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPPrint.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPPrint.java
new file mode 100644
index 0000000..1ceab63
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPPrint.java
@@ -0,0 +1,10 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPPrint extends LIPCode {
+
+	protected LIPCode message;
+
+	public LIPPrint(LIPCode message) {
+		this.message = message;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotCode.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotCode.java
new file mode 100644
index 0000000..e3f5e6d
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotCode.java
@@ -0,0 +1,62 @@
+package org.lisaac.ldt.model.lip;
+
+import org.lisaac.ldt.model.ILisaacModel;
+
+public class LIPSlotCode extends LIPCode {
+	protected String section;
+	
+	protected String name;
+	protected String comment;
+	
+	protected LIPSlotData argument;
+	protected LIPCode[] code;
+	
+	public LIPSlotCode(String section, String name, LIPSlotData argument, LIPCode[] code) {
+		this.section = section;
+		this.name = name;
+		this.argument = argument;
+		this.code = code;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public String getComment() {
+		return comment;
+	}
+	
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+	
+	public boolean isPublic() {
+		return section.equals(ILisaacModel.section_public);
+	}
+	
+	public String toString() {
+		StringBuffer result = new StringBuffer("  -");
+		result.append(name);
+		if (argument != null) {
+			result.append(" <");
+			result.append(argument);
+			result.append(">");
+		}
+		result.append(" :\n");
+		if (comment != null) {
+			result.append(comment);
+		} else {
+			result.append("\t Sorry, no comment (see `make.lip').\n");
+		}
+		return result.toString();
+	}
+
+	public void addLastCode(LIPCode instr) { // TODO use array list
+		
+		LIPCode[] newCode = new LIPCode[code.length + 1];
+		System.arraycopy(code, 0, newCode, 0, code.length);
+		newCode[newCode.length - 1] = instr;
+		
+		code = newCode;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotData.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotData.java
new file mode 100644
index 0000000..1c845e7
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPSlotData.java
@@ -0,0 +1,29 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPSlotData extends LIPCode {
+
+	protected String name;
+	protected LIPConstant value;
+	
+	public LIPSlotData(String name, LIPConstant value) {
+		this.name = name;
+		this.value = value;
+		// TODO check double declaration
+	}
+	
+	public String toString() {
+		StringBuffer result = new StringBuffer();
+		result.append(name);
+		result.append(":");
+		result.append(value.getName());
+		return result.toString();
+	}
+
+	public void setValue(LIPConstant value) {
+		this.value = value;
+	}
+
+	public String getName() {
+		return name;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPString.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPString.java
new file mode 100644
index 0000000..63f710b
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPString.java
@@ -0,0 +1,23 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPString extends LIPConstant {
+
+	protected String value;
+
+	LIPString(String i) {
+		value = i;
+	}
+
+	public static LIPString get(String i) {
+		// TODO storage..
+		return new LIPString(i);
+	}
+
+	public void free() {
+		// TODO storage.add_last Self;
+	}
+
+	public String getName() {
+		return "STRING";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPUnary.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPUnary.java
new file mode 100644
index 0000000..30d5135
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPUnary.java
@@ -0,0 +1,13 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPUnary extends LIPCode {
+
+	protected LIPCode value;
+	protected char operator;
+	
+	public LIPUnary(char operator, LIPCode value) {
+		this.value = value;
+		this.operator = operator;
+	}	
+	
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPValue.java b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPValue.java
new file mode 100644
index 0000000..33ad0a3
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/lip/LIPValue.java
@@ -0,0 +1,10 @@
+package org.lisaac.ldt.model.lip;
+
+public class LIPValue extends LIPCode {
+
+	protected LIPConstant value;
+
+	public LIPValue(LIPConstant value) {
+		this.value = value;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/IType.java b/editor/eclipse/src/org/lisaac/ldt/model/types/IType.java
new file mode 100644
index 0000000..6c4441f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/IType.java
@@ -0,0 +1,8 @@
+package org.lisaac.ldt.model.types;
+
+public interface IType {
+	
+	void rename(String oldName, String newName);
+	
+	public String toString();
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/ITypeMono.java b/editor/eclipse/src/org/lisaac/ldt/model/types/ITypeMono.java
new file mode 100644
index 0000000..eeeed50
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/ITypeMono.java
@@ -0,0 +1,4 @@
+package org.lisaac.ldt.model.types;
+
+public interface ITypeMono extends IType {
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeBlock.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeBlock.java
new file mode 100644
index 0000000..79ebf93
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeBlock.java
@@ -0,0 +1,57 @@
+package org.lisaac.ldt.model.types;
+
+import org.lisaac.ldt.model.ILisaacModel;
+
+/**
+ * Type block definition
+ */
+public class TypeBlock implements ITypeMono {
+
+	//private static List<TypeBlock> dico;
+	
+	protected IType typeArgument;
+	protected IType typeResult;
+	
+	TypeBlock(IType typeArgument, IType typeResult) {
+		this.typeArgument = typeArgument;
+		this.typeResult = typeResult;
+	}
+	
+	public static TypeBlock get(IType typ_arg, IType typ_res) {
+		
+		return new TypeBlock(typ_arg, typ_res);
+		
+		/*TypeBlock result=null;
+		
+		if (dico == null) {
+			dico = new ArrayList<TypeBlock>();
+		}
+		int idx = 0;
+		while (idx < dico.size() && 
+				(!dico.get(idx).getTypeArg().equals(typ_arg) || !dico.get(idx).getTypeRes().equals(typ_res))) {
+			idx++;
+		}
+		if (idx <= dico.size()-1) {
+			result = dico.get(idx);
+		} else {
+			result = new TypeBlock(typ_arg, typ_res);
+			dico.add(result);
+		}
+		return result;*/
+	}
+
+	public IType getTypeArg() {
+		return typeArgument;
+	}
+	public IType getTypeRes() {
+		return typeResult;
+	}
+	
+	public String toString() {
+		return ILisaacModel.prototype_block;
+	}
+
+	public void rename(String oldName, String newName) {
+		// TODO emit error
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeGeneric.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeGeneric.java
new file mode 100644
index 0000000..be734f1
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeGeneric.java
@@ -0,0 +1,11 @@
+package org.lisaac.ldt.model.types;
+
+public class TypeGeneric extends TypeStyle {
+
+	protected ITypeMono[] listType;
+	
+	public TypeGeneric(String name, String style, ITypeMono[] lt) {
+		super(name, style);
+		listType = lt;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeMulti.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeMulti.java
new file mode 100644
index 0000000..934e2f0
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeMulti.java
@@ -0,0 +1,54 @@
+package org.lisaac.ldt.model.types;
+
+import java.util.*;
+
+/**
+ * List of type
+ */
+public class TypeMulti implements IType {
+
+	private static List<TypeMulti> dico;
+	
+	protected ITypeMono[] listType;
+
+	public TypeMulti(ITypeMono[] lst) {
+		listType = lst;
+	}
+
+	public ITypeMono[] getTypeList() {
+		return listType;
+	}
+	
+	public IType getSubType(int index) {
+		return listType[index];
+	}
+	
+	public static IType get(ITypeMono[] lst) {
+		TypeMulti result=null;
+		
+		if (dico == null) {
+			dico = new ArrayList<TypeMulti>();
+		}
+		int idx = 0;
+		while (idx < dico.size() && !dico.get(idx).getTypeList().equals(lst)) {
+			idx++;
+		}
+		if (idx <= dico.size()-1) {
+			result = dico.get(idx);
+		} else {
+			result = new TypeMulti(lst);
+			dico.add(result);
+		}
+		return result;
+	}
+	
+	public String toString() {
+		return "(...)"; // TODO multi type print
+	}
+
+	public void rename(String oldName, String newName) {
+		for (int i=0; i<listType.length; i++) {
+			listType[i].rename(oldName, newName);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeParameter.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeParameter.java
new file mode 100644
index 0000000..9d2a1e1
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeParameter.java
@@ -0,0 +1,11 @@
+package org.lisaac.ldt.model.types;
+
+/**
+ * Parameter type for argument define.
+ */
+public class TypeParameter extends TypeSimple {
+
+	public TypeParameter(String name) {
+		super(name);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSelf.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSelf.java
new file mode 100644
index 0000000..796e821
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSelf.java
@@ -0,0 +1,39 @@
+package org.lisaac.ldt.model.types;
+
+import java.util.HashMap;
+
+public class TypeSelf implements ITypeMono {
+
+	private static HashMap<String,TypeSelf> dico;
+	
+	protected String staticType;
+
+	TypeSelf(String staticType) {
+		this.staticType = staticType;
+	}
+	
+	public static TypeSelf get(String n) {
+		TypeSelf result=null;
+		
+		if (dico == null) {
+			dico = new HashMap<String,TypeSelf>();
+		}
+		result = dico.get(n == null ? "" : n);
+		if (result == null) {
+			result = new TypeSelf(n);
+		}
+		return result;
+	}
+	
+	public String getStaticType() {
+		return staticType;
+	}
+	
+	public String toString() {      
+		return staticType;// ou SELF 
+	}
+
+	public void rename(String oldName, String newName) {
+		// TODO emit error
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSimple.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSimple.java
new file mode 100644
index 0000000..3c91bbc
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeSimple.java
@@ -0,0 +1,71 @@
+package org.lisaac.ldt.model.types;
+
+import java.util.HashMap;
+
+import org.lisaac.ldt.model.ILisaacModel;
+
+public class TypeSimple implements ITypeMono {
+
+	private static HashMap<String,TypeSimple> dico;
+
+	protected String name;
+
+	TypeSimple(String name) {
+		this.name = name;
+
+		if (dico == null) {
+			dico = new HashMap<String,TypeSimple>();
+		}
+		dico.put(name, this);
+	}
+	public String getName() {
+		return name;
+	}
+
+	protected static TypeSimple typeNull;
+	protected static TypeSimple typeVoid;
+	protected static TypeSimple typeBoolean; // for '=' operator
+
+	public static void init() {
+		typeNull = new TypeSimple(ILisaacModel.variable_null);
+		typeVoid = new TypeSimple(ILisaacModel.variable_void);
+		typeBoolean = new TypeSimple(ILisaacModel.prototype_boolean);
+	}
+
+	public static TypeSimple get(String n) {
+		TypeSimple result=null;
+
+		if (dico == null) {
+			dico = new HashMap<String,TypeSimple>();
+		}
+		result = dico.get(n);
+		if (result == null) {
+			result = new TypeSimple(n);
+		}
+		return result;
+	}
+
+	public static ITypeMono getTypeVoid() {
+		return typeVoid;
+	}
+	public static ITypeMono getTypeNull() {
+		return typeNull;
+	}
+	public static ITypeMono getTypeBoolean() {
+		return typeBoolean;
+	}
+
+	public String toString() {        // FIXME VOID pb
+		if (this.equals(typeVoid) || name.compareTo("VOID") == 0) {
+			return null; // do not print void type
+		}
+		return name;
+	}
+	public void rename(String oldName, String newName) {
+		if (name.compareTo(oldName) == 0) {
+			dico.put(name, null);
+			name = newName;
+			dico.put(name, this);
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/model/types/TypeStyle.java b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeStyle.java
new file mode 100644
index 0000000..7fdc595
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/model/types/TypeStyle.java
@@ -0,0 +1,43 @@
+package org.lisaac.ldt.model.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type with style
+ */
+public class TypeStyle extends TypeSimple {
+
+	private static List<TypeStyle> dico;
+	
+	protected String style;
+	
+	TypeStyle(String name, String style) {
+		super(name);
+		this.style = style;
+	}
+	
+	public String getStyle() {
+		return style;
+	}
+	
+	public static TypeStyle get(String n, String s) {
+		TypeStyle result=null;
+		
+		if (dico == null) {
+			dico = new ArrayList<TypeStyle>();
+		}
+		int idx = 0;
+		while (idx < dico.size() && 
+				(!dico.get(idx).getName().equals(n) || !dico.get(idx).getStyle().equals(s))) {
+			idx++;
+		}
+		if (idx <= dico.size()-1) {
+			result = dico.get(idx);
+		} else {
+			result = new TypeStyle(n, s);
+			dico.add(result);
+		}
+		return result;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineContentProvider.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineContentProvider.java
new file mode 100644
index 0000000..fafbac2
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineContentProvider.java
@@ -0,0 +1,53 @@
+package org.lisaac.ldt.outline;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class OutlineContentProvider implements ITreeContentProvider {
+
+	/**
+     * @see ITreeContentProvider#getChildren(Object)
+     */
+    public Object[] getChildren(Object parentElement) {
+        if (parentElement instanceof OutlineItem) {
+            OutlineItem outlineElement = (OutlineItem) parentElement;
+            List<OutlineItem> children = outlineElement.getChildren();
+            if (children != null) {
+            	return children.toArray(new Object[children.size()]);
+            }
+        } else if (parentElement instanceof Object[]) {
+            return ((Object[]) parentElement);
+        }
+        return new Object[0];
+    }
+
+
+	 /**
+     * @see ITreeContentProvider#getParent(Object)
+     */
+    public Object getParent(Object element) {
+        return null;
+    }
+
+	 /**
+     * @see ITreeContentProvider#hasChildren(Object)
+     */
+	public boolean hasChildren(Object element) {
+        return (getChildren(element).length > 0);
+    }
+
+	 /**
+     * @see IStructuredContentProvider#getElements(Object)
+     */
+    public Object[] getElements(Object inputElement) {
+        return getChildren(inputElement);
+    }
+
+	public void dispose() {
+	}
+
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineImages.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineImages.java
new file mode 100644
index 0000000..a07b4b0
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineImages.java
@@ -0,0 +1,27 @@
+package org.lisaac.ldt.outline;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.lisaac.ldt.LisaacPlugin;
+
+public class OutlineImages {
+	public static final Image PROTOTYPE = getImage("/icons/prototype.gif");
+	
+	public static final Image PUBLIC_SHARED = getImage("/icons/public-shared.gif");
+	public static final Image PRIVATE_SHARED = getImage("/icons/private-shared.gif");
+	public static final Image PUBLIC_NONSHARED = getImage("/icons/public-nonshared.gif");
+	public static final Image PRIVATE_NONSHARED = getImage("/icons/private-nonshared.gif");
+	
+	public static final Image KEYWORD = getImage("/icons/keyword.gif");
+	
+	public static final Image BLANK = getImage("/icons/blank.gif");
+	
+	
+	public static final String SORT_ALPHA = "/icons/alphab_sort_co.gif";
+	public static final String SORT_SECTION = "/icons/sections_co.gif";
+	
+	private static Image getImage(String path) {
+		ImageDescriptor descr = LisaacPlugin.getImageDescriptor(path);
+		return descr.createImage();
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineItem.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineItem.java
new file mode 100644
index 0000000..bb520c2
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineItem.java
@@ -0,0 +1,39 @@
+package org.lisaac.ldt.outline;
+
+import java.util.List;
+import org.eclipse.swt.graphics.Image;
+
+public abstract class OutlineItem implements Comparable<Object> {
+	
+	public static boolean showSections = true;
+	
+	protected int fstartOffset;
+	protected int fLength;
+	
+	/**
+     * Returns the image which corresponds to the element, null otherwise.
+     * @see ILabelProvider#getImage(Object)
+     */
+    public abstract Image getImage();
+    
+	
+	/**
+     * Returns the label which corresponds to the element, null otherwise.
+     * @see ILabelProvider#getText(Object)
+     */
+    public abstract String getText();
+	
+	/**
+     * Returns the children of this element.
+     */
+    public abstract List<OutlineItem> getChildren();
+
+
+	public int startOffset() {
+		return fstartOffset;
+	}
+
+	public int length() {
+		return fLength;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineLabelProvider.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineLabelProvider.java
new file mode 100644
index 0000000..51c96eb
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineLabelProvider.java
@@ -0,0 +1,41 @@
+package org.lisaac.ldt.outline;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+public class OutlineLabelProvider extends LabelProvider  {
+	
+	/**
+     * @see WorkbenchLabelProvider#getImage(Object)
+     * @param element the element for which an image is created
+     * @return the image associated to the element
+     */
+    public Image getImage(Object element) {
+        if (element instanceof OutlineItem) {
+            OutlineItem item = (OutlineItem) element;
+            Image image = item.getImage();
+            
+            if (image != null) {
+                return image;
+            }
+        }
+        return OutlineImages.BLANK;
+    }
+
+    /**
+     * @see WorkbenchLabelProvider#getText(Object)
+     * @param element the element for which a label is created
+     * @return the label associated to the element
+     */
+    public String getText(Object element) {
+        if (element instanceof OutlineItem) {
+            OutlineItem item = (OutlineItem) element;
+            return item.getText();
+        }
+        if (element != null) {
+            return element.toString();
+        } else {
+            return new String();
+        }
+    }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlinePrototype.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlinePrototype.java
new file mode 100644
index 0000000..d55daff
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlinePrototype.java
@@ -0,0 +1,57 @@
+package org.lisaac.ldt.outline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.lisaac.ldt.model.items.Prototype;
+
+public class OutlinePrototype extends OutlineItem {
+	protected String name;
+	
+	protected List<OutlineItem> sections;
+	
+	
+	public OutlinePrototype(Prototype prototype, List<OutlineItem> sections) {
+		name = prototype.getName();
+		this.sections = sections;
+	}
+	
+	/**
+     * Returns the label which corresponds to the element, null otherwise.
+     * @see ILabelProvider#getText(Object)
+     */
+    public String getText() {
+    	return name;
+    }
+    
+    public String toString() {
+    	return name;
+    }
+    
+    /**
+     * Returns the image which corresponds to the element, null otherwise.
+     * @see ILabelProvider#getImage(Object)
+     */
+    public Image getImage() {
+    	return OutlineImages.PROTOTYPE;
+    }
+    
+	public List<OutlineItem> getChildren() {
+		List<OutlineItem> result;
+		
+		if (showSections) {
+			result = sections;
+		} else {
+			result = new ArrayList<OutlineItem>();
+			for (int i=0; i<sections.size(); i++) {
+				result.addAll(((OutlineSection)sections.get(i)).slots);
+			}
+		}
+		return result;
+	}
+
+	public int compareTo(Object arg0) {
+		return 0;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSection.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSection.java
new file mode 100644
index 0000000..d45a4e1
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSection.java
@@ -0,0 +1,72 @@
+package org.lisaac.ldt.outline;
+
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.items.Section;
+import org.lisaac.ldt.model.types.ITypeMono;
+
+public class OutlineSection extends OutlineItem {
+
+	protected Section section;
+
+	protected List<OutlineItem> slots;
+	
+	public OutlineSection(Section section) {
+		this.section = section;
+		this.slots = section.getOutlineItems();
+		
+		Position position = section.getPosition();
+		
+		fstartOffset = position.getStartOffset() - 7;
+		fLength = 7;
+		//fstartOffset = position.getStartOffset();
+		//fLength = position.length();
+	}
+
+	/**
+	 * Returns the label which corresponds to the element, null otherwise.
+	 * @see ILabelProvider#getText(Object)
+	 */
+	public String getText() {
+		String result="";
+		if (section != null) {
+			if (section.getName() != null) {
+				result = section.getName();
+			} else {
+				ITypeMono[] types = section.getTypeList();
+				for (int i=0; i<types.length; i++) {
+					result += types[i];
+					if (i != types.length-1) {
+						result += ", ";
+					}
+				}
+			}
+		}
+		return result;
+	}
+
+	public String toString() {
+		return getText();
+	}
+
+	/**
+	 * Returns the image which corresponds to the element, null otherwise.
+	 * @see ILabelProvider#getImage(Object)
+	 */
+	public Image getImage() {
+		if (section != null) {
+			return OutlineImages.PRIVATE_NONSHARED;
+		}
+		return null;
+	}
+
+	public List<OutlineItem> getChildren() {
+		return slots;
+	}
+
+	public int compareTo(Object arg0) {
+		return 0;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSlot.java b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSlot.java
new file mode 100644
index 0000000..62de449
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/outline/OutlineSlot.java
@@ -0,0 +1,75 @@
+package org.lisaac.ldt.outline;
+
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.lisaac.ldt.model.Position;
+import org.lisaac.ldt.model.items.Slot;
+import org.lisaac.ldt.model.types.IType;
+
+public class OutlineSlot extends OutlineItem {
+
+	protected Slot slot;
+
+	public OutlineSlot(Slot slot) {
+		this.slot = slot;
+		
+		Position position = slot.getPosition();
+		
+		fstartOffset = position.getStartOffset();
+		fLength = position.length();
+	}
+
+	/**
+	 * Returns the label which corresponds to the element, null otherwise.
+	 * @see ILabelProvider#getText(Object)
+	 */
+	public String getText() {
+		String result=null;
+		if (slot != null) {
+			result = slot.getSignature(false);
+		}
+		return result;
+	}
+
+	public String toString() {
+		return getText();
+	}
+
+	/**
+	 * Returns the image which corresponds to the element, null otherwise.
+	 * @see ILabelProvider#getImage(Object)
+	 */
+	public Image getImage() {
+		if (slot != null) {
+			if (slot.getStyle() == '+') {
+				if (slot.getSectionId() != null && 
+						slot.getSectionId().isPrivateStyle()) {
+					return OutlineImages.PRIVATE_NONSHARED;
+				} else {
+					return OutlineImages.PUBLIC_NONSHARED;
+				}
+			} else {
+				if (slot.getSectionId() != null && 
+						slot.getSectionId().isPrivateStyle()) {
+					return OutlineImages.PRIVATE_SHARED;
+				} else {
+					return OutlineImages.PUBLIC_SHARED;
+				}
+			}
+		}
+		return null;
+	}
+
+	public List<OutlineItem> getChildren() {
+		return null;
+	}
+
+	public int compareTo(Object obj) {
+		if (obj instanceof OutlineSlot) {
+			OutlineSlot slot = (OutlineSlot) obj;
+			return getText().compareTo(slot.getText());
+		}
+		return 0;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/perspectives/LisaacPerspective.java b/editor/eclipse/src/org/lisaac/ldt/perspectives/LisaacPerspective.java
new file mode 100644
index 0000000..63cef86
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/perspectives/LisaacPerspective.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.lisaac.ldt.perspectives;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+import org.eclipse.ui.console.IConsoleConstants;
+
+/**
+ *  This class is meant to serve as an example for how various contributions 
+ *  are made to a perspective. Note that some of the extension point id's are
+ *  referred to as API constants while others are hardcoded and may be subject 
+ *  to change. 
+ */
+public class LisaacPerspective implements IPerspectiveFactory {
+
+	private IPageLayout factory;
+
+	public LisaacPerspective() {
+		super();
+	}
+
+	public void createInitialLayout(IPageLayout factory) {
+		this.factory = factory;
+		addViews();
+		addActionSets();
+		addNewWizardShortcuts();
+		addPerspectiveShortcuts();
+		addViewShortcuts();
+	}
+
+	private void addViews() {
+		// Creates the overall folder layout. 
+		// Note that each new Folder uses a percentage of the remaining EditorArea.
+		
+		IFolderLayout topLeft =
+			factory.createFolder(
+				"topLeft", //NON-NLS-1
+				IPageLayout.LEFT,
+				0.25f,
+				factory.getEditorArea());
+		topLeft.addView(IPageLayout.ID_RES_NAV);
+		
+		IFolderLayout bottom =
+			factory.createFolder(
+				"bottomRight", //NON-NLS-1
+				IPageLayout.BOTTOM,
+				0.75f,
+				factory.getEditorArea());
+		bottom.addView(IPageLayout.ID_PROBLEM_VIEW);
+		bottom.addView("org.eclipse.team.ui.GenericHistoryView"); //NON-NLS-1
+		bottom.addPlaceholder(IConsoleConstants.ID_CONSOLE_VIEW);
+		
+		IFolderLayout topRight =
+			factory.createFolder(
+				"topRight", //NON-NLS-1
+				IPageLayout.RIGHT,
+				0.80f,
+				factory.getEditorArea());
+		topRight.addView(IPageLayout.ID_OUTLINE);
+		
+		factory.addFastView("org.eclipse.team.sync.views.SynchronizeView", 0.50f); //NON-NLS-1
+	}
+
+	private void addActionSets() {
+		factory.addActionSet("org.eclipse.debug.ui.launchActionSet"); //NON-NLS-1
+		//factory.addActionSet("org.eclipse.debug.ui.debugActionSet"); //NON-NLS-1
+		//factory.addActionSet("org.eclipse.debug.ui.profileActionSet"); //NON-NLS-1
+		factory.addActionSet("org.eclipse.team.ui.actionSet"); //NON-NLS-1
+		//factory.addActionSet("org.eclipse.ant.ui.actionSet.presentation"); //NON-NLS-1
+		factory.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET); //NON-NLS-1
+	}
+
+	private void addPerspectiveShortcuts() {
+		factory.addPerspectiveShortcut("org.eclipse.team.ui.TeamSynchronizingPerspective"); //NON-NLS-1
+		factory.addPerspectiveShortcut("org.eclipse.ui.resourcePerspective"); //NON-NLS-1
+	}
+
+	private void addNewWizardShortcuts() {
+		factory.addNewWizardShortcut("org.lisaac.ldt.prototype");//NON-NLS-1
+		factory.addNewWizardShortcut("org.lisaac.ldt.wizard");//NON-NLS-1
+		factory.addNewWizardShortcut("org.eclipse.ui.wizards.new.folder");//NON-NLS-1
+		factory.addNewWizardShortcut("org.eclipse.ui.wizards.new.file");//NON-NLS-1
+	}
+
+	private void addViewShortcuts() {
+		factory.addShowViewShortcut("org.eclipse.pde.ui.DependenciesView"); //NON-NLS-1
+		factory.addShowViewShortcut("org.eclipse.team.ui.GenericHistoryView"); //NON-NLS-1
+		factory.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW);
+		factory.addShowViewShortcut(IPageLayout.ID_RES_NAV);
+		factory.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
+		factory.addShowViewShortcut(IPageLayout.ID_OUTLINE);
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacColoringPage.java b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacColoringPage.java
new file mode 100644
index 0000000..c87cbd9
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacColoringPage.java
@@ -0,0 +1,110 @@
+package org.lisaac.ldt.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.jface.preference.*;
+import org.eclipse.ui.*;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.ILisaacColor;
+
+/**
+ * Lisaac Syntax coloring preference page.
+ */
+public class LisaacColoringPage extends FieldEditorPreferencePage
+implements IWorkbenchPreferencePage {
+
+	private Group colorGroup;
+	
+	private String[][] comboValues;
+	
+	public LisaacColoringPage() {
+		super(GRID);
+		setPreferenceStore(LisaacPlugin.getDefault().getPreferenceStore());
+	}
+
+	public void createFieldEditors() {   		   	
+		colorGroup = new Group(getFieldEditorParent(),SWT.SHADOW_ETCHED_IN);
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 3;
+		colorGroup.setLayoutData(gd);
+		colorGroup.setLayout(new GridLayout(2, false));
+		colorGroup.setText(LisaacMessages.getString("LisaacColoringPage.0")); //$NON-NLS-1$
+
+		String bold = LisaacMessages.getString("LisaacColoringPage.20");
+		String italics = LisaacMessages.getString("LisaacColoringPage.21");
+		String normal = LisaacMessages.getString("LisaacColoringPage.22");
+		String underline = LisaacMessages.getString("LisaacColoringPage.23");
+		String[][] values = {
+				{normal, ILisaacColor.PREF_NORMAL}, 
+				{bold, ILisaacColor.PREF_BOLD},
+				{italics, ILisaacColor.PREF_ITALICS},
+				{underline, ILisaacColor.PREF_UNDERLINE}
+		};
+		this.comboValues = values;
+		
+		
+		addField(new ColorFieldEditor(
+				ILisaacColor.PREF_COMMENT,
+				LisaacMessages.getString("LisaacColoringPage.2"), colorGroup)); //$NON-NLS-1$
+
+		
+		createColorField(ILisaacColor.PREF_PROTOTYPE, ILisaacColor.STYLE_PROTOTYPE, 
+				LisaacMessages.getString("LisaacColoringPage.3")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_PROTOTYPE_STYLE, ILisaacColor.STYLE_PROTOTYPE_STYLE, 
+				LisaacMessages.getString("LisaacColoringPage.4")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_KEYWORD, ILisaacColor.STYLE_KEYWORD, 
+				LisaacMessages.getString("LisaacColoringPage.5")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_SLOT, ILisaacColor.STYLE_SLOT, 
+				LisaacMessages.getString("LisaacColoringPage.11")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_LOCAL_SLOT, ILisaacColor.STYLE_LOCAL_SLOT, 
+				LisaacMessages.getString("LisaacColoringPage.12")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_CHARACTER, ILisaacColor.STYLE_CHARACTER, 
+				LisaacMessages.getString("LisaacColoringPage.6")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_STRING, ILisaacColor.STYLE_STRING, 
+				LisaacMessages.getString("LisaacColoringPage.7")); //$NON-NLS-1$
+		
+		createColorField(ILisaacColor.PREF_NUMBER, ILisaacColor.STYLE_NUMBER, 
+				LisaacMessages.getString("LisaacColoringPage.8")); //$NON-NLS-1$
+
+		createColorField(ILisaacColor.PREF_OPERATOR, ILisaacColor.STYLE_OPERATOR, 
+				LisaacMessages.getString("LisaacColoringPage.9")); //$NON-NLS-1$
+		
+		
+		addField(new ColorFieldEditor(
+				ILisaacColor.PREF_EXTERNAL,
+				LisaacMessages.getString("LisaacColoringPage.10"), colorGroup));	 //$NON-NLS-1$
+	}
+
+	private void createColorField(String prefColor, String prefStyle, String tokenName) {
+		Composite c = new Composite(colorGroup, SWT.NONE);
+		c.setLayout(new GridLayout(3, false));
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 2;
+		c.setLayoutData(gd);
+		
+		Label label = new Label(c, SWT.NONE);
+		gd = new GridData(80, 15);
+		label.setLayoutData(gd);
+		label.setText(tokenName);
+		
+		Composite c2 = new Composite(c, SWT.NONE);
+		addField(new ColorFieldEditor(prefColor, "", c2)); 
+		
+		c2 = new Composite(c, SWT.NONE);
+		addField(new ComboFieldEditor(prefStyle, "", comboValues, c2)); //$NON-NLS-1$
+	}
+
+	public void init(IWorkbench workbench) {
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacEditorPage.java b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacEditorPage.java
new file mode 100644
index 0000000..9c5bd51
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacEditorPage.java
@@ -0,0 +1,53 @@
+package org.lisaac.ldt.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.jface.preference.*;
+import org.eclipse.ui.*;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+
+/**
+ * Lisaac Syntax coloring preference page.
+ */
+public class LisaacEditorPage extends FieldEditorPreferencePage
+implements IWorkbenchPreferencePage {
+
+	public LisaacEditorPage() {
+		super(GRID);
+		setPreferenceStore(LisaacPlugin.getDefault().getPreferenceStore());
+	}
+
+	public void createFieldEditors() {   
+		Composite g = getFieldEditorParent();
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 3;
+		g.setLayoutData(gd);
+	
+
+		addField(new BooleanFieldEditor(PreferenceConstants.P_LISAAC_INDENT,
+				LisaacMessages.getString("LisaacEditorPage.0"), g)); //$NON-NLS-1$
+		addField(new BooleanFieldEditor(PreferenceConstants.P_LISAAC_HOVER,
+					LisaacMessages.getString("LisaacEditorPage.1"), g)); //$NON-NLS-1$
+		addField(new BooleanFieldEditor(PreferenceConstants.P_LISAAC_FOLD,
+				LisaacMessages.getString("LisaacEditorPage.5"), g)); //$NON-NLS-1$
+		
+		Group completionGroup = new Group(g,SWT.SHADOW_ETCHED_IN);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 3;
+		gd.verticalSpan = 2;
+		completionGroup.setLayoutData(gd);
+		completionGroup.setText(LisaacMessages.getString("LisaacEditorPage.2")); //$NON-NLS-1$
+
+		addField(new BooleanFieldEditor(PreferenceConstants.P_LISAAC_COMPLETION,
+				LisaacMessages.getString("LisaacEditorPage.3"), completionGroup)); //$NON-NLS-1$
+		
+		addField(new StringFieldEditor(PreferenceConstants.P_LISAAC_COMPLETION_DELAY, 
+				LisaacMessages.getString("LisaacEditorPage.4"), completionGroup)); //$NON-NLS-1$
+	}
+	
+	public void init(IWorkbench workbench) {
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacPreferencePage.java b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacPreferencePage.java
new file mode 100644
index 0000000..c699394
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacPreferencePage.java
@@ -0,0 +1,69 @@
+package org.lisaac.ldt.preferences;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.IWorkbench;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+
+/**
+ * This class represents a preference page that
+ * is contributed to the Preferences dialog. By 
+ * subclassing <samp>FieldEditorPreferencePage</samp>, we
+ * can use the field support built into JFace that allows
+ * us to create a page that is small and knows how to 
+ * save, restore and apply itself.
+ * <p>
+ * This page is used to modify preferences only. They
+ * are stored in the preference store that belongs to
+ * the main plug-in class. That way, preferences can
+ * be accessed directly via the preference store.
+ */
+
+public class LisaacPreferencePage
+	extends FieldEditorPreferencePage
+	implements IWorkbenchPreferencePage {
+
+	public LisaacPreferencePage() {
+		super(GRID);
+		setPreferenceStore(LisaacPlugin.getDefault().getPreferenceStore());
+		setDescription(LisaacMessages.getString("LisaacPreferencePage.0")); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Creates the field editors. Field editors are abstractions of
+	 * the common GUI blocks needed to manipulate various types
+	 * of preferences. Each field editor knows how to save and
+	 * restore itself.
+	 */
+	public void createFieldEditors() {
+		addField(new StringFieldEditor(PreferenceConstants.P_LISAAC_USER, 
+					LisaacMessages.getString("LisaacPreferencePage.1"), getFieldEditorParent())); //$NON-NLS-1$
+		
+		//addField(new DirectoryFieldEditor(PreferenceConstants.P_LISAAC_PATH, 
+			//	"&Lisaac Environment Directory:", getFieldEditorParent()));
+		/*addField(
+			new BooleanFieldEditor(
+				PreferenceConstants.P_BOOLEAN,
+				"&An example of a boolean preference",
+				getFieldEditorParent()));
+
+		addField(new RadioGroupFieldEditor(
+				PreferenceConstants.P_CHOICE,
+			"An example of a multiple-choice preference",
+			1,
+			new String[][] { { "&Choice 1", "choice1" }, {
+				"C&hoice 2", "choice2" }
+		}, getFieldEditorParent()));
+		addField(
+			new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent()));
+			*/
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+	 */
+	public void init(IWorkbench workbench) {
+	}
+	
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacTemplatePage.java b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacTemplatePage.java
new file mode 100644
index 0000000..382a089
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/LisaacTemplatePage.java
@@ -0,0 +1,25 @@
+package org.lisaac.ldt.preferences;
+
+
+import org.eclipse.ui.texteditor.templates.TemplatePreferencePage;
+import org.lisaac.ldt.LisaacPlugin;
+
+
+public class LisaacTemplatePage extends TemplatePreferencePage {
+  public LisaacTemplatePage() {
+	  setPreferenceStore(LisaacPlugin.getDefault().getPreferenceStore());
+    setTemplateStore(LisaacPlugin.getDefault().getTemplateStore());
+    setContextTypeRegistry(LisaacPlugin.getDefault().getContextTypeRegistry());
+  }
+  
+  protected boolean isShowFormatterSetting() {
+      return true;
+  }
+
+  public boolean performOk() {
+      boolean ok = super.performOk();
+
+      LisaacPlugin.getDefault().savePluginPreferences();
+      return ok;
+  }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceConstants.java b/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceConstants.java
new file mode 100644
index 0000000..0756575
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceConstants.java
@@ -0,0 +1,16 @@
+package org.lisaac.ldt.preferences;
+
+/**
+ * Constant definitions for plug-in preferences
+ */
+public class PreferenceConstants {
+
+	public static final String P_LISAAC_PATH = "lisaac_path";
+	public static final String P_LISAAC_USER = "lisaac_user";
+	
+	public static final String P_LISAAC_INDENT = "lisaac_indent";
+	public static final String P_LISAAC_HOVER =  "lisaac_hover";
+	public static final String P_LISAAC_FOLD =  "lisaac_fold";
+	public static final String P_LISAAC_COMPLETION =  "lisaac_competion";
+	public static final String P_LISAAC_COMPLETION_DELAY =  "lisaac_competion_delay";
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceInitializer.java b/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..7bca019
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/preferences/PreferenceInitializer.java
@@ -0,0 +1,77 @@
+package org.lisaac.ldt.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.StringConverter;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.ILisaacColor;
+
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+	 */
+	public void initializeDefaultPreferences() {
+		IPreferenceStore store = LisaacPlugin.getDefault().getPreferenceStore();
+		//store.setDefault(PreferenceConstants.P_LISAAC_PATH, "TODO");
+
+		store.setDefault(PreferenceConstants.P_LISAAC_INDENT, true);
+		store.setDefault(PreferenceConstants.P_LISAAC_HOVER, true);
+		store.setDefault(PreferenceConstants.P_LISAAC_FOLD, true);
+		store.setDefault(PreferenceConstants.P_LISAAC_COMPLETION, true);
+		store.setDefault(PreferenceConstants.P_LISAAC_COMPLETION_DELAY, 200);
+		
+		// Colors for syntax highlighting.
+		store.setDefault(
+				ILisaacColor.PREF_COMMENT,
+				StringConverter.asString(ILisaacColor.COMMENT));
+		store.setDefault(
+				ILisaacColor.PREF_PROTOTYPE,
+				StringConverter.asString(ILisaacColor.PROTOTYPE));
+		store.setDefault(
+				ILisaacColor.PREF_PROTOTYPE_STYLE,
+				StringConverter.asString(ILisaacColor.PROTOTYPE_STYLE));
+		store.setDefault(
+				ILisaacColor.PREF_KEYWORD,
+				StringConverter.asString(ILisaacColor.KEYWORD));
+		store.setDefault(
+				ILisaacColor.PREF_SLOT,
+				StringConverter.asString(ILisaacColor.UNDEFINED));
+		store.setDefault(
+				ILisaacColor.PREF_LOCAL_SLOT,
+				StringConverter.asString(ILisaacColor.DEFAULT));
+		store.setDefault(
+				ILisaacColor.PREF_CHARACTER,
+				StringConverter.asString(ILisaacColor.CHARACTER));
+		store.setDefault(
+				ILisaacColor.PREF_STRING,
+				StringConverter.asString(ILisaacColor.STRING));
+		store.setDefault(
+				ILisaacColor.PREF_NUMBER,
+				StringConverter.asString(ILisaacColor.NUMBER));
+		store.setDefault(
+				ILisaacColor.PREF_OPERATOR,
+				StringConverter.asString(ILisaacColor.OPERATOR));
+		store.setDefault(
+				ILisaacColor.PREF_EXTERNAL,
+				StringConverter.asString(ILisaacColor.EXTERNAL));
+		
+		// styles
+		store.setDefault(ILisaacColor.STYLE_CHARACTER, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_KEYWORD, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_LOCAL_SLOT, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_NUMBER, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_OPERATOR, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_PROTOTYPE, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_PROTOTYPE_STYLE, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_SLOT, ILisaacColor.PREF_NORMAL);
+		store.setDefault(ILisaacColor.STYLE_STRING, ILisaacColor.PREF_NORMAL);
+	}
+}
+
diff --git a/editor/eclipse/src/org/lisaac/ldt/properties/LisaacProjectPropertyPage.java b/editor/eclipse/src/org/lisaac/ldt/properties/LisaacProjectPropertyPage.java
new file mode 100644
index 0000000..9d3219c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/properties/LisaacProjectPropertyPage.java
@@ -0,0 +1,101 @@
+package org.lisaac.ldt.properties;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.lisaac.ldt.model.LisaacModel;
+
+public class LisaacProjectPropertyPage extends PropertyPage {
+
+	private List pathValueList;
+	
+	/**
+	 * Constructor for SamplePropertyPage.
+	 */
+	public LisaacProjectPropertyPage() {
+		super();
+	}
+
+	private void addSection(Composite parent) {	
+		Composite composite = createDefaultComposite(parent);
+		Label label = new Label(composite, SWT.NONE);
+		label.setText("Project Path");
+
+		pathValueList = new List(composite, SWT.SINGLE | SWT.BORDER);
+		GridData gd = new GridData();
+		pathValueList.setLayoutData(gd);
+
+		Button refreshPathButton = new Button(parent, SWT.PUSH);
+		refreshPathButton.setText("Refresh Lisaac Path");
+		refreshPathButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				refreshList();
+			}
+		});
+		refreshList();
+	}
+
+	/**
+	 * @see PreferencePage#createContents(Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		composite.setLayout(layout);
+		GridData data = new GridData(GridData.FILL);
+		data.grabExcessHorizontalSpace = true;
+		composite.setLayoutData(data);
+
+		addSection(composite);
+		return composite;
+	}
+
+	private Composite createDefaultComposite(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		composite.setLayout(layout);
+
+		GridData data = new GridData();
+		data.verticalAlignment = GridData.FILL;
+		data.horizontalAlignment = GridData.FILL;
+		composite.setLayoutData(data);
+
+		return composite;
+	}
+
+	public void refreshList() {
+		pathValueList.removeAll();
+		
+		// Populate list
+		IProject project = (IProject) getElement();
+		LisaacModel model = LisaacModel.getModel(project);
+		if (model != null) {
+			model.getPathManager().refreshPath(project);
+			
+			Iterator<String> it = model.getPathManager().getPathIterator();
+			while (it.hasNext()) {
+				pathValueList.add(it.next());
+			}
+		}
+	}
+	
+	protected void performDefaults() {
+	}
+	
+	public boolean performOk() {
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderRefactor.java b/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderRefactor.java
new file mode 100644
index 0000000..dd7c1b3
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderRefactor.java
@@ -0,0 +1,94 @@
+package org.lisaac.ldt.refactor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.lisaac.ldt.model.AbstractLisaacParser;
+import org.lisaac.ldt.model.ILisaacFileVisitor;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+
+public class ChangeHeaderRefactor extends Refactoring {
+
+	private String author, bibliography, copyright, license;
+
+	private LisaacModel model;
+
+
+	public ChangeHeaderRefactor(LisaacModel model) {
+		this.model = model;
+	}
+
+	public RefactoringStatus setLicense(String license) {
+		this.license = license;
+		return isValidLicense(license);
+	} 
+
+	public void setAuthor(String author) {
+		this.author = author;
+	} 
+
+	public void setBibliography(String bibliography) {
+		this.bibliography = bibliography;
+	} 
+
+	public void setCopyright(String copyright) {
+		this.copyright = copyright;
+	} 
+
+	public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
+	throws CoreException, OperationCanceledException {
+		RefactoringStatus status = isValidLicense(license);
+		return status;
+	}
+
+	public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
+	throws CoreException, OperationCanceledException {
+		RefactoringStatus status = isValidLicense(license);
+		return status;
+	}
+
+	public Change createChange(final IProgressMonitor pm) throws CoreException,
+	OperationCanceledException {
+		final CompositeChange result = new CompositeChange(getName());
+
+		int work = model.getPathManager().getSize();
+		pm.beginTask("Updating headers...", work);
+
+		model.accept(new ILisaacFileVisitor() {
+			public void visit(Prototype prototype) {
+				if (prototype != null) {
+					Change change = prototype.refactorHeader(author, bibliography, copyright, license);
+					if (change != null) {
+						result.add(change);
+					}
+				}
+				pm.worked(1);
+			}
+		});
+		pm.done();
+		return result;
+	}
+
+	private RefactoringStatus isValidLicense(String source) {
+		RefactoringStatus status = new RefactoringStatus();
+		if (source != null) {
+			AbstractLisaacParser parser = new AbstractLisaacParser(source);
+			parser.readSpace();
+			int offset = parser.getOffset();
+			
+			if (offset < source.length()) {
+				status.addFatalError("The license must be inside Lisaac comments");
+			}
+		}
+		return status;
+	}
+
+	public String getName() {
+		return "Change Project Headers...";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderWizard.java b/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderWizard.java
new file mode 100644
index 0000000..d8c2834
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/refactor/ChangeHeaderWizard.java
@@ -0,0 +1,128 @@
+package org.lisaac.ldt.refactor;
+
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+
+class ChangeHeaderInputPage extends UserInputWizardPage {
+
+	private Text authorField;
+	private Text bibliographyField;
+	private Text copyrightField;
+	private Text licenseField;
+	
+	public ChangeHeaderInputPage() {
+		super("ChangeHeaderInputPage");
+	}
+
+	public void createControl(Composite parent) {
+		Composite result= new Composite(parent, SWT.NONE);
+		setControl(result);
+
+		GridLayout layout= new GridLayout();
+		layout.numColumns= 2;
+		result.setLayout(layout);
+
+		Label label= new Label(result, SWT.NONE);
+		label.setText("&Author :");
+		authorField = createNameField(result);
+		
+		label= new Label(result, SWT.NONE);
+		label.setText("&Bibliography :");
+		bibliographyField = createNameField(result);
+		
+		label= new Label(result, SWT.NONE);
+		label.setText("&Copyright :");
+		copyrightField = createNameField(result);
+
+		Group group = new Group(result, SWT.NONE);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.horizontalSpan = 2;
+		gd.heightHint = 100;
+		gd.verticalSpan = 2;
+		group.setLayoutData(gd);
+		group.setLayout(new GridLayout());
+		group.setText("&License :");
+		
+		licenseField = new Text(group, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+		licenseField.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		authorField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				handleInputChanged(authorField);
+			}
+		});
+		bibliographyField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				handleInputChanged(bibliographyField);
+			}
+		});
+		copyrightField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				handleInputChanged(copyrightField);
+			}
+		});
+		licenseField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				handleInputChanged(licenseField);
+			}
+		});
+		authorField.setFocus();
+	}
+
+	private Text createNameField(Composite result) {
+		Text field= new Text(result, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+		field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		return field;
+	}
+
+	void handleInputChanged(Text field) {
+		RefactoringStatus status= new RefactoringStatus();
+	
+		ChangeHeaderRefactor refactoring = (ChangeHeaderRefactor) getRefactoring();
+		if (field == authorField) {
+			refactoring.setAuthor(field.getText());
+		} else if (field == bibliographyField) {
+			refactoring.setBibliography(field.getText());
+		} else if (field == copyrightField) {
+			refactoring.setCopyright(field.getText());
+		} else {
+			status.merge(refactoring.setLicense(field.getText()));
+		}
+		setPageComplete(!status.hasError());
+		int severity= status.getSeverity();
+		String message= status.getMessageMatchingSeverity(severity);
+		if (severity >= RefactoringStatus.INFO) {
+			setMessage(message, severity);
+		} else {
+			setMessage("", NONE); //$NON-NLS-1$
+		}
+	}
+}
+
+public class ChangeHeaderWizard extends RefactoringWizard {
+	
+	ChangeHeaderInputPage page;
+	
+	public ChangeHeaderWizard(Refactoring refactoring, String title) {
+		super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
+		setDefaultPageTitle(title);
+		
+		page = new ChangeHeaderInputPage();
+	}
+
+	protected void addUserInputPages() {
+		addPage(page);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeRefactor.java b/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeRefactor.java
new file mode 100644
index 0000000..0a2800c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeRefactor.java
@@ -0,0 +1,109 @@
+package org.lisaac.ldt.refactor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.ltk.core.refactoring.Change;
+import org.eclipse.ltk.core.refactoring.CompositeChange;
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
+import org.lisaac.ldt.editors.LisaacScanner;
+import org.lisaac.ldt.model.ILisaacFileVisitor;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+
+public class RenamePrototypeRefactor extends Refactoring {
+
+	private String oldName, newName;
+
+	private LisaacModel model;
+	private IPath prototypePath;
+
+	private boolean updateReferences;
+
+	public RenamePrototypeRefactor(String oldName, LisaacModel model) {
+		this.oldName = oldName;
+		this.model = model;
+		updateReferences = true;
+	}
+
+	public RefactoringStatus setNewPrototypeName(String newName) {
+		this.newName = newName;
+
+		return isValidPrototypeName(newName);
+	}
+
+	public void setUpdateReferences(boolean update) {
+		updateReferences = update;
+	}
+
+	public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
+	throws CoreException, OperationCanceledException {
+
+		RefactoringStatus status = isValidPrototypeName(newName);
+		// ...
+		return status;
+	}
+
+	public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
+	throws CoreException, OperationCanceledException {
+		RefactoringStatus status = isValidPrototypeName(oldName);
+
+		Prototype prototype = model.getPrototype(oldName);
+		if (prototype != null) {
+			prototypePath = prototype.getWorkspacePath();
+		} else {
+			status.addFatalError("The prototype do not exist in project");
+		}
+		return status;
+	}
+
+	public Change createChange(final IProgressMonitor pm) throws CoreException,
+	OperationCanceledException {
+		final CompositeChange result = new CompositeChange(getName());
+
+		// 1. rename the prototype in section header
+		Prototype prototype = model.getPrototype(oldName);
+		result.add(prototype.refactorRenameSelf(newName));
+
+		// 2. rename occurences in the project program
+		if (updateReferences) {
+			int work = model.getPathManager().getSize();
+			pm.beginTask("Collecting occurences...", work);
+			
+			model.accept(new ILisaacFileVisitor() {
+				public void visit(Prototype prototype) {
+					if (prototype != null) {
+						Change change = prototype.refactorRenamePrototype(oldName, newName);
+						if (change != null) {
+							result.add(change);
+						}
+					}
+					pm.worked(1);
+				}
+			});
+		}
+		// 3. rename the prototype file
+		result.add(new RenameResourceChange(prototypePath, newName.toLowerCase()+".li"));
+		pm.done();
+		
+		return result;
+	}
+
+	private RefactoringStatus isValidPrototypeName(String name) {
+		RefactoringStatus status = new RefactoringStatus();
+
+		if (name.length() == 0) {
+			status.addError("Empty name");
+		} else if (! LisaacScanner.isPrototypeIdentifier(name)) {
+			status.addError("Invalid prototype name");	
+		}
+		return status;
+	}
+
+	public String getName() {
+		return "Rename Prototype...";
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeWizard.java b/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeWizard.java
new file mode 100644
index 0000000..fdb39be
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/refactor/RenamePrototypeWizard.java
@@ -0,0 +1,112 @@
+package org.lisaac.ldt.refactor;
+
+import org.eclipse.ltk.core.refactoring.Refactoring;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+
+class RenamePrototypeInputPage extends UserInputWizardPage {
+
+	Text fNameField;
+
+	String prototypeToRename;
+	
+	public RenamePrototypeInputPage(String prototypeToRename) {
+		super("RenamePrototypeInputPage");
+		this.prototypeToRename = prototypeToRename;
+	}
+
+	public void createControl(Composite parent) {
+		Composite result= new Composite(parent, SWT.NONE);
+		setControl(result);
+
+		GridLayout layout= new GridLayout();
+		layout.numColumns= 2;
+		result.setLayout(layout);
+
+		Label label= new Label(result, SWT.NONE);
+		label.setText("&New name:");
+
+		fNameField= createNameField(result);
+
+		final Button referenceButton= new Button(result, SWT.CHECK);
+		referenceButton.setText("&Update references");
+		GridData data= new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan= 2;
+		data.verticalIndent= 2;
+		referenceButton.setLayoutData(data);
+
+		fNameField.setText(prototypeToRename);
+
+		fNameField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent event) {
+				handleInputChanged();
+			}
+		});
+
+		referenceButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				RenamePrototypeRefactor refactoring = (RenamePrototypeRefactor) getRefactoring();
+				refactoring.setUpdateReferences(referenceButton.getSelection());
+			}
+		});
+
+		referenceButton.setSelection(true);
+
+		fNameField.setFocus();
+		fNameField.selectAll();
+		handleInputChanged();
+	}
+
+	private Text createNameField(Composite result) {
+		Text field= new Text(result, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+		field.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		return field;
+	}
+
+	void handleInputChanged() {
+		RefactoringStatus status= new RefactoringStatus();
+	
+		RenamePrototypeRefactor refactoring = (RenamePrototypeRefactor) getRefactoring();
+		status.merge(refactoring.setNewPrototypeName(fNameField.getText()));
+		
+		setPageComplete(!status.hasError());
+		int severity= status.getSeverity();
+		String message= status.getMessageMatchingSeverity(severity);
+		if (severity >= RefactoringStatus.INFO) {
+			setMessage(message, severity);
+		} else {
+			setMessage("", NONE); //$NON-NLS-1$
+		}
+	}
+
+}
+
+public class RenamePrototypeWizard extends RefactoringWizard {
+	
+	RenamePrototypeInputPage page;
+	
+	public RenamePrototypeWizard(Refactoring refactoring, String prototypeToRename, String title) {
+		super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
+		setDefaultPageTitle(title);
+		
+		page = new RenamePrototypeInputPage(prototypeToRename);
+	}
+
+	protected void addUserInputPages() {
+		addPage(page);
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/templates/LisaacContextType.java b/editor/eclipse/src/org/lisaac/ldt/templates/LisaacContextType.java
new file mode 100644
index 0000000..8619a7f
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/templates/LisaacContextType.java
@@ -0,0 +1,28 @@
+package org.lisaac.ldt.templates;
+
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+public class LisaacContextType extends TemplateContextType {
+	/** This context's id */
+	public static final String ID_CONTEXT_TYPE= "org.lisaac.ldt.contexttype"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new Lisaac context type.
+	 */
+	public LisaacContextType() {
+		addGlobalResolvers();
+	}
+
+	private void addGlobalResolvers() {
+		addResolver(new GlobalTemplateVariables.Cursor());
+		addResolver(new GlobalTemplateVariables.WordSelection());
+		addResolver(new GlobalTemplateVariables.LineSelection());
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new GlobalTemplateVariables.Date());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/templates/LisaacTemplateProcessor.java b/editor/eclipse/src/org/lisaac/ldt/templates/LisaacTemplateProcessor.java
new file mode 100644
index 0000000..1321bc6
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/templates/LisaacTemplateProcessor.java
@@ -0,0 +1,48 @@
+package org.lisaac.ldt.templates;
+
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Image;
+import org.lisaac.ldt.LisaacPlugin;
+
+public class LisaacTemplateProcessor extends TemplateCompletionProcessor {
+
+
+	/**
+	 * Simply return all templates.
+	 *
+	 * @param contextTypeId the context type, ignored in this implementation
+	 * @return all templates
+	 */
+	protected Template[] getTemplates(String contextTypeId) {
+		return LisaacPlugin.getDefault().getTemplateStore().getTemplates();
+	}
+
+	/**
+	 * Return the XML context type that is supported by this plug-in.
+	 *
+	 * @param viewer the viewer, ignored in this implementation
+	 * @param region the region, ignored in this implementation
+	 * @return the supported XML context type
+	 */
+	protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) {
+		return LisaacPlugin.getDefault().getContextTypeRegistry().getContextType(LisaacContextType.ID_CONTEXT_TYPE);
+	}
+
+	/**
+	 * Always return the default image.
+	 *
+	 * @param template the template, ignored in this implementation
+	 * @return the default template image
+	 */
+	protected Image getImage(Template template) {
+		ImageDescriptor descr = LisaacPlugin.getImageDescriptor("icons/template.gif");
+		return descr.createImage();
+	}
+
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/views/ConsoleFactory.java b/editor/eclipse/src/org/lisaac/ldt/views/ConsoleFactory.java
new file mode 100644
index 0000000..974b4bc
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/views/ConsoleFactory.java
@@ -0,0 +1,54 @@
+package org.lisaac.ldt.views;
+
+import java.util.Arrays;
+
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleFactory;
+import org.eclipse.ui.console.IConsoleListener;
+import org.eclipse.ui.console.IConsoleManager;
+
+public class ConsoleFactory implements IConsoleFactory{
+
+	/** The console created by this factory if any. */
+	private static LisaacConsole openConsole = null;
+
+	public ConsoleFactory() {
+
+		ConsolePlugin.getDefault().getConsoleManager().addConsoleListener(new IConsoleListener() {
+			public void consolesAdded(IConsole[] consoles) {
+			}
+			public void consolesRemoved(IConsole[] consoles) {
+				if (Arrays.asList(consoles).contains(openConsole)) {
+					openConsole = null;
+				}
+			}
+		});
+	}
+
+	/**
+	 * Opens a new console.
+	 */
+	public void openConsole() {
+		createConsole();
+	}
+
+	public static void createConsole() {
+		IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager();
+
+		if (openConsole == null) {
+			openConsole = new LisaacConsole();
+			openConsole.initializeDocument();
+
+			consoleManager.addConsoles(new IConsole[] {openConsole});
+		}
+		consoleManager.showConsoleView(openConsole);
+	}
+	
+	public static LisaacConsole getConsole() {
+		if (openConsole == null) {
+			createConsole();
+		}
+		return openConsole;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/views/LisaacConsole.java b/editor/eclipse/src/org/lisaac/ldt/views/LisaacConsole.java
new file mode 100644
index 0000000..628bffb
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/views/LisaacConsole.java
@@ -0,0 +1,27 @@
+package org.lisaac.ldt.views;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.ui.console.IOConsole;
+import org.lisaac.ldt.LisaacMessages;
+
+public class LisaacConsole extends IOConsole  {
+
+	public final static String CONSOLE_TYPE = "lisaacConsole"; //$NON-NLS-1$
+	public static final String CONSOLE_FONT= "org.eclipse.debug.ui.consoleFont"; //$NON-NLS-1$
+
+	public LisaacConsole() {
+		super(LisaacMessages.getString("LisaacConsole.1"), CONSOLE_TYPE, null, true); //$NON-NLS-1$
+
+		Font font = JFaceResources.getFont(CONSOLE_FONT);
+		setFont(font);
+	}
+
+	/**
+	 * Set the document's initial contents.
+	 * Called by ConsoleFactory.
+	 */
+	void initializeDocument() {
+		getDocument().set(""); //$NON-NLS-1$
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/views/LisaacOutlineView.java b/editor/eclipse/src/org/lisaac/ldt/views/LisaacOutlineView.java
new file mode 100644
index 0000000..17f9dd8
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/views/LisaacOutlineView.java
@@ -0,0 +1,268 @@
+package org.lisaac.ldt.views;
+
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.editors.LisaacEditor;
+import org.lisaac.ldt.model.LisaacModel;
+import org.lisaac.ldt.model.items.Prototype;
+import org.lisaac.ldt.outline.OutlineContentProvider;
+import org.lisaac.ldt.outline.OutlineImages;
+import org.lisaac.ldt.outline.OutlineItem;
+import org.lisaac.ldt.outline.OutlineLabelProvider;
+
+public class LisaacOutlineView extends ContentOutlinePage implements IDocumentListener {
+
+	/** the delay before the outline view is updated. */
+	private static final long UPDATE_DELAY = 1000; 
+
+	/** the document provider. */
+	private IDocumentProvider documentProvider;
+
+	/** the text editor. */
+	private AbstractDecoratedTextEditor textEditor;
+
+	/** the current document. */
+	private IDocument document;
+
+	/** the update timer which manages update task scheduling. */
+	private Timer updateTimer;
+
+
+	public LisaacOutlineView(IDocumentProvider documentProvider, AbstractDecoratedTextEditor textEditor) {
+		super();
+		this.documentProvider = documentProvider;
+		this.textEditor = textEditor;
+		createTimer();
+	}
+
+	/**
+	 * @see ContentOutlinePage#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {
+		super.createControl(parent);
+
+		TreeViewer viewer = getTreeViewer();
+		viewer.setContentProvider(new OutlineContentProvider());
+		viewer.setLabelProvider(new OutlineLabelProvider());
+		viewer.addSelectionChangedListener(this);
+		createActions();
+
+		document = getDocument();
+		if (document != null) {
+			document.addDocumentListener(this);
+		}
+		update();
+	}
+
+	private void createActions() {
+
+		//---- Sort by name
+		Action sortByName = new Action("Sort by name", IAction.AS_CHECK_BOX) {
+
+			ViewerSorter sortByNameSorter;
+
+			public void setAlphaSort(boolean doSort) {
+				if (sortByNameSorter == null) {
+					sortByNameSorter = new ViewerSorter() {
+						public int compare(Viewer viewer, Object e1, Object e2) {
+							return ((Comparable) e1).compareTo(e2);
+						}
+					};
+				}
+				getTreeViewer().setSorter(doSort ? sortByNameSorter : null);
+			}
+			
+			public void run() {
+				setAlphaSort(isChecked());
+			}
+		};
+		sortByName.run();
+		
+		//---- Sort by name
+		Action sortBySection= new Action("Sort by Section", IAction.AS_CHECK_BOX) {
+			public void run() {
+				OutlineItem.showSections = isChecked();
+				getTreeViewer().refresh();
+				getTreeViewer().expandAll();
+			}
+		};
+		sortBySection.setChecked(true);
+		
+		try {
+			sortByName.setImageDescriptor(LisaacPlugin.getImageDescriptor(OutlineImages.SORT_ALPHA));
+			sortBySection.setImageDescriptor(LisaacPlugin.getImageDescriptor(OutlineImages.SORT_SECTION));
+		} catch (Exception e) {
+		}
+
+		// Add actions to the toolbar
+		IActionBars actionBars = getSite().getActionBars();
+		IToolBarManager toolbarManager = actionBars.getToolBarManager();
+		toolbarManager.add(sortByName);
+		toolbarManager.add(sortBySection);
+		
+		/* IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(new OutlineHideCommentsAction(this, imageCache));
+        menuManager.add(new OutlineHideImportsAction(this, imageCache));
+        menuManager.add(new OutlineHideMagicObjectsAction(this, imageCache));
+        menuManager.add(new OutlineHideFieldsAction(this, imageCache));
+        menuManager.add(new OutlineHideNonPublicMembersAction(this, imageCache));
+        menuManager.add(new OutlineHideStaticMethodsAction(this, imageCache));
+		 */
+	}
+
+	/**
+	 * Returns the document attached to this view.
+	 * @return the document attached to this view
+	 */
+	public IDocument getDocument() {
+		if (document == null) {
+			document = documentProvider.getDocument(textEditor.getEditorInput());
+		}
+		return document;
+	}
+
+	/**
+	 * Fired when Outline selection changed
+	 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+	 */
+	public void selectionChanged(SelectionChangedEvent event) {
+		ISelection abstractSelection = event.getSelection();
+		IDocument document = getDocument();
+
+		if (document != null) {   
+			if ((abstractSelection != null) && (abstractSelection instanceof TreeSelection)) {
+				TreeSelection selection = (TreeSelection) abstractSelection;
+				Object selectedElement = selection.getFirstElement();
+
+				if ((selectedElement != null) && (selectedElement instanceof OutlineItem)) {
+					OutlineItem item = (OutlineItem) selectedElement;
+					// select current outline item in editor
+					textEditor.selectAndReveal(item.startOffset(), item.length());
+				}
+			}
+		}
+	}
+
+	/**
+	 * Sends the input to the tree viewer.
+	 * @param input the input
+	 */
+	public void setInput(Object input) {
+		if (!getTreeViewer().getControl().isDisposed()) {
+			getTreeViewer().setInput(input);
+			getTreeViewer().expandAll();
+		}
+	}
+
+	public void documentAboutToBeChanged(DocumentEvent event) {
+	}
+	/**
+	 * Notify document modifications.
+	 */
+	public void documentChanged(DocumentEvent event) {
+		document = event.getDocument();
+		update();
+	}
+
+	/**
+	 * Get the outline data.
+	 * 
+	 * @param project Current project
+	 * @param filename File to outline
+	 * @return List of outline items
+	 * @throws CoreException 
+	 */
+	public List<OutlineItem> getSourceOutline(IProject project, String filename) throws CoreException {
+		LisaacModel model = LisaacModel.getModel(project);
+		if (model != null) {
+			Prototype prototype = model.getPrototype(LisaacModel.extractPrototypeName(filename));
+			
+			if (prototype != null) {
+				return prototype.getOutlineItems();
+			}
+		}
+		return null;
+	}
+
+	private void createTimer() {
+		updateTimer = new Timer("org.lisaac.ldt.outlinetimer");
+	}
+
+	/**
+	 * Updates the outline content view.
+	 */
+	public void update() {
+		updateTimer.cancel();
+		updateTimer.purge();
+		createTimer();
+
+		OutlineUpdateTask updateTask = new OutlineUpdateTask();
+		updateTimer.schedule(updateTask, UPDATE_DELAY);
+	}
+
+	/**
+	 * This class is in charge of updating the outline.
+	 */
+	class OutlineUpdateTask extends TimerTask {
+		public OutlineUpdateTask() {
+			super();
+		}
+
+		/**
+		 * Updates the outline content view.
+		 * @see TimerTask#run()
+		 */
+		public void run() {
+			final IDocument document = getDocument();
+			Display display = PlatformUI.getWorkbench().getDisplay();
+
+			if (document != null && (textEditor instanceof LisaacEditor)) {
+				IProject project = ((LisaacEditor) textEditor).getProject();
+				String filename = ((LisaacEditor) textEditor).getFileName();
+				
+				try {
+					final List<OutlineItem> items = getSourceOutline(project, filename);
+
+					display.asyncExec(new Runnable() {
+						public void run() {
+							if (items != null) {
+								setInput(items.toArray(new OutlineItem[items.size()]));
+								//
+								((LisaacEditor) textEditor).refreshPresentation();
+								//
+							} 
+						}
+					});
+				} catch (CoreException e)  {
+				}
+			}
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizard.java b/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizard.java
new file mode 100644
index 0000000..e371f07
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizard.java
@@ -0,0 +1,155 @@
+package org.lisaac.ldt.wizards;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.IDE;
+
+public abstract class AbstractNewFileWizard extends Wizard implements INewWizard {
+
+	private AbstractNewFileWizardPage page;
+
+	private IStructuredSelection selection;
+
+	
+	public AbstractNewFileWizard() {
+		super();
+		setNeedsProgressMonitor(true);
+	}
+
+	abstract protected AbstractNewFileWizardPage createPage();
+	
+	/**
+	 * Adding the page to the wizard.
+	 */
+	public void addPages() {
+		page = createPage();
+		addPage(page);
+	}
+	
+	/**
+	 * This method is called when 'Finish' button is pressed in the wizard. We
+	 * will create an operation and run it using wizard as execution context.
+	 */
+	public boolean performFinish() {
+		final String containerName = page.getContainerName();
+		final String fileName = getFileNameWithExtension();
+		final InputStream stream = page.getInitialContents(fileName);
+		
+		IRunnableWithProgress op = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor)
+					throws InvocationTargetException {
+				try {
+					doFinish(containerName, fileName, stream, monitor);
+				} catch (CoreException e) {
+					throw new InvocationTargetException(e);
+				} finally {
+					monitor.done();
+				}
+			}
+		};
+		try {
+			getContainer().run(true, false, op);
+		} catch (InterruptedException e) {
+			return false;
+		} catch (InvocationTargetException e) {
+			Throwable realException = e.getTargetException();
+			MessageDialog.openError(getShell(), 
+					"Wizard error", realException.getMessage());
+			return false;
+		}
+		return true;
+	}
+	
+	/**
+	 * The worker method. It will find the container, create the file if missing
+	 * or just replace its contents, and open the editor on the newly created
+	 * file.
+	 */
+	private void doFinish(String containerName, String fileName, InputStream stream,
+			IProgressMonitor monitor) throws CoreException {
+		// create a sample file
+		monitor.beginTask("Creating File " + fileName, 2);
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IResource resource = root.findMember(new Path(containerName));
+		if (!resource.exists() || !(resource instanceof IContainer)) {
+			throwCoreException("Container does not exist.");
+		}
+		IContainer container = (IContainer) resource;
+		final IFile file = container.getFile(new Path(fileName));
+
+		try {		
+			if (file.exists()) {
+				file.setContents(stream, true, true, monitor);
+			} else {
+				file.create(stream, true, monitor);
+			}
+			stream.close();
+		} catch (IOException e) {
+		}
+		monitor.worked(1);
+		monitor.setTaskName("Opening file...");
+				
+		getShell().getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				IWorkbenchPage page = PlatformUI.getWorkbench()
+						.getActiveWorkbenchWindow().getActivePage();
+				try {
+					IDE.openEditor(page, file, true);
+				} catch (PartInitException e) {
+				}
+			}
+		});
+		monitor.worked(1);
+	}
+	
+	public String getFileNameWithExtension() {
+		String filename = page.getFileName();
+		int index = filename.lastIndexOf('.');
+		if (index == -1) {
+			filename += page.getFileExtension();
+		}
+		return filename;
+	}
+
+
+	private void throwCoreException(String message) throws CoreException {
+		IStatus status = new Status(IStatus.ERROR,
+				"org.lisaac.ldt.wizards", IStatus.OK, message, null);
+		throw new CoreException(status);
+	}
+	
+	/**
+	 * We will accept the selection in the workbench to see if we can initialize
+	 * from it.
+	 * 
+	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
+	 */
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		this.selection = selection;
+	}
+	
+	protected IStructuredSelection getSelection() {
+		return selection;
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizardPage.java b/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizardPage.java
new file mode 100644
index 0000000..a53312e
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/wizards/AbstractNewFileWizardPage.java
@@ -0,0 +1,259 @@
+package org.lisaac.ldt.wizards;
+
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+import org.lisaac.ldt.LisaacMessages;
+
+
+public abstract class AbstractNewFileWizardPage extends WizardPage {
+
+	/** initial source folder selection */
+	private IStructuredSelection selection;
+
+	/** source folder path */
+	private Text containerText;
+
+	/** file name */
+	private Text fileText;
+	
+	/** file extension */
+	private String fileExtension = ""; //$NON-NLS-1$
+
+	
+	protected AbstractNewFileWizardPage(String pageName, IStructuredSelection selection) {
+		super(pageName);
+		this.selection = selection;
+		setPageComplete(false);
+	}
+
+	public String getContainerName() {
+		return containerText.getText();
+	}
+
+	public String getFileName() {
+		return fileText.getText();
+	}
+	
+	public String getFileExtension() {
+		return fileExtension;
+	}
+	
+	/**
+	 * set the extension of files created with this wizard.
+	 */
+	protected void setFileExtension(String ext) {
+		fileExtension = ext;
+	}
+	
+	/**
+	 * Content File Initialisation.
+	 */
+	abstract protected InputStream getInitialContents(String filename);
+	
+	
+	/**
+	 * @see IDialogPage#createControl(Composite)
+	 */
+	public void createControl(Composite parent) {
+		Composite container = new Composite(parent, SWT.NULL);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 3;
+		container.setLayout(layout);
+		
+		Label label = new Label(container, SWT.NULL);
+		label.setText(LisaacMessages.getString("AbstractNewFileWizardPage_1"));
+
+		containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+		containerText.setLayoutData(gd);
+		containerText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				dialogChanged();
+			}
+		});
+		Button button = new Button(container, SWT.PUSH);
+		button.setText(LisaacMessages.getString("AbstractNewFileWizardPage_2"));
+		button.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleBrowse();
+			}
+		});
+		
+		label = new Label(container, SWT.NULL);
+		label.setText(LisaacMessages.getString("AbstractNewFileWizardPage_3"));
+
+		fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 2;
+		fileText.setLayoutData(gd);
+		fileText.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				dialogChanged();
+			}
+		});
+		
+		label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
+		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gd.horizontalSpan = 3;
+		label.setLayoutData(gd);
+		
+		//
+		createAdvancedControls(container);
+		//
+		initialize();
+		dialogChanged();
+		setControl(container);
+	}
+	
+	protected void createAdvancedControls(Composite parent) {
+		// should be override
+	}
+	
+	/**
+	 * Tests if the current workbench selection is a suitable container to use.
+	 */
+	private void initialize() {
+		if (selection != null && selection.isEmpty() == false
+				&& selection instanceof IStructuredSelection) {
+			IStructuredSelection ssel = (IStructuredSelection) selection;
+			if (ssel.size() > 1)
+				return;
+			Object obj = ssel.getFirstElement();
+			if (obj instanceof IResource) {
+				IContainer container;
+				if (obj instanceof IContainer)
+					container = (IContainer) obj;
+				else
+					container = ((IResource) obj).getParent();
+				containerText.setText(container.getFullPath().toString());
+				fileText.setFocus();
+			}
+		}
+		fileText.setText(getInitialFileName());
+	}
+
+	protected abstract String getInitialFileName();
+	
+	/**
+	 * Uses the standard container selection dialog to choose the new value for
+	 * the container field.
+	 */
+
+	private void handleBrowse() {
+		ContainerSelectionDialog dialog = new ContainerSelectionDialog(
+				getShell(), ResourcesPlugin.getWorkspace().getRoot(), false,
+				LisaacMessages.getString("AbstractNewFileWizardPage_4"));
+		if (dialog.open() == ContainerSelectionDialog.OK) {
+			Object[] results = dialog.getResult();
+			if (results.length == 1) {
+				Object result = results[0];
+				if (result instanceof IPath) {
+					IPath ipath = (IPath) result;
+					containerText.setText(ipath.toString());
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Ensures that both text fields are set.
+	 */
+	private void dialogChanged() {
+		String container = getContainerName();
+		String fileName = getFileName();
+
+		if (container.length() == 0) {
+			updateStatus(LisaacMessages.getString("AbstractNewFileWizardPage_5"));
+			return;
+		}
+		if (fileName.length() == 0) {
+			updateStatus(LisaacMessages.getString("AbstractNewFileWizardPage_6"));
+			return;
+		}
+		// TODO check container -> source folder !
+		updateStatus(null);
+	}
+
+	private void updateStatus(String message) {
+		setErrorMessage(message);
+		setPageComplete(message == null);
+	}
+	
+	/**
+	 * @see WizardPage#isPageComplete()
+	 */
+	public boolean isPageComplete() {
+		return !checkFolderForExistingFile() && super.isPageComplete();
+	}
+
+	/**
+	 * Finds the current directory where the file should be created
+	 */
+	protected boolean checkFolderForExistingFile() {
+		IContainer container = getFileContainer();
+		if (container != null) {
+			IResource file = container.getFile(new Path(fileText.getText()
+					.trim()));
+			if (file != null && file.exists()) {
+				this.setErrorMessage(LisaacMessages.getString("AbstractNewFileWizardPage_7"));
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private IContainer getFileContainer() {
+		if (containerText.getText() != null) {
+			IPath containerPath = new Path(containerText.getText().trim());
+			IContainer container = null;
+			if (containerPath.segmentCount() > 1) {
+				container = ResourcesPlugin.getWorkspace().getRoot().getFolder(
+						containerPath);
+			} else {
+				if (containerPath.segmentCount() == 1) {
+					// this is a project
+					container = ResourcesPlugin.getWorkspace().getRoot()
+							.getProject(containerText.getText().trim());
+				}
+			}
+			if (container != null && container.exists()) {
+				return container;
+			}
+		}
+		return null;
+	}
+	
+	public void setVisible(boolean visible) {
+		super.setVisible(visible);
+		if (visible) {
+			String fileName = fileText.getText().trim();
+			if (getFileContainer() != null
+					&& fileName.equalsIgnoreCase(getInitialFileName())) {
+				fileText.setFocus();
+				fileText.setText(fileName);
+				fileText.setSelection(0, fileName.length()
+						- (new Path(getInitialFileName())).getFileExtension()
+								.length() - 1);
+			}
+		}
+	}
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/wizards/InputParentDialog.java b/editor/eclipse/src/org/lisaac/ldt/wizards/InputParentDialog.java
new file mode 100644
index 0000000..66afe2a
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/wizards/InputParentDialog.java
@@ -0,0 +1,72 @@
+package org.lisaac.ldt.wizards;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.lisaac.ldt.model.ILisaacModel;
+
+public class InputParentDialog extends InputDialog {
+	
+	private String parentType;
+	
+	public InputParentDialog(Shell parentShell, String dialogTitle) {
+		super(parentShell, dialogTitle, "Parent prototype name", "", new IInputValidator() {
+			public String isValid(String newText) {
+				if (newText.length() == 0) {
+					return "Empty name";
+				}
+				String correct = newText.toUpperCase();
+				if (newText.compareTo(correct) != 0) {
+					return "Invalid prototype name";
+				}
+				return null;
+			}
+		});
+	}
+
+	 /*
+     * (non-Javadoc) Method declared on Dialog.
+     */
+    protected Control createDialogArea(Composite parent) {
+    	Composite c = (Composite) super.createDialogArea(parent);
+    	
+    	Label label = new Label(c, SWT.NONE);
+    	label.setText("Choose Parent inheritance type");
+    
+    	String[] values = {
+    			ILisaacModel.inherit_shared,
+    			ILisaacModel.inherit_nonshared,
+    			ILisaacModel.inherit_shared_expanded,
+    			ILisaacModel.inherit_nonshared_expanded
+    	};
+    	parentType = values[0];
+    	
+    	final Combo combo = new Combo(c, SWT.NONE);
+    	combo.setItems(values);
+    	combo.select(0);
+    	combo.addSelectionListener(new SelectionListener() {
+			public void widgetDefaultSelected(SelectionEvent e) {
+				widgetSelected(e);
+			}
+			public void widgetSelected(SelectionEvent e) {
+				parentType = combo.getText();
+			}
+    	});
+    	return c;
+    }
+    
+    public String getParentName() {
+    	return getValue();
+    }
+    
+    public String getParentType() {
+    	return parentType;
+    }
+}
diff --git a/editor/eclipse/src/org/lisaac/ldt/wizards/NewProjectWizard.java b/editor/eclipse/src/org/lisaac/ldt/wizards/NewProjectWizard.java
new file mode 100644
index 0000000..0291659
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/wizards/NewProjectWizard.java
@@ -0,0 +1,248 @@
+package org.lisaac.ldt.wizards;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.builder.LisaacNature;
+import org.lisaac.ldt.editors.LisaacResourceDecorator;
+import org.lisaac.ldt.model.LisaacModel;
+
+
+public class NewProjectWizard extends Wizard implements INewWizard {
+
+	NewProjectWizardPage mainPage;
+
+	public NewProjectWizard() {
+		super();
+		setNeedsProgressMonitor(true);
+	}
+
+	// called with the 'finish' button
+	public boolean performFinish() {
+		final String name;
+		final IPath path;
+		IRunnableWithProgress op = null;
+		try {
+			name = mainPage.getProjectName();
+			path = mainPage.getLocationPath();
+			//lisaacPath = mainPage.getLisaacPath();
+			op = new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) throws InvocationTargetException {
+					try {						
+						doFinish(name, path, monitor);
+					} catch (CoreException e) {
+						throw new InvocationTargetException(e);
+					} finally {
+						monitor.done();
+					}
+				}
+			};
+		} catch (NullPointerException e1) {
+			e1.printStackTrace();
+		}
+
+		try {
+			getContainer().run(false, false, op);
+		} catch (InterruptedException e) {
+			return false;
+		} catch (InvocationTargetException e) {
+			Throwable realException = e.getTargetException();
+			MessageDialog.openError(getShell(), "Error !", realException.getMessage()); //$NON-NLS-1$
+			return false;
+		}
+		return true;
+	}
+
+	private void doFinish(String projectName, IPath nomRep, IProgressMonitor monitor)
+	throws CoreException
+	{
+		monitor.beginTask("Project Creation " + projectName, 4); //$NON-NLS-1$
+
+		// get project root
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+		try {
+			IProject project = root.getProject(projectName);
+			if (project.exists() && !project.isOpen()) {
+				project.open(monitor);
+			} else {
+				project.create(monitor);
+				project.open(monitor);
+			}
+			try {
+
+				// set lisaac builder
+				LisaacNature nature = new LisaacNature();
+				nature.setProject(project);
+				nature.configure();
+
+				// set lisaac nature
+				IProjectDescription description = project.getDescription();
+				description.setNatureIds(new String[]{LisaacNature.NATURE_ID});
+				project.setDescription(description, monitor);
+
+			} catch (CoreException e) {
+				// Something went wrong
+			}
+			monitor.worked(1);
+
+			//
+			new LisaacModel(project);
+			//
+
+			monitor.worked(1);
+
+			// create make file for project
+			IFile lipFile = project.getFile("make.lip"); //$NON-NLS-1$
+			if (! lipFile.exists()) {
+				lipFile.create(new ByteArrayInputStream(getLipStream(project)), false, monitor);
+			}
+
+			// create default folder & files in project
+			IFolder src = project.getFolder("src"); //$NON-NLS-1$
+			if (! src.exists()) {
+				src.create(false, true, monitor);
+				src.setPersistentProperty(
+						new QualifiedName("", LisaacResourceDecorator.SOURCE_FOLDER_PROPERTY),
+				"true");
+			}
+
+			monitor.worked(1);
+			IFile mainPrototype = src.getFile(projectName.toLowerCase()+".li"); //$NON-NLS-1$
+			if (! mainPrototype.exists()) {
+				mainPrototype.create(new ByteArrayInputStream(getMainPrototypeStream(projectName)), false, monitor);
+			}
+			IFolder bin = project.getFolder("bin"); //$NON-NLS-1$
+			if (! bin.exists()) {
+				bin.create(false,true,monitor);
+			}
+			monitor.worked(1);
+			IFolder lib = project.getFolder("lib"); //$NON-NLS-1$
+			if (! lib.exists()) {
+				// create link to lib
+				/*IPath location = new Path(lisaacPath+"/lib");// FIXME path delimiter
+				lib.createLink(location, IResource.NONE, monitor);*/
+				lib.create(false,true,monitor);
+				lib.setPersistentProperty(
+						new QualifiedName("", LisaacResourceDecorator.LIB_PROPERTY),
+				"true");
+			}
+		} catch (IOException e) {
+			MessageDialog.openError(getShell(), "Project creation Error !", e.getMessage());	 //$NON-NLS-1$
+		} catch (CoreException e) {
+			MessageDialog.openError(getShell(), "Project settings Error !", e.getMessage()); //$NON-NLS-1$
+		}
+		monitor.done();
+	}
+
+
+	public byte[] getMainPrototypeStream(String projectName) throws IOException {
+		String contents = "\nSection Header\n\n"; //$NON-NLS-1$
+		contents +=	"  + name    := "+projectName.toUpperCase()+";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		contents +=	"  - comment := \"Main Prototype\";\n";  //$NON-NLS-1$
+		contents +=	"\nSection Inherit\n\n";  //$NON-NLS-1$
+		contents += "  - parent_object:OBJECT := OBJECT;\n"; //$NON-NLS-1$
+		contents +=	"\nSection Public\n\n";  //$NON-NLS-1$
+		contents += "  - main <- \n"; //$NON-NLS-1$
+		contents += "  // Main entry point.\n"; //$NON-NLS-1$
+		contents += "  (\n\n"; //$NON-NLS-1$
+		contents += "    \n"; //$NON-NLS-1$
+		contents += "  );\n"; //$NON-NLS-1$
+		return contents.getBytes();
+	}
+
+	public byte[] getLipStream(IProject project) throws IOException {
+		String contents = "//\n// `"+project.getName()+"`  LIsaac Project file\n//"; //$NON-NLS-1$ //$NON-NLS-2$
+		contents += "\nSection Inherit\n\n"; //$NON-NLS-1$
+		contents += "  + parent:STRING;\n"; //$NON-NLS-1$
+		contents +=	"\nSection Private\n\n";  //$NON-NLS-1$
+		contents += "  + project_root:STRING := \""+project.getLocationURI().getPath()+"/\";\n\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		contents += "  - project_src_path <- \n"; //$NON-NLS-1$
+		contents += "  // Define the project path for source code.\n"; //$NON-NLS-1$
+		contents += "  (\n"; //$NON-NLS-1$
+		contents += "    path (project_root + \"src/\");\n"; //$NON-NLS-1$
+		contents += "  );\n\n"; //$NON-NLS-1$
+		contents += "  - front_end <- \n"; //$NON-NLS-1$
+		contents += "  // Executed by compiler, before compilation step.\n"; //$NON-NLS-1$
+		contents += "  (\n"; //$NON-NLS-1$
+		contents += "    project_src_path;\n"; //$NON-NLS-1$
+		contents += "    general_front_end;\n"; //$NON-NLS-1$
+		contents += "  );\n"; //$NON-NLS-1$
+		contents +=	"\nSection Public\n\n"; //$NON-NLS-1$
+		contents += "  - debug_mode <- \n"; //$NON-NLS-1$
+		contents += "  // Run in Debug Mode.\n"; //$NON-NLS-1$
+		contents += "  (\n"; //$NON-NLS-1$
+		contents += "    debug 15; // default level [1-20]\n"; //$NON-NLS-1$
+		contents += "  );\n\n"; //$NON-NLS-1$
+		contents += "  - clean <- \n"; //$NON-NLS-1$
+		contents += "  // Clean project.\n"; //$NON-NLS-1$
+		contents += "  (\n"; //$NON-NLS-1$
+		contents += "  );\n"; //$NON-NLS-1$
+		return contents.getBytes();
+	}
+
+	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		setWindowTitle(LisaacMessages.getString("NewProjectWizard_46"));
+		setNeedsProgressMonitor(true);
+		mainPage = new NewProjectWizardPage(LisaacMessages.getString("NewProjectWizard_47"));
+	}
+
+	public void addPages() {
+		super.addPages(); 
+		addPage(mainPage);      
+	}
+}
+
+class NewProjectWizardPage extends WizardNewProjectCreationPage {
+
+	NewProjectWizardPage(String pageName) {
+		super(pageName);
+		setTitle(pageName);
+		setDescription(LisaacMessages.getString("NewProjectWizard_48")); 
+	}
+}
+/*
+class LicenseWizardPage extends WizardPage {
+
+	private Text licenseText;
+
+	LicenseWizardPage(String pageName) {
+		super(pageName);
+		setTitle(pageName);
+		setDescription("Specify the project license"); 
+	}
+
+	public String getLicense() {
+		return licenseText.getText();
+	}
+
+	public void createControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NONE);
+		composite.setLayout(new GridLayout());
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		licenseText = new Text(composite, SWT.MULTI);
+		licenseText.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		setControl(composite);
+	}
+}*/
diff --git a/editor/eclipse/src/org/lisaac/ldt/wizards/NewPrototypeWizard.java b/editor/eclipse/src/org/lisaac/ldt/wizards/NewPrototypeWizard.java
new file mode 100644
index 0000000..5b3291c
--- /dev/null
+++ b/editor/eclipse/src/org/lisaac/ldt/wizards/NewPrototypeWizard.java
@@ -0,0 +1,288 @@
+package org.lisaac.ldt.wizards;
+
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.lisaac.ldt.LisaacMessages;
+import org.lisaac.ldt.LisaacPlugin;
+import org.lisaac.ldt.actions.GenerateConstructor;
+import org.lisaac.ldt.model.ILisaacModel;
+import org.lisaac.ldt.preferences.PreferenceConstants;
+import org.eclipse.jface.dialogs.InputDialog;
+
+import java.io.*;
+
+/**
+ * Lisaac source file creator.
+ */
+public class NewPrototypeWizard extends AbstractNewFileWizard {
+
+	public NewPrototypeWizard() {
+		super();
+		setWindowTitle(LisaacMessages.getString("NewPrototypeWizard_0"));
+	}
+
+	/**
+	 * Create wizard page
+	 */
+	protected AbstractNewFileWizardPage createPage() {
+		return new NewPrototypeWizardPage(getSelection());
+	}
+}
+
+/**
+ * Represent the main page in "new lisaac prototype" wizard.
+ */
+class NewPrototypeWizardPage extends AbstractNewFileWizardPage  {
+	final private String INITIAL_PROTOTYPE_NAME = "prototype.li"; //$NON-NLS-1$
+
+	protected Text commentField;
+
+	protected Button styleNone;
+	protected Button styleExpanded;
+	protected Button styleStrict;
+
+	protected Table tableInherit;
+
+	protected Button generateConstructor, generateMain;
+
+
+	protected NewPrototypeWizardPage(IStructuredSelection selection) {
+		super(NewPrototypeWizardPage.class.getName(), selection);
+
+		setTitle(LisaacMessages.getString("NewPrototypeWizard_2"));
+		setDescription(LisaacMessages.getString("NewPrototypeWizard_3"));
+		setFileExtension(".li"); //$NON-NLS-1$
+		
+	}
+
+	public String getPrototypeDescription() {
+		return commentField.getText();
+	}
+
+	/**
+	 * Return the initial content of new file.
+	 */
+	protected InputStream getInitialContents(String filename) {
+		try {
+			int index = filename.lastIndexOf('.');
+			if (index != -1) {
+				filename = filename.substring(0, index);
+			}
+			return new ByteArrayInputStream(getPrototypeStream(filename));
+		} catch (IOException e) {
+			return null; // ignore and create empty comments
+		}
+	}
+
+	public byte[] getPrototypeStream(String filename) throws IOException {
+		boolean isExpanded = styleExpanded.getSelection();
+		boolean isStrict = styleExpanded.getSelection();
+
+	/*	//IProject project = (IProject) ();
+		try {
+			String license = project.getPersistentProperty(new QualifiedName("",LICENSE_PROPERTY));
+			licenseText.setText(license);
+		} catch (CoreException e) {
+		}*/
+		
+		String contents = "\nSection Header\n\n"; //$NON-NLS-1$
+		contents +=	"  + name    := "; //$NON-NLS-1$
+		if (isExpanded) {
+			contents += "Expanded "; //$NON-NLS-1$
+		} else if (isStrict) {
+			contents += "Strict "; //$NON-NLS-1$
+		}
+		contents +=	filename.toUpperCase()+";\n"; //$NON-NLS-1$
+
+		String descr = getPrototypeDescription();
+		if (descr != null && descr.length() > 0) {
+			contents +=	"  - comment := \""+descr+"\";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		String username = LisaacPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.P_LISAAC_USER);
+		if (username != null && username.length() > 0) {
+			contents += "\n  - author := \""+username+"\";\n"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+
+		if (! isExpanded) {
+			contents +=	"\nSection Inherit\n\n"; //$NON-NLS-1$
+		} else {
+			contents +=	"\nSection Insert\n\n"; //$NON-NLS-1$
+		}
+		int n = tableInherit.getItemCount();
+		if (n > 0) {
+			for (int i=0; i<n; i++) {
+				TableItem item = tableInherit.getItem(i);
+				String type = item.getText(1);
+				if (type.equals(ILisaacModel.inherit_shared) ||
+						type.equals(ILisaacModel.inherit_shared_expanded)) {
+					contents += "  - "; //$NON-NLS-1$
+				} else {
+					contents += "  + "; //$NON-NLS-1$
+				}
+				contents += "parent_"; //$NON-NLS-1$
+				contents += item.getText(0).toLowerCase() + ":"; //$NON-NLS-1$
+				if (type.equals(ILisaacModel.inherit_shared_expanded) ||
+						type.equals(ILisaacModel.inherit_nonshared_expanded)) {
+					contents +=  "Expanded " + item.getText(0); //$NON-NLS-1$
+				} else {
+					contents += item.getText(0) + " := " + item.getText(0); //$NON-NLS-1$
+				}
+				contents += ";\n"; //$NON-NLS-1$
+			}
+		} else {
+			contents += "  - parent_object:OBJECT := OBJECT;\n"; //$NON-NLS-1$
+		}
+		contents +=	"\nSection Public\n\n";  //$NON-NLS-1$
+		
+		if (generateConstructor.getSelection()) {
+			contents +=	GenerateConstructor.getConstructor();
+		}
+		if (generateMain.getSelection()) {
+			contents += "  - main <- \n"; //$NON-NLS-1$
+			contents += "  // Main entry point.\n"; //$NON-NLS-1$
+			contents += "  (\n\n"; //$NON-NLS-1$
+			contents += "    \n"; //$NON-NLS-1$
+			contents += "  );\n"; //$NON-NLS-1$
+		}
+		return contents.getBytes();
+	}
+
+	/**
+	 * Additional wizard information
+	 */
+	public void createAdvancedControls(Composite parent) {
+
+		// -- Style --
+		Label label = new Label(parent, SWT.NONE);
+		label.setText(LisaacMessages.getString("NewPrototypeWizard_25"));
+		label.setFont(parent.getFont());
+
+		Composite radioGroup = new Composite(parent, SWT.NONE);
+		radioGroup.setLayout(new RowLayout());
+		styleNone = new Button(radioGroup, SWT.RADIO);
+		styleNone.setFont(parent.getFont());
+		styleNone.setSelection(true);
+		styleNone.setText(LisaacMessages.getString("NewPrototypeWizard_26"));
+		styleExpanded = new Button(radioGroup, SWT.RADIO);
+		styleExpanded.setFont(parent.getFont());
+		styleExpanded.setText(LisaacMessages.getString("NewPrototypeWizard_27"));
+		styleStrict = new Button(radioGroup, SWT.RADIO);
+		styleStrict.setFont(parent.getFont());
+		styleStrict.setText(LisaacMessages.getString("NewPrototypeWizard_28"));
+		GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 2;
+		radioGroup.setLayoutData(gridData);
+		//
+
+		// -- Description --
+		label = new Label(parent, SWT.NONE);
+		label.setText(LisaacMessages.getString("NewPrototypeWizard_29"));
+		label.setFont(parent.getFont());
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 1;
+		label.setLayoutData(gridData);
+
+		commentField = new Text(parent, SWT.BORDER);
+		commentField.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 2;
+		commentField.setLayoutData(gridData);
+		//
+
+		// -- inherits --
+		label = new Label(parent, SWT.NONE);
+		label.setText(LisaacMessages.getString("NewPrototypeWizard_30"));
+		label.setFont(parent.getFont());
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 1;
+		label.setLayoutData(gridData);
+
+		Composite tableGroup = new Composite(parent, SWT.NONE);
+		tableGroup.setLayout(new RowLayout());
+
+		final Table table = new Table(tableGroup, SWT.BORDER | SWT.SINGLE |
+				SWT.H_SCROLL | SWT.FULL_SELECTION);
+		final TableColumn c1  = new TableColumn(table, SWT.LEFT);
+		c1.setText("Prototype"); //$NON-NLS-1$
+		c1.setWidth(150);
+		final TableColumn c2  = new TableColumn(table, SWT.LEFT);
+		c2.setText(LisaacMessages.getString("NewPrototypeWizard_32"));
+		c2.setWidth(100);
+		table.setHeaderVisible(true);
+		table.setLinesVisible(true);
+
+		final TableItem itemDefault = new TableItem(table, SWT.NONE);
+		itemDefault.setText(new String[] {"OBJECT", ILisaacModel.inherit_shared}); //$NON-NLS-1$
+
+		Composite buttonGroup = new Composite(tableGroup, SWT.NONE);
+		buttonGroup.setLayout(new GridLayout());
+		Button tableAdd = new Button(buttonGroup, SWT.PUSH);
+		tableAdd.setFont(parent.getFont());
+		tableAdd.setText(LisaacMessages.getString("NewPrototypeWizard_34"));
+		tableAdd.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				InputParentDialog input = new InputParentDialog(getShell(), "New Parent...");
+				if (input.open() == InputDialog.OK) {
+					TableItem item = new TableItem(table, SWT.NONE);
+					item.setText(new String[] {input.getParentName(), input.getParentType()});		
+				}
+			}
+		});
+		Button tableRemove= new Button(buttonGroup, SWT.PUSH);
+		tableRemove.setFont(parent.getFont());
+		tableRemove.setText(LisaacMessages.getString("NewPrototypeWizard_35"));
+		tableRemove.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int[] indices = table.getSelectionIndices();
+				if (indices != null && indices.length > 0) {
+					int index = indices[0];
+					table.remove(index);
+				}
+			}
+		});
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 2;
+		tableGroup.setLayoutData(gridData);
+
+		tableInherit = table;
+		//
+
+		label = new Label(parent, SWT.NONE);
+		label.setText(LisaacMessages.getString("NewPrototypeWizard_36"));
+		label.setFont(parent.getFont());
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 3;
+		label.setLayoutData(gridData);
+
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		gridData.horizontalSpan = 3;
+		gridData.horizontalAlignment = SWT.CENTER;
+		generateMain = new Button(parent, SWT.CHECK);
+		generateMain.setText(LisaacMessages.getString("NewPrototypeWizard_37"));
+		generateMain.setLayoutData(gridData);
+		generateConstructor = new Button(parent, SWT.CHECK);
+		generateConstructor.setText(LisaacMessages.getString("NewPrototypeWizard_38"));
+		generateConstructor.setLayoutData(gridData);
+	}
+
+	protected String getInitialFileName() {
+		return INITIAL_PROTOTYPE_NAME;
+	}
+}

-- 
Lisaac compiler



More information about the Lisaac-commits mailing list