/*******************************************************************************
 * 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
 ******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.impl;

import java.util.Collection;
import java.util.Date;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EDataTypeEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
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.internal.client.model.ModelPackage;
import org.eclipse.emf.emfstore.internal.client.model.Usersession;
import org.eclipse.emf.emfstore.internal.client.model.Workspace;
import org.eclipse.emf.emfstore.internal.common.model.EMFStoreProperty;
import org.eclipse.emf.emfstore.internal.common.model.Project;
import org.eclipse.emf.emfstore.internal.server.model.FileIdentifier;
import org.eclipse.emf.emfstore.internal.server.model.ProjectId;
import org.eclipse.emf.emfstore.internal.server.model.versioning.AbstractChangePackage;
import org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec;

/**
 * <!-- begin-user-doc --> An implementation of the model object ' <em><b>Project Container</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getProject <em>Project</em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getProjectId <em>Project Id</em>}
 * </li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getProjectName <em>Project Name
 * </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getProjectDescription <em>Project
 * Description </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getUsersession <em>Usersession </em>}
 * </li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getLastUpdated <em>Last Updated
 * </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getBaseVersion <em>Base Version
 * </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getResourceCount <em>Resource Count
 * </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#isDirty <em>Dirty</em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getOldLogMessages <em>Old Log
 * Messages</em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getLocalChangePackage() <em>Local
 * Change Package</em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getWaitingUploads <em>Waiting Uploads
 * </em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getProperties <em>Properties</em>}
 * </li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getChangedSharedProperties <em>
 * Changed Shared Properties</em>}</li>
 * <li>{@link org.eclipse.emf.emfstore.internal.client.model.impl.ProjectSpaceImpl#getWorkspace <em>Workspace</em>}</li>
 * </ul>
 * </p>
 *
 */
public class ProjectSpaceImpl extends ProjectSpaceBase {

	/**
	 * The cached value of the '{@link #getProject() <em>Project</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getProject()
	 * @generated
	 * @ordered
	 */
	protected Project project;

	/**
	 * The cached value of the '{@link #getProjectId() <em>Project Id</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getProjectId()
	 * @generated
	 * @ordered
	 */
	protected ProjectId projectId;

	/**
	 * The default value of the '{@link #getProjectName() <em>Project Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getProjectName()
	 * @generated
	 * @ordered
	 */
	protected static final String PROJECT_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getProjectName() <em>Project Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getProjectName()
	 * @generated
	 * @ordered
	 */
	protected String projectName = PROJECT_NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getProjectDescription() <em>Project Description</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getProjectDescription()
	 * @generated
	 * @ordered
	 */
	protected static final String PROJECT_DESCRIPTION_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getProjectDescription() <em>Project Description</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getProjectDescription()
	 * @generated
	 * @ordered
	 */
	protected String projectDescription = PROJECT_DESCRIPTION_EDEFAULT;

	/**
	 * The cached value of the '{@link #getUsersession() <em>Usersession</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getUsersession()
	 * @generated
	 * @ordered
	 */
	protected Usersession usersession;

	/**
	 * The default value of the '{@link #getLastUpdated() <em>Last Updated</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getLastUpdated()
	 * @generated
	 * @ordered
	 */
	protected static final Date LAST_UPDATED_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getLastUpdated() <em>Last Updated</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getLastUpdated()
	 * @generated
	 * @ordered
	 */
	protected Date lastUpdated = LAST_UPDATED_EDEFAULT;

	/**
	 * The cached value of the '{@link #getBaseVersion() <em>Base Version</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getBaseVersion()
	 * @generated
	 * @ordered
	 */
	protected PrimaryVersionSpec baseVersion;

	/**
	 * The default value of the '{@link #getResourceCount() <em>Resource Count</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getResourceCount()
	 * @generated
	 * @ordered
	 */
	protected static final int RESOURCE_COUNT_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getResourceCount() <em>Resource Count</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getResourceCount()
	 * @generated
	 * @ordered
	 */
	protected int resourceCount = RESOURCE_COUNT_EDEFAULT;

	/**
	 * The default value of the '{@link #isDirty() <em>Dirty</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #isDirty()
	 * @generated
	 * @ordered
	 */
	protected static final boolean DIRTY_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isDirty() <em>Dirty</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #isDirty()
	 * @generated
	 * @ordered
	 */
	protected boolean dirty = DIRTY_EDEFAULT;

	/**
	 * The cached value of the '{@link #getOldLogMessages() <em>Old Log Messages</em>}' attribute list.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getOldLogMessages()
	 * @generated
	 * @ordered
	 */
	protected EList<String> oldLogMessages;

	/**
	 * The cached value of the '{@link #getWaitingUploads()
	 * <em>Waiting Uploads</em>}' containment reference list. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getWaitingUploads()
	 * @generated
	 * @ordered
	 */
	protected EList<FileIdentifier> waitingUploads;

	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected EList<EMFStoreProperty> properties;

	/**
	 * The cached value of the '{@link #getChangedSharedProperties() <em>Changed Shared Properties</em>}' reference
	 * list.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 *
	 * @see #getChangedSharedProperties()
	 * @generated
	 * @ordered
	 */
	protected EList<EMFStoreProperty> changedSharedProperties;

	/**
	 * The cached value of the '{@link #getLocalChangePackage() <em>Local Change Package</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getLocalChangePackage()
	 * @generated
	 * @ordered
	 */
	protected AbstractChangePackage localChangePackage;

	/**
	 * The cached value of the '{@link #getMergedVersion() <em>Merged Version</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @see #getMergedVersion()
	 * @generated
	 * @ordered
	 */
	protected PrimaryVersionSpec mergedVersion;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	protected ProjectSpaceImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public PrimaryVersionSpec basicGetBaseVersion() {
		return baseVersion;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Project basicGetProject() {
		return project;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public ProjectId basicGetProjectId() {
		return projectId;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Usersession basicGetUsersession() {
		return usersession;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Workspace basicGetWorkspace() {
		if (eContainerFeatureID() != ModelPackage.PROJECT_SPACE__WORKSPACE) {
			return null;
		}
		return (Workspace) eInternalContainer();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetBaseVersion(PrimaryVersionSpec newBaseVersion, NotificationChain msgs) {
		final PrimaryVersionSpec oldBaseVersion = baseVersion;
		baseVersion = newBaseVersion;
		if (eNotificationRequired()) {
			final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET,
				ModelPackage.PROJECT_SPACE__BASE_VERSION, oldBaseVersion, newBaseVersion);
			if (msgs == null) {
				msgs = notification;
			} else {
				msgs.add(notification);
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetProject(Project newProject, NotificationChain msgs) {
		final Project oldProject = project;
		project = newProject;
		if (eNotificationRequired()) {
			final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET,
				ModelPackage.PROJECT_SPACE__PROJECT, oldProject, newProject);
			if (msgs == null) {
				msgs = notification;
			} else {
				msgs.add(notification);
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetProjectId(ProjectId newProjectId, NotificationChain msgs) {
		final ProjectId oldProjectId = projectId;
		projectId = newProjectId;
		if (eNotificationRequired()) {
			final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET,
				ModelPackage.PROJECT_SPACE__PROJECT_ID, oldProjectId, newProjectId);
			if (msgs == null) {
				msgs = notification;
			} else {
				msgs.add(notification);
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetWorkspace(Workspace newWorkspace, NotificationChain msgs) {
		msgs = eBasicSetContainer((InternalEObject) newWorkspace, ModelPackage.PROJECT_SPACE__WORKSPACE, msgs);
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs) {
		switch (eContainerFeatureID()) {
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			return eInternalContainer().eInverseRemove(this, ModelPackage.WORKSPACE__PROJECT_SPACES, Workspace.class,
				msgs);
		}
		return super.eBasicRemoveFromContainerFeature(msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__PROJECT:
			if (resolve) {
				return getProject();
			}
			return basicGetProject();
		case ModelPackage.PROJECT_SPACE__PROJECT_ID:
			if (resolve) {
				return getProjectId();
			}
			return basicGetProjectId();
		case ModelPackage.PROJECT_SPACE__PROJECT_NAME:
			return getProjectName();
		case ModelPackage.PROJECT_SPACE__PROJECT_DESCRIPTION:
			return getProjectDescription();
		case ModelPackage.PROJECT_SPACE__USERSESSION:
			if (resolve) {
				return getUsersession();
			}
			return basicGetUsersession();
		case ModelPackage.PROJECT_SPACE__LAST_UPDATED:
			return getLastUpdated();
		case ModelPackage.PROJECT_SPACE__BASE_VERSION:
			if (resolve) {
				return getBaseVersion();
			}
			return basicGetBaseVersion();
		case ModelPackage.PROJECT_SPACE__RESOURCE_COUNT:
			return getResourceCount();
		case ModelPackage.PROJECT_SPACE__DIRTY:
			return isDirty();
		case ModelPackage.PROJECT_SPACE__OLD_LOG_MESSAGES:
			return getOldLogMessages();
		case ModelPackage.PROJECT_SPACE__WAITING_UPLOADS:
			return getWaitingUploads();
		case ModelPackage.PROJECT_SPACE__PROPERTIES:
			return getProperties();
		case ModelPackage.PROJECT_SPACE__CHANGED_SHARED_PROPERTIES:
			return getChangedSharedProperties();
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			if (resolve) {
				return getWorkspace();
			}
			return basicGetWorkspace();
		case ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE:
			if (resolve) {
				return getLocalChangePackage();
			}
			return basicGetLocalChangePackage();
		case ModelPackage.PROJECT_SPACE__MERGED_VERSION:
			if (resolve) {
				return getMergedVersion();
			}
			return basicGetMergedVersion();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			return basicSetWorkspace((Workspace) otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__PROJECT:
			return basicSetProject(null, msgs);
		case ModelPackage.PROJECT_SPACE__PROJECT_ID:
			return basicSetProjectId(null, msgs);
		case ModelPackage.PROJECT_SPACE__BASE_VERSION:
			return basicSetBaseVersion(null, msgs);
		case ModelPackage.PROJECT_SPACE__WAITING_UPLOADS:
			return ((InternalEList<?>) getWaitingUploads()).basicRemove(otherEnd, msgs);
		case ModelPackage.PROJECT_SPACE__PROPERTIES:
			return ((InternalEList<?>) getProperties()).basicRemove(otherEnd, msgs);
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			return basicSetWorkspace(null, msgs);
		case ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE:
			return basicSetLocalChangePackage(null, msgs);
		case ModelPackage.PROJECT_SPACE__MERGED_VERSION:
			return basicSetMergedVersion(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__PROJECT:
			return project != null;
		case ModelPackage.PROJECT_SPACE__PROJECT_ID:
			return projectId != null;
		case ModelPackage.PROJECT_SPACE__PROJECT_NAME:
			return PROJECT_NAME_EDEFAULT == null ? projectName != null : !PROJECT_NAME_EDEFAULT.equals(projectName);
		case ModelPackage.PROJECT_SPACE__PROJECT_DESCRIPTION:
			return PROJECT_DESCRIPTION_EDEFAULT == null ? projectDescription != null : !PROJECT_DESCRIPTION_EDEFAULT
				.equals(projectDescription);
		case ModelPackage.PROJECT_SPACE__USERSESSION:
			return usersession != null;
		case ModelPackage.PROJECT_SPACE__LAST_UPDATED:
			return LAST_UPDATED_EDEFAULT == null ? lastUpdated != null : !LAST_UPDATED_EDEFAULT.equals(lastUpdated);
		case ModelPackage.PROJECT_SPACE__BASE_VERSION:
			return baseVersion != null;
		case ModelPackage.PROJECT_SPACE__RESOURCE_COUNT:
			return resourceCount != RESOURCE_COUNT_EDEFAULT;
		case ModelPackage.PROJECT_SPACE__DIRTY:
			return dirty != DIRTY_EDEFAULT;
		case ModelPackage.PROJECT_SPACE__OLD_LOG_MESSAGES:
			return oldLogMessages != null && !oldLogMessages.isEmpty();
		case ModelPackage.PROJECT_SPACE__WAITING_UPLOADS:
			return waitingUploads != null && !waitingUploads.isEmpty();
		case ModelPackage.PROJECT_SPACE__PROPERTIES:
			return properties != null && !properties.isEmpty();
		case ModelPackage.PROJECT_SPACE__CHANGED_SHARED_PROPERTIES:
			return changedSharedProperties != null && !changedSharedProperties.isEmpty();
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			return basicGetWorkspace() != null;
		case ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE:
			return localChangePackage != null;
		case ModelPackage.PROJECT_SPACE__MERGED_VERSION:
			return mergedVersion != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__PROJECT:
			setProject((Project) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_ID:
			setProjectId((ProjectId) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_NAME:
			setProjectName((String) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_DESCRIPTION:
			setProjectDescription((String) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__USERSESSION:
			setUsersession((Usersession) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__LAST_UPDATED:
			setLastUpdated((Date) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__BASE_VERSION:
			setBaseVersion((PrimaryVersionSpec) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__RESOURCE_COUNT:
			setResourceCount((Integer) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__DIRTY:
			setDirty((Boolean) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__OLD_LOG_MESSAGES:
			getOldLogMessages().clear();
			getOldLogMessages().addAll((Collection<? extends String>) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__WAITING_UPLOADS:
			getWaitingUploads().clear();
			getWaitingUploads().addAll((Collection<? extends FileIdentifier>) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__PROPERTIES:
			getProperties().clear();
			getProperties().addAll((Collection<? extends EMFStoreProperty>) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__CHANGED_SHARED_PROPERTIES:
			getChangedSharedProperties().clear();
			getChangedSharedProperties().addAll((Collection<? extends EMFStoreProperty>) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			setWorkspace((Workspace) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE:
			setLocalChangePackage((AbstractChangePackage) newValue);
			return;
		case ModelPackage.PROJECT_SPACE__MERGED_VERSION:
			setMergedVersion((PrimaryVersionSpec) newValue);
			return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ModelPackage.Literals.PROJECT_SPACE;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
		case ModelPackage.PROJECT_SPACE__PROJECT:
			setProject((Project) null);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_ID:
			setProjectId((ProjectId) null);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_NAME:
			setProjectName(PROJECT_NAME_EDEFAULT);
			return;
		case ModelPackage.PROJECT_SPACE__PROJECT_DESCRIPTION:
			setProjectDescription(PROJECT_DESCRIPTION_EDEFAULT);
			return;
		case ModelPackage.PROJECT_SPACE__USERSESSION:
			setUsersession((Usersession) null);
			return;
		case ModelPackage.PROJECT_SPACE__LAST_UPDATED:
			setLastUpdated(LAST_UPDATED_EDEFAULT);
			return;
		case ModelPackage.PROJECT_SPACE__BASE_VERSION:
			setBaseVersion((PrimaryVersionSpec) null);
			return;
		case ModelPackage.PROJECT_SPACE__RESOURCE_COUNT:
			setResourceCount(RESOURCE_COUNT_EDEFAULT);
			return;
		case ModelPackage.PROJECT_SPACE__DIRTY:
			setDirty(DIRTY_EDEFAULT);
			return;
		case ModelPackage.PROJECT_SPACE__OLD_LOG_MESSAGES:
			getOldLogMessages().clear();
			return;
		case ModelPackage.PROJECT_SPACE__WAITING_UPLOADS:
			getWaitingUploads().clear();
			return;
		case ModelPackage.PROJECT_SPACE__PROPERTIES:
			getProperties().clear();
			return;
		case ModelPackage.PROJECT_SPACE__CHANGED_SHARED_PROPERTIES:
			getChangedSharedProperties().clear();
			return;
		case ModelPackage.PROJECT_SPACE__WORKSPACE:
			setWorkspace((Workspace) null);
			return;
		case ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE:
			setLocalChangePackage((AbstractChangePackage) null);
			return;
		case ModelPackage.PROJECT_SPACE__MERGED_VERSION:
			setMergedVersion((PrimaryVersionSpec) null);
			return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public PrimaryVersionSpec getBaseVersion() {
		if (baseVersion != null && baseVersion.eIsProxy()) {
			final InternalEObject oldBaseVersion = (InternalEObject) baseVersion;
			baseVersion = (PrimaryVersionSpec) eResolveProxy(oldBaseVersion);
			if (baseVersion != oldBaseVersion) {
				final InternalEObject newBaseVersion = (InternalEObject) baseVersion;
				NotificationChain msgs = oldBaseVersion.eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__BASE_VERSION, null, null);
				if (newBaseVersion.eInternalContainer() == null) {
					msgs = newBaseVersion.eInverseAdd(this, EOPPOSITE_FEATURE_BASE
						- ModelPackage.PROJECT_SPACE__BASE_VERSION, null, msgs);
				}
				if (msgs != null) {
					msgs.dispatch();
				}
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ModelPackage.PROJECT_SPACE__BASE_VERSION,
						oldBaseVersion, baseVersion));
				}
			}
		}
		return baseVersion;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public EList<EMFStoreProperty> getChangedSharedProperties() {
		if (changedSharedProperties == null) {
			changedSharedProperties = new EObjectResolvingEList<EMFStoreProperty>(EMFStoreProperty.class, this,
				ModelPackage.PROJECT_SPACE__CHANGED_SHARED_PROPERTIES);
		}
		return changedSharedProperties;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Date getLastUpdated() {
		return lastUpdated;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public EList<String> getOldLogMessages() {
		if (oldLogMessages == null) {
			oldLogMessages = new EDataTypeEList<String>(String.class, this,
				ModelPackage.PROJECT_SPACE__OLD_LOG_MESSAGES);
		}
		return oldLogMessages;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Project getProject() {
		if (project != null && project.eIsProxy()) {
			final InternalEObject oldProject = (InternalEObject) project;
			project = (Project) eResolveProxy(oldProject);
			if (project != oldProject) {
				final InternalEObject newProject = (InternalEObject) project;
				NotificationChain msgs = oldProject.eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT, null, null);
				if (newProject.eInternalContainer() == null) {
					msgs = newProject.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.PROJECT_SPACE__PROJECT,
						null, msgs);
				}
				if (msgs != null) {
					msgs.dispatch();
				}
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ModelPackage.PROJECT_SPACE__PROJECT,
						oldProject, project));
				}
			}
		}
		return project;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public String getProjectDescription() {
		return projectDescription;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public ProjectId getProjectId() {
		if (projectId != null && projectId.eIsProxy()) {
			final InternalEObject oldProjectId = (InternalEObject) projectId;
			projectId = (ProjectId) eResolveProxy(oldProjectId);
			if (projectId != oldProjectId) {
				final InternalEObject newProjectId = (InternalEObject) projectId;
				NotificationChain msgs = oldProjectId.eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT_ID, null, null);
				if (newProjectId.eInternalContainer() == null) {
					msgs = newProjectId.eInverseAdd(this, EOPPOSITE_FEATURE_BASE
						- ModelPackage.PROJECT_SPACE__PROJECT_ID, null, msgs);
				}
				if (msgs != null) {
					msgs.dispatch();
				}
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ModelPackage.PROJECT_SPACE__PROJECT_ID,
						oldProjectId, projectId));
				}
			}
		}
		return projectId;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public String getProjectName() {
		return projectName;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public EList<EMFStoreProperty> getProperties() {
		if (properties == null) {
			properties = new EObjectContainmentEList.Resolving<EMFStoreProperty>(EMFStoreProperty.class, this,
				ModelPackage.PROJECT_SPACE__PROPERTIES);
		}
		return properties;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public int getResourceCount() {
		return resourceCount;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Usersession getUsersession() {
		if (usersession != null && usersession.eIsProxy()) {
			final InternalEObject oldUsersession = (InternalEObject) usersession;
			usersession = (Usersession) eResolveProxy(oldUsersession);
			if (usersession != oldUsersession) {
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ModelPackage.PROJECT_SPACE__USERSESSION,
						oldUsersession, usersession));
				}
			}
		}
		return usersession;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public EList<FileIdentifier> getWaitingUploads() {
		if (waitingUploads == null) {
			waitingUploads = new EObjectContainmentEList.Resolving<FileIdentifier>(FileIdentifier.class, this,
				ModelPackage.PROJECT_SPACE__WAITING_UPLOADS);
		}
		return waitingUploads;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public Workspace getWorkspace() {
		if (eContainerFeatureID() != ModelPackage.PROJECT_SPACE__WORKSPACE) {
			return null;
		}
		return (Workspace) eContainer();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public boolean isDirty() {
		return dirty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setBaseVersion(PrimaryVersionSpec newBaseVersion) {
		if (newBaseVersion != baseVersion) {
			NotificationChain msgs = null;
			if (baseVersion != null) {
				msgs = ((InternalEObject) baseVersion).eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__BASE_VERSION, null, msgs);
			}
			if (newBaseVersion != null) {
				msgs = ((InternalEObject) newBaseVersion).eInverseAdd(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__BASE_VERSION, null, msgs);
			}
			msgs = basicSetBaseVersion(newBaseVersion, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__BASE_VERSION,
				newBaseVersion, newBaseVersion));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setDirty(boolean newDirty) {
		final boolean oldDirty = dirty;
		dirty = newDirty;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__DIRTY, oldDirty, dirty));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setLastUpdated(Date newLastUpdated) {
		final Date oldLastUpdated = lastUpdated;
		lastUpdated = newLastUpdated;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__LAST_UPDATED,
				oldLastUpdated, lastUpdated));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setProject(Project newProject) {
		if (newProject != project) {
			NotificationChain msgs = null;
			if (project != null) {
				msgs = ((InternalEObject) project).eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT, null, msgs);
			}
			if (newProject != null) {
				msgs = ((InternalEObject) newProject).eInverseAdd(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT, null, msgs);
			}
			msgs = basicSetProject(newProject, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__PROJECT, newProject,
				newProject));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setProjectDescription(String newProjectDescription) {
		final String oldProjectDescription = projectDescription;
		projectDescription = newProjectDescription;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__PROJECT_DESCRIPTION,
				oldProjectDescription, projectDescription));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setProjectId(ProjectId newProjectId) {
		if (newProjectId != projectId) {
			NotificationChain msgs = null;
			if (projectId != null) {
				msgs = ((InternalEObject) projectId).eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT_ID, null, msgs);
			}
			if (newProjectId != null) {
				msgs = ((InternalEObject) newProjectId).eInverseAdd(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__PROJECT_ID, null, msgs);
			}
			msgs = basicSetProjectId(newProjectId, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__PROJECT_ID, newProjectId,
				newProjectId));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setProjectName(String newProjectName) {
		final String oldProjectName = projectName;
		projectName = newProjectName;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__PROJECT_NAME,
				oldProjectName, projectName));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setResourceCount(int newResourceCount) {
		final int oldResourceCount = resourceCount;
		resourceCount = newResourceCount;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__RESOURCE_COUNT,
				oldResourceCount, resourceCount));
		}
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setUsersession(Usersession newUsersession) {
		final Usersession oldUsersession = usersession;
		usersession = newUsersession;
		if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__USERSESSION,
				oldUsersession, usersession));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setWorkspace(Workspace newWorkspace) {
		if (newWorkspace != eInternalContainer()
			|| eContainerFeatureID() != ModelPackage.PROJECT_SPACE__WORKSPACE && newWorkspace != null) {
			if (EcoreUtil.isAncestor(this, newWorkspace)) {
				throw new IllegalArgumentException("Recursive containment not allowed for " + toString()); //$NON-NLS-1$
			}
			NotificationChain msgs = null;
			if (eInternalContainer() != null) {
				msgs = eBasicRemoveFromContainer(msgs);
			}
			if (newWorkspace != null) {
				msgs = ((InternalEObject) newWorkspace).eInverseAdd(this, ModelPackage.WORKSPACE__PROJECT_SPACES,
					Workspace.class, msgs);
			}
			msgs = basicSetWorkspace(newWorkspace, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__WORKSPACE, newWorkspace,
				newWorkspace));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public AbstractChangePackage getLocalChangePackage() {
		if (localChangePackage != null && localChangePackage.eIsProxy()) {
			final InternalEObject oldLocalChangePackage = (InternalEObject) localChangePackage;
			localChangePackage = (AbstractChangePackage) eResolveProxy(oldLocalChangePackage);
			if (localChangePackage != oldLocalChangePackage) {
				final InternalEObject newLocalChangePackage = (InternalEObject) localChangePackage;
				NotificationChain msgs = oldLocalChangePackage.eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, null, null);
				if (newLocalChangePackage.eInternalContainer() == null) {
					msgs = newLocalChangePackage.eInverseAdd(this, EOPPOSITE_FEATURE_BASE
						- ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, null, msgs);
				}
				if (msgs != null) {
					msgs.dispatch();
				}
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE,
						ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, oldLocalChangePackage, localChangePackage));
				}
			}
		}
		return localChangePackage;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public AbstractChangePackage basicGetLocalChangePackage() {
		return localChangePackage;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetLocalChangePackage(AbstractChangePackage newLocalChangePackage,
		NotificationChain msgs) {
		final AbstractChangePackage oldLocalChangePackage = localChangePackage;
		localChangePackage = newLocalChangePackage;
		if (eNotificationRequired()) {
			final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET,
				ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, oldLocalChangePackage, newLocalChangePackage);
			if (msgs == null) {
				msgs = notification;
			} else {
				msgs.add(notification);
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setLocalChangePackage(AbstractChangePackage newLocalChangePackage) {
		if (newLocalChangePackage != localChangePackage) {
			NotificationChain msgs = null;
			if (localChangePackage != null) {
				msgs = ((InternalEObject) localChangePackage).eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, null, msgs);
			}
			if (newLocalChangePackage != null) {
				msgs = ((InternalEObject) newLocalChangePackage).eInverseAdd(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE, null, msgs);
			}
			msgs = basicSetLocalChangePackage(newLocalChangePackage, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__LOCAL_CHANGE_PACKAGE,
				newLocalChangePackage, newLocalChangePackage));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public PrimaryVersionSpec getMergedVersion() {
		if (mergedVersion != null && mergedVersion.eIsProxy()) {
			final InternalEObject oldMergedVersion = (InternalEObject) mergedVersion;
			mergedVersion = (PrimaryVersionSpec) eResolveProxy(oldMergedVersion);
			if (mergedVersion != oldMergedVersion) {
				final InternalEObject newMergedVersion = (InternalEObject) mergedVersion;
				NotificationChain msgs = oldMergedVersion.eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__MERGED_VERSION, null, null);
				if (newMergedVersion.eInternalContainer() == null) {
					msgs = newMergedVersion.eInverseAdd(this, EOPPOSITE_FEATURE_BASE
						- ModelPackage.PROJECT_SPACE__MERGED_VERSION, null, msgs);
				}
				if (msgs != null) {
					msgs.dispatch();
				}
				if (eNotificationRequired()) {
					eNotify(new ENotificationImpl(this, Notification.RESOLVE,
						ModelPackage.PROJECT_SPACE__MERGED_VERSION, oldMergedVersion, mergedVersion));
				}
			}
		}
		return mergedVersion;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public PrimaryVersionSpec basicGetMergedVersion() {
		return mergedVersion;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public NotificationChain basicSetMergedVersion(PrimaryVersionSpec newMergedVersion, NotificationChain msgs) {
		final PrimaryVersionSpec oldMergedVersion = mergedVersion;
		mergedVersion = newMergedVersion;
		if (eNotificationRequired()) {
			final ENotificationImpl notification = new ENotificationImpl(this, Notification.SET,
				ModelPackage.PROJECT_SPACE__MERGED_VERSION, oldMergedVersion, newMergedVersion);
			if (msgs == null) {
				msgs = notification;
			} else {
				msgs.add(notification);
			}
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	public void setMergedVersion(PrimaryVersionSpec newMergedVersion) {
		if (newMergedVersion != mergedVersion) {
			NotificationChain msgs = null;
			if (mergedVersion != null) {
				msgs = ((InternalEObject) mergedVersion).eInverseRemove(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__MERGED_VERSION, null, msgs);
			}
			if (newMergedVersion != null) {
				msgs = ((InternalEObject) newMergedVersion).eInverseAdd(this, EOPPOSITE_FEATURE_BASE
					- ModelPackage.PROJECT_SPACE__MERGED_VERSION, null, msgs);
			}
			msgs = basicSetMergedVersion(newMergedVersion, msgs);
			if (msgs != null) {
				msgs.dispatch();
			}
		} else if (eNotificationRequired()) {
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.PROJECT_SPACE__MERGED_VERSION,
				newMergedVersion, newMergedVersion));
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 *
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) {
			return super.toString();
		}

		final StringBuffer result = new StringBuffer(super.toString());
		result.append(" (projectName: "); //$NON-NLS-1$
		result.append(projectName);
		result.append(", projectDescription: "); //$NON-NLS-1$
		result.append(projectDescription);
		result.append(", lastUpdated: "); //$NON-NLS-1$
		result.append(lastUpdated);
		result.append(", resourceCount: "); //$NON-NLS-1$
		result.append(resourceCount);
		result.append(", dirty: "); //$NON-NLS-1$
		result.append(dirty);
		result.append(", oldLogMessages: "); //$NON-NLS-1$
		result.append(oldLogMessages);
		result.append(')');
		return result.toString();
	}

	/**
	 * {@inheritDoc}
	 *
	 * @generated NOT
	 *
	 * @see org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.ChangePackageContainer#setChangePackage(org.eclipse.emf.emfstore.internal.server.model.versioning.AbstractChangePackage)
	 */
	public void setChangePackage(final AbstractChangePackage changePackage) {
		// move change package into its own resource
		final Resource resource = getResourceSet().createResource(ESClientURIUtil.createOperationsURI(this));
		RunESCommand.run(new ESVoidCallable() {
			@Override
			public void run() {
				resource.getContents().add(changePackage);
				setLocalChangePackage(changePackage);
			}
		});
	}

	/**
	 * {@inheritDoc}
	 *
	 * @generated NOT
	 *
	 * @see org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.ChangePackageContainer#getChangePackageUri()
	 */
	public URI getChangePackageUri() {
		final URI localChangePackageUri = ESClientURIUtil.createOperationsURI(this);
		final URI normalizedUri = getResourceSet().getURIConverter().normalize(localChangePackageUri);
		return normalizedUri;
	}
}