[bugzilla 384447] Improve RepositoryAdapter's SaveContexts Lifecycle
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/META-INF/MANIFEST.MF b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/META-INF/MANIFEST.MF
index 55c1b5f..266fd11 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/META-INF/MANIFEST.MF
@@ -23,4 +23,5 @@
  org.eclipse.emf.compare.match;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.mylyn.docs.intent.retro;bundle-version="0.7.0",
  org.eclipse.mylyn.docs.intent.compare;bundle-version="0.7.0",
- org.eclipse.mylyn.docs.intent.modelingunit.update;bundle-version="0.7.0"
+ org.eclipse.mylyn.docs.intent.modelingunit.update;bundle-version="0.7.0",
+ org.eclipse.mylyn.docs.intent.test.server
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/suite/UITestSuite.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/suite/UITestSuite.java
index d523407..1a4c6ab 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/suite/UITestSuite.java
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/suite/UITestSuite.java
@@ -15,6 +15,7 @@
 import junit.framework.TestSuite;
 import junit.textui.TestRunner;
 
+import org.eclipse.mylyn.docs.intent.client.ui.test.unit.cdo.CDOIntegrationTest;
 import org.eclipse.mylyn.docs.intent.client.ui.test.unit.compare.ChangeEditorUpdateTest;
 import org.eclipse.mylyn.docs.intent.client.ui.test.unit.compare.IntentMatchEngineTests;
 import org.eclipse.mylyn.docs.intent.client.ui.test.unit.compare.SimpleOrderTests;
@@ -109,6 +110,14 @@
 		updatesSuite.addTestSuite(DragAndDropTest.class);
 		uiTestSuite.addTest(updatesSuite);
 
+		/*
+		 * CDO related test Suite
+		 */
+		final TestSuite cdoSuite = new TestSuite("CDO integration tests");
+		suite.addTest(cdoSuite);
+
+		cdoSuite.addTestSuite(CDOIntegrationTest.class);
+
 		return suite;
 	}
 
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/CDOIntegrationTest.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/CDOIntegrationTest.java
new file mode 100644
index 0000000..284979a
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/CDOIntegrationTest.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 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.client.ui.test.unit.cdo;
+
+import org.eclipse.mylyn.docs.intent.client.ui.test.unit.cdo.util.AbstractIntentCDOTest;
+import org.eclipse.mylyn.docs.intent.collab.common.location.IntentLocations;
+import org.eclipse.mylyn.docs.intent.collab.common.repository.IntentRepositoryManager;
+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.IntentDocument;
+import org.eclipse.mylyn.docs.intent.core.document.IntentDocumentFactory;
+
+/**
+ * Basic tests ensuring that Intent works correctly when the document is stored on a CDO Repository.
+ * 
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public class CDOIntegrationTest extends AbstractIntentCDOTest {
+
+	private static final String INTENT_ABSTRACT_RESOURCE_DOCUMENT_PATH = "data/unit/documents/scenario/abstract_resources.intent";
+
+	/**
+	 * A test that ensure that a local user can :
+	 * <ul>
+	 * <li>Create/get an intent document located on a cdo repository</li>
+	 * <li>Receive changes made by remote users.</li>
+	 * </ul>
+	 * 
+	 * @throws Exception
+	 */
+	public void testBasicRelationshipBetweenLocalAndRemoteUser() throws Exception {
+		// Local user creates and get the intent project
+		setUpIntentProject("myIntentProject", INTENT_ABSTRACT_RESOURCE_DOCUMENT_PATH, false);
+		final IntentDocument cdoIntentDocument = getIntentDocument();
+		repositoryAdapter.save();
+		final int initialChapterNumber = cdoIntentDocument.getChapters().size();
+		assertNotNull("Intent document has not been correctly created on the repository", cdoIntentDocument);
+
+		// Some remote user modifies the intent document by adding a chapter
+		final RepositoryAdapter remoteUser = IntentRepositoryManager.INSTANCE.getRepository(
+				"cdo:/myIntentProject").createRepositoryAdapter();
+		remoteUser.openSaveContext();
+		remoteUser.execute(new IntentCommand() {
+
+			public void execute() {
+				IntentDocument remoteIntentDocument;
+				try {
+					remoteIntentDocument = (IntentDocument)remoteUser
+							.getOrCreateResource(IntentLocations.INTENT_INDEX).getContents().iterator()
+							.next();
+					assertFalse("Remote and Local user should not share the same instance",
+							remoteIntentDocument == cdoIntentDocument);
+					remoteIntentDocument.getChapters().add(
+							IntentDocumentFactory.eINSTANCE.createIntentChapter());
+				} catch (ReadOnlyException e) {
+					fail(e.getMessage());
+				}
+			}
+		});
+		assertEquals("Remote modification should not have been received by the local user",
+				initialChapterNumber, cdoIntentDocument.getChapters().size());
+		remoteUser.save();
+		remoteUser.closeContext();
+
+		assertEquals("Remote modification should have been received by the local user",
+				initialChapterNumber + 1, cdoIntentDocument.getChapters().size());
+	}
+
+	/**
+	 * Ensures that when remote users make modifications and commit.
+	 * 
+	 * @throws Exception
+	 */
+	// public void testRemoteChangesIntegrationInsideEditor() throws Exception {
+	// Local user opens an editor on an Intent document
+	// setUpIntentProject("myIntentProject", INTENT_ABSTRACT_RESOURCE_DOCUMENT_PATH, false);
+	// waitForAllOperationsInUIThread();
+	// IntentEditor editor = openIntentEditor(getIntentDocument());
+	// waitForAllOperationsInUIThread();
+	// String initialContent = ((IntentEditorDocument)editor.getDocumentProvider().getDocument(
+	// editor.getEditorInput())).get();
+
+	// Remote user adds an untitle chapter
+	// final RepositoryAdapter remoteUser = IntentRepositoryManager.INSTANCE.getRepository(
+	// "cdo:/myIntentProject").createRepositoryAdapter();
+	// remoteUser.openSaveContext();
+	// remoteUser.execute(new IntentCommand() {
+	//
+	// public void execute() {
+	// IntentDocument remoteIntentDocument;
+	// try {
+	// remoteIntentDocument = (IntentDocument)remoteUser
+	// .getOrCreateResource(IntentLocations.INTENT_INDEX).getContents().iterator()
+	// .next();
+	// remoteIntentDocument.getChapters().add(
+	// IntentDocumentFactory.eINSTANCE.createIntentChapter());
+	// } catch (ReadOnlyException e) {
+	// fail(e.getMessage());
+	// }
+	// }
+	// });
+	// remoteUser.save();
+	// remoteUser.closeContext();
+	// waitForAllOperationsInUIThread();
+
+	// Local user should see the new chapter
+	// assertNotSame(initialContent,
+	// ((IntentEditorDocument)editor.getDocumentProvider().getDocument(editor.getEditorInput()))
+	// .get());
+	//
+	// editor.close(false);
+	// }
+}
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/util/AbstractIntentCDOTest.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/util/AbstractIntentCDOTest.java
new file mode 100644
index 0000000..1a8deee
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/cdo/util/AbstractIntentCDOTest.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.client.ui.test.unit.cdo.util;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest;
+import org.eclipse.mylyn.docs.intent.collab.common.repository.IntentRepositoryInitializer;
+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.repository.RepositoryConnectionException;
+import org.eclipse.mylyn.docs.intent.test.server.IntentCDORepository;
+
+/**
+ * An abstract test class providing API for managing an Intent document stored in a CDO Repository.
+ * 
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public class AbstractIntentCDOTest extends AbstractIntentUITest {
+
+	private static final String INTENT_REPOSITORY_NAME = "intent-server";
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest#setUp()
+	 */
+	@Override
+	protected void setUp() throws Exception {
+		// First step is to launch a CDOServer
+		IntentCDORepository.start(true, INTENT_REPOSITORY_NAME);
+
+		// Otherwise, everything is the same as local
+		super.setUp();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest#tearDown()
+	 */
+	@Override
+	protected void tearDown() throws Exception {
+		super.tearDown();
+
+		// Stopping the CDOServer
+		IntentCDORepository.stop();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest#setUpIntentProject(java.lang.String,
+	 *      java.lang.String, boolean)
+	 */
+	@Override
+	protected void setUpIntentProject(String projectName, String intentDocumentPath,
+			boolean listenForRepository) {
+		super.setUpIntentProject("cdo:/" + INTENT_REPOSITORY_NAME + "/" + projectName, intentDocumentPath,
+				listenForRepository);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest#doCreateIntentProject(java.lang.String,
+	 *      java.lang.String)
+	 */
+	@Override
+	protected void doCreateIntentProject(String projectName, String intentDocumentContent)
+			throws CoreException {
+		// Step 1: create the repository
+		try {
+			repository = IntentRepositoryManager.INSTANCE.getRepository(projectName);
+
+			repositoryAdapter = repository.createRepositoryAdapter();
+			repositoryAdapter.openSaveContext();
+			assertNotNull(repository);
+			assertNotNull(repositoryAdapter);
+
+			// Step 2: initialise content
+			IntentRepositoryInitializer.initializeContent(projectName, intentDocumentContent);
+		} catch (RepositoryConnectionException e) {
+			fail("Failed to create CDO Repository '" + projectName + "': " + e.getMessage());
+		} catch (ReadOnlyException e) {
+			fail("Failed to open a Transaction on the CDO Repository '" + projectName + "': "
+					+ e.getMessage());
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest#additionalSetUpOperations()
+	 */
+	@Override
+	protected void additionalSetUpOperations() {
+
+	}
+}
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/compare/IntentMatchEngineTests.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/compare/IntentMatchEngineTests.java
index ed32f42..e09121d 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/compare/IntentMatchEngineTests.java
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/compare/IntentMatchEngineTests.java
@@ -32,10 +32,17 @@
 import org.eclipse.mylyn.docs.intent.parser.IntentParser;
 import org.eclipse.mylyn.docs.intent.parser.modelingunit.ParseException;
 
+/**
+ * Test ensuring that the Intent match engine works as expected.
+ * 
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
 public class IntentMatchEngineTests extends AbstractIntentUITest {
 
 	private static final String INTENT_DOCUMENT_FOLDER = "data/unit/documents/editorupdates/";
 
+	private static final String LINEBREAK = "\n";
+
 	private Collection<AssertionFailedError> errors = Sets.newLinkedHashSet();
 
 	private int compareCasesNumber;
@@ -121,7 +128,7 @@
 				String message = "One new chapter should be detected at position " + position;
 				try {
 					DiffElement diff = assertDiffElementIsAsExpected(message, differences, 2);
-					assertEquals(message + "\n" + getDiffAsString(differences), DifferenceKind.ADDITION,
+					assertEquals(message + LINEBREAK + getDiffAsString(differences), DifferenceKind.ADDITION,
 							diff.getKind());
 					assertEquals(message + getDiffAsString(differences), newChapter,
 							((ModelElementChangeLeftTarget)diff).getLeftElement());
@@ -153,11 +160,11 @@
 			try {
 				List<DiffElement> differences = IntentASTMerger.getDifferences(copy, getIntentDocument());
 				DiffElement diff = assertDiffElementIsAsExpected(message, differences, 2);
-				assertEquals(message + "\n" + getDiffAsString(differences), DifferenceKind.DELETION,
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), DifferenceKind.DELETION,
 						diff.getKind());
-				assertEquals(message + "\n" + getDiffAsString(differences), chapterToRemoveInOriginal,
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), chapterToRemoveInOriginal,
 						((ModelElementChangeRightTarget)diff).getRightElement());
-				assertEquals(message + "\n" + getDiffAsString(differences), copy,
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), copy,
 						((ModelElementChangeRightTarget)diff).getLeftParent());
 			} catch (AssertionFailedError e) {
 				errors.add(e);
@@ -199,11 +206,11 @@
 						+ sectionID;
 				try {
 					DiffElement diff = assertDiffElementIsAsExpected(message, differences, containerLevel);
-					assertEquals(message + "\n" + getDiffAsString(differences), DifferenceKind.ADDITION,
+					assertEquals(message + LINEBREAK + getDiffAsString(differences), DifferenceKind.ADDITION,
 							diff.getKind());
-					assertEquals(message + "\n" + getDiffAsString(differences), newSection,
+					assertEquals(message + LINEBREAK + getDiffAsString(differences), newSection,
 							((ModelElementChangeLeftTarget)diff).getLeftElement());
-					assertEquals(message + "\n" + getDiffAsString(differences), container,
+					assertEquals(message + LINEBREAK + getDiffAsString(differences), container,
 							((ModelElementChangeLeftTarget)diff).getRightParent());
 				} catch (AssertionFailedError e) {
 					errors.add(e);
@@ -255,12 +262,11 @@
 
 			try {
 				DiffElement diff = assertDiffElementIsAsExpected(message, differences, containerLevel);
-				assertEquals(message + "\n" + getDiffAsString(differences), DifferenceKind.DELETION,
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), DifferenceKind.DELETION,
 						diff.getKind());
-				assertEquals(message + "\n" + getDiffAsString(differences),
-						container.getIntentContent().get(trueIndex),
-						((ModelElementChangeRightTarget)diff).getRightElement());
-				assertEquals(message + "\n" + getDiffAsString(differences), containerCopy,
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), container.getIntentContent()
+						.get(trueIndex), ((ModelElementChangeRightTarget)diff).getRightElement());
+				assertEquals(message + LINEBREAK + getDiffAsString(differences), containerCopy,
 						((ModelElementChangeRightTarget)diff).getLeftParent());
 			} catch (AssertionFailedError e) {
 				errors.add(e);
@@ -291,27 +297,28 @@
 	protected DiffElement assertDiffElementIsAsExpected(String message, Collection<DiffElement> differences,
 			int expectedLevel) {
 		compareCasesNumber++;
-		assertEquals(message + "\n" + getDiffAsString(differences), 1, differences.size());
+		assertEquals(message + LINEBREAK + getDiffAsString(differences), 1, differences.size());
 
 		// We want to have exactly one difference at the expected level
 		DiffElement childDiff = differences.iterator().next();
 		int currentLevel = 0;
 		while (childDiff != null && currentLevel < expectedLevel) {
-			assertEquals(message + "\n" + getDiffAsString(differences), 1, childDiff.getSubDiffElements()
-					.size());
+			assertEquals(message + LINEBREAK + getDiffAsString(differences), 1, childDiff
+					.getSubDiffElements().size());
 			currentLevel++;
 			childDiff = childDiff.getSubDiffElements().iterator().next();
 		}
 
 		// This difference should not have any sub difference elements
-		assertEquals(message + "\n" + getDiffAsString(differences), 0, childDiff.getSubDiffElements().size());
+		assertEquals(message + LINEBREAK + getDiffAsString(differences), 0, childDiff.getSubDiffElements()
+				.size());
 		return childDiff;
 	}
 
 	protected String getDiffAsString(Collection<DiffElement> differences) {
 		String diff = "";
 		for (DiffElement element : differences) {
-			diff += element.toString() + "\n";
+			diff += element.toString() + LINEBREAK;
 			diff += getDiffAsString(element.getSubDiffElements());
 		}
 		return diff;
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/repository/IntentRepositoryStructurerTest.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/repository/IntentRepositoryStructurerTest.java
index 17e5114..90e8421 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/repository/IntentRepositoryStructurerTest.java
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/repository/IntentRepositoryStructurerTest.java
@@ -39,6 +39,20 @@
  */
 public class IntentRepositoryStructurerTest extends AbstractIntentUITest {
 
+	private static final String CHAPTER_KEYWORD = "Chapter";
+	private static final String SUBSECTION_2_1_1 = "2.1.1";
+	private static final String SUBSECTION_4_1_2 = "4.1.2";
+	private static final String SUBSECTION_4_1_1 = "4.1.1";
+	private static final String SECTION_4_1 = "4.1";
+	private static final String CHAPTER_4 = "4";
+	private static final String CHAPTER_3 = "3";
+	private static final String CHAPTER_2 = "2";
+	private static final String CHAPTER_1 = "1";
+	private static final String SECTION_3_2 = "3.2";
+	private static final String SECTION_3_1 = "3.1";
+	private static final String SECTION_2_2 = "2.2";
+	private static final String SECTION_2_1 = "2.1";
+	private static final String SECTION1_1 = "1.1";
 	private static final String NEW_CHAPTER = "\tChapter {\n\t\tSection {\n\t\t}\n\t}\n}";
 
 	/**
@@ -52,8 +66,8 @@
 		IntentEditor editor = openIntentEditor();
 
 		// Step 2: we check the initial structure of the project
-		checkRepositoryStructure(Lists.newArrayList("1", "2", "3"),
-				Lists.newArrayList("1.1", "2.1", "2.2", "3.1", "3.1.1", "3.1.2"),
+		checkRepositoryStructure(Lists.newArrayList(CHAPTER_1, CHAPTER_2, CHAPTER_3),
+				Lists.newArrayList(SECTION1_1, SECTION_2_1, SECTION_2_2, SECTION_3_1, "3.1.1", "3.1.2"),
 				Lists.newArrayList("1.1.1", "3.1.1"));
 
 		// Step 3: adding a new chapter a the begging
@@ -66,9 +80,9 @@
 
 		editor.doSave(new NullProgressMonitor());
 		waitForAllOperationsInUIThread();
-		checkRepositoryStructure(Lists.newArrayList("1", "2", "3", "4"),
-				Lists.newArrayList("1.1", "2.1", "3.1", "3.2", "4.1", "4.1.1", "4.1.2"),
-				Lists.newArrayList("2.1.1", "4.1.1"));
+		checkRepositoryStructure(Lists.newArrayList(CHAPTER_1, CHAPTER_2, CHAPTER_3, CHAPTER_4),
+				Lists.newArrayList(SECTION1_1, SECTION_2_1, SECTION_3_1, SECTION_3_2, SECTION_4_1, SUBSECTION_4_1_1, SUBSECTION_4_1_2),
+				Lists.newArrayList(SUBSECTION_2_1_1, SUBSECTION_4_1_1));
 
 		// Step 4: adding a new chapter at the end
 		String documentWithChapterAtTheEnd = document.get().substring(0, document.get().lastIndexOf("}"))
@@ -77,34 +91,34 @@
 		document.set(documentWithChapterAtTheEnd);
 		editor.doSave(new NullProgressMonitor());
 		waitForAllOperationsInUIThread();
-		checkRepositoryStructure(Lists.newArrayList("1", "2", "3", "4", "5"),
-				Lists.newArrayList("1.1", "2.1", "3.1", "3.2", "4.1", "4.1.1", "4.1.2", "5.1"),
-				Lists.newArrayList("2.1.1", "4.1.1"));
+		checkRepositoryStructure(Lists.newArrayList(CHAPTER_1, CHAPTER_2, CHAPTER_3, CHAPTER_4, "5"),
+				Lists.newArrayList(SECTION1_1, SECTION_2_1, SECTION_3_1, SECTION_3_2, SECTION_4_1, SUBSECTION_4_1_1, SUBSECTION_4_1_2, "5.1"),
+				Lists.newArrayList(SUBSECTION_2_1_1, SUBSECTION_4_1_1));
 
 		// Step 5 : adding a new chapter in the middle
 		String chapterToAdd = "";
 		int index = document.get().indexOf("The 2.2 Section");
 		chapterToAdd = document.get().substring(index);
-		chapterToAdd = chapterToAdd.substring(chapterToAdd.indexOf("Chapter"),
-				chapterToAdd.lastIndexOf("Chapter"));
+		chapterToAdd = chapterToAdd.substring(chapterToAdd.indexOf(CHAPTER_KEYWORD),
+				chapterToAdd.lastIndexOf(CHAPTER_KEYWORD));
 		document.set(document.get().replace(chapterToAdd, chapterToAdd + NEW_CHAPTER));
 		editor.doSave(new NullProgressMonitor());
 		waitForAllOperationsInUIThread();
-		checkRepositoryStructure(Lists.newArrayList("1", "2", "3", "4", "5"),
-				Lists.newArrayList("1.1", "2.1", "3.1", "3.2", "4.1", "4.1.1", "4.1.2", "5.1"),
-				Lists.newArrayList("2.1.1", "4.1.1"));
+		checkRepositoryStructure(Lists.newArrayList(CHAPTER_1, CHAPTER_2, CHAPTER_3, CHAPTER_4, "5"),
+				Lists.newArrayList(SECTION1_1, SECTION_2_1, SECTION_3_1, SECTION_3_2, SECTION_4_1, SUBSECTION_4_1_1, SUBSECTION_4_1_2, "5.1"),
+				Lists.newArrayList(SUBSECTION_2_1_1, SUBSECTION_4_1_1));
 
 		// Step 6 : deleting a chapter in the middle
 		String chapterToDelete = "";
 		index = document.get().indexOf("The 2.2 Section");
 		chapterToDelete = document.get().substring(index);
-		chapterToDelete = chapterToDelete.substring(chapterToDelete.indexOf("Chapter"),
-				chapterToDelete.lastIndexOf("Chapter"));
+		chapterToDelete = chapterToDelete.substring(chapterToDelete.indexOf(CHAPTER_KEYWORD),
+				chapterToDelete.lastIndexOf(CHAPTER_KEYWORD));
 		document.set(document.get().replace(chapterToDelete, ""));
 		editor.doSave(new NullProgressMonitor());
 		waitForAllOperationsInUIThread();
-		checkRepositoryStructure(Lists.newArrayList("1", "2", "3", "4"),
-				Lists.newArrayList("1.1", "2.1", "3.1", "3.2", "4.1"), Lists.newArrayList("2.1.1"));
+		checkRepositoryStructure(Lists.newArrayList(CHAPTER_1, CHAPTER_2, CHAPTER_3, CHAPTER_4),
+				Lists.newArrayList(SECTION1_1, SECTION_2_1, SECTION_3_1, SECTION_3_2, SECTION_4_1), Lists.newArrayList(SUBSECTION_2_1_1));
 	}
 
 	/**
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/scenario/CompilerNotificationsTest.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/scenario/CompilerNotificationsTest.java
index 75ab90b..5e0d4ab 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/scenario/CompilerNotificationsTest.java
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/unit/scenario/CompilerNotificationsTest.java
@@ -19,6 +19,7 @@
 import org.eclipse.mylyn.docs.intent.client.ui.editor.annotation.IntentAnnotationMessageType;
 import org.eclipse.mylyn.docs.intent.client.ui.test.util.AbstractIntentUITest;
 import org.eclipse.mylyn.docs.intent.client.ui.test.util.AnnotationUtils;
+import org.eclipse.mylyn.docs.intent.parser.IntentKeyWords;
 import org.eclipse.mylyn.docs.intent.parser.test.utils.FileToStringConverter;
 
 /**
@@ -28,6 +29,10 @@
  */
 public class CompilerNotificationsTest extends AbstractIntentUITest {
 
+	private static final String COMPILER_SHOULD_NOT_DETECT_ISSUE_FAILURE_MESSAGE = "The compiler should not detect any issue";
+
+	private static final String ECLASS_NAME = "c1";
+
 	private static final String INTENT_DATA_FOLDER = "data/unit/documents/scenario/compilerNotifications/";
 
 	private IntentEditor editor;
@@ -55,21 +60,21 @@
 	public void testCompilerIsNotifiedWhenModifyingMU() {
 		// Update Modeling Unit : make it pass
 		repositoryListener.clearPreviousEntries();
-		document.set(document.get().replace("c1", "new EClass c1 {}"));
+		document.set(document.get().replace(ECLASS_NAME, "new EClass c1 {}"));
 		editor.doSave(new NullProgressMonitor());
 		waitForCompiler(true);
-		assertFalse("The compiler should not detect any issue", AnnotationUtils.hasIntentAnnotation(editor,
-				IntentAnnotationMessageType.COMPILER_ERROR, "", false));
+		assertFalse(COMPILER_SHOULD_NOT_DETECT_ISSUE_FAILURE_MESSAGE, AnnotationUtils.hasIntentAnnotation(
+				editor, IntentAnnotationMessageType.COMPILER_ERROR, "", false));
 		// FIXME add this condition
 		// waitForCompiler(false);
 
 		// Update Modeling Unit : Add an error
 		repositoryListener.clearPreviousEntries();
-		document.set(document.get().replace("new EClass c1 {}", "c1"));
+		document.set(document.get().replace("new EClass c1 {}", ECLASS_NAME));
 		editor.doSave(new NullProgressMonitor());
 		waitForCompiler(true);
-		assertTrue("The compiler should not detect any issue", AnnotationUtils.hasIntentAnnotation(editor,
-				IntentAnnotationMessageType.COMPILER_ERROR, "The Entity c1 cannot be resolved", true));
+		assertTrue(COMPILER_SHOULD_NOT_DETECT_ISSUE_FAILURE_MESSAGE, AnnotationUtils.hasIntentAnnotation(
+				editor, IntentAnnotationMessageType.COMPILER_ERROR, "The Entity c1 cannot be resolved", true));
 		// FIXME add this condition
 		// waitForCompiler(false);
 	}
@@ -88,7 +93,7 @@
 
 		// Renaming the section and change the issue
 		repositoryListener.clearPreviousEntries();
-		document.set(document.get().replace("c1", "cRenamed"));
+		document.set(document.get().replace(ECLASS_NAME, "cRenamed"));
 
 		editor.doSave(new NullProgressMonitor());
 		waitForCompiler(true);
@@ -104,7 +109,8 @@
 		repositoryListener.clearPreviousEntries();
 		String newSection = FileToStringConverter.getFileAsString(new File(INTENT_DATA_FOLDER
 				+ "newSection01.intent"));
-		document.set(document.get().replace("M@", "M@\n" + newSection));
+		document.set(document.get().replace(IntentKeyWords.MODELING_UNIT_END,
+				IntentKeyWords.MODELING_UNIT_END + "\n" + newSection));
 
 		editor.doSave(new NullProgressMonitor());
 		waitForCompiler(true);
@@ -115,8 +121,8 @@
 
 		// Create another new Modeling Unit : Add an error
 		repositoryListener.clearPreviousEntries();
-		int beginIndex = document.get().lastIndexOf("@M");
-		int endIndex = document.get().lastIndexOf("M@");
+		int beginIndex = document.get().lastIndexOf(IntentKeyWords.MODELING_UNIT_END);
+		int endIndex = document.get().lastIndexOf(IntentKeyWords.MODELING_UNIT_END);
 		document.set(document.get().substring(0, beginIndex) + document.get().substring(endIndex + 2));
 
 		editor.doSave(new NullProgressMonitor());
@@ -137,8 +143,8 @@
 
 		editor.doSave(new NullProgressMonitor());
 		waitForCompiler(true);
-		assertFalse("The compiler should not detect any issue", AnnotationUtils.hasIntentAnnotation(editor,
-				IntentAnnotationMessageType.COMPILER_ERROR, "", false));
+		assertFalse(COMPILER_SHOULD_NOT_DETECT_ISSUE_FAILURE_MESSAGE, AnnotationUtils.hasIntentAnnotation(
+				editor, IntentAnnotationMessageType.COMPILER_ERROR, "", false));
 		// FIXME add this condition
 		// waitForCompiler(false);
 
diff --git a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/util/AbstractIntentUITest.java b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/util/AbstractIntentUITest.java
index 2fbc81b..add2340 100644
--- a/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/util/AbstractIntentUITest.java
+++ b/tests/org.eclipse.mylyn.docs.intent.client.ui.test/src/org/eclipse/mylyn/docs/intent/client/ui/test/util/AbstractIntentUITest.java
@@ -56,7 +56,7 @@
 import org.eclipse.ui.PlatformUI;

 

 /**

- * An abstract test class providing API for manage an Intent IDE projects and editors.

+ * An abstract test class providing API for managing an Intent IDE projects and editors.

  * 

  * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>

  */

@@ -110,9 +110,6 @@
 		waitForAllOperationsInUIThread();

 		IntentEditorActivator.getDefault().getLog().addLogListener(this);

 

-		System.out.println("-- SETTED UP.;");

-		traceHeapSize();

-

 		openedEditors = new ArrayList<IntentEditor>();

 	}

 

@@ -169,17 +166,13 @@
 		setAllFieldsToNull();

 

 		super.tearDown();

-		long totalHeapSize = Runtime.getRuntime().totalMemory();

-		long usedHeap = totalHeapSize - Runtime.getRuntime().freeMemory();

-		System.out.println("-- TEARED DOWN.");

-		traceHeapSize();

 	}

 

 	/**

 	 * Creates and register an new {@link org.eclipse.mylyn.docs.intent.collab.handlers.RepositoryClient } in

 	 * charge of detecting that events happened on the repository.

 	 */

-	protected void registerRepositoryListener() {

+	protected final void registerRepositoryListener() {

 		this.repositoryListener = new RepositoryListenerForTests();

 		Platform.addLogListener(repositoryListener);

 	}

@@ -190,7 +183,7 @@
 	 * @param projectName

 	 *            the intent project name

 	 */

-	protected void setUpIntentProject(final String projectName) {

+	protected final void setUpIntentProject(final String projectName) {

 		setUpIntentProject(projectName, INTENT_EMPTY_DOC_PATH, false);

 	}

 

@@ -203,7 +196,7 @@
 	 *            the path of the intent document to use (relative to the

 	 *            org.eclipse.mylyn.docs.intent.client.ui.test project).

 	 */

-	protected void setUpIntentProject(final String projectName, String intentDocumentPath) {

+	protected final void setUpIntentProject(final String projectName, String intentDocumentPath) {

 		setUpIntentProject(projectName, intentDocumentPath, false);

 	}

 

@@ -223,38 +216,23 @@
 	protected void setUpIntentProject(final String projectName, String intentDocumentPath,

 			boolean listenForRepository) {

 		try {

-			// Step 1 : getting the content of the intent document located at the given path.

+			// Step 1: getting the content of the intent document located at the given path.

 			File file = new File(intentDocumentPath);

 			final String intentDocumentContent = FileToStringConverter.getFileAsString(file);

 

-			// Step 2 : creating the intent project

-			IWorkspaceRunnable create = new IWorkspaceRunnable() {

-				public void run(IProgressMonitor monitor) throws CoreException {

-					IProject project = WorkspaceUtils.createProject(projectName, monitor);

-					ToggleNatureAction.toggleNature(project);

+			// Step 2: creating the intent project

+			doCreateIntentProject(projectName, intentDocumentContent);

 

-					IntentRepositoryInitializer.initializeContent(projectName, intentDocumentContent);

-

-					// Step 3 : initializing all useful informations

-					intentProject = project;

-					setUpRepository(project);

-				}

-			};

-			ResourcesPlugin.getWorkspace().run(create, null);

-

-			while (repositoryAdapter == null

-			// && (repository == null || ((WorkspaceRepository)repository).getEditingDomain()

-			// .getCommandStack() == null)

-			) {

+			while (repositoryAdapter == null) {

 				Thread.sleep(10);

 			}

 

-			// Step 3 : registering the repository listener

+			// Step 3: registering the repository listener

 			registerRepositoryListener();

-

-			// Step 4: waiting for synchronizer to pass

 			repositoryListener.clearPreviousEntries();

-			waitForSynchronizer();

+

+			// Step 4: additional setup operations

+			additionalSetUpOperations();

 

 		} catch (CoreException e) {

 			AssertionFailedError error = new AssertionFailedError("Failed to create Intent project");

@@ -273,12 +251,39 @@
 	}

 

 	/**

+	 * Creates the intent project with the given name, with the given content.

+	 * 

+	 * @param projectName

+	 *            the name of the project to create

+	 * @param intentDocumentContent

+	 *            the content to associate to the created intent document

+	 * @throws CoreException

+	 *             if the project cannot be created properly

+	 */

+	protected void doCreateIntentProject(final String projectName, final String intentDocumentContent)

+			throws CoreException {

+		IWorkspaceRunnable create = new IWorkspaceRunnable() {

+			public void run(IProgressMonitor monitor) throws CoreException {

+				IProject project = WorkspaceUtils.createProject(projectName, monitor);

+				ToggleNatureAction.toggleNature(project);

+

+				IntentRepositoryInitializer.initializeContent(projectName, intentDocumentContent);

+

+				// Step 3 : initializing all useful informations

+				intentProject = project;

+				setUpRepository(project);

+			}

+		};

+		ResourcesPlugin.getWorkspace().run(create, null);

+	}

+

+	/**

 	 * Set up the repository for the given project.

 	 * 

 	 * @param project

 	 *            the project

 	 */

-	protected void setUpRepository(IProject project) {

+	protected final void setUpRepository(IProject project) {

 		assertNotNull(project);

 		try {

 			repository = IntentRepositoryManager.INSTANCE.getRepository(project.getName());

@@ -354,7 +359,7 @@
 	 * 

 	 * @return the intentDocument associated to the current Intent project

 	 */

-	protected IntentDocument getIntentDocument() {

+	protected final IntentDocument getIntentDocument() {

 		if (intentDocument == null) {

 			intentDocument = new IntentDocumentQuery(repositoryAdapter).getOrCreateIntentDocument();

 		}

@@ -368,7 +373,7 @@
 	 *            the number of the chapter

 	 * @return the chapter

 	 */

-	protected IntentChapter getIntentChapter(int number) {

+	protected final IntentChapter getIntentChapter(int number) {

 		return getIntentDocument().getChapters().get(number - 1);

 	}

 

@@ -379,7 +384,7 @@
 	 *            the number of the section

 	 * @return the section

 	 */

-	protected IntentSection getIntentSection(int... number) {

+	protected final IntentSection getIntentSection(int... number) {

 		IntentSection section = getIntentChapter(number[0]).getSubSections().get(number[1] - 1);

 		if (number.length > 2) {

 			for (int i = 2; i < number.length; i++) {

@@ -394,7 +399,7 @@
 	 * 

 	 * @return the opened editor

 	 */

-	protected IntentEditor openIntentEditor() {

+	protected final IntentEditor openIntentEditor() {

 		return openIntentEditor(getIntentDocument());

 	}

 

@@ -405,7 +410,7 @@
 	 *            the {@link IntentStructuredElement} to open an editor on

 	 * @return the opened editor

 	 */

-	protected IntentEditor openIntentEditor(IntentStructuredElement element) {

+	protected final IntentEditor openIntentEditor(IntentStructuredElement element) {

 		IntentEditorOpener.openIntentEditor(repository, element, true, null, true);

 		waitForAllOperationsInUIThread();

 		IntentEditor editor = IntentEditorOpener.getAlreadyOpenedEditor(element);

@@ -441,28 +446,28 @@
 	/**

 	 * Wait for synchronizer to complete work.

 	 */

-	protected void waitForSynchronizer() {

+	protected final void waitForSynchronizer() {

 		waitForSynchronizer(true);

 	}

 

 	/**

 	 * Wait for repository to complete work.

 	 */

-	protected void waitForIndexer() {

+	protected final void waitForIndexer() {

 		waitForIndexer(true);

 	}

 

 	/**

 	 * Wait for compiler to complete work.

 	 */

-	protected void waitForCompiler() {

+	protected final void waitForCompiler() {

 		waitForCompiler(true);

 	}

 

 	/**

 	 * Wait for the project explorer refresher to complete work.

 	 */

-	protected void waitForProjectExplorerRefresher() {

+	protected final void waitForProjectExplorerRefresher() {

 		waitForProjectExplorerRefresher(true);

 	}

 

@@ -472,7 +477,7 @@
 	 * @param synchronizerShouldBeNotified

 	 *            indicates whether the synchronizer should be notified or not

 	 */

-	protected void waitForSynchronizer(boolean synchronizerShouldBeNotified) {

+	protected final void waitForSynchronizer(boolean synchronizerShouldBeNotified) {

 		waitForAllOperationsInUIThread();

 		assertNotNull(

 				"Cannot wait for synchronizer : you need to initialize a repository listener by calling the registerRepositoryListener() method",

@@ -498,7 +503,7 @@
 	 * @param indexerShouldBeNotified

 	 *            indicates whether the indexer should be notified or not

 	 */

-	protected void waitForIndexer(boolean indexerShouldBeNotified) {

+	protected final void waitForIndexer(boolean indexerShouldBeNotified) {

 		waitForAllOperationsInUIThread();

 		assertNotNull(

 				"Cannot wait for Indexer : you need to initialize a repository listener by calling the registerRepositoryListener() method",

@@ -519,7 +524,7 @@
 	 * @param refresherShouldBeNotified

 	 *            indicates whether the indexer should be notified or not

 	 */

-	protected void waitForProjectExplorerRefresher(boolean refresherShouldBeNotified) {

+	protected final void waitForProjectExplorerRefresher(boolean refresherShouldBeNotified) {

 		waitForAllOperationsInUIThread();

 		assertNotNull(

 				"Cannot wait for Project Explorer Refresher : you need to initialize a repository listener by calling the registerRepositoryListener() method",

@@ -540,7 +545,7 @@
 	 * @param compilerShouldBeNotified

 	 *            indicates whether the compiler should be notified or not

 	 */

-	protected void waitForCompiler(boolean compilerShouldBeNotified) {

+	protected final void waitForCompiler(boolean compilerShouldBeNotified) {

 		waitForAllOperationsInUIThread();

 		assertNotNull(

 				"Cannot wait for compiler : you need to initialize a repository listener by calling the registerRepositoryListener() method",

@@ -561,6 +566,14 @@
 	}

 

 	/**

+	 * Additional operations performed at the end of set-up.

+	 */

+	protected void additionalSetUpOperations() {

+		// waiting for synchronizer to pass

+		waitForSynchronizer();

+	}

+

+	/**

 	 * Sets all fields of the current test case to null (to avoid memory leaks).

 	 */

 	private void setAllFieldsToNull() {

diff --git a/tests/org.eclipse.mylyn.docs.intent.parser.test/src/org/eclipse/mylyn/docs/intent/parser/errors/test/TestParserErrors.java b/tests/org.eclipse.mylyn.docs.intent.parser.test/src/org/eclipse/mylyn/docs/intent/parser/errors/test/TestParserErrors.java
index c707a2b..f426ee4 100644
--- a/tests/org.eclipse.mylyn.docs.intent.parser.test/src/org/eclipse/mylyn/docs/intent/parser/errors/test/TestParserErrors.java
+++ b/tests/org.eclipse.mylyn.docs.intent.parser.test/src/org/eclipse/mylyn/docs/intent/parser/errors/test/TestParserErrors.java
@@ -22,19 +22,28 @@
 
 	@Test
 	public void testMissingBracket() {
+		final int expectedErrorposition = 10;
+		final int expectedErrorLength = 22;
 		testErrorsOnFile("dataTests/intentDocuments/errors/missing_bracket.intent", new ParseException(
-				"Cannot handle any description unit here : only in sections or chapters.", 10, 22));
+				"Cannot handle any description unit here : only in sections or chapters.",
+				expectedErrorposition, expectedErrorLength));
 	}
 
 	@Test
 	public void testNewLines() {
+		final int expectedErrorposition = 10;
+		final int expectedErrorLength = 21;
 		testErrorsOnFile("dataTests/intentDocuments/errors/newlines.intent", new ParseException(
-				"Cannot handle any description unit here : only in sections or chapters.", 10, 21));
+				"Cannot handle any description unit here : only in sections or chapters.",
+				expectedErrorposition, expectedErrorLength));
 	}
 
 	@Test
 	public void testMisplacedModelingUnit() {
+		final int expectedErrorposition = 40;
+		final int expectedErrorLength = 7;
 		testErrorsOnFile("dataTests/intentDocuments/errors/misplacedModelingUnit.intent", new ParseException(
-				"Cannot handle any modeling unit here : only in sections.", 40, 7));
+				"Cannot handle any modeling unit here : only in sections.", expectedErrorposition,
+				expectedErrorLength));
 	}
 }
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/.checkstyle b/tests/org.eclipse.mylyn.docs.intent.test.server/.checkstyle
new file mode 100644
index 0000000..14d1806
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/.checkstyle
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fileset-config file-format-version="1.2.0" simple-config="true">
+    <fileset name="tous" enabled="true" check-config-name="Intent" local="false">
+        <file-match-pattern match-pattern="." include-pattern="true"/>
+    </fileset>
+</fileset-config>
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/.classpath b/tests/org.eclipse.mylyn.docs.intent.test.server/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/.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/tests/org.eclipse.mylyn.docs.intent.test.server/.project b/tests/org.eclipse.mylyn.docs.intent.test.server/.project
new file mode 100644
index 0000000..b344f29
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.mylyn.docs.intent.test.server</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>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+		<nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.mylyn.docs.intent.test.server/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..af0f20f
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/.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/tests/org.eclipse.mylyn.docs.intent.test.server/META-INF/MANIFEST.MF b/tests/org.eclipse.mylyn.docs.intent.test.server/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..0172c83
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Server
+Bundle-SymbolicName: org.eclipse.mylyn.docs.intent.test.server
+Bundle-Version: 0.7.0.qualifier
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.emf.cdo.server.db,
+ org.eclipse.emf.cdo.server.net4j,
+ org.eclipse.net4j.db.h2,
+ org.eclipse.net4j.tcp,
+ org.eclipse.emf.cdo.net4j
+Import-Package: org.h2,
+ org.h2.api,
+ org.h2.jdbcx,
+ org.h2.tools,
+ org.h2.util
+Export-Package: org.eclipse.mylyn.docs.intent.test.server
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/about.html b/tests/org.eclipse.mylyn.docs.intent.test.server/about.html
new file mode 100644
index 0000000..670d108
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/about.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
+<html xmlns="http://www.w3.org/1999/xhtml"> 
+<head> 
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> 
+<title>Eclipse Foundation Software User Agreement</title> 
+</head> 
+ 
+<body lang="EN-US"> 
+<h2>Eclipse Foundation Software User Agreement</h2> 
+<p>April 14, 2010</p> 
+ 
+<h3>Usage Of Content</h3> 
+ 
+<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
+   (COLLECTIVELY &quot;CONTENT&quot;).  USE OF THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND
+   CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW.  BY USING THE CONTENT, YOU AGREE THAT YOUR USE
+   OF THE CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR
+   NOTICES INDICATED OR REFERENCED BELOW.  IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND
+   CONDITIONS OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT USE THE CONTENT.</p> 
+ 
+<h3>Applicable Licenses</h3> 
+ 
+<p>Unless otherwise indicated, all Content made available by the Eclipse Foundation is provided to you under the terms and conditions of the Eclipse Public License Version 1.0
+   (&quot;EPL&quot;).  A copy of the EPL is provided with this Content and is also available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+   For purposes of the EPL, &quot;Program&quot; will mean the Content.</p> 
+ 
+<p>Content includes, but is not limited to, source code, object code, documentation and other files maintained in the Eclipse Foundation source code
+   repository (&quot;Repository&quot;) in software modules (&quot;Modules&quot;) and made available as downloadable archives (&quot;Downloads&quot;).</p> 
+ 
+<ul> 
+       <li>Content may be structured and packaged into modules to facilitate delivering, extending, and upgrading the Content.  Typical modules may include plug-ins (&quot;Plug-ins&quot;), plug-in fragments (&quot;Fragments&quot;), and features (&quot;Features&quot;).</li> 
+       <li>Each Plug-in or Fragment may be packaged as a sub-directory or JAR (Java&trade; ARchive) in a directory named &quot;plugins&quot;.</li> 
+       <li>A Feature is a bundle of one or more Plug-ins and/or Fragments and associated material.  Each Feature may be packaged as a sub-directory in a directory named &quot;features&quot;.  Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of the Plug-ins
+      and/or Fragments associated with that Feature.</li> 
+       <li>Features may also include other Features (&quot;Included Features&quot;). Within a Feature, files named &quot;feature.xml&quot; may contain a list of the names and version numbers of Included Features.</li> 
+</ul> 
+ 
+<p>The terms and conditions governing Plug-ins and Fragments should be contained in files named &quot;about.html&quot; (&quot;Abouts&quot;). The terms and conditions governing Features and
+Included Features should be contained in files named &quot;license.html&quot; (&quot;Feature Licenses&quot;).  Abouts and Feature Licenses may be located in any directory of a Download or Module
+including, but not limited to the following locations:</p> 
+ 
+<ul> 
+       <li>The top-level (root) directory</li> 
+       <li>Plug-in and Fragment directories</li> 
+       <li>Inside Plug-ins and Fragments packaged as JARs</li> 
+       <li>Sub-directories of the directory named &quot;src&quot; of certain Plug-ins</li> 
+       <li>Feature directories</li> 
+</ul> 
+ 
+<p>Note: if a Feature made available by the Eclipse Foundation is installed using the Provisioning Technology (as defined below), you must agree to a license (&quot;Feature Update License&quot;) during the
+installation process.  If the Feature contains Included Features, the Feature Update License should either provide you with the terms and conditions governing the Included Features or
+inform you where you can locate them.  Feature Update Licenses may be found in the &quot;license&quot; property of files named &quot;feature.properties&quot; found within a Feature.
+Such Abouts, Feature Licenses, and Feature Update Licenses contain the terms and conditions (or references to such terms and conditions) that govern your use of the associated Content in
+that directory.</p> 
+ 
+<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS.  SOME OF THESE
+OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):</p> 
+ 
+<ul> 
+       <li>Common Public License Version 1.0 (available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>)</li> 
+       <li>Apache Software License 1.1 (available at <a href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>)</li> 
+       <li>Apache Software License 2.0 (available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)</li> 
+       <li>Metro Link Public License 1.00 (available at <a href="http://www.opengroup.org/openmotif/supporters/metrolink/license.html">http://www.opengroup.org/openmotif/supporters/metrolink/license.html</a>)</li> 
+       <li>Mozilla Public License Version 1.1 (available at <a href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)</li> 
+</ul> 
+ 
+<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO USE OF THE CONTENT.  If no About, Feature License, or Feature Update License is provided, please
+contact the Eclipse Foundation to determine what terms and conditions govern that particular Content.</p> 
+ 
+ 
+<h3>Use of Provisioning Technology</h3> 
+ 
+<p>The Eclipse Foundation makes available provisioning software, examples of which include, but are not limited to, p2 and the Eclipse
+   Update Manager (&quot;Provisioning Technology&quot;) for the purpose of allowing users to install software, documentation, information and/or
+   other materials (collectively &quot;Installable Software&quot;). This capability is provided with the intent of allowing such users to
+   install, extend and update Eclipse-based products. Information about packaging Installable Software is available at <a 
+       href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a> 
+   (&quot;Specification&quot;).</p> 
+ 
+<p>You may use Provisioning Technology to allow other parties to install Installable Software. You shall be responsible for enabling the
+   applicable license agreements relating to the Installable Software to be presented to, and accepted by, the users of the Provisioning Technology
+   in accordance with the Specification. By using Provisioning Technology in such a manner and making it available in accordance with the
+   Specification, you further acknowledge your agreement to, and the acquisition of all necessary rights to permit the following:</p> 
+ 
+<ol> 
+       <li>A series of actions may occur (&quot;Provisioning Process&quot;) in which a user may execute the Provisioning Technology
+       on a machine (&quot;Target Machine&quot;) with the intent of installing, extending or updating the functionality of an Eclipse-based
+       product.</li> 
+       <li>During the Provisioning Process, the Provisioning Technology may cause third party Installable Software or a portion thereof to be
+       accessed and copied to the Target Machine.</li> 
+       <li>Pursuant to the Specification, you will provide to the user the terms and conditions that govern the use of the Installable
+       Software (&quot;Installable Software Agreement&quot;) and such Installable Software Agreement shall be accessed from the Target
+       Machine in accordance with the Specification. Such Installable Software Agreement must inform the user of the terms and conditions that govern
+       the Installable Software and must solicit acceptance by the end user in the manner prescribed in such Installable Software Agreement. Upon such
+       indication of agreement by the user, the provisioning Technology will complete installation of the Installable Software.</li> 
+</ol> 
+ 
+<h3>Cryptography</h3> 
+ 
+<p>Content may contain encryption software. The country in which you are currently may have restrictions on the import, possession, and use, and/or re-export to
+   another country, of encryption software. BEFORE using any encryption software, please check the country's laws, regulations and policies concerning the import,
+   possession, or use, and re-export of encryption software, to see if this is permitted.</p> 
+ 
+<p><small>Java and all Java-based trademarks are trademarks of Oracle Corporation in the United States, other countries, or both.</small></p> 
+</body> 
+</html> 
\ No newline at end of file
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/build.properties b/tests/org.eclipse.mylyn.docs.intent.test.server/build.properties
new file mode 100644
index 0000000..aa1a008
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.properties
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/plugin.properties b/tests/org.eclipse.mylyn.docs.intent.test.server/plugin.properties
new file mode 100644
index 0000000..8eec0c5
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/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 UI Test
+providerName = Eclipse Mylyn
\ No newline at end of file
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/pom.xml b/tests/org.eclipse.mylyn.docs.intent.test.server/pom.xml
new file mode 100644
index 0000000..5c50db1
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (C) 2011 Obeo
+
+   Cedric Brun <cedric.brun@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.7.0-SNAPSHOT</version>
+    <relativePath>../..</relativePath>
+  </parent>
+
+  <artifactId>org.eclipse.mylyn.docs.intent.test.server</artifactId>
+  <packaging>eclipse-test-plugin</packaging>
+
+ <build>   
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.tycho</groupId>
+        <artifactId>tycho-source-plugin</artifactId>
+      </plugin>      
+    </plugins>
+  </build>
+
+
+
+</project>
diff --git a/tests/org.eclipse.mylyn.docs.intent.test.server/src/org/eclipse/mylyn/docs/intent/test/server/IntentCDORepository.java b/tests/org.eclipse.mylyn.docs.intent.test.server/src/org/eclipse/mylyn/docs/intent/test/server/IntentCDORepository.java
new file mode 100644
index 0000000..9984818
--- /dev/null
+++ b/tests/org.eclipse.mylyn.docs.intent.test.server/src/org/eclipse/mylyn/docs/intent/test/server/IntentCDORepository.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * 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.test.server;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.emf.cdo.server.CDOServerUtil;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IStore;
+import org.eclipse.emf.cdo.server.db.CDODBUtil;
+import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
+import org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalMappingStrategy;
+import org.eclipse.emf.cdo.server.net4j.CDONet4jServerUtil;
+import org.eclipse.net4j.acceptor.IAcceptor;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.IDBAdapter;
+import org.eclipse.net4j.db.IDBConnectionProvider;
+import org.eclipse.net4j.db.h2.H2Adapter;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.h2.jdbcx.JdbcDataSource;
+
+/**
+ * A CDO repository used to test Intent.
+ * 
+ * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
+ */
+public final class IntentCDORepository {
+
+	private static IRepository repository;
+
+	private static IAcceptor acceptor;
+
+	private static final String SERVER_LOCATION = "localhost";
+
+	private static final String SERVER_PORT_NUMBER = "2036";
+
+	/**
+	 * Private constructor.
+	 */
+	private IntentCDORepository() {
+
+	}
+
+	/**
+	 * Starts the Intent test Server (if not already launched).
+	 * 
+	 * @param cleanStore
+	 *            true if the store must be clean (i.e. database should be dropped)
+	 * @param repositoryName
+	 *            the name of the repository to launch
+	 */
+	public static void start(boolean cleanStore, String repositoryName) {
+		if (acceptor == null) {
+			// Step 1 : setting up the db
+			// Step 1.1 : defining the datasource
+			JdbcDataSource dataSource = new JdbcDataSource();
+			dataSource.setURL("jdbc:h2:_database/" + repositoryName);
+
+			// Step 1.2 : defining the mapping strategy
+			IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(true);
+			Map<String, String> mappingProperties = new LinkedHashMap<String, String>();
+			mappingProperties.put(AbstractHorizontalMappingStrategy.PROP_OBJECT_TYPE_CACHE_SIZE, "1000");
+			mappingProperties.put(AbstractHorizontalMappingStrategy.PROP_QUALIFIED_NAMES,
+					Boolean.TRUE.toString());
+			mappingStrategy.setProperties(mappingProperties);
+
+			// Step 1.3 : use a H2 database
+			IDBAdapter dbAdapter = new H2Adapter();
+			IDBConnectionProvider dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
+
+			// Clean the store if needed
+			if (cleanStore) {
+				DBUtil.dropAllTables(dbConnectionProvider.getConnection(), repositoryName);
+			}
+
+			// Step 1.4 : creating the IStore from the specified DB
+			IStore store = CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider);
+
+			// Step 2 : creating the repository
+			Map<String, String> props = new HashMap<String, String>();
+			props.put(IRepository.Props.OVERRIDE_UUID, repositoryName);
+			props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
+			props.put(IRepository.Props.SUPPORTING_BRANCHES, "false");
+			props.put(IRepository.Props.SUPPORTING_ECORE, "true");
+
+			repository = CDOServerUtil.createRepository(repositoryName, store, props);
+
+			CDOServerUtil.addRepository(IPluginContainer.INSTANCE, repository);
+			CDONet4jServerUtil.prepareContainer(IPluginContainer.INSTANCE);
+
+			// Step 3 : creating an acceptor on the server side
+			acceptor = (IAcceptor)IPluginContainer.INSTANCE.getElement("org.eclipse.net4j.acceptors", "tcp",
+					SERVER_LOCATION + ":" + SERVER_PORT_NUMBER);
+		}
+	}
+
+	/**
+	 * Stops the currently running Intent test server.
+	 */
+	public static void stop() {
+		if (acceptor != null) {
+			LifecycleUtil.deactivate(acceptor);
+			LifecycleUtil.deactivate(repository);
+			acceptor = null;
+			repository = null;
+		}
+	}
+}