/*******************************************************************************
 * 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:
 * Otto von Wesendonk, Edgar Mueller, Maximilian Koegel - initial API and implementation
 * Johannes Faltermeier - adaptions for independent storage
 ******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.impl;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;

import org.apache.commons.io.FileUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.ecore.util.EcoreUtil.UsageCrossReferencer;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.emfstore.client.ESUsersession;
import org.eclipse.emf.emfstore.client.callbacks.ESCommitCallback;
import org.eclipse.emf.emfstore.client.callbacks.ESUpdateCallback;
import org.eclipse.emf.emfstore.client.changetracking.ESCommandStack;
import org.eclipse.emf.emfstore.client.handler.ESRunnableContext;
import org.eclipse.emf.emfstore.client.observer.ESLoginObserver;
import org.eclipse.emf.emfstore.client.observer.ESMergeObserver;
import org.eclipse.emf.emfstore.client.util.ESClientURIUtil;
import org.eclipse.emf.emfstore.client.util.ESVoidCallable;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionElement;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionPoint;
import org.eclipse.emf.emfstore.internal.client.importexport.impl.ExportChangesController;
import org.eclipse.emf.emfstore.internal.client.importexport.impl.ExportProjectController;
import org.eclipse.emf.emfstore.internal.client.model.CompositeOperationHandle;
import org.eclipse.emf.emfstore.internal.client.model.Configuration;
import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.Usersession;
import org.eclipse.emf.emfstore.internal.client.model.changeTracking.merging.ConflictResolver;
import org.eclipse.emf.emfstore.internal.client.model.changeTracking.notification.recording.NotificationRecorder;
import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.ConnectionManager;
import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.ServerCall;
import org.eclipse.emf.emfstore.internal.client.model.controller.CommitController;
import org.eclipse.emf.emfstore.internal.client.model.controller.ShareController;
import org.eclipse.emf.emfstore.internal.client.model.controller.UpdateController;
import org.eclipse.emf.emfstore.internal.client.model.exceptions.ChangeConflictException;
import org.eclipse.emf.emfstore.internal.client.model.exceptions.IllegalProjectSpaceStateException;
import org.eclipse.emf.emfstore.internal.client.model.exceptions.MEUrlResolutionException;
import org.eclipse.emf.emfstore.internal.client.model.exceptions.PropertyNotFoundException;
import org.eclipse.emf.emfstore.internal.client.model.filetransfer.FileDownloadStatus;
import org.eclipse.emf.emfstore.internal.client.model.filetransfer.FileInformation;
import org.eclipse.emf.emfstore.internal.client.model.filetransfer.FileTransferManager;
import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESLocalProjectImpl;
import org.eclipse.emf.emfstore.internal.client.model.util.WorkspaceUtil;
import org.eclipse.emf.emfstore.internal.client.observers.DeleteProjectSpaceObserver;
import org.eclipse.emf.emfstore.internal.client.properties.PropertyManager;
import org.eclipse.emf.emfstore.internal.common.ESDisposable;
import org.eclipse.emf.emfstore.internal.common.ExtensionRegistry;
import org.eclipse.emf.emfstore.internal.common.model.ModelElementId;
import org.eclipse.emf.emfstore.internal.common.model.Project;
import org.eclipse.emf.emfstore.internal.common.model.impl.IdentifiableElementImpl;
import org.eclipse.emf.emfstore.internal.common.model.impl.ProjectImpl;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.common.model.util.SerializationException;
import org.eclipse.emf.emfstore.internal.server.conflictDetection.ChangeConflictSet;
import org.eclipse.emf.emfstore.internal.server.conflictDetection.ConflictBucket;
import org.eclipse.emf.emfstore.internal.server.conflictDetection.ConflictDetector;
import org.eclipse.emf.emfstore.internal.server.exceptions.FileTransferException;
import org.eclipse.emf.emfstore.internal.server.exceptions.InvalidVersionSpecException;
import org.eclipse.emf.emfstore.internal.server.model.FileIdentifier;
import org.eclipse.emf.emfstore.internal.server.model.ProjectInfo;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.ACUser;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.OrgUnitProperty;
import org.eclipse.emf.emfstore.internal.server.model.url.ModelElementUrlFragment;
import org.eclipse.emf.emfstore.internal.server.model.versioning.AbstractChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.BranchInfo;
import org.eclipse.emf.emfstore.internal.server.model.versioning.BranchVersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.ChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.FileBasedChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.LogMessage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.TagVersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.VersioningFactory;
import org.eclipse.emf.emfstore.internal.server.model.versioning.Versions;
import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.FileBasedChangePackageImpl;
import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.ChangePackageContainer;
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.util.ChangePackageUtil;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.util.OperationUtil;
import org.eclipse.emf.emfstore.server.ESCloseableIterable;
import org.eclipse.emf.emfstore.server.exceptions.ESException;
import org.eclipse.emf.emfstore.server.model.ESChangePackage;

/**
 * Project space base class that contains custom user methods.
 *
 * @author koegel
 * @author wesendon
 * @author emueller
 * @author jfaltermeier
 *
 */
public abstract class ProjectSpaceBase extends IdentifiableElementImpl
	implements ProjectSpace, ESLoginObserver, ESDisposable, ChangePackageContainer {

	private ESLocalProjectImpl esLocalProjectImpl;

	private boolean initCompleted;
	private boolean isTransient;
	private boolean disposed;

	private FileTransferManager fileTransferManager;
	private OperationManager operationManager;

	private PropertyManager propertyManager;
	private final Map<String, OrgUnitProperty> propertyMap;

	private ResourceSet resourceSet;
	private ResourcePersister resourcePersister;

	private ECrossReferenceAdapter crossReferenceAdapter;
	private ESRunnableContext runnableContext;

	/**
	 * Constructor.
	 */
	public ProjectSpaceBase() {
		propertyMap = new LinkedHashMap<String, OrgUnitProperty>();
		initRunnableContext();
	}

	/**
	 * <p>
	 * Provides a context in which a {@link Runnable} is executed.
	 * </p>
	 * <p>
	 * This may be used to provide a context while applying operations on a
	 * {@link org.eclipse.emf.emfstore.client.ESLocalProject}.
	 * </p>
	 *
	 * @param runnableContext
	 *            the runnable context to be set
	 */
	public void setRunnableContext(ESRunnableContext runnableContext) {
		this.runnableContext = runnableContext;
	}

	private void initRunnableContext() {
		runnableContext = ExtensionRegistry.INSTANCE.get(
			RUNNABLE_CONTEXT_ID,
			ESRunnableContext.class,
			new DefaultRunnableContext(), true);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#addFile(java.io.File)
	 */
	public FileIdentifier addFile(File file) throws FileTransferException {
		return fileTransferManager.addFile(file);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#addFile(java.io.File, java.lang.String)
	 */
	public FileIdentifier addFile(File file, String fileIdentifier) throws FileTransferException {
		return fileTransferManager.addFile(file, fileIdentifier);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#addOperations(java.util.List)
	 */
	public void addOperations(List<? extends AbstractOperation> operations) {

		final List<AbstractOperation> ops = new ArrayList<AbstractOperation>();
		for (final AbstractOperation operation : operations) {
			ops.add(operation);
		}

		getLocalChangePackage().addAll(ops);

		updateDirtyState();

		for (final AbstractOperation op : operations) {
			operationManager.notifyOperationExecuted(op);
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#addTag(org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec,
	 *      org.eclipse.emf.emfstore.internal.server.model.versioning.TagVersionSpec)
	 */
	public void addTag(PrimaryVersionSpec versionSpec, TagVersionSpec tag) throws ESException {
		final ConnectionManager cm = ESWorkspaceProviderImpl.getInstance().getConnectionManager();
		cm.addTag(getUsersession().getSessionId(), getProjectId(), versionSpec, tag);
	}

	/**
	 * Helper method which applies merged changes on the ProjectSpace. This
	 * method is used by merge mechanisms in update as well as branch merging.
	 *
	 * @param baseSpec
	 *            new base version
	 * @param incomingChangePackages
	 *            changes from the current branch
	 * @param myChanges
	 *            merged changes
	 * @param progressMonitor
	 *            an {@link IProgressMonitor} to inform about the progress of the UpdateCallback in case it is called
	 * @param runChecksumCheckOnBaseSpec
	 *            whether the checksum check is performed while applying the changes
	 *
	 * @throws ESException in case the checksum comparison failed and the activated IChecksumErrorHandler
	 *             also failed
	 */
	public void applyChanges(PrimaryVersionSpec baseSpec, List<AbstractChangePackage> incomingChangePackages,
		AbstractChangePackage myChanges, IProgressMonitor progressMonitor, boolean runChecksumCheckOnBaseSpec)
			throws ESException {

		// revert local changes
		notifyPreRevertMyChanges(getLocalChangePackage());
		revert();
		notifyPostRevertMyChanges();

		// apply changes from repo. incoming (aka theirs)
		applyChangePackages(incomingChangePackages, false);
		if (runChecksumCheckOnBaseSpec) {
			runChecksumTests(baseSpec, incomingChangePackages, progressMonitor);
		}
		notifyPostApplyTheirChanges(incomingChangePackages);

		reapplyLocalChanges(myChanges);
		notifyPostApplyMergedChanges(myChanges);

		setBaseVersion(baseSpec);
		save();
	}

	private void reapplyLocalChanges(AbstractChangePackage myChangePackage) {
		final ESCloseableIterable<AbstractOperation> operations = myChangePackage.operations();
		try {
			if (Configuration.getClientBehavior().isRerecordingActivated()) {
				applyOperationsWithRerecording(operations.iterable());
			} else {
				applyOperations(operations.iterable(), true);
			}
		} finally {
			operations.close();
		}
	}

	private void runChecksumTests(PrimaryVersionSpec baseSpec, List<AbstractChangePackage> incomingChangePackages,
		IProgressMonitor progressMonitor)
			throws ESException {

		progressMonitor.subTask(Messages.ProjectSpaceBase_Computing_Checksum);

		if (!performChecksumCheck(baseSpec, getProject())) {
			progressMonitor.subTask(Messages.ProjectSpaceBase_Activate_ChecksumErrorHandler_Invalid_Chekcum);
			final boolean errorHandled = Configuration.getClientBehavior()
				.getChecksumErrorHandler()
				.execute(toAPI(), baseSpec.toAPI(), progressMonitor);

			if (!errorHandled) {
				// rollback
				for (int i = incomingChangePackages.size() - 1; i >= 0; i--) {
					final ESCloseableIterable<AbstractOperation> reversedOperations = incomingChangePackages.get(i)
						.reversedOperations();
					try {
						applyChangePackage(reversedOperations.iterable(), false);
					} finally {
						reversedOperations.close();
					}
				}
				// TODO
				// applyChangePackage(getLocalChangePackage2().iterator(), true);

				throw new ESException(Messages.ProjectSpaceBase_Update_Cancelled_Invalid_Checksum);
			}
		}
	}

	// FIXME: rename
	private void applyChangePackage(Iterable<AbstractOperation> operations, boolean addOperations) {
		applyOperations(operations, addOperations);
	}

	private void applyChangePackages(Iterable<AbstractChangePackage> changePackages, boolean addOperations) {
		for (final AbstractChangePackage changePackage : changePackages) {
			final ESCloseableIterable<AbstractOperation> operations = changePackage.operations();
			try {
				applyChangePackage(operations.iterable(), addOperations);
			} finally {
				operations.close();
			}
		}
	}

	private boolean performChecksumCheck(PrimaryVersionSpec baseVersion, Project project) {

		if (Configuration.getClientBehavior().isChecksumCheckActive()) {
			final long expectedChecksum = baseVersion.getProjectStateChecksum();
			try {
				final long computedChecksum = ModelUtil.computeChecksum(project);
				return expectedChecksum == computedChecksum;
			} catch (final SerializationException e) {
				WorkspaceUtil.logWarning(Messages.ProjectSpaceBase_Cannot_Compute_Checksum, e);
			}
		}

		return true;
	}

	/**
	 * Applies a list of operations to the project. The change tracking will be
	 * stopped meanwhile.
	 *
	 *
	 * @param operations
	 *            the list of operations to be applied upon the project space
	 * @param addOperations
	 *            whether the operations should be saved in project space
	 *
	 */
	public void applyOperations(Iterable<AbstractOperation> operations, boolean addOperations) {
		executeRunnable(new ApplyOperationsRunnable(this, operations, addOperations));
	}

	/**
	 * Applies a list of operations to the project. The change tracking will be
	 * stopped meanwhile.
	 *
	 *
	 * @param operations
	 *            the list of operations to be applied upon the project space
	 *
	 */
	public void applyOperationsWithRerecording(Iterable<AbstractOperation> operations) {
		executeRunnable(new ApplyOperationsAndRecordRunnable(this, operations));
	}

	/**
	 * Executes a given {@link Runnable} in the context of this {@link ProjectSpace}.<br>
	 * The {@link Runnable} usually modifies the Project contained in the {@link ProjectSpace}.
	 *
	 * @param runnable
	 *            the {@link Runnable} to be executed in the context of this {@link ProjectSpace}
	 */
	public void executeRunnable(Runnable runnable) {
		getRunnableContext().executeRunnable(runnable);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#beginCompositeOperation()
	 */
	public CompositeOperationHandle beginCompositeOperation() {
		return operationManager.beginCompositeOperation();
	}

	/**
	 * Removes the elements that are marked as cutted from the project.
	 */
	public void cleanCutElements() {
		final List<EObject> cutElements = new ArrayList<EObject>(getProject().getCutElements());
		for (final EObject cutElement : cutElements) {
			getProject().deleteModelElement(cutElement);
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#commit(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public PrimaryVersionSpec commit(IProgressMonitor monitor) throws ESException {
		return new CommitController(this, null, null, monitor).execute();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#commit(java.lang.String,
	 *      org.eclipse.emf.emfstore.client.callbacks.ESCommitCallback, org.eclipse.core.runtime.IProgressMonitor)
	 */
	public PrimaryVersionSpec commit(String logMessage, ESCommitCallback callback, IProgressMonitor monitor)
		throws ESException {
		return new CommitController(this, logMessage, callback, monitor).execute();
	}

	/**
	 * {@inheritDoc}
	 */
	public PrimaryVersionSpec commitToBranch(BranchVersionSpec branch, String logMessage,
		ESCommitCallback callback,
		IProgressMonitor monitor) throws ESException {
		return new CommitController(this, branch, logMessage, callback, monitor).execute();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#exportLocalChanges(java.io.File,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void exportLocalChanges(File file, IProgressMonitor progressMonitor) throws IOException {
		new ExportChangesController(this).execute(file, progressMonitor);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#exportLocalChanges(java.io.File)
	 */
	public void exportLocalChanges(File file) throws IOException {
		new ExportChangesController(this).execute(file, new NullProgressMonitor());
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#exportProject(java.io.File,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void exportProject(File file, IProgressMonitor progressMonitor) throws IOException {
		new ExportProjectController(this).execute(file, progressMonitor);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#exportProject(java.io.File)
	 */
	public void exportProject(File file) throws IOException {
		new ExportProjectController(this).execute(file, new NullProgressMonitor());
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getChanges(org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec,
	 *      org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec)
	 */
	public List<AbstractChangePackage> getChanges(VersionSpec sourceVersion, VersionSpec targetVersion)
		throws InvalidVersionSpecException, ESException {
		// TODO: is this a server call?
		final ConnectionManager connectionManager = ESWorkspaceProviderImpl.getInstance().getConnectionManager();
		final List<AbstractChangePackage> changes = connectionManager.getChanges(getUsersession().getSessionId(),
			getProjectId(),
			sourceVersion, targetVersion);
		return changes;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getFile(org.eclipse.emf.emfstore.internal.server.model.FileIdentifier)
	 */
	public FileDownloadStatus getFile(FileIdentifier fileIdentifier) throws FileTransferException {
		return fileTransferManager.getFile(fileIdentifier, false);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getFileInfo(org.eclipse.emf.emfstore.internal.server.model.FileIdentifier)
	 */
	public FileInformation getFileInfo(FileIdentifier fileIdentifier) {
		return fileTransferManager.getFileInfo(fileIdentifier);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getLocalChangePackage(boolean)
	 */
	public AbstractChangePackage getLocalChangePackage(boolean canonize) {
		final AbstractChangePackage changePackage = ChangePackageUtil.createChangePackage(
			Configuration.getClientBehavior().useInMemoryChangePackage());

		// copy operations from ProjectSpace
		final ESCloseableIterable<AbstractOperation> operations = getLocalChangePackage().operations();
		try {
			for (final AbstractOperation operation : operations.iterable()) {
				final AbstractOperation clonedOperation = ModelUtil.clone(operation);
				changePackage.add(clonedOperation);
			}
		} finally {
			operations.close();
		}
		final LogMessage logMessage = VersioningFactory.eINSTANCE.createLogMessage();
		if (getUsersession() != null) {
			logMessage.setAuthor(getUsersession().getUsername());
		} else {
			logMessage.setAuthor(Messages.ProjectSpaceBase_Unknown_Author);
		}
		logMessage.setClientDate(new Date());
		changePackage.setLogMessage(logMessage);
		return changePackage;
	}

	/**
	 * Get the current notification recorder.
	 *
	 * @return the recorder
	 */
	public NotificationRecorder getNotificationRecorder() {
		return operationManager.getNotificationRecorder();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getOperationManager()
	 */
	public OperationManager getOperationManager() {
		return operationManager;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getProjectInfo()
	 */
	public ProjectInfo getProjectInfo() {
		final ProjectInfo projectInfo = org.eclipse.emf.emfstore.internal.server.model.ModelFactory.eINSTANCE
			.createProjectInfo();
		projectInfo.setProjectId(ModelUtil.clone(getProjectId()));
		projectInfo.setName(getProjectName());
		projectInfo.setDescription(getProjectDescription());
		projectInfo.setVersion(ModelUtil.clone(getBaseVersion()));
		return projectInfo;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getPropertyManager()
	 */
	public PropertyManager getPropertyManager() {
		if (propertyManager == null) {
			propertyManager = new PropertyManager(this);
		}

		return propertyManager;
	}

	/**
	 * getter for a string argument - see {@link #setProperty(OrgUnitProperty)}.
	 */
	private OrgUnitProperty getProperty(String name) throws PropertyNotFoundException {
		// sanity checks
		if (getUsersession() != null && getUsersession().getACUser() != null) {
			final OrgUnitProperty orgUnitProperty = propertyMap.get(name);
			if (orgUnitProperty != null) {
				return orgUnitProperty;
			}
		}
		throw new PropertyNotFoundException(MessageFormat.format(
			Messages.ProjectSpaceBase_Property_Not_Found, name));
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#importLocalChanges(java.lang.String)
	 */
	public void importLocalChanges(String fileName) throws IOException {

		final ResourceSetImpl resourceSet = new ResourceSetImpl();
		final Resource resource = resourceSet.getResource(URI.createFileURI(fileName), true);
		final EList<EObject> directContents = resource.getContents();
		// sanity check

		if (directContents.size() != 1 && !(directContents.get(0) instanceof ChangePackage)) {
			throw new IOException(Messages.ProjectSpaceBase_Corrupt_File);
		}

		final AbstractChangePackage changePackage = (AbstractChangePackage) directContents.get(0);

		if (!initCompleted) {
			init();
		}

		final ESCloseableIterable<AbstractOperation> operations = changePackage.operations();
		try {
			applyOperations(operations.iterable(), true);
		} finally {
			operations.close();
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#init()
	 */
	public void init() {
		initCrossReferenceAdapter();

		final ESCommandStack commandStack = (ESCommandStack) ESWorkspaceProviderImpl.getInstance().getEditingDomain()
			.getCommandStack();

		fileTransferManager = new FileTransferManager(this);
		operationManager = new OperationManager(this);

		// initialization order is important!

		initPropertyMap();

		final URI localChangePackageUri = ESClientURIUtil.createOperationsURI(this);
		final AbstractChangePackage localChangePackage = getLocalChangePackage();

		if (localChangePackage == null) {
			setChangePackage(createChangePackage(localChangePackageUri, true));
		} else if (localChangePackage.eIsProxy()) {
			setChangePackage(createChangePackage(localChangePackageUri, false));
		} else {
			if (!Configuration.getClientBehavior().useInMemoryChangePackage()) {
				final FileBasedChangePackage changePackage = (FileBasedChangePackage) getLocalChangePackage();
				if (changePackage.eResource() == eResource()) {
					migrateFileBasedChangePackageIntoDedicatedResource(localChangePackageUri, changePackage);
				} else {
					// TODO: move to FileBasedChangePackage
					try {
						FileUtils.copyFile(
							new File(changePackage.getFilePath()),
							new File(changePackage.getTempFilePath()));
					} catch (final IOException ex) {
						WorkspaceUtil.logException(ex.getMessage(), ex);
					}
				}
			}
		}

		initResourcePersister();
		// TODO: use ObserverBug to register observers
		commandStack.addCommandStackObserver(resourcePersister);
		commandStack.addCommandStackObserver(operationManager);

		getProject().addIdEObjectCollectionChangeObserver(operationManager);
		getProject().addIdEObjectCollectionChangeObserver(resourcePersister);

		if (getProject() instanceof ProjectImpl) {
			((ProjectImpl) getProject()).setUndetachable(operationManager);
			((ProjectImpl) getProject()).setUndetachable(resourcePersister);
		}

		initCompleted = true;

		startChangeRecording();
		cleanCutElements();
	}

	private AbstractChangePackage createChangePackage(URI localChangePackageUri, boolean initialize) {

		AbstractChangePackage localChangePackage;

		if (Configuration.getClientBehavior().useInMemoryChangePackage()) {
			localChangePackage = VersioningFactory.eINSTANCE.createChangePackage();
			final Resource resource = getResourceSet().createResource(localChangePackageUri);
			resource.getContents().add(localChangePackage);
		} else {
			final URI normalizedUri = getResourceSet().getURIConverter().normalize(localChangePackageUri);
			final String filePath = normalizedUri.toFileString();
			localChangePackage = VersioningFactory.eINSTANCE.createFileBasedChangePackage();

			if (initialize) {
				((FileBasedChangePackage) localChangePackage)
					.initialize(filePath + FileBasedChangePackageImpl.FILE_OP_INDEX);
			} else {
				((FileBasedChangePackage) localChangePackage).setFilePath(
					filePath + FileBasedChangePackageImpl.FILE_OP_INDEX);
			}

			final Resource resource = getResourceSet().createResource(localChangePackageUri);
			resource.getContents().add(localChangePackage);
			try {
				resource.save(ModelUtil.getResourceSaveOptions());
			} catch (final IOException ex) {
				WorkspaceUtil.logException(ex.getMessage(), ex);
			}
		}

		return localChangePackage;
	}

	private void migrateFileBasedChangePackageIntoDedicatedResource(final URI localChangePackageUri,
		final FileBasedChangePackage changePackage) {

		final URI normalizedUri = getResourceSet().getURIConverter().normalize(localChangePackageUri);
		final String filePath = normalizedUri.toFileString();

		final String tempPath = changePackage.getTempFilePath();
		final String path = changePackage.getFilePath();

		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				changePackage.setFilePath(filePath + ".1"); //$NON-NLS-1$
			}
		});

		if (path != null) {
			// temp file depends on path
			try {
				FileUtils.moveFile(new File(tempPath), new File(changePackage.getTempFilePath()));
				FileUtils.moveFile(new File(path), new File(changePackage.getFilePath()));
			} catch (final IOException ex) {
				WorkspaceUtil.logException(ex.getMessage(), ex);
			}
		}

		Resource resource = getResourceSet().getResource(localChangePackageUri, true);
		if (resource == null) {
			resource = getResourceSet().createResource(localChangePackageUri);
		}

		final Resource r = resource;
		// move change package into its own resource
		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				r.getContents().add(changePackage);
				setChangePackage(changePackage);
			}
		});
		try {
			eResource().save(ModelUtil.getResourceSaveOptions());
			resource.save(ModelUtil.getResourceSaveOptions());
		} catch (final IOException ex) {
			WorkspaceUtil.logException(ex.getMessage(), ex);
		}
	}

	@SuppressWarnings("unchecked")
	private void initPropertyMap() {
		// TODO: deprecated, OrgUnitPropertiy will be removed soon
		if (getUsersession() != null) {
			ESWorkspaceProviderImpl.getObserverBus().register(this, ESLoginObserver.class);
			final ACUser acUser = getUsersession().getACUser();
			if (acUser != null) {
				for (final OrgUnitProperty p : acUser.getProperties()) {
					if (p.getProject() != null && p.getProject().equals(getProjectId())) {
						propertyMap.put(p.getName(), p);
					}
				}
			}
		}
	}

	private void initCrossReferenceAdapter() {

		// default
		boolean useCrossReferenceAdapter = true;

		for (final ESExtensionElement element : new ESExtensionPoint(
			"org.eclipse.emf.emfstore.client.inverseCrossReferenceCache") //$NON-NLS-1$
				.getExtensionElements()) {
			useCrossReferenceAdapter &= element.getBoolean("activated"); //$NON-NLS-1$
		}

		if (useCrossReferenceAdapter) {
			crossReferenceAdapter = new ECrossReferenceAdapter();
			getProject().eAdapters().add(crossReferenceAdapter);
		}
	}

	private void initResourcePersister() {

		resourcePersister = new ResourcePersister(toAPI());

		if (!isTransient) {
			resourcePersister.addResource(eResource());
			resourcePersister.addResource(getLocalChangePackage().eResource());
			resourcePersister.addResource(getProject().eResource());
			resourcePersister.addDirtyStateChangeLister(new ESLocalProjectSaveStateNotifier(toAPI()));
			ESWorkspaceProviderImpl.getObserverBus().register(resourcePersister);
		}
	}

	/**
	 * Returns the file transfer manager.
	 *
	 * @return the file transfer manager
	 */
	public FileTransferManager getFileTransferManager() {
		return fileTransferManager;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#initResources(org.eclipse.emf.ecore.resource.ResourceSet)
	 */
	public void initResources(ResourceSet resourceSet) {
		this.resourceSet = resourceSet;
		initCompleted = true;

		final URI projectSpaceURI = ESClientURIUtil.createProjectSpaceURI(this);
		final URI operationsURI = ESClientURIUtil.createOperationsURI(this);
		final URI projectURI = ESClientURIUtil.createProjectURI(this);

		setResourceCount(0);

		final List<Resource> resources = new ArrayList<Resource>();
		final Resource resource = resourceSet.createResource(projectURI);
		// if resource splitting fails, we need a reference to the old resource
		resource.getContents().add(getProject());
		resources.add(resource);
		setResourceCount(getResourceCount() + 1);

		for (final EObject modelElement : getProject().getAllModelElements()) {
			((XMIResource) resource).setID(modelElement, getProject().getModelElementId(modelElement).getId());
		}

		final Resource localChangePackageResource = resourceSet.createResource(operationsURI);

		// TODO: LCP
		resources.add(localChangePackageResource);

		final Resource projectSpaceResource = resourceSet.createResource(projectSpaceURI);
		projectSpaceResource.getContents().add(this);
		resources.add(projectSpaceResource);

		// save all resources that have been created
		for (final Resource currentResource : resources) {
			try {
				ModelUtil.saveResource(currentResource, WorkspaceUtil.getResourceLogger());
			} catch (final IOException e) {
				WorkspaceUtil.logException(Messages.ProjectSpaceBase_Resource_Init_Failed, e);
			}
		}

		init();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#delete(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void delete(IProgressMonitor monitor) throws IOException {

		ESWorkspaceProviderImpl.getObserverBus().notify(DeleteProjectSpaceObserver.class).projectSpaceDeleted(this);

		// delete project to notify listeners
		getProject().delete();

		// remove resources from resource set and delete them
		deleteResource(getProject().eResource());
		deleteResource(eResource());

		if (FileBasedChangePackage.class.isInstance(getLocalChangePackage())) {
			FileBasedChangePackageImpl.class.cast(getLocalChangePackage()).delete();
		} else {
			// LCP - no change package in memory anymore, hence no resource available
			final URI localChangePackageUri = ESClientURIUtil.createOperationsURI(this);
			final URI normalizedUri = getResourceSet().getURIConverter().normalize(localChangePackageUri);
			final String fileString = normalizedUri.toFileString();
			final File operationsFile = new File(fileString);

			operationsFile.delete();

			boolean isDeleted = !operationsFile.exists();
			int retries = 0;
			while (!isDeleted && retries < 3) {
				operationsFile.delete();
				isDeleted = !operationsFile.exists();
				retries++;
			}
		}

		// TODO: remove project space from workspace, this is not the case if delete
		// is performed via Workspace#deleteProjectSpace
		ESWorkspaceProviderImpl.getInstance().getInternalWorkspace().getProjectSpaces().remove(this);

		dispose();
	}

	private void deleteResource(Resource resource) throws IOException {
		if (resource != null) {
			resource.delete(null);
		}
	}

	/**
	 * Returns the {@link ECrossReferenceAdapter}, if available.
	 *
	 * @param modelElement
	 *            the model element for which to find inverse cross references
	 *
	 * @return the {@link ECrossReferenceAdapter}
	 */
	public Collection<Setting> findInverseCrossReferences(EObject modelElement) {
		if (crossReferenceAdapter != null) {
			return crossReferenceAdapter.getInverseReferences(modelElement);
		}

		return UsageCrossReferencer.find(modelElement, resourceSet);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getResourceSet()
	 */
	public ResourceSet getResourceSet() {
		return resourceSet;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#setResourceSet(org.eclipse.emf.ecore.resource.ResourceSet)
	 */
	public void setResourceSet(ResourceSet resourceSet) {
		this.resourceSet = resourceSet;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#isTransient()
	 */
	public boolean isTransient() {
		return isTransient;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#isUpdated()
	 */
	public boolean isUpdated() throws ESException {
		final PrimaryVersionSpec headVersion = resolveVersionSpec(Versions.createHEAD(getBaseVersion()),
			new NullProgressMonitor());
		return getBaseVersion().equals(headVersion);
	}

	/**
	 * {@inheritDoc}
	 */
	public void loginCompleted(ESUsersession session) {
		// TODO Implement possibility in observerbus to register only for
		// certain notifier
		if (getUsersession() == null || !getUsersession().toAPI().equals(session)) {
			return;
		}
		try {
			transmitProperties();
			// BEGIN SUPRESS CATCH EXCEPTION
		} catch (final RuntimeException e) {
			// END SUPRESS CATCH EXCEPTION
			WorkspaceUtil.logException(Messages.ProjectSpaceBase_Transmit_Properties_Failed, e);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#makeTransient()
	 */
	public void makeTransient() {
		if (initCompleted) {
			throw new IllegalAccessError(Messages.ProjectSpaceBase_Make_Transient_Error);
		}
		isTransient = true;
	}

	/**
	 * {@inheritDoc}
	 */
	public void mergeBranch(final PrimaryVersionSpec branchSpec, final ConflictResolver conflictResolver,
		final IProgressMonitor monitor)
			throws ESException {

		if (branchSpec == null || conflictResolver == null) {
			throw new IllegalArgumentException(Messages.ProjectSpaceBase_Arguments_Must_Not_Be_Null);
		}

		if (Versions.isSameBranch(getBaseVersion(), branchSpec)) {
			throw new InvalidVersionSpecException(Messages.ProjectSpaceBase_Cannot_Merge_Branch_With_Itself);
		}

		final PrimaryVersionSpec commonAncestor = new ServerCall<PrimaryVersionSpec>(this) {
			@Override
			protected PrimaryVersionSpec run() throws ESException {
				return resolveVersionSpec(Versions.createANCESTOR(getBaseVersion(),
					branchSpec), monitor);
			}
		}.execute();

		final List<AbstractChangePackage> baseChanges = getChanges(commonAncestor, getBaseVersion());
		final List<AbstractChangePackage> branchChanges = getChanges(commonAncestor, branchSpec);

		final ChangeConflictSet conflictSet = new ConflictDetector().calculateConflicts(branchChanges,
			baseChanges, getProject());

		if (conflictResolver.resolveConflicts(getProject(), conflictSet)) {
			final AbstractChangePackage copyOfResolvedConflicts = mergeResolvedConflicts(conflictSet, branchChanges,
				baseChanges);
			RunESCommand.WithException.run(ESException.class, new Callable<Void>() {
				public Void call() throws Exception {
					applyChanges(getBaseVersion(), baseChanges, copyOfResolvedConflicts, monitor, false);
					setMergedVersion(ModelUtil.clone(branchSpec));
					return null;
				}
			});
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#mergeResolvedConflicts(org.eclipse.emf.emfstore.internal.server.conflictDetection.ChangeConflictSet,
	 *      java.util.List, java.util.List)
	 */
	public AbstractChangePackage mergeResolvedConflicts(ChangeConflictSet conflictSet,
		List<AbstractChangePackage> myChangePackages, List<AbstractChangePackage> theirChangePackages)
			throws ChangeConflictException {

		final Set<AbstractOperation> accceptedMineSet = new LinkedHashSet<AbstractOperation>();
		final Set<AbstractOperation> rejectedTheirsSet = new LinkedHashSet<AbstractOperation>();

		for (final ConflictBucket conflict : conflictSet.getConflictBuckets()) {
			if (!conflict.isResolved()) {
				throw new ChangeConflictException(
					Messages.ProjectSpaceBase_Conflict_During_Update_No_Resolution,
					conflictSet);
			}
			accceptedMineSet.addAll(conflict.getAcceptedLocalOperations());
			rejectedTheirsSet.addAll(conflict.getRejectedRemoteOperations());
		}

		final List<AbstractOperation> acceptedMineList = new LinkedList<AbstractOperation>();
		for (final AbstractChangePackage locChangePackage : myChangePackages) {
			final ESCloseableIterable<AbstractOperation> operations = locChangePackage.operations();
			try {
				for (final AbstractOperation myOperation : operations.iterable()) {
					final Set<AbstractOperation> notInvolvedInConflict = conflictSet.getNotInvolvedInConflict();
					final List<AbstractOperation> ops = new ArrayList<AbstractOperation>(notInvolvedInConflict);

					if (containsOp(ops, myOperation)) {
						acceptedMineList.add(myOperation);
					} else if (containsOp(accceptedMineSet, myOperation)) {
						acceptedMineList.add(myOperation);
					}
					final Iterator<AbstractOperation> iterator = accceptedMineSet.iterator();
					while (iterator.hasNext()) {
						final AbstractOperation operation = iterator.next();
						if (operation.getIdentifier().equals(myOperation.getIdentifier())) {
							iterator.remove();
							break;
						}
					}

				}
			} finally {
				operations.close();
			}
		}
		// add all remaining operations in acceptedMineSet (they have been generated during merge)
		acceptedMineList.addAll(accceptedMineSet);

		final List<AbstractOperation> rejectedTheirsList = new LinkedList<AbstractOperation>();
		for (final AbstractChangePackage theirCP : theirChangePackages) {
			final ESCloseableIterable<AbstractOperation> operations = theirCP.operations();
			try {
				for (final AbstractOperation theirOperation : operations.iterable()) {

					if (containsOp(rejectedTheirsSet, theirOperation)) {
						rejectedTheirsList.add(theirOperation);
					}
				}
			} finally {
				operations.close();
			}
		}

		final List<AbstractOperation> mergeResult = new ArrayList<AbstractOperation>(rejectedTheirsList.size()
			+ acceptedMineList.size());
		for (final AbstractOperation operationToReverse : rejectedTheirsList) {
			mergeResult.add(0, operationToReverse.reverse());
		}

		mergeResult.addAll(acceptedMineList);
		final AbstractChangePackage result = ChangePackageUtil.createChangePackage(
			Configuration.getClientBehavior().useInMemoryChangePackage());

		// dup op in mergeResult
		result.addAll(mergeResult);

		return result;
	}

	// TODO LCP: do we elsewhere compare operations?
	private static boolean containsOp(Collection<AbstractOperation> ops, AbstractOperation op) {
		for (final AbstractOperation abstractOperation : ops) {
			if (OperationUtil.isCreateDelete(abstractOperation) &&
				OperationUtil.isCreateDelete(op)) {

				final CreateDeleteOperation createDeleteOperation = CreateDeleteOperation.class.cast(abstractOperation);
				final CreateDeleteOperation otherCreateDeleteOperation = CreateDeleteOperation.class.cast(op);

				if (createDeleteOperation.getOperationId().equals(otherCreateDeleteOperation.getOperationId())
					&& createDeleteOperation.getModelElementId()
						.equals(otherCreateDeleteOperation.getModelElementId())) {
					return true;
				}

			} else if (abstractOperation.getOperationId().equals(op.getOperationId())) {
				return true;
			}
		}

		return false;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#getBranches()
	 */
	public List<BranchInfo> getBranches() throws ESException {
		return new ServerCall<List<BranchInfo>>(this) {
			@Override
			protected List<BranchInfo> run() throws ESException {
				final ConnectionManager cm = ESWorkspaceProviderImpl.getInstance().getConnectionManager();
				return cm.getBranches(getSessionId(), getProjectId());
			}
		}.execute();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#removeTag(org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec,
	 *      org.eclipse.emf.emfstore.internal.server.model.versioning.TagVersionSpec)
	 */
	public void removeTag(PrimaryVersionSpec versionSpec, TagVersionSpec tag) throws ESException {
		final ConnectionManager cm = ESWorkspaceProviderImpl.getInstance().getConnectionManager();
		cm.removeTag(getUsersession().getSessionId(), getProjectId(), versionSpec, tag);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#resolve(org.eclipse.emf.emfstore.internal.server.model.url.ModelElementUrlFragment)
	 */
	public EObject resolve(ModelElementUrlFragment modelElementUrlFragment) throws MEUrlResolutionException {
		final ModelElementId modelElementId = modelElementUrlFragment.getModelElementId();
		final EObject modelElement = getProject().getModelElement(modelElementId);
		if (modelElement == null) {
			throw new MEUrlResolutionException();
		}
		return modelElement;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#resolveVersionSpec(org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public PrimaryVersionSpec resolveVersionSpec(final VersionSpec versionSpec, IProgressMonitor monitor)
		throws InvalidVersionSpecException, ESException {
		return new ServerCall<PrimaryVersionSpec>(this, monitor) {
			@Override
			protected PrimaryVersionSpec run() throws ESException {
				return getConnectionManager().resolveVersionSpec(
					getSessionId(),
					getProjectId(),
					versionSpec);
			}
		}.execute();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#revert()
	 */
	public void revert() {
		while (!getLocalChangePackage().isEmpty()) {
			undoLastOperation();
		}
		updateDirtyState();
	}

	/**
	 * Saves the project space itself only, no containment children.
	 */
	public void saveProjectSpaceOnly() {
		saveResource(eResource());
	}

	/**
	 * Saves the project space.
	 */
	public void save() {
		saveProjectSpaceOnly();
		saveChangePackage();
		resourcePersister.saveDirtyResources(true);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#hasUnsavedChanges()
	 */
	public boolean hasUnsavedChanges() {

		if (resourcePersister != null) {
			return resourcePersister.isDirty();
		}

		// in case the project space has not been initialized yet
		return false;
	}

	private void saveChangePackage() {
		try {
			getLocalChangePackage().save();
		} catch (final IOException e) {
			WorkspaceUtil.logException(Messages.ProjectSpaceBase_Error_During_Save
				+ Messages.ProjectSpaceBase_Delete_Project_And_Checkout_Again, e);
		}
	}

	/**
	 * Save the given resource that is part of the project space resource set.
	 *
	 * @param resource
	 *            the resource
	 */
	public void saveResource(Resource resource) {
		try {
			if (resource == null) {
				if (!isTransient) {
					WorkspaceUtil.logException(Messages.ProjectSpaceBase_Resource_Not_Initialized,
						new IllegalProjectSpaceStateException(Messages.ProjectSpaceBase_Resource_Is_Null));
				}
				return;
			}
			ModelUtil.saveResource(resource, WorkspaceUtil.getResourceLogger());
		} catch (final IOException e) {
			WorkspaceUtil.logException(Messages.ProjectSpaceBase_Error_During_Save
				+ Messages.ProjectSpaceBase_Delete_Project_And_Checkout_Again, e);
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#setProperty(org.eclipse.emf.emfstore.internal.server.model.accesscontrol.OrgUnitProperty)
	 */
	public void setProperty(OrgUnitProperty property) {
		// sanity checks
		if (getUsersession() != null && getUsersession().getACUser() != null) {
			try {
				if (property.getProject() == null) {
					property.setProject(ModelUtil.clone(getProjectId()));
				} else if (!property.getProject().equals(getProjectId())) {
					return;
				}
				final OrgUnitProperty prop = getProperty(property.getName());
				prop.setValue(property.getValue());
			} catch (final PropertyNotFoundException e) {
				getUsersession().getACUser().getProperties().add(property);
				propertyMap.put(property.getName(), property);
			}
			// the properties that have been altered are retained in a separate
			// list
			for (final OrgUnitProperty changedProperty : getUsersession().getChangedProperties()) {
				if (changedProperty.getName().equals(property.getName())
					&& changedProperty.getProject().equals(getProjectId())) {
					changedProperty.setValue(property.getValue());
					ESWorkspaceProviderImpl.getInstance().getWorkspace().toInternalAPI().save();
					return;
				}
			}
			getUsersession().getChangedProperties().add(property);
			ESWorkspaceProviderImpl.getInstance().getWorkspace().toInternalAPI().save();
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#shareProject(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public ProjectInfo shareProject(IProgressMonitor monitor) throws ESException {
		return shareProject(null, monitor);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#shareProject(org.eclipse.emf.emfstore.internal.client.model.Usersession,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 */
	public ProjectInfo shareProject(Usersession session, IProgressMonitor monitor) throws ESException {
		return new ShareController(this, session, monitor).execute();
	}

	/**
	 * Starts change recording on this workspace, resumes previous recordings if
	 * there are any.
	 */
	public void startChangeRecording() {
		operationManager.startChangeRecording();
		updateDirtyState();
	}

	/**
	 * Stops current recording of changes and adds recorded changes to this
	 * project spaces changes.
	 */
	public void stopChangeRecording() {
		if (operationManager != null) {
			operationManager.stopChangeRecording();
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#transmitProperties()
	 */
	public void transmitProperties() {
		final List<OrgUnitProperty> temp = new ArrayList<OrgUnitProperty>();
		for (final OrgUnitProperty changedProperty : getUsersession().getChangedProperties()) {
			if (changedProperty.getProject() != null && changedProperty.getProject().equals(getProjectId())) {
				temp.add(changedProperty);
			}
		}
		final ListIterator<OrgUnitProperty> iterator = temp.listIterator();
		while (iterator.hasNext()) {
			try {
				ESWorkspaceProviderImpl
					.getInstance()
					.getConnectionManager()
					.transmitProperty(getUsersession().getSessionId(), iterator.next(), getUsersession().getACUser(),
						getProjectId());
				iterator.remove();
			} catch (final ESException e) {
				WorkspaceUtil.logException(Messages.ProjectSpaceBase_Transmission_Of_Properties_Failed, e);
			}
		}
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#undoLastOperation()
	 */
	public void undoLastOperation() {
		undoLastOperations(1);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#undoLastOperation()
	 */
	public void undoLastOperations(int numberOfOperations) {

		if (numberOfOperations <= 0) {
			return;
		}

		if (!getLocalChangePackage().isEmpty()) {
			final List<AbstractOperation> operations = getLocalChangePackage().removeAtEnd(1);
			final AbstractOperation lastOperation = operations.get(0);
			final AbstractOperation reversedOperation = lastOperation.reverse();

			final Iterable<AbstractOperation> iterable = Collections.singletonList(reversedOperation);

			applyOperations(iterable, false);
			operationManager.notifyOperationUndone(lastOperation);

			undoLastOperations(--numberOfOperations);
		}
		updateDirtyState();
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#update(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public PrimaryVersionSpec update(IProgressMonitor monitor) throws ESException {
		return update(Versions.createHEAD(getBaseVersion()), null, monitor);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#update(org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec)
	 */
	public PrimaryVersionSpec update(final VersionSpec version) throws ESException {
		return update(version, null, null);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#update(org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec,
	 *      org.eclipse.emf.emfstore.client.callbacks.ESUpdateCallback, org.eclipse.core.runtime.IProgressMonitor)
	 */
	public PrimaryVersionSpec update(VersionSpec version, ESUpdateCallback callback, IProgressMonitor progress)
		throws ESException {
		return new UpdateController(this, version, callback, progress).execute();
	}

	/**
	 * Updates the dirty state of the project space.
	 */
	public void updateDirtyState() {
		boolean isEmpty = true;
		final AbstractChangePackage localChangePackage = getLocalChangePackage();
		if (localChangePackage == null) {
			return;
		}
		isEmpty = localChangePackage.isEmpty();
		if (isDirty() == !isEmpty) {
			return;
		}
		setDirty(!isEmpty);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.common.ESDisposable#dispose()
	 */
	@SuppressWarnings("unchecked")
	public void dispose() {

		if (disposed) {
			return;
		}

		stopChangeRecording();

		if (crossReferenceAdapter != null) {
			getProject().eAdapters().remove(crossReferenceAdapter);
		}

		final ESCommandStack commandStack = (ESCommandStack) ESWorkspaceProviderImpl.getInstance().getEditingDomain()
			.getCommandStack();
		commandStack.removeCommandStackObserver(operationManager);
		commandStack.removeCommandStackObserver(resourcePersister);

		getProject().removeIdEObjectCollectionChangeObserver(operationManager);
		getProject().removeIdEObjectCollectionChangeObserver(resourcePersister);

		ESWorkspaceProviderImpl.getObserverBus().unregister(resourcePersister);
		ESWorkspaceProviderImpl.getObserverBus().unregister(this, ESLoginObserver.class);
		ESWorkspaceProviderImpl.getObserverBus().unregister(this);

		operationManager.dispose();
		resourcePersister.dispose();
		disposed = true;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.client.model.ProjectSpace#isShared()
	 */
	public boolean isShared() {
		return getUsersession() != null && getBaseVersion() != null;
	}

	private void notifyPreRevertMyChanges(final AbstractChangePackage changePackage) {
		ESWorkspaceProviderImpl.getObserverBus().notify(ESMergeObserver.class)
			.preRevertMyChanges(toAPI(), changePackage.toAPI());
	}

	private void notifyPostRevertMyChanges() {
		ESWorkspaceProviderImpl.getObserverBus().notify(ESMergeObserver.class).postRevertMyChanges(toAPI());
	}

	private void notifyPostApplyTheirChanges(List<AbstractChangePackage> theirChangePackages) {

		final List<ESChangePackage> changePackages = new ArrayList<ESChangePackage>();
		for (final AbstractChangePackage theirChangePackage : theirChangePackages) {
			changePackages.add(theirChangePackage.toAPI());
		}

		// TODO ASYNC review this cancel
		ESWorkspaceProviderImpl.getObserverBus().notify(ESMergeObserver.class)
			.postApplyTheirChanges(toAPI(), changePackages);
	}

	private void notifyPostApplyMergedChanges(AbstractChangePackage changePackage) {
		ESWorkspaceProviderImpl.getObserverBus().notify(ESMergeObserver.class)
			.postApplyMergedChanges(
				toAPI(), changePackage.toAPI());
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.common.api.APIDelegate#toAPI()
	 */
	public ESLocalProjectImpl toAPI() {
		if (esLocalProjectImpl == null) {
			esLocalProjectImpl = createAPI();
		}
		return esLocalProjectImpl;
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emf.emfstore.internal.common.api.APIDelegate#createAPI()
	 */
	public ESLocalProjectImpl createAPI() {
		return new ESLocalProjectImpl(this);
	}

	/**
	 * Returns the {@link ESRunnableContext} operations are applied in.
	 *
	 * @return the runnable context operations are executed in
	 */
	public ESRunnableContext getRunnableContext() {
		return runnableContext;
	}
}
