/*******************************************************************************
 * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
 * Technische Universitaet Muenchen.
 * 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:
 * Edgar Mueller - intial API and implementation
 ******************************************************************************/
package org.eclipse.emf.emfstore.client.conflictdetection.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.emfstore.client.ESLocalProject;
import org.eclipse.emf.emfstore.client.test.common.dsl.Create;
import org.eclipse.emf.emfstore.client.test.common.util.TestLogListener;
import org.eclipse.emf.emfstore.client.util.ESVoidCallable;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESLocalProjectImpl;
import org.eclipse.emf.emfstore.internal.common.model.IdEObjectCollection;
import org.eclipse.emf.emfstore.internal.common.model.ModelElementId;
import org.eclipse.emf.emfstore.internal.common.model.impl.IdEObjectCollectionImpl;
import org.eclipse.emf.emfstore.internal.common.model.util.IdEObjectCollectionChangeObserver;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.server.conflictDetection.ConflictBucket;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.CreateDeleteOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiReferenceOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.SingleReferenceOperation;
import org.eclipse.emf.emfstore.test.model.TestElement;
import org.eclipse.emf.emfstore.test.model.TestmodelFactory;
import org.eclipse.emf.emfstore.test.model.impl.TestElementToStringMapImpl;
import org.eclipse.emf.emfstore.test.model.impl.TestmodelFactoryImpl;
import org.junit.Ignore;
import org.junit.Test;

/**
 * Conflict detection tests for map entries.
 *
 * @author emueller
 */
public class ConflictDetectionMapTest extends ConflictDetectionTest {

	private static final String HELLO2 = "hello2"; //$NON-NLS-1$
	private static final String HELLO1 = "hello1"; //$NON-NLS-1$
	private static final String BAR2 = "bar2"; //$NON-NLS-1$
	private static final String KEY_IS_NULL_CAN_NOT_BE_USED_FOR_CONFLICT_DETECTION = "Key is null. Can not be used for conflict detection."; //$NON-NLS-1$
	private static final String FOO = "foo"; //$NON-NLS-1$
	private static final String ORG_ECLIPSE_EMF_EMFSTORE_COMMON_MODEL = "org.eclipse.emf.emfstore.common.model"; //$NON-NLS-1$
	private static final String SINGLE_REFERENCE_SUB_OPERATION_OF_CREATE_OPERATION = "Single reference sub operation of create operation"; //$NON-NLS-1$
	private static final String QUUX = "quux"; //$NON-NLS-1$
	private static final String BAR = "bar"; //$NON-NLS-1$

	/**
	 * Tests if creating map entries with the same key conflict.
	 */
	@Test
	public void testConflictCreateVSCreateMapEntryNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedKey, QUUX);

		final List<ConflictBucket> conflicts = getConflicts(
			forceGetOperations(),
			forceGetOperations(clonedProjectSpace), getProject());

		assertFalse(conflicts.isEmpty());
	}

	/**
	 * Tests if creating map entries with the same key conflict.
	 */
	@Test
	public void testConflictCreateVsMoveNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		final TestmodelFactoryImpl factory = (TestmodelFactoryImpl) TestmodelFactory.eINSTANCE;
		final TestElementToStringMapImpl newEntry = (TestElementToStringMapImpl) factory.createTestElementToStringMap();
		addTestElement(testElement);
		addTestElement(key);
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				getProject().getModelElements().add(newEntry);
				clearOperations();
				return null;
			}
		});

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);
		final ModelElementId newEntryId = getProjectSpace().getProject().getModelElementId(newEntry);
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElementToStringMapImpl clonedNewEntry = (TestElementToStringMapImpl) clonedProjectSpace.getProject()
			.getModelElement(newEntryId);

		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(keyId);

		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				newEntry.setKey(key);
				testElement.getElementToStringMap().add(newEntry);
				return null;
			}
		});

		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				clonedNewEntry.setKey(clonedKey);
				clonedTestElement.getElementToStringMap().add(clonedNewEntry);
				return null;
			}
		});

		final List<ConflictBucket> conflicts = getConflicts(
			forceGetOperations(),
			forceGetOperations(clonedProjectSpace),
			getProject());

		assertFalse(conflicts.isEmpty());
	}

	/**
	 * Tests if creating map entries with the same key conflict.
	 */
	@Test
	@Ignore
	public void testConflictCreateVSCreateMapEntryNonContainedKeySingleRefSubOpMissing() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedKey, QUUX);

		final List<AbstractOperation> operations = forceGetOperations();
		final CreateDeleteOperation createDeleteOperation = CreateDeleteOperation.class.cast(operations.get(0));
		// TODO: LCP - clearing of subops does not affect forceGetOperations()
		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				createDeleteOperation.getSubOperations().clear();
			}
		});

		// expect part of the log message
		final TestLogListener logListener = new TestLogListener(SINGLE_REFERENCE_SUB_OPERATION_OF_CREATE_OPERATION);
		Platform.getLog(Platform
			.getBundle(ORG_ECLIPSE_EMF_EMFSTORE_COMMON_MODEL)).addLogListener(logListener);

		final List<ConflictBucket> conflicts = getConflicts(
			forceGetOperations(),
			forceGetOperations(clonedProjectSpace),
			getProject());

		assertEquals(1, conflicts.size());

		assertTrue(logListener.didReceive());
	}

	/**
	 * Tests if creating map entries with the same key conflict.
	 */
	@Test
	public void testConflictCreateVSCreateMapEntryNonContainedKeyKeyIsNull() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedKey, QUUX);

		final List<AbstractOperation> operations = ModelUtil.clone(
			forceGetOperations());
		final CreateDeleteOperation createDeleteOperation = CreateDeleteOperation.class.cast(operations.get(0));
		final SingleReferenceOperation singleReferenceOperation = SingleReferenceOperation.class.cast(
			createDeleteOperation.getSubOperations().get(0));
		// causes null to be returned when trying to find the key
		singleReferenceOperation.getOtherInvolvedModelElements().iterator().next().setId(FOO);

		final List<AbstractOperation> operations2 = ModelUtil.clone(
			forceGetOperations(clonedProjectSpace));
		// causes null to be returned when trying to find the key
		singleReferenceOperation.getOtherInvolvedModelElements().iterator().next().setId(BAR);

		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				getProject().getModelElements().remove(key);
				clonedProjectSpace.getProject().getModelElements().remove(clonedKey);
				return null;
			}
		});

		// expect part of the log message
		final TestLogListener logListener = new TestLogListener(KEY_IS_NULL_CAN_NOT_BE_USED_FOR_CONFLICT_DETECTION);
		Platform.getLog(Platform
			.getBundle(ORG_ECLIPSE_EMF_EMFSTORE_COMMON_MODEL)).addLogListener(logListener);

		getConflicts(operations, operations2, getProject());

		assertTrue(logListener.didReceive());
	}

	@Test
	public void testNonConflictingCreateVsCreate() {
		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement secondKey = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);
		addTestElement(secondKey);

		final ModelElementId testElementId = getProject().getModelElementId(testElement);
		final ModelElementId secondKeyId = getProject().getModelElementId(secondKey);

		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			testElementId);
		final TestElement clonedSecondKey = (TestElement) clonedProjectSpace.getProject().getModelElement(secondKeyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, FOO);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedSecondKey, BAR);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());
		assertTrue(conflicts.isEmpty());
	}

	@Test
	public void testNonConflictingRemoveVsRemove() {
		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement secondKey = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);
		addTestElement(secondKey);

		final ModelElementId testElementId = getProject().getModelElementId(testElement);
		final ModelElementId secondKeyId = getProject().getModelElementId(secondKey);

		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			testElementId);
		final TestElement clonedSecondKey = (TestElement) clonedProjectSpace.getProject().getModelElement(secondKeyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, FOO);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedSecondKey, BAR);

		clearOperations();

		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				testElement.getElementToStringMap().clear();
				clonedTestElement.getElementToStringMap().clear();
				return null;
			}
		});

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());
		assertTrue(conflicts.isEmpty());
	}

	@Test
	public void testConflictCreateVSDeleteMapEntryNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR2);
		deleteMapEntryNonContainedKey(clonedTestElement, clonedKey);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());

		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictUpdateVSUpdateMapEntryNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(
			keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, HELLO1);
		putIntoMapEntryWithNonContainedKey(clonedTestElement, clonedKey, HELLO2);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());
		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictUpdateVSDeleteMapEntryNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(
			keyId);

		putIntoMapEntryWithNonContainedKey(testElement, key, HELLO1);
		deleteMapEntryNonContainedKey(clonedTestElement, clonedKey);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());
		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictDeleteVSDeleteMapEntryNonContainedKey() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		final TestElement key = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);
		addTestElement(key);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ModelElementId keyId = getProjectSpace().getProject().getModelElementId(key);

		putIntoMapEntryWithNonContainedKey(testElement, key, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);
		final TestElement clonedKey = (TestElement) clonedProjectSpace.getProject().getModelElement(
			keyId);

		deleteMapEntryNonContainedKey(testElement, key);
		deleteMapEntryNonContainedKey(clonedTestElement, clonedKey);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2, getProject());

		assertEquals(1, conflicts.size());
	}

	/**
	 * Tests if creating map entries with the same key conflict.
	 */
	@Test
	public void testConflictCreateVSCreateMapEntry() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);

		putIntoMapEntry(testElement, FOO, BAR);
		putIntoMapEntry(clonedTestElement, FOO, QUUX);

		final List<ConflictBucket> conflicts = getConflicts(
			forceGetOperations(),
			forceGetOperations(clonedProjectSpace));

		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictCreateVSDeleteMapEntry() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);

		putIntoMapEntry(testElement, FOO, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);

		putIntoMapEntry(testElement, FOO, BAR2);
		deleteMapEntry(clonedTestElement, FOO);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testDeleteMapEntry() {

		final Map<EObject, String> deletedElements = new LinkedHashMap<EObject, String>();

		final TestElement testElement = Create.testElement();
		final TestElement keyElement = Create.testElement();
		addTestElement(testElement);
		addTestElement(keyElement);

		final ModelElementId testElementId = getProject().getModelElementId(testElement);

		putIntoMapEntryWithNonContainedKey(testElement, keyElement, "foo"); //$NON-NLS-1$

		clearOperations();

		// TOOD: provide adapter
		addObserverTo(getLocalProject(), new IdEObjectCollectionChangeObserver() {
			public void modelElementRemoved(IdEObjectCollection collection, EObject eObject) {
				final String id = IdEObjectCollectionImpl.class.cast(collection).getDeletedModelElementId(eObject)
					.getId();
				deletedElements.put(eObject, id);
			}

			public void notify(Notification notification, IdEObjectCollection collection, EObject modelElement) {
			}

			public void modelElementAdded(IdEObjectCollection collection, EObject eObject) {
			}

			public void collectionDeleted(IdEObjectCollection collection) {
			}
		});

		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				getLocalProject().getModelElements().remove(testElement);
			}
		});

		assertEquals(1, getLocalProject().getAllModelElements().size());
		assertEquals(2, deletedElements.size());
		assertTrue(testElement.getElementToStringMap().isEmpty());

		deletedElements.clear();

		final List<AbstractOperation> operations = forceGetOperations();
		assertEquals(2, operations.size());
		final CreateDeleteOperation createDeleteOperation = checkAndCast(operations.get(0), CreateDeleteOperation.class);

		final MultiReferenceOperation multiRefOp = checkAndCast(
			createDeleteOperation.getSubOperations().get(0),
			MultiReferenceOperation.class);
		final SingleReferenceOperation singleRefOp = checkAndCast(
			createDeleteOperation.getSubOperations().get(1),
			SingleReferenceOperation.class);

		assertEquals("key", singleRefOp.getFeatureName()); //$NON-NLS-1$
		assertNull(singleRefOp.getNewValue());

		assertEquals("elementToStringMap", multiRefOp.getFeatureName()); //$NON-NLS-1$
		assertFalse(multiRefOp.isAdd());

		// revert
		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				getProjectSpace().revert();
			}
		});

		final TestElement element = (TestElement) getProject().getModelElement(testElementId);

		// forward
		assertEquals(1,
			element.getElementToStringMap().size());
		assertEquals("foo", //$NON-NLS-1$
			element.getElementToStringMap().get(keyElement));
	}

	/**
	 * @param localProject
	 * @param idEObjectCollectionChangeObserver
	 */
	@SuppressWarnings("restriction")
	private void addObserverTo(ESLocalProject localProject,
		IdEObjectCollectionChangeObserver idEObjectCollectionChangeObserver) {
		ESLocalProjectImpl.class.cast(
			localProject
			).toInternalAPI().getProject().addIdEObjectCollectionChangeObserver(
				idEObjectCollectionChangeObserver
			);
	}

	@Test
	public void testConflictUpdateVSUpdateMapEntry() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);

		putIntoMapEntry(testElement, FOO, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);

		putIntoMapEntry(testElement, FOO, HELLO1);
		putIntoMapEntry(clonedTestElement, FOO, HELLO2);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictUpdateVSDeleteMapEntry() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);

		putIntoMapEntry(testElement, FOO, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);

		putIntoMapEntry(testElement, FOO, HELLO1);
		deleteMapEntry(clonedTestElement, FOO);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertFalse(conflicts.isEmpty());
	}

	@Test
	public void testConflictDeleteVSDeleteMapEntry() {

		final TestElement testElement = TestmodelFactory.eINSTANCE.createTestElement();
		addTestElement(testElement);

		final ModelElementId modelElementId = getProjectSpace().getProject().getModelElementId(testElement);

		putIntoMapEntry(testElement, FOO, BAR);
		clearOperations();
		final ProjectSpace clonedProjectSpace = cloneProjectSpace(getProjectSpace());
		final TestElement clonedTestElement = (TestElement) clonedProjectSpace.getProject().getModelElement(
			modelElementId);

		deleteMapEntry(testElement, FOO);
		deleteMapEntry(clonedTestElement, FOO);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(clonedProjectSpace);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertEquals(1, conflicts.size());
	}

	private void deleteMapEntry(final TestElement testElement, final String key) {
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				testElement.getStringToStringMap().remove(key);
				return null;
			}
		});
	}

	private void deleteMapEntryNonContainedKey(final TestElement testElement, final TestElement key) {
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				testElement.getElementToStringMap().remove(key);
				return null;
			}
		});
	}

	private void putIntoMapEntry(final TestElement testElement, final String key, final String value) {
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				testElement.getStringToStringMap().put(key, value);
				return null;
			}
		});
	}

	private void putIntoMapEntryWithNonContainedKey(final TestElement testElement, final TestElement key,
		final String value) {
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				testElement.getElementToStringMap().put(key, value);
				return null;
			}
		});
	}

	private void addTestElement(final TestElement testElement) {
		RunESCommand.run(new Callable<Void>() {
			public Void call() throws Exception {
				getProject().addModelElement(testElement);
				clearOperations();
				return null;
			}
		});
	}
}
