[bugzilla 413929] External parsers - step 1

Integration of Melanie Bats work with some minor changes (checkstyle
activation & fixes, poms)

Signed-off-by: Melanie Bats <melanie.bats@obeo.fr>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/.checkstyle b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.checkstyle
new file mode 100644
index 0000000..959808a
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.checkstyle
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
+  <fileset name="all" enabled="true" check-config-name="intent" local="false">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+</fileset-config>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/.classpath b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.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/plugins/org.eclipse.mylyn.docs.intent.external.parser/.project b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.project
new file mode 100644
index 0000000..af13f3f
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.mylyn.docs.intent.external.parser</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>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..af0f20f
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+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.compliance=1.5
+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/plugins/org.eclipse.mylyn.docs.intent.external.parser/META-INF/MANIFEST.MF b/plugins/org.eclipse.mylyn.docs.intent.external.parser/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..fa9c25d
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/META-INF/MANIFEST.MF
@@ -0,0 +1,18 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.mylyn.docs.intent.external.parser;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: org.eclipse.mylyn.docs.intent.external.parser.internal.IntentExternalParserActivator
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.swt,
+ org.eclipse.mylyn.docs.intent.core,
+ org.eclipse.mylyn.docs.intent.collab,
+ com.google.guava,
+ org.eclipse.mylyn.docs.intent.collab.common
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Export-Package: org.eclipse.mylyn.docs.intent.external.parser,
+ org.eclipse.mylyn.docs.intent.external.parser.client,
+ org.eclipse.mylyn.docs.intent.external.parser.contribution
+Bundle-Vendor: %providerName
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/build.properties b/plugins/org.eclipse.mylyn.docs.intent.external.parser/build.properties
new file mode 100644
index 0000000..d67426f
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/build.properties
@@ -0,0 +1,7 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml,\
+               schema/,\
+               plugin.properties
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.properties b/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.properties
new file mode 100644
index 0000000..6e53dfa
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.properties
@@ -0,0 +1,12 @@
+#################################################################################
+# Copyright (c) 2010, 2011 Obeo.
+# 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:
+#     Obeo - initial API and implementation
+#################################################################################
+pluginName = Intent Collaboration
+providerName = Eclipse Mylyn
\ No newline at end of file
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.xml b/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.xml
new file mode 100644
index 0000000..39eb82d
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/plugin.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension-point id="externalparsercontribution" name="org.eclipse.mylyn.docs.intent.parser.externalparser" schema="schema/externalparsercontribution.exsd"/>
+
+</plugin>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/pom.xml b/plugins/org.eclipse.mylyn.docs.intent.external.parser/pom.xml
new file mode 100644
index 0000000..3af6740
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2013 Obeo
+
+  Alex Lagarde <alex.lagarde@obeo.fr>
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.eclipse.mylyn.docs.intent-group</groupId>
+    <artifactId>intent-parent</artifactId>
+    <version>0.9.0-SNAPSHOT</version>
+    <relativePath>../..</relativePath>
+  </parent>
+
+  <artifactId>org.eclipse.mylyn.docs.intent.external.parser</artifactId>
+  <packaging>eclipse-plugin</packaging>
+
+ <build>   
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-source-plugin</artifactId>
+      </plugin>   
+    </plugins>
+  </build>
+
+</project>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/schema/externalparsercontribution.exsd b/plugins/org.eclipse.mylyn.docs.intent.external.parser/schema/externalparsercontribution.exsd
new file mode 100644
index 0000000..887e5e3
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/schema/externalparsercontribution.exsd
@@ -0,0 +1,102 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.mylyn.docs.intent.external.parser" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.mylyn.docs.intent.external.parser" id="externalparsercontribution" name="org.eclipse.mylyn.docs.intent.external.parser.externalparser"/>
+      </appinfo>
+      <documentation>
+         [Enter description of this extension point.]
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <sequence>
+            <element ref="externalparser"/>
+         </sequence>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="externalparser">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.mylyn.docs.intent.external.parser.contribution.IntentExternalParserContribution"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         [Enter the first release in which this extension point appears.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         [Enter extension point usage example here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/IntentExternalParserContributionRegistry.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/IntentExternalParserContributionRegistry.java
new file mode 100644
index 0000000..c220d9a
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/IntentExternalParserContributionRegistry.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser;
+
+import com.google.common.collect.Maps;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
+import org.eclipse.mylyn.docs.intent.external.parser.internal.IntentExternalParserContributionDescriptor;
+
+/**
+ * Stores the external parser contributions.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public final class IntentExternalParserContributionRegistry {
+
+	/**
+	 * All the registered IntentExternalParserContributions.
+	 */
+	private static final Map<IntentExternalParserContributionDescriptor, IExternalParser> DECLARED_CONTRIBUTIONS = Maps
+			.newLinkedHashMap();
+
+	/**
+	 * Utility classes don't need a default constructor.
+	 */
+	private IntentExternalParserContributionRegistry() {
+
+	}
+
+	/**
+	 * Returns all declared external parser Contributions (instantiates it if needed).
+	 * 
+	 * @return all the declared contributions
+	 */
+	public static Collection<IExternalParser> getExternalParserContributions() {
+		for (Entry<IntentExternalParserContributionDescriptor, IExternalParser> descriptorToContribution : DECLARED_CONTRIBUTIONS
+				.entrySet()) {
+			if (descriptorToContribution.getValue() == null) {
+				descriptorToContribution.setValue(descriptorToContribution.getKey()
+						.createExternalParserContribution());
+			}
+		}
+		return DECLARED_CONTRIBUTIONS.values();
+	}
+
+	/**
+	 * Registers the given external parser contribution descriptor.
+	 * 
+	 * @param descriptor
+	 *            the external parser contribution descriptor to register
+	 */
+	public static void addExternalParserContribution(IntentExternalParserContributionDescriptor descriptor) {
+		DECLARED_CONTRIBUTIONS.put(descriptor, null);
+	}
+
+	/**
+	 * Removes a phantom from the registry.
+	 * 
+	 * @param extensionClassName
+	 *            Qualified class name of the sync element which corresponding phantom is to be removed from
+	 *            the registry.
+	 */
+	public static void removeExtension(String extensionClassName) {
+		for (IntentExternalParserContributionDescriptor extension : DECLARED_CONTRIBUTIONS.keySet()) {
+			if (extension.getExtensionClassName().equals(extensionClassName)) {
+				DECLARED_CONTRIBUTIONS.remove(extension);
+			}
+		}
+	}
+
+	/**
+	 * Clears all registered IntentExternalParserContributions.
+	 */
+	public static void clearContributedExternalParserContributions() {
+		DECLARED_CONTRIBUTIONS.clear();
+	}
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/client/ExternalParserCreator.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/client/ExternalParserCreator.java
new file mode 100644
index 0000000..080dc35
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/client/ExternalParserCreator.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.client;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.mylyn.docs.intent.collab.handlers.RepositoryObjectHandler;
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.ReadOnlyException;
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.collab.handlers.impl.ReadWriteRepositoryObjectHandlerImpl;
+import org.eclipse.mylyn.docs.intent.collab.handlers.impl.notification.typeListener.TypeNotificator;
+import org.eclipse.mylyn.docs.intent.collab.handlers.notification.Notificator;
+import org.eclipse.mylyn.docs.intent.collab.repository.Repository;
+import org.eclipse.mylyn.docs.intent.collab.repository.RepositoryConnectionException;
+import org.eclipse.mylyn.docs.intent.core.document.IntentDocumentPackage;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
+import org.eclipse.mylyn.docs.intent.external.parser.internal.ExternalParserRepositoryClient;
+
+/**
+ * Creates external parser repository clients.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public final class ExternalParserCreator {
+
+	/**
+	 * CompilerCreator constructor.
+	 */
+	private ExternalParserCreator() {
+
+	}
+
+	/**
+	 * Creates a {@link ExternalParserRepositoryClient}, in charge of calling contributed
+	 * {@link IExternalParser}s when document changes.
+	 * 
+	 * @param repository
+	 *            is the repository containing the modeling units to compile
+	 * @param externalParserContribution
+	 *            is the external parser contribution
+	 * @throws RepositoryConnectionException
+	 *             if a connection to the given repository cannot be established
+	 * @return the created ExternalParserRepositoryClient
+	 * @throws ReadOnlyException
+	 *             if no sufficient rights to write on the repository
+	 */
+	public static ExternalParserRepositoryClient createParser(Repository repository,
+			IExternalParser externalParserContribution) throws RepositoryConnectionException,
+			ReadOnlyException {
+
+		// Step 1: initialize the listened types
+		Set<EStructuralFeature> listenedTypes = new LinkedHashSet<EStructuralFeature>();
+
+		listenedTypes.add(IntentDocumentPackage.eINSTANCE.getIntentSection_DescriptionUnits());
+
+		// Step 2: create the adapter and the handler for these types
+		final RepositoryAdapter repositoryAdapter = repository.createRepositoryAdapter();
+		repositoryAdapter.openSaveContext();
+
+		RepositoryObjectHandler handler;
+		handler = new ReadWriteRepositoryObjectHandlerImpl(repositoryAdapter);
+
+		Notificator notificator = new TypeNotificator(listenedTypes);
+		handler.addNotificator(notificator);
+
+		// Step 3: create the external parser
+		ExternalParserRepositoryClient externalParserClient = new ExternalParserRepositoryClient(repository,
+				externalParserContribution);
+		externalParserClient.addRepositoryObjectHandler(handler);
+
+		return externalParserClient;
+	}
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/ExternalParserCompletionProposal.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/ExternalParserCompletionProposal.java
new file mode 100644
index 0000000..b20380f
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/ExternalParserCompletionProposal.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.contribution;
+
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Completion proposal provided by external parsers.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class ExternalParserCompletionProposal {
+	/**
+	 * Completion proposal name.
+	 */
+	private String name;
+
+	/**
+	 * Completion proposal description.
+	 */
+	private String description;
+
+	/**
+	 * Completion proposal template pattern.
+	 */
+	private String pattern;
+
+	/**
+	 * Completion proposal image.
+	 */
+	private Image image;
+
+	/**
+	 * Default constructor.
+	 * 
+	 * @param name
+	 *            Name
+	 * @param description
+	 *            Description
+	 * @param pattern
+	 *            Pattern
+	 * @param image
+	 *            Image
+	 */
+	public ExternalParserCompletionProposal(String name, String description, String pattern, Image image) {
+		this.name = name;
+		this.description = description;
+		this.pattern = pattern;
+		this.image = image;
+	}
+
+	/**
+	 * Get completion proposal name.
+	 * 
+	 * @return Name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Get completion proposal description.
+	 * 
+	 * @return Description
+	 */
+	public String getDescription() {
+		return description;
+	}
+
+	/**
+	 * Get completion proposal pattern.
+	 * 
+	 * @return Pattern
+	 */
+	public String getPattern() {
+		return pattern;
+	}
+
+	/**
+	 * Get completion proposal image.
+	 * 
+	 * @return Image
+	 */
+	public Image getImage() {
+		return image;
+	}
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/IExternalParser.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/IExternalParser.java
new file mode 100644
index 0000000..5997e10
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/contribution/IExternalParser.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.contribution;
+
+import java.util.List;
+
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.core.document.IntentSection;
+
+/**
+ * A parser which is called any time a section of interest for this parser is modified, and provides
+ * additional behavior. For example, you can automatically create Java files or models out of a description in
+ * natural langage.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public interface IExternalParser {
+
+	/**
+	 * Init parser.
+	 */
+	void init();
+
+	/**
+	 * Parse.
+	 * 
+	 * @param intentSection
+	 *            Intent section parsed
+	 * @param descriptionUnitToParse
+	 *            The description unit to parse
+	 */
+	void parse(IntentSection intentSection, String descriptionUnitToParse);
+
+	/**
+	 * Post operations launched after the parse operation.
+	 * 
+	 * @param repositoryAdapter
+	 *            Repository adapter
+	 */
+	void parsePostOperations(RepositoryAdapter repositoryAdapter);
+
+	/**
+	 * Get completion variables proposal.
+	 * 
+	 * @param currentSentences
+	 *            Current parsed sentences
+	 * @return List of completion proposals
+	 */
+	List<ExternalParserCompletionProposal> getCompletionVariablesProposals(Iterable<String> currentSentences);
+
+	/**
+	 * Get completion templates proposal.
+	 * 
+	 * @param currentSentences
+	 *            Current parsed sentences
+	 * @return List of completion templates
+	 */
+	List<ExternalParserCompletionProposal> getCompletionTemplatesProposals(Iterable<String> currentSentences);
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserJob.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserJob.java
new file mode 100644
index 0000000..5c04970
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserJob.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.mylyn.docs.intent.collab.common.query.IntentDocumentQuery;
+import org.eclipse.mylyn.docs.intent.collab.handlers.RepositoryObjectHandler;
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.IntentCommand;
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.ReadOnlyException;
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.core.document.IntentSection;
+import org.eclipse.mylyn.docs.intent.core.document.UnitInstruction;
+import org.eclipse.mylyn.docs.intent.core.document.descriptionunit.DescriptionBloc;
+import org.eclipse.mylyn.docs.intent.core.document.descriptionunit.DescriptionUnit;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
+import org.eclipse.mylyn.docs.intent.markup.markup.BlockContent;
+import org.eclipse.mylyn.docs.intent.markup.markup.Paragraph;
+import org.eclipse.mylyn.docs.intent.markup.markup.StructureElement;
+import org.eclipse.mylyn.docs.intent.markup.markup.Text;
+
+/**
+ * Represents a external parser operation, that parses all the description units contained in the repository.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class ExternalParserJob extends Job {
+	/**
+	 * Name to associate to this job.
+	 */
+	public static final String EXTERNAL_PARSE_JOB_NAME = "Parsing Intent Document with contibuted external parsers";
+
+	/**
+	 * The repository object handler.
+	 */
+	private RepositoryObjectHandler repositoryObjectHandler;
+
+	/**
+	 * External parser contribution.
+	 */
+	private IExternalParser externalParserContribution;
+
+	/**
+	 * {@link ExternalParserJob} constructor.
+	 * 
+	 * @param repositoryObjectHandler
+	 *            the repository object handler
+	 * @param externalParserContribution
+	 *            the {@link IExternalParser} to call
+	 */
+	public ExternalParserJob(RepositoryObjectHandler repositoryObjectHandler,
+			IExternalParser externalParserContribution) {
+		super(EXTERNAL_PARSE_JOB_NAME);
+		this.repositoryObjectHandler = repositoryObjectHandler;
+		this.externalParserContribution = externalParserContribution;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	@Override
+	protected IStatus run(final IProgressMonitor monitor) {
+		final RepositoryAdapter repositoryAdapter = repositoryObjectHandler.getRepositoryAdapter();
+		// Parsing
+		if (repositoryAdapter != null) {
+			repositoryAdapter.execute(new IntentCommand() {
+
+				public void execute() {
+					parse(monitor, repositoryAdapter);
+				}
+
+			});
+		}
+		return Status.OK_STATUS;
+	}
+
+	/**
+	 * Compile.
+	 * 
+	 * @param monitor
+	 *            the progress monitor
+	 * @param repositoryAdapter
+	 *            the repository adapter
+	 */
+	private void parse(final IProgressMonitor monitor, final RepositoryAdapter repositoryAdapter) {
+		try {
+			repositoryAdapter.openSaveContext();
+
+			externalParserContribution.init();
+
+			IntentDocumentQuery query = new IntentDocumentQuery(repositoryAdapter);
+			for (DescriptionUnit descriptionUnit : query.getAllDescriptionUnits()) {
+				IntentSection intentSection = null;
+
+				EObject container = descriptionUnit;
+				while (container != null
+						&& !(container instanceof IntentSection && ((IntentSection)container).getTitle() != null)) {
+					container = container.eContainer();
+				}
+				if (container instanceof IntentSection) {
+					intentSection = (IntentSection)container;
+				}
+				for (UnitInstruction instruction : descriptionUnit.getInstructions()) {
+					if (instruction instanceof DescriptionBloc) {
+						DescriptionBloc bloc = (DescriptionBloc)instruction;
+						for (StructureElement blocElement : bloc.getDescriptionBloc().getContent()) {
+							if (blocElement instanceof Paragraph) {
+								parseParagraph(monitor, repositoryAdapter, intentSection,
+										(Paragraph)blocElement);
+							}
+						}
+					}
+				}
+			}
+			externalParserContribution.parsePostOperations(repositoryAdapter);
+
+			repositoryAdapter.closeContext();
+		} catch (ReadOnlyException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Parse.
+	 * 
+	 * @param monitor
+	 *            the progress monitor
+	 * @param repositoryAdapter
+	 *            the repository adapter
+	 * @param intentSection
+	 *            the intent section
+	 * @param paragraph
+	 *            the paragraph to parse
+	 */
+	private void parseParagraph(IProgressMonitor monitor, RepositoryAdapter repositoryAdapter,
+			IntentSection intentSection, Paragraph paragraph) {
+		StringBuffer text = new StringBuffer();
+		boolean isVariable = false;
+		for (BlockContent element : paragraph.getContent()) {
+			if (element instanceof Text) {
+				String data = ((Text)element).getData();
+				if ("#8249".equals(data)) {
+					text.append("'");
+					isVariable = true;
+				} else if ("#8250".equals(data)) {
+					text.append("'");
+					isVariable = false;
+				} else if (data.endsWith("$") || isVariable) {
+					text.append(data);
+					isVariable = false;
+				} else {
+					text.append(data + "\n");
+					isVariable = false;
+				}
+			}
+		}
+		externalParserContribution.parse(intentSection, text.toString());
+	}
+
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserRepositoryClient.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserRepositoryClient.java
new file mode 100644
index 0000000..7b74c7c
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/ExternalParserRepositoryClient.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.internal;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IIntentLogger.LogType;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IntentLogger;
+import org.eclipse.mylyn.docs.intent.collab.handlers.impl.AbstractRepositoryClient;
+import org.eclipse.mylyn.docs.intent.collab.handlers.notification.RepositoryChangeNotification;
+import org.eclipse.mylyn.docs.intent.collab.repository.Repository;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
+
+/**
+ * In charge of communication between the repository and the external parsers ; launch a parsing operation
+ * each time a modification on description units is detected.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class ExternalParserRepositoryClient extends AbstractRepositoryClient {
+	/**
+	 * External parser contribution.
+	 */
+	private IExternalParser externalParserContribution;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param repository
+	 *            the repository
+	 * @param externalParserContribution
+	 *            the {@link IExternalParser}
+	 */
+	public ExternalParserRepositoryClient(Repository repository,
+			IExternalParser externalParserContribution) {
+		super(repository);
+		this.externalParserContribution = externalParserContribution;
+		IntentLogger.getInstance().log(LogType.LIFECYCLE, "[External parsers] Ready");
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.collab.handlers.impl.AbstractRepositoryClient#createNotificationJob(org.eclipse.mylyn.docs.intent.collab.handlers.notification.RepositoryChangeNotification)
+	 */
+	@Override
+	protected Job createNotificationJob(RepositoryChangeNotification notification) {
+		return new ExternalParserJob(this.repositoryObjectHandler, this.externalParserContribution);
+	}
+
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserActivator.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserActivator.java
new file mode 100644
index 0000000..4c82606
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserActivator.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.internal;
+
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class IntentExternalParserActivator extends Plugin {
+
+	/**
+	 * External parser.
+	 */
+	private IntentExternalParserContributionRegistryListener externalParserContributionsRegistryListener = new IntentExternalParserContributionRegistryListener();
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+
+		// Initializing registry listener for all extension points
+		externalParserContributionsRegistryListener.init();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+	 */
+	@Override
+	public void stop(BundleContext context) throws Exception {
+		// Disposing registry listener for all extension points
+		externalParserContributionsRegistryListener.dispose();
+		externalParserContributionsRegistryListener = null;
+		super.stop(context);
+	}
+
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionDescriptor.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionDescriptor.java
new file mode 100644
index 0000000..5600b6f
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionDescriptor.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.internal;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IIntentLogger.LogType;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IntentLogger;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
+
+/**
+ * Describes an extension as contibuted to the
+ * {@link IntentExternalParserContributionRegistryListener#INTENT_EXTERNAL_PARSER_CONTRIBUTION_EXTENSION_POINT}
+ * extension point.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class IntentExternalParserContributionDescriptor {
+
+	/**
+	 * Name of the attribute corresponding to the contributed class's path.
+	 */
+	public static final String EXTERNAL_PARSER_CONTRIBUTION_CLASS_NAME = "class";
+
+	/**
+	 * Configuration element of this descriptor .
+	 */
+	private final IConfigurationElement element;
+
+	/**
+	 * The path of the contributed class.
+	 */
+	private String extensionClassName;
+
+	/**
+	 * The {@link IExternalParser} described by this descriptor.
+	 */
+	private IExternalParser extension;
+
+	/**
+	 * Instantiates a descriptor with all information.
+	 * 
+	 * @param configuration
+	 *            Configuration element from which to create this descriptor.
+	 */
+	public IntentExternalParserContributionDescriptor(IConfigurationElement configuration) {
+		element = configuration;
+		extensionClassName = configuration.getAttribute(EXTERNAL_PARSER_CONTRIBUTION_CLASS_NAME);
+	}
+
+	/**
+	 * Creates an instance of this descriptor's {@link IExternalParser} .
+	 * 
+	 * @return A new instance of this descriptor's {@link IExternalParser}.
+	 */
+	public IExternalParser createExternalParserContribution() {
+		try {
+			extension = (IExternalParser)element
+					.createExecutableExtension(EXTERNAL_PARSER_CONTRIBUTION_CLASS_NAME);
+		} catch (CoreException e) {
+			IntentLogger.getInstance().log(LogType.ERROR,
+					"Could not create external parser manager contribution " + extensionClassName, e);
+		}
+		return extension;
+	}
+
+	/**
+	 * Returns the fully qualified name of the contributed class.
+	 * 
+	 * @return the fully qualified name of the contributed class
+	 */
+	public String getExtensionClassName() {
+		return extensionClassName;
+	}
+}
diff --git a/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionRegistryListener.java b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionRegistryListener.java
new file mode 100644
index 0000000..3119c71
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.external.parser/src/org/eclipse/mylyn/docs/intent/external/parser/internal/IntentExternalParserContributionRegistryListener.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mylyn.docs.intent.external.parser.internal;
+
+import com.google.common.collect.Sets;
+
+import java.util.Set;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IIntentLogger.LogType;
+import org.eclipse.mylyn.docs.intent.collab.common.logger.IntentLogger;
+import org.eclipse.mylyn.docs.intent.external.parser.IntentExternalParserContributionRegistry;
+
+/**
+ * This listener allows to be aware of contribution changes against the
+ * {@link IntentExternalParserContributionRegistryListener#INTENT_REPOSITORY_MANAGER_CONTRIBUTION_EXTENSION_POINT}
+ * extension point.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class IntentExternalParserContributionRegistryListener implements IRegistryChangeListener {
+
+	/** Name of the extension point to parse for extensions. */
+	public static final String INTENT_EXTERNAL_PARSER_CONTRIBUTION_EXTENSION_POINT = "org.eclipse.mylyn.docs.intent.external.parser.externalparsercontribution"; //$NON-NLS-1$
+
+	/** Name of the extension point's tag. */
+	private static final String EXTERNAL_PARSER_CONTRIBUTION_TAG = "externalparser"; //$NON-NLS-1$
+
+	/**
+	 * Register this listener and parse initial contributions.
+	 */
+	public void init() {
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		registry.addRegistryChangeListener(this, INTENT_EXTERNAL_PARSER_CONTRIBUTION_EXTENSION_POINT);
+		parseInitialContributions();
+	}
+
+	/**
+	 * Parses a single extension contribution.
+	 * 
+	 * @param extension
+	 *            Parses the given extension and adds its contribution to the registry.
+	 */
+	private void parseExtension(IExtension extension) {
+		final IConfigurationElement[] configElements = extension.getConfigurationElements();
+		for (IConfigurationElement elem : configElements) {
+			if (EXTERNAL_PARSER_CONTRIBUTION_TAG.equals(elem.getName())) {
+				try {
+					IntentExternalParserContributionRegistry
+							.addExternalParserContribution(new IntentExternalParserContributionDescriptor(
+									elem));
+				} catch (IllegalArgumentException e) {
+					IntentLogger.getInstance().log(LogType.ERROR,
+							"Could not create external parser contribution " + elem.getValue(), e);
+				}
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtensionPoint[])
+	 */
+	public void added(IExtensionPoint[] extensionPoints) {
+		for (IExtensionPoint extensionPoint : extensionPoints) {
+			for (IExtension extension : extensionPoint.getExtensions()) {
+				parseExtension(extension);
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
+	 */
+	public void registryChanged(IRegistryChangeEvent event) {
+		Set<IExtension> addedExtensions = Sets.newLinkedHashSet();
+		for (IExtensionDelta extensionDelta : event.getExtensionDeltas()) {
+			addedExtensions.add(extensionDelta.getExtension());
+		}
+		added(addedExtensions.toArray(new IExtension[addedExtensions.size()]));
+	}
+
+	/**
+	 * Behavior when the given extensions are added.
+	 * 
+	 * @param extensions
+	 *            the added extensions
+	 */
+	public void added(IExtension[] extensions) {
+		for (IExtension extension : extensions) {
+			parseExtension(extension);
+		}
+	}
+
+	/**
+	 * Though this listener reacts to the extension point changes, there could have been contributions before
+	 * it's been registered. This will parse these initial contributions.
+	 */
+	public void parseInitialContributions() {
+		final IExtensionRegistry registry = Platform.getExtensionRegistry();
+
+		for (IExtension extension : registry.getExtensionPoint(
+				INTENT_EXTERNAL_PARSER_CONTRIBUTION_EXTENSION_POINT).getExtensions()) {
+			parseExtension(extension);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtension[])
+	 */
+	public void removed(IExtension[] extensions) {
+		for (IExtension extension : extensions) {
+			final IConfigurationElement[] configElements = extension.getConfigurationElements();
+			for (IConfigurationElement elem : configElements) {
+				if (EXTERNAL_PARSER_CONTRIBUTION_TAG.equals(elem.getName())) {
+					final String extensionClassName = elem
+							.getAttribute(IntentExternalParserContributionDescriptor.EXTERNAL_PARSER_CONTRIBUTION_CLASS_NAME);
+					IntentExternalParserContributionRegistry.removeExtension(extensionClassName);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Remove this listener and flush the contributions registry.
+	 */
+	public void dispose() {
+		IExtensionRegistry registry = Platform.getExtensionRegistry();
+		registry.removeRegistryChangeListener(this);
+		IntentExternalParserContributionRegistry.clearContributedExternalParserContributions();
+	}
+}