[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.client.ui.ide/META-INF/MANIFEST.MF b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/META-INF/MANIFEST.MF
index 3d41bb4..09007d4 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/META-INF/MANIFEST.MF
@@ -8,14 +8,6 @@
 Bundle-Activator: org.eclipse.mylyn.docs.intent.client.ui.ide.Activator
 Require-Bundle: org.eclipse.ui;visibility:=reexport,
  org.eclipse.core.runtime,
- org.eclipse.mylyn.docs.intent.core,
- org.eclipse.mylyn.docs.intent.collab.ide,
- org.eclipse.mylyn.docs.intent.collab.common,
- org.eclipse.mylyn.docs.intent.client.ui,
- org.eclipse.mylyn.docs.intent.client.compiler,
- org.eclipse.mylyn.docs.intent.client.indexer,
- org.eclipse.mylyn.docs.intent.client.synchronizer,
- org.eclipse.mylyn.docs.intent.client.linkresolver,
  org.eclipse.ui.navigator,
  org.eclipse.ui.navigator.resources,
  org.eclipse.core.resources;visibility:=reexport,
@@ -23,8 +15,17 @@
  org.eclipse.jface.text;visibility:=reexport,
  org.eclipse.core.expressions,
  org.eclipse.emf.common.ui,
+ org.eclipse.ui.cheatsheets,
  org.eclipse.mylyn.docs.intent.exporter.client;bundle-version="0.9.0",
- org.eclipse.ui.cheatsheets
+ org.eclipse.mylyn.docs.intent.external.parser;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.core;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.collab.ide;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.collab.common;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.client.ui;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.client.compiler;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.client.indexer;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.client.synchronizer;bundle-version="0.9.0",
+ org.eclipse.mylyn.docs.intent.client.linkresolver;bundle-version="0.9.0"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Import-Package: com.google.common.base,
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/projectmanager/IntentProjectManager.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/projectmanager/IntentProjectManager.java
index 946c95a..3cb013f 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/projectmanager/IntentProjectManager.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/projectmanager/IntentProjectManager.java
@@ -11,16 +11,18 @@
  *******************************************************************************/
 package org.eclipse.mylyn.docs.intent.client.ui.ide.projectmanager;
 
+import com.google.common.collect.Lists;
+
+import java.util.Iterator;
+import java.util.List;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.mylyn.docs.intent.client.compiler.launcher.CompilerCreator;
 import org.eclipse.mylyn.docs.intent.client.compiler.repositoryconnection.CompilerRepositoryClient;
-import org.eclipse.mylyn.docs.intent.client.indexer.IndexerRepositoryClient;
 import org.eclipse.mylyn.docs.intent.client.indexer.launcher.IndexerCreator;
-import org.eclipse.mylyn.docs.intent.client.linkresolver.repository.LinkResolverClient;
 import org.eclipse.mylyn.docs.intent.client.linkresolver.repository.LinkResolverCreator;
 import org.eclipse.mylyn.docs.intent.client.synchronizer.SynchronizerCreator;
-import org.eclipse.mylyn.docs.intent.client.synchronizer.SynchronizerRepositoryClient;
 import org.eclipse.mylyn.docs.intent.client.ui.editor.IntentDocumentProvider;
 import org.eclipse.mylyn.docs.intent.client.ui.editor.IntentEditor;
 import org.eclipse.mylyn.docs.intent.client.ui.ide.builder.IntentNature;
@@ -32,10 +34,13 @@
 import org.eclipse.mylyn.docs.intent.collab.common.logger.IntentLogger;
 import org.eclipse.mylyn.docs.intent.collab.common.repository.IntentRepositoryManager;
 import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.ReadOnlyException;
+import org.eclipse.mylyn.docs.intent.collab.handlers.impl.AbstractRepositoryClient;
 import org.eclipse.mylyn.docs.intent.collab.repository.Repository;
 import org.eclipse.mylyn.docs.intent.collab.repository.RepositoryConnectionException;
-import org.eclipse.mylyn.docs.intent.exporter.client.IntentExporterClient;
 import org.eclipse.mylyn.docs.intent.exporter.client.IntentExporterClientCreator;
+import org.eclipse.mylyn.docs.intent.external.parser.IntentExternalParserContributionRegistry;
+import org.eclipse.mylyn.docs.intent.external.parser.client.ExternalParserCreator;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IWorkbenchPage;
@@ -60,29 +65,34 @@
 	private CompilerRepositoryClient compilerClient;
 
 	/**
+	 * The external parsers repository client.
+	 */
+	private List<AbstractRepositoryClient> externalParserClients = Lists.newArrayList();
+
+	/**
 	 * The synchronized repository client.
 	 */
-	private SynchronizerRepositoryClient synchronizerClient;
+	private AbstractRepositoryClient synchronizerClient;
 
 	/**
 	 * The indexer repository client.
 	 */
-	private IndexerRepositoryClient indexerClient;
+	private AbstractRepositoryClient indexerClient;
 
 	/**
 	 * The project explorer refresher repository client.
 	 */
-	private ProjectExplorerRefresher refresher;
+	private AbstractRepositoryClient refresher;
 
 	/**
 	 * The link resolver repository client.
 	 */
-	private LinkResolverClient linkResolverClient;
+	private AbstractRepositoryClient linkResolverClient;
 
 	/**
 	 * The export repository client.
 	 */
-	private IntentExporterClient exporterClient;
+	private AbstractRepositoryClient exporterClient;
 
 	/**
 	 * The project associated to this IntentProjectManager (must be associated to the Intent nature).
@@ -157,6 +167,14 @@
 					refresher = ProjectExplorerRefresher.createProjectExplorerRefresher(project);
 				}
 
+				// External parsers
+				for (Iterator<IExternalParser> iterator = IntentExternalParserContributionRegistry
+						.getExternalParserContributions().iterator(); iterator.hasNext();) {
+					IExternalParser externalParserContribution = iterator.next();
+					externalParserClients.add(ExternalParserCreator.createParser(repository,
+							externalParserContribution));
+				}
+
 				// Exporter client: no need to create it if preview page is hidden in the intent editor
 				boolean shouldDisplayPReviewPage = IntentPreferenceService
 						.getBoolean(IntentPreferenceConstants.SHOW_PREVIEW_PAGE);
@@ -206,6 +224,12 @@
 				compilerClient.dispose();
 				compilerClient = null;
 			}
+
+			for (AbstractRepositoryClient externalParserClient : externalParserClients) {
+				externalParserClient.dispose();
+				externalParserClients.remove(externalParserClient);
+			}
+
 			if (linkResolverClient != null) {
 				linkResolverClient.dispose();
 				linkResolverClient = null;
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.mylyn.docs.intent.client.ui/META-INF/MANIFEST.MF
index 5971b01..9b006b1 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui/META-INF/MANIFEST.MF
@@ -25,7 +25,8 @@
  org.eclipse.mylyn.docs.intent.modelingunit.update;bundle-version="0.7.0",
  org.eclipse.emf.compare.ide.ui;bundle-version="2.1.0",
  org.eclipse.emf.compare.edit;bundle-version="3.0.0",
- org.eclipse.ui.forms
+ org.eclipse.ui.forms,
+ org.eclipse.mylyn.docs.intent.external.parser
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Export-Package: org.eclipse.mylyn.docs.intent.client.ui,
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/AbstractIntentCompletionProcessor.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/AbstractIntentCompletionProcessor.java
index 87ac0c9..254b66f 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/AbstractIntentCompletionProcessor.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/AbstractIntentCompletionProcessor.java
@@ -31,6 +31,7 @@
 import org.eclipse.mylyn.docs.intent.client.ui.IntentEditorActivator;
 import org.eclipse.mylyn.docs.intent.client.ui.logger.IntentUiLogger;
 import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.ExternalParserCompletionProposal;
 import org.eclipse.swt.graphics.Image;
 
 /**
@@ -39,6 +40,11 @@
  * @author <a href="mailto:william.piers@obeo.fr">William Piers</a>
  */
 public abstract class AbstractIntentCompletionProcessor implements IContentAssistProcessor {
+	/**
+	 * New line.
+	 */
+	private static final String NEWLINE = "\n";
+
 	/** The auto activation characters for completion proposal. */
 	private static final char[] AUTO_ACTIVATION_CHARACTERS = new char[] {' ',
 	};
@@ -220,6 +226,18 @@
 	}
 
 	/**
+	 * Create a variable proposal with the given parameters.
+	 * 
+	 * @param proposal
+	 *            the proposal
+	 * @return the variable proposal
+	 */
+	protected ICompletionProposal createVariableProposal(ExternalParserCompletionProposal proposal) {
+		return new CompletionProposal(proposal.getName(), offset - start.length(), start.length(), proposal
+				.getName().length(), proposal.getImage(), proposal.getName(), null, null);
+	}
+
+	/**
 	 * Create a template proposal with the given parameters.
 	 * 
 	 * @param templateName
@@ -236,7 +254,7 @@
 			String templatePattern, String templateImagePath) {
 		int startLength = start.length();
 		Template template = new Template(templateName, templateDescription, getContextType(),
-				templatePattern.replaceAll("\n", "\n" + indentation), true);
+				templatePattern.replaceAll(NEWLINE, NEWLINE + indentation), true);
 		TemplateContextType type = new TemplateContextType(getContextType(), getContextType());
 		TemplateContext context = new DocumentTemplateContext(type, document, offset - startLength,
 				startLength);
@@ -249,6 +267,31 @@
 	}
 
 	/**
+	 * Create a template proposal with the given parameters.
+	 * 
+	 * @param templateName
+	 *            the template name
+	 * @param templateDescription
+	 *            the template description
+	 * @param templatePattern
+	 *            the template pattern
+	 * @param templateImage
+	 *            the template image
+	 * @return the template proposal
+	 */
+	protected TemplateProposal createTemplateProposalWithExternalImage(String templateName,
+			String templateDescription, String templatePattern, Image templateImage) {
+		int startLength = start.length();
+		Template template = new Template(templateName, templateDescription, getContextType(),
+				templatePattern.replaceAll(NEWLINE, NEWLINE + indentation), true);
+		TemplateContextType type = new TemplateContextType(getContextType(), getContextType());
+		TemplateContext context = new DocumentTemplateContext(type, document, offset - startLength,
+				startLength);
+		Region region = new Region(offset - startLength, startLength);
+		return new TemplateProposal(template, context, region, templateImage);
+	}
+
+	/**
 	 * Returns the last index of the given pattern inside the given text.
 	 * 
 	 * @param text
@@ -265,5 +308,4 @@
 		}
 		return end;
 	}
-
 }
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/DescriptionUnitCompletionProcessor.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/DescriptionUnitCompletionProcessor.java
index 2cf5df2..6ada502 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/DescriptionUnitCompletionProcessor.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/DescriptionUnitCompletionProcessor.java
@@ -10,18 +10,29 @@
  *******************************************************************************/
 package org.eclipse.mylyn.docs.intent.client.ui.editor.completion;
 
+import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
 
+import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.mylyn.docs.intent.client.ui.editor.scanner.IntentPartitionScanner;
 import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.external.parser.IntentExternalParserContributionRegistry;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.ExternalParserCompletionProposal;
+import org.eclipse.mylyn.docs.intent.external.parser.contribution.IExternalParser;
 
 /**
  * Computes the completion proposal for DescriptionUnits.
  * 
  * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
  */
 public class DescriptionUnitCompletionProcessor extends AbstractIntentCompletionProcessor {
 
@@ -43,11 +54,64 @@
 	@Override
 	protected ICompletionProposal[] computeCompletionProposals() {
 		ArrayList<ICompletionProposal> proposals = Lists.newArrayList();
+		// Get proposals provided by extended parsers
+		proposals.addAll(getExtendedParsersCompletionProposals(getCurrentSentences()));
+
 		// TODO propose @see ...
 		return proposals.toArray(new ICompletionProposal[proposals.size()]);
 	}
 
 	/**
+	 * Get extended parser completion proposals.
+	 * 
+	 * @param currentSentences
+	 *            Current sentence
+	 * @return Completion proposals provided by extended parsers
+	 */
+	private Collection<? extends ICompletionProposal> getExtendedParsersCompletionProposals(
+			Iterable<String> currentSentences) {
+		List<ICompletionProposal> proposals = Lists.newArrayList();
+		for (Iterator<IExternalParser> iterator = IntentExternalParserContributionRegistry
+				.getExternalParserContributions().iterator(); iterator.hasNext();) {
+			IExternalParser externalParserContribution = iterator.next();
+			for (ExternalParserCompletionProposal proposal : externalParserContribution
+					.getCompletionVariablesProposals(currentSentences)) {
+				proposals.add(createVariableProposal(proposal));
+			}
+			for (ExternalParserCompletionProposal proposal : externalParserContribution
+					.getCompletionTemplatesProposals(currentSentences)) {
+				proposals.add(createTemplateProposalWithExternalImage(proposal.getName(),
+						proposal.getDescription(), proposal.getPattern(), proposal.getImage()));
+			}
+		}
+		return proposals;
+	}
+
+	/**
+	 * Get parsed sentences.
+	 * 
+	 * @return Parsed sentences
+	 */
+	private Iterable<String> getCurrentSentences() {
+		try {
+			// Get the currently focused paragraph
+			String text = document.get(0, offset);
+			int paragraphStartOffset = -1;
+			for (Pattern startPargraphPattern : IntentCompletionProcessor.PATTERNS_BY_CONTEXT) {
+				paragraphStartOffset = Math.max(paragraphStartOffset,
+						getLastIndexOf(text, startPargraphPattern));
+			}
+			if (paragraphStartOffset > -1) {
+				text = text.substring(paragraphStartOffset);
+			}
+			return Splitter.on("\n").split(text);
+		} catch (BadLocationException e) {
+			// Silent catch: we return an empty collection
+			return Sets.newLinkedHashSet();
+		}
+	}
+
+	/**
 	 * {@inheritDoc}
 	 * 
 	 * @see org.eclipse.mylyn.docs.intent.client.ui.editor.completion.AbstractIntentCompletionProcessor#getContextType()
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/IntentCompletionProcessor.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/IntentCompletionProcessor.java
index f941591..954feea 100644
--- a/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/IntentCompletionProcessor.java
+++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui/src/org/eclipse/mylyn/docs/intent/client/ui/editor/completion/IntentCompletionProcessor.java
@@ -34,6 +34,32 @@
  */
 public class IntentCompletionProcessor extends AbstractIntentCompletionProcessor {
 
+	// Patterns by contexts.
+	/**
+	 * All patterns allowing to detect the current context.
+	 */
+	public static final Pattern[] PATTERNS_BY_CONTEXT = new Pattern[] {
+			Pattern.compile("Document\\s+[^{\r\n]*\\{"), Pattern.compile("Chapter\\s+[^{\r\n]*\\{"),
+			Pattern.compile("Section\\s+[^{\r\n]*\\{"),
+	};
+
+	// Keywords by contexts.
+	// CHECKSTYLE:OFF Keywords have the same name than templates names & templates description, but merging
+	// their declaration have no sense.
+	private static final String[][] KEYWORDS_BY_CONTEXT = new String[][] {
+			// Document-level keywords
+			new String[] {"Chapter",
+			},
+			// Chapter-level keywords
+			new String[] {"Section",
+			},
+			// Section-level keywords
+			new String[] {"Section", "@M",
+			},
+	};
+
+	// CHECKSTYLE:ON
+
 	// Accurate contexts.
 	/**
 	 * Constant representing default context.
@@ -55,31 +81,6 @@
 	 */
 	private static final int SECTION_CONTEXT = 2;
 
-	// Patterns by contexts.
-	/**
-	 * All patterns allowing to detect the current context.
-	 */
-	private static final Pattern[] PATTERNS_BY_CONTEXT = new Pattern[] {
-			Pattern.compile("Document\\s+[^{\r\n]*\\{"), Pattern.compile("Chapter\\s+[^{\r\n]*\\{"),
-			Pattern.compile("Section\\s+[^{\r\n]*\\{"),
-	};
-
-	// Keywords by contexts.
-	// CHECKSTYLE:OFF Keywords have the same name than templates names & templates description, but merging
-	// their declaration have no sense.
-	private static final String[][] KEYWORDS_BY_CONTEXT = new String[][] {
-			// Document-level keywords
-			new String[] {"Chapter",
-			},
-			// Chapter-level keywords
-			new String[] {"Section",
-			},
-			// Section-level keywords
-			new String[] {"Section", "@M",
-			},
-	};
-
-	// CHECKSTYLE:ON
 	/**
 	 * Current context ID.
 	 */
diff --git a/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/query/ModelingUnitQuery.java b/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/query/ModelingUnitQuery.java
new file mode 100644
index 0000000..f81826c
--- /dev/null
+++ b/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/query/ModelingUnitQuery.java
@@ -0,0 +1,45 @@
+package org.eclipse.mylyn.docs.intent.collab.common.query;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+import java.util.Collection;
+
+import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryAdapter;
+import org.eclipse.mylyn.docs.intent.core.modelingunit.ExternalContentReference;
+import org.eclipse.mylyn.docs.intent.core.modelingunit.ModelingUnit;
+
+/**
+ * An utility class allowing to query the {@link ModelingUnit}.
+ * 
+ * @author <a href="mailto:melanie.bats@obeo.fr">Melanie Bats</a>
+ */
+public class ModelingUnitQuery extends AbstractIntentQuery {
+	/**
+	 * Creates the query.
+	 * 
+	 * @param repositoryAdapter
+	 *            the {@link RepositoryAdapter} to use for querying the repository.
+	 */
+	public ModelingUnitQuery(RepositoryAdapter repositoryAdapter) {
+		super(repositoryAdapter);
+	}
+
+	/**
+	 * Returns all the {@link org.eclipse.mylyn.docs.intent.core.document.IntentReference}s contained in the
+	 * queried {@link org.eclipse.mylyn.docs.intent.core.document.IntentDocument}.
+	 * 
+	 * @return all the {@link org.eclipse.mylyn.docs.intent.core.document.IntentReference}s contained in the
+	 *         queried {@link org.eclipse.mylyn.docs.intent.core.document.IntentDocument}
+	 */
+	public Collection<ExternalContentReference> getAllExternalContentReferences() {
+		IntentDocumentQuery intentDocumentQuery = new IntentDocumentQuery(repositoryAdapter);
+
+		Collection<ExternalContentReference> externalContentReferences = Sets.newLinkedHashSet();
+		for (ModelingUnit unit : intentDocumentQuery.getAllModelingUnits()) {
+			externalContentReferences.addAll(Sets.newLinkedHashSet(Iterables.filter(unit.getInstructions(),
+					ExternalContentReference.class)));
+		}
+		return externalContentReferences;
+	}
+}
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();
+	}
+}