From 3f89370275f963802955bfe11248ad859d92ae53 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Tue, 24 May 2011 15:10:22 +0000
Subject: [PATCH] Implemented IPersistencyService and IStorageProvider for
 Eclipse workspace projects.

---
 .../trunk/META-INF/MANIFEST.MF                |   9 +-
 .../trunk/icons/server.png                    | Bin 3153 -> 0 bytes
 org.fortiss.tooling.kernel/trunk/plugin.xml   |  71 ----
 .../IStorageProvider.java}                    |  32 +-
 .../ITopLevelElementChangeListener.java}      |  27 +-
 .../kernel/internal/ActionService.java        |   9 +-
 .../kernel/internal/CommandStackService.java  | 166 +-------
 .../kernel/internal/PersistencyService.java   | 130 ++++++
 .../EclipseWorkspaceLocationProviderBase.java |  99 -----
 .../NavigatorTreeContentProvider.java         |  29 +-
 .../navigator/NavigatorTreeLabelProvider.java |   2 +
 .../internal/navigator/NavigatorViewPart.java | 122 +-----
 .../properties/PropertiesAdapterFactory.java  |   5 +-
 .../storage/eclipse/AutoUndoCommandStack.java | 141 +++++++
 .../eclipse/EMFTransactionalCommand.java      | 182 ++++++++
 .../eclipse/EMultiContentsIterator.java}      |  79 ++--
 .../EclipseResourceStorageProvider.java       | 233 +++++++++++
 .../storage/eclipse/ModelContext.java         | 390 ++++++++++++++++++
 .../kernel/services/IPersistencyService.java  |  39 +-
 .../EMFResourceUtils.java}                    |  47 ++-
 .../kernel/util/ProjectRootElementUtils.java  |  23 +-
 21 files changed, 1268 insertions(+), 567 deletions(-)
 delete mode 100644 org.fortiss.tooling.kernel/trunk/icons/server.png
 rename org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/{internal/emfstore/EclipseWorkspaceUnicaseClientLocationProvider.java => interfaces/IStorageProvider.java} (66%)
 rename org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/{internal/emfstore/EclipseWorkspaceEMFStoreLocationProvider.java => interfaces/ITopLevelElementChangeListener.java} (66%)
 delete mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceLocationProviderBase.java
 create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/AutoUndoCommandStack.java
 create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMFTransactionalCommand.java
 rename org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/{handler/ProjectModelElementHandler.java => storage/eclipse/EMultiContentsIterator.java} (50%)
 create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java
 create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
 rename org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/{internal/compose/ProjectCompositor.java => util/EMFResourceUtils.java} (54%)

diff --git a/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF b/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
index 3b108be87..9a1cbf726 100644
--- a/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
@@ -14,12 +14,9 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
  org.eclipse.gef;visibility:=reexport,
  org.conqat.ide.commons;bundle-version="2.7.0";visibility:=reexport,
  org.conqat.ide.commons.ui;bundle-version="2.7.0";visibility:=reexport,
- org.conqat.ide.commons.gef;bundle-version="2.7.0",
- org.eclipse.jdt.ui;bundle-version="3.6.2",
- org.eclipse.emf.transaction;bundle-version="1.4.0",
- org.eclipse.emf.emfstore.server;bundle-version="0.7.3",
- org.eclipse.emf.emfstore.client;bundle-version="0.7.3",
- org.eclipse.emf.emfstore.client.ui;bundle-version="0.7.3"
+ org.conqat.ide.commons.gef;bundle-version="2.7.0";visibility:=reexport,
+ org.eclipse.emf.ecore.xmi;bundle-version="2.5.0",
+ org.eclipse.emf.transaction;bundle-version="1.4.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.fortiss.tooling.kernel;uses:="org.eclipse.jface.resource,org.eclipse.ui.plugin,org.osgi.framework",
diff --git a/org.fortiss.tooling.kernel/trunk/icons/server.png b/org.fortiss.tooling.kernel/trunk/icons/server.png
deleted file mode 100644
index 4e472dd74433e92014ba5198172235eadc404aec..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3153
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

diff --git a/org.fortiss.tooling.kernel/trunk/plugin.xml b/org.fortiss.tooling.kernel/trunk/plugin.xml
index 004894271..02b98324e 100644
--- a/org.fortiss.tooling.kernel/trunk/plugin.xml
+++ b/org.fortiss.tooling.kernel/trunk/plugin.xml
@@ -13,18 +13,6 @@
             uri="http://www.fortiss.org/tooling/kernel">
       </package>
    </extension>
-   <extension
-         point="org.eclipse.emf.emfstore.server.locationprovider">
-      <LocationProvider
-            providerClass="org.fortiss.tooling.kernel.internal.emfstore.EclipseWorkspaceEMFStoreLocationProvider">
-      </LocationProvider>
-   </extension>
-   <extension
-         point="org.eclipse.emf.emfstore.client.workspaceLocationProvider">
-      <LocationProvider
-            providerClass="org.fortiss.tooling.kernel.internal.emfstore.EclipseWorkspaceUnicaseClientLocationProvider">
-      </LocationProvider>
-   </extension>
    <extension
          point="org.eclipse.ui.editors">
       <editor
@@ -76,51 +64,6 @@
             </dynamic>
          </menu>
       </menuContribution>
-      <menuContribution
-            allPopups="false"
-            locationURI="popup:org.fortiss.tooling.kernel.model.navigator?after=repository">
-         <menu
-               icon="icons/server.png"
-               id="org.fortiss.tooling.kernel.model.navigator.repositorymenu"
-               label="Repository">
-            <visibleWhen
-                  checkEnabled="false">
-               <with
-                     variable="activeMenuSelection">
-                  <iterate>
-                     <adapt
-                           type="org.eclipse.emf.emfstore.client.model.ProjectSpace">
-                     </adapt>
-                  </iterate>
-               </with>
-            </visibleWhen>
-            <command
-                  commandId="org.eclipse.emf.emfstore.client.ui.commitProject"
-                  label="Commit..."
-                  style="push">
-            </command>
-            <command
-                  commandId="org.eclipse.emf.emfstore.client.ui.updateProject"
-                  label="Update to HEAD"
-                  style="push">
-            </command>
-            <command
-                  commandId="org.eclipse.emf.emfstore.client.ui.updateProjectVersion"
-                  label="Update to Version..."
-                  style="push">
-            </command>
-            <command
-                  commandId="org.eclipse.emf.emfstore.client.ui.revert"
-                  label="Revert"
-                  style="push">
-            </command>
-            <command
-                  commandId="org.eclipse.emf.emfstore.client.ui.deleteProject"
-                  label="Delete Local Project"
-                  style="push">
-            </command>
-         </menu>
-      </menuContribution>
    </extension>
    <extension
          point="org.eclipse.core.runtime.adapters">
@@ -182,19 +125,5 @@
          </propertySection>
       </propertySections>
    </extension>
-   <extension
-         point="org.fortiss.tooling.kernel.modelElementHandler">
-      <modelElementHandler
-            handler="org.fortiss.tooling.kernel.internal.handler.ProjectModelElementHandler"
-            modelElementClass="org.eclipse.emf.emfstore.common.model.Project">
-      </modelElementHandler>
-   </extension>
-   <extension
-         point="org.fortiss.tooling.kernel.modelElementCompositor">
-      <modelElementCompositor
-            compositor="org.fortiss.tooling.kernel.internal.compose.ProjectCompositor"
-            modelElementClass="org.eclipse.emf.emfstore.common.model.Project">
-      </modelElementCompositor>
-   </extension>
 
 </plugin>
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceUnicaseClientLocationProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IStorageProvider.java
similarity index 66%
rename from org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceUnicaseClientLocationProvider.java
rename to org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IStorageProvider.java
index d2144334e..58a620d44 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceUnicaseClientLocationProvider.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IStorageProvider.java
@@ -15,32 +15,30 @@ $Id$
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.internal.emfstore;
+package org.fortiss.tooling.kernel.interfaces;
 
-import org.eclipse.emf.emfstore.server.LocationProvider;
+import java.util.List;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.ecore.EObject;
 
 /**
- * A {@link LocationProvider} which uses the Eclipse workspace location as base
- * location. This provider is intended to be used with the
- * <code>org.unicase.workspace.workspaceLocationProvider</code> extension point.
+ * An {@link IStorageProvider} implements a storage mechanism for EMF models.
  * 
  * @author hoelzlf
  * @author $Author$
  * @version $Rev$
  * @levd.rating RED Rev:
  */
-public final class EclipseWorkspaceUnicaseClientLocationProvider extends
-		EclipseWorkspaceLocationProviderBase {
+public interface IStorageProvider {
+
+	/** Returns the top-level elements provided by this storage provider. */
+	List<EObject> getTopLevelElements();
+
+	/** Returns the command stack for accessing the stored model. */
+	CommandStack getCommandStack(EObject modelElement);
 
-	/** {@inheritDoc} */
-	@Override
-	protected String getWorkspaceProjectName() {
-		return ".unicase_client";
-	}
+	/** Executes the given {@link Runnable} as model changing command-. */
+	void runAsCommand(EObject modelElement, Runnable runner);
 
-	/** {@inheritDoc} */
-	@Override
-	protected String getBackupProjectName() {
-		return ".unicase_client_backup";
-	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceEMFStoreLocationProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/ITopLevelElementChangeListener.java
similarity index 66%
rename from org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceEMFStoreLocationProvider.java
rename to org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/ITopLevelElementChangeListener.java
index c46d678d1..38119cc5b 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceEMFStoreLocationProvider.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/ITopLevelElementChangeListener.java
@@ -15,31 +15,24 @@ $Id$
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.internal.emfstore;
+package org.fortiss.tooling.kernel.interfaces;
 
-import org.eclipse.emf.emfstore.server.LocationProvider;
+import org.eclipse.emf.ecore.EObject;
 
 /**
- * A {@link LocationProvider} which uses the Eclipse workspace location as base
- * location. This provider is intended to be used with the
- * <code>org.unicase.emfstore.locationprovider</code> extension point.
+ * Listener interface notified by the persistency service whenever the list of
+ * top-level elements changes.
  * 
  * @author hoelzlf
  * @author $Author$
  * @version $Rev$
  * @levd.rating RED Rev:
  */
-public final class EclipseWorkspaceEMFStoreLocationProvider extends
-		EclipseWorkspaceLocationProviderBase {
-	/** {@inheritDoc} */
-	@Override
-	protected String getWorkspaceProjectName() {
-		return ".emfStoreServerWorkspaceProject";
-	}
+public interface ITopLevelElementChangeListener {
 
-	/** {@inheritDoc} */
-	@Override
-	protected String getBackupProjectName() {
-		return ".emfStoreServerBackupProject";
-	}
+	/** Notifies the listener about the adding of the given element. */
+	void topLevelElementAdded(EObject topLevelElement);
+
+	/** Notifies the listener about the removal of the given element. */
+	void topLevelElementRemoved(EObject topLevelElement);
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java
index e41893138..3861ea32a 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ActionService.java
@@ -19,8 +19,6 @@ package org.fortiss.tooling.kernel.internal;
 
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.emfstore.client.model.ProjectSpace;
-import org.eclipse.emf.emfstore.common.model.Project;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IEditorSite;
@@ -32,6 +30,7 @@ import org.fortiss.tooling.kernel.base.EObjectAction;
 import org.fortiss.tooling.kernel.model.IRemovable;
 import org.fortiss.tooling.kernel.services.IActionService;
 import org.fortiss.tooling.kernel.services.ICommandStackService;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 import org.fortiss.tooling.kernel.util.EObjectSelectionUtils;
 
 /**
@@ -157,9 +156,9 @@ public class ActionService implements IActionService {
 
 		boolean canDelete = (target instanceof IRemovable)
 				&& ((IRemovable) target).canRemove();
-		canDelete = canDelete || !(target instanceof Project)
-				&& !(target instanceof ProjectSpace)
-				&& target.eContainer() != null;
+		canDelete = canDelete
+				|| !IPersistencyService.INSTANCE.getTopLevelElements()
+						.contains(target);
 		globalDeleteAction.setTarget(target);
 		globalDeleteAction.setEnabled(canDelete);
 	}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
index aff44d5db..7609c5d7c 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
@@ -17,28 +17,13 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.internal;
 
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Stack;
-
-import org.eclipse.emf.common.command.BasicCommandStack;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.client.model.Configuration;
-import org.eclipse.emf.emfstore.client.model.ModelPackage;
-import org.eclipse.emf.emfstore.client.model.ProjectSpace;
-import org.eclipse.emf.emfstore.client.model.Workspace;
-import org.eclipse.emf.emfstore.client.model.WorkspaceManager;
-import org.eclipse.emf.emfstore.client.model.impl.ProjectSpaceImpl;
-import org.eclipse.emf.emfstore.client.model.observers.OperationListener;
-import org.eclipse.emf.emfstore.client.model.util.EMFStoreCommand;
-import org.eclipse.emf.emfstore.server.model.versioning.operations.AbstractOperation;
 import org.fortiss.tooling.kernel.services.ICommandStackService;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 
 /**
- * This class implements the {@link ICommandStackService} interface.
+ * This class implements the {@link ICommandStackService} interface. This class
+ * mainly delegates its calls to the {@link IPersistencyService}.
  * 
  * @author hoelzl
  * @author $Author$
@@ -46,165 +31,34 @@ import org.fortiss.tooling.kernel.services.ICommandStackService;
  * @levd.rating RED Rev:
  */
 public class CommandStackService implements ICommandStackService {
-
-	/** Stores the EMFStore command stack. */
-	private BasicCommandStack emfStoreCommandStack;
-
-	/** Stores the project state observers. */
-	private Map<ProjectSpace, ProjectSpaceObserver> projectSpaceObserverMap = new HashMap<ProjectSpace, CommandStackService.ProjectSpaceObserver>();
-
-	/** Stores the workspace listener. */
-	private AdapterImpl workspaceListener;
-
-	/** Constructor. */
-	public CommandStackService() {
-
-		Workspace ws = WorkspaceManager.getInstance().getCurrentWorkspace();
-		createWorkspaceListener();
-		ws.eAdapters().add(workspaceListener);
-
-		for (ProjectSpace ps : ws.getProjectSpaces()) {
-			ProjectSpaceObserver state = new ProjectSpaceObserver(ps);
-			projectSpaceObserverMap.put(ps, state);
-		}
-
-		emfStoreCommandStack = (BasicCommandStack) Configuration
-				.getEditingDomain().getCommandStack();
-	}
-
 	/** {@inheritDoc} */
 	@Override
-	public void runAsCommand(EObject target, final Runnable runner) {
-		EMFStoreCommand command = new EMFStoreCommand() {
-
-			@Override
-			protected void doRun() {
-				runner.run();
-			}
-		};
-		emfStoreCommandStack.execute(command);
+	public void runAsCommand(EObject target, Runnable runner) {
+		IPersistencyService.INSTANCE.getStorageProviderFor(target)
+				.runAsCommand(target, runner);
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public boolean canUndo(EObject target) {
-		ProjectSpace projectSpace = WorkspaceManager.getProjectSpace(target);
-		return !projectSpace.getOperations().isEmpty();
+		return IPersistencyService.INSTANCE.getCommandStack(target).canUndo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public boolean canRedo(EObject target) {
-		ProjectSpace projectSpace = WorkspaceManager.getProjectSpace(target);
-		return projectSpaceObserverMap.get(projectSpace).canRedo();
+		return IPersistencyService.INSTANCE.getCommandStack(target).canRedo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void undo(EObject target) {
-		final ProjectSpace projectSpace = WorkspaceManager
-				.getProjectSpace(target);
-		// also pushes the operation on the project state observer's redo stack
-		emfStoreCommandStack.execute(new EMFStoreCommand() {
-
-			@Override
-			protected void doRun() {
-				projectSpace.undoLastOperation();
-			}
-		});
+		IPersistencyService.INSTANCE.getCommandStack(target).undo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void redo(EObject target) {
-		ProjectSpace projectSpace = WorkspaceManager.getProjectSpace(target);
-		projectSpaceObserverMap.get(projectSpace).redo();
-	}
-
-	/** Creates the workspace listener. */
-	private void createWorkspaceListener() {
-		workspaceListener = new AdapterImpl() {
-			@Override
-			public void notifyChanged(Notification msg) {
-				if ((msg.getFeatureID(Workspace.class)) == ModelPackage.WORKSPACE__PROJECT_SPACES) {
-					if (msg.getEventType() == Notification.ADD
-							&& ModelPackage.eINSTANCE.getProjectSpace()
-									.isInstance(msg.getNewValue())) {
-						ProjectSpace projectSpace = (ProjectSpace) msg
-								.getNewValue();
-						ProjectSpaceObserver obs = new ProjectSpaceObserver(
-								projectSpace);
-						projectSpaceObserverMap.put(projectSpace, obs);
-					} else if (msg.getEventType() == Notification.REMOVE
-							&& ModelPackage.eINSTANCE.getProjectSpace()
-									.isInstance(msg.getOldValue())) {
-						ProjectSpace projectSpace = (ProjectSpace) msg
-								.getOldValue();
-						ProjectSpaceObserver obs = projectSpaceObserverMap
-								.remove(projectSpace);
-						obs.dispose();
-					}
-				}
-			}
-		};
-	}
-
-	/** Observes the state of a {@link ProjectSpace}. */
-	private class ProjectSpaceObserver implements OperationListener {
-
-		/** Stores the project space reference. */
-		private final ProjectSpace projectSpace;
-
-		/** Stores the redo stack. */
-		private final Stack<AbstractOperation> redoStack = new Stack<AbstractOperation>();
-
-		/** Flag indicating the current operation is a redo. */
-		private boolean redoInProgress = false;
-
-		/** Constructor. */
-		public ProjectSpaceObserver(ProjectSpace projectSpace) {
-			this.projectSpace = projectSpace;
-			projectSpace.addOperationListener(this);
-		}
-
-		/** {@inheritDoc} */
-		@Override
-		public void operationExecuted(AbstractOperation operation) {
-			if (!redoInProgress) {
-				// clear stack if not observing a redo
-				redoStack.clear();
-			}
-		}
-
-		/** {@inheritDoc} */
-		@Override
-		public void operationUnDone(AbstractOperation operation) {
-			redoStack.add(operation);
-		}
-
-		/** Returns whether redo is possible. */
-		public boolean canRedo() {
-			return !redoStack.isEmpty();
-		}
-
-		/** Redo the last operation. */
-		public void redo() {
-			final LinkedList<AbstractOperation> ops = new LinkedList<AbstractOperation>();
-			ops.add(redoStack.pop());
-			emfStoreCommandStack.execute(new EMFStoreCommand() {
-
-				@Override
-				protected void doRun() {
-					redoInProgress = true;
-					((ProjectSpaceImpl) projectSpace).applyOperations(ops);
-					redoInProgress = false;
-				}
-			});
-		}
-
-		/** Disposes the project state observer. */
-		public void dispose() {
-			projectSpace.removeOperationListener(this);
-		}
+		IPersistencyService.INSTANCE.getCommandStack(target).redo();
 	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java
index 1231b3ea9..0e4c389ae 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java
@@ -17,6 +17,18 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.internal;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.conqat.lib.commons.collections.CollectionUtils;
+import org.conqat.lib.commons.collections.UnmodifiableList;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.ecore.EObject;
+import org.fortiss.tooling.kernel.interfaces.IStorageProvider;
+import org.fortiss.tooling.kernel.interfaces.ITopLevelElementChangeListener;
+import org.fortiss.tooling.kernel.internal.storage.eclipse.EclipseResourceStorageProvider;
 import org.fortiss.tooling.kernel.services.IPersistencyService;
 
 /**
@@ -29,4 +41,122 @@ import org.fortiss.tooling.kernel.services.IPersistencyService;
  */
 public class PersistencyService implements IPersistencyService {
 
+	/** Stores the storage providers and their element caches. */
+	private final Map<IStorageProvider, List<EObject>> storageProviderCache = new HashMap<IStorageProvider, List<EObject>>();
+
+	/** Stores the top-level element listeners. */
+	private final List<ITopLevelElementChangeListener> listeners = new ArrayList<ITopLevelElementChangeListener>();
+
+	/** Constructor. */
+	public PersistencyService() {
+		// TODO (FH): replace with extension mechanism
+		IStorageProvider provider = new EclipseResourceStorageProvider();
+		storageProviderCache.put(provider, provider.getTopLevelElements());
+
+		refreshAllProviderElements();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public UnmodifiableList<EObject> getTopLevelElements() {
+		List<EObject> result = new ArrayList<EObject>();
+		for (IStorageProvider provider : storageProviderCache.keySet()) {
+			result.addAll(storageProviderCache.get(provider));
+		}
+		return CollectionUtils.asUnmodifiable(result);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void refreshTopLevelElements(IStorageProvider provider) {
+		if (!storageProviderCache.containsKey(provider)) {
+			return;
+		}
+		List<EObject> elementCache = storageProviderCache.get(provider);
+		List<EObject> providedElements = provider.getTopLevelElements();
+		for (EObject top : elementCache) {
+			if (!providedElements.contains(top)) {
+				elementCache.remove(top);
+				notifyListenersAboutRemove(top);
+			}
+		}
+		for (EObject top : providedElements) {
+			if (!elementCache.contains(top)) {
+				elementCache.add(top);
+				notifyListenersAboutAdd(top);
+			}
+		}
+	}
+
+	/** Refreshes all providers' top-level elements. */
+	private void refreshAllProviderElements() {
+		for (IStorageProvider provider : storageProviderCache.keySet()) {
+			refreshTopLevelElements(provider);
+		}
+	}
+
+	/** Notifies listener about top-level element adding. */
+	private void notifyListenersAboutAdd(EObject top) {
+		for (ITopLevelElementChangeListener listener : listeners) {
+			listener.topLevelElementAdded(top);
+		}
+	}
+
+	/** Notifies listener about top-level element removal. */
+	private void notifyListenersAboutRemove(EObject top) {
+		for (ITopLevelElementChangeListener listener : listeners) {
+			listener.topLevelElementRemoved(top);
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void addTopLevelElementListener(
+			ITopLevelElementChangeListener listener) {
+		if (!listeners.contains(listener)) {
+			listeners.add(listener);
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void removeTopLevelElementListener(
+			ITopLevelElementChangeListener listener) {
+		listeners.remove(listener);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public EObject getTopLevelElementFor(EObject modelElement) {
+		while (modelElement != null) {
+			for (List<EObject> topLevelElements : storageProviderCache.values()) {
+				if (topLevelElements.contains(modelElement)) {
+					return modelElement;
+				}
+			}
+			modelElement = modelElement.eContainer();
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public IStorageProvider getStorageProviderFor(EObject modelElement) {
+		while (modelElement != null) {
+			for (IStorageProvider provider : storageProviderCache.keySet()) {
+				if (storageProviderCache.get(provider).contains(modelElement)) {
+					return provider;
+				}
+			}
+			modelElement = modelElement.eContainer();
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public CommandStack getCommandStack(EObject modelElement) {
+		return getStorageProviderFor(modelElement)
+				.getCommandStack(modelElement);
+	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceLocationProviderBase.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceLocationProviderBase.java
deleted file mode 100644
index e8f3f179e..000000000
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/emfstore/EclipseWorkspaceLocationProviderBase.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*--------------------------------------------------------------------------+
-$Id$
-|                                                                          |
-| Copyright 2011 ForTISS GmbH                     |
-|                                                                          |
-| Licensed under the Apache License, Version 2.0 (the "License");          |
-| you may not use this file except in compliance with the License.         |
-| You may obtain a copy of the License at                                  |
-|                                                                          |
-|    http://www.apache.org/licenses/LICENSE-2.0                            |
-|                                                                          |
-| Unless required by applicable law or agreed to in writing, software      |
-| distributed under the License is distributed on an "AS IS" BASIS,        |
-| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-| See the License for the specific language governing permissions and      |
-| limitations under the License.                                           |
-+--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.internal.emfstore;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.emf.emfstore.server.LocationProvider;
-
-/**
- * Base implementation of a {@link LocationProvider} which uses the Eclipse
- * workspace location as base location.
- * 
- * @author hoelzlf
- * @author $Author$
- * @version $Rev$
- * @levd.rating RED Rev:
- */
-public abstract class EclipseWorkspaceLocationProviderBase implements
-		LocationProvider {
-
-	/** Store the workspace location. */
-	private IProject workspaceProject;
-
-	/** Stores the backup location. */
-	private IProject backupProject;
-
-	/** Stores initilization flag. */
-	private boolean initialized = false;
-
-	/** Initialize the locations. */
-	private void initialize() {
-		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
-		this.workspaceProject = workspaceRoot
-				.getProject(getWorkspaceProjectName());
-		if (!workspaceProject.exists()) {
-			try {
-				workspaceProject.create(null);
-			} catch (CoreException e) {
-				printCreationError(getWorkspaceProjectName(), e);
-			}
-		}
-		this.backupProject = workspaceRoot.getProject(getBackupProjectName());
-		if (!backupProject.exists()) {
-			try {
-				backupProject.create(null);
-			} catch (CoreException e) {
-				printCreationError(getBackupProjectName(), e);
-			}
-		}
-		initialized = true;
-	}
-
-	/** Prints error message to standard error. */
-	private final void printCreationError(String projectName, Exception ex) {
-		System.err.println("Could not create project " + projectName);
-		ex.printStackTrace(System.err);
-	}
-
-	/** Returns the name of the workspace project. */
-	protected abstract String getWorkspaceProjectName();
-
-	/** Returns the name of the backup project. */
-	protected abstract String getBackupProjectName();
-
-	/** {@inheritDoc} */
-	@Override
-	public final String getWorkspaceDirectory() {
-		if (!initialized) {
-			initialize();
-		}
-		return workspaceProject.getLocation().toString();
-	}
-
-	/** {@inheritDoc} */
-	@Override
-	public final String getBackupDirectory() {
-		if (!initialized) {
-			initialize();
-		}
-		return backupProject.getLocation().toString();
-	}
-}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeContentProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeContentProvider.java
index 35f60cb74..6ec7533b1 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeContentProvider.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeContentProvider.java
@@ -17,17 +17,12 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.internal.navigator;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.client.model.ProjectSpace;
-import org.eclipse.emf.emfstore.client.model.Workspace;
-import org.eclipse.emf.emfstore.common.model.Project;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 import org.fortiss.tooling.kernel.interfaces.IHandler;
 import org.fortiss.tooling.kernel.services.IModelElementService;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 
 /**
  * Content provider for the model navigator tree viewer.
@@ -42,20 +37,14 @@ public class NavigatorTreeContentProvider implements ITreeContentProvider {
 	/** {@inheritDoc} */
 	@Override
 	public Object[] getElements(Object inputElement) {
-		if (inputElement instanceof Workspace) {
-			List<Project> result = new ArrayList<Project>();
-			for (ProjectSpace space : ((Workspace) inputElement)
-					.getProjectSpaces()) {
-				result.add(space.getProject());
-			}
-			return result.toArray();
-		}
-		return null;
+		// delegate to the top-level elements of the persistency service
+		return IPersistencyService.INSTANCE.getTopLevelElements().toArray();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public Object[] getChildren(Object parentElement) {
+		// delegate to the model element handlers
 		if (parentElement instanceof EObject) {
 			IHandler<EObject> handler = IModelElementService.INSTANCE
 					.getModelElementHandler((EObject) parentElement);
@@ -69,8 +58,11 @@ public class NavigatorTreeContentProvider implements ITreeContentProvider {
 	/** {@inheritDoc} */
 	@Override
 	public Object getParent(Object element) {
-		if (element instanceof EObject && !(element instanceof Workspace)) {
-			return ((EObject) element).eContainer();
+		if (element instanceof EObject
+				&& IPersistencyService.INSTANCE.getTopLevelElements().contains(
+						element)) {
+			// delegate to persistency service
+			return IPersistencyService.INSTANCE;
 		}
 		return null;
 	}
@@ -90,6 +82,7 @@ public class NavigatorTreeContentProvider implements ITreeContentProvider {
 	/** {@inheritDoc} */
 	@Override
 	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-		// FIXME (FH): ignore?
+		// the input of this viewer is the persistency service singleton and
+		// therefore never changes.
 	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeLabelProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeLabelProvider.java
index 0a3eede08..ec06fb910 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeLabelProvider.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorTreeLabelProvider.java
@@ -38,6 +38,7 @@ public final class NavigatorTreeLabelProvider extends BaseLabelProvider
 	/** {@inheritDoc} */
 	@Override
 	public Image getImage(Object element) {
+		// delegate to the model element handlers
 		if (element instanceof EObject) {
 			IHandler<EObject> handler = IModelElementService.INSTANCE
 					.getModelElementHandler((EObject) element);
@@ -51,6 +52,7 @@ public final class NavigatorTreeLabelProvider extends BaseLabelProvider
 	/** {@inheritDoc} */
 	@Override
 	public String getText(Object element) {
+		// delegate to the model element handlers
 		if (element instanceof EObject) {
 			IHandler<EObject> handler = IModelElementService.INSTANCE
 					.getModelElementHandler((EObject) element);
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java
index 699317bd4..b1d43b138 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/navigator/NavigatorViewPart.java
@@ -23,15 +23,7 @@ import java.util.List;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.client.model.ModelPackage;
-import org.eclipse.emf.emfstore.client.model.ProjectSpace;
-import org.eclipse.emf.emfstore.client.model.Workspace;
-import org.eclipse.emf.emfstore.client.model.WorkspaceManager;
-import org.eclipse.emf.emfstore.common.model.Project;
-import org.eclipse.emf.emfstore.common.model.util.ProjectChangeObserver;
 import org.eclipse.jface.action.IContributionItem;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.viewers.DecoratingLabelProvider;
@@ -60,6 +52,7 @@ import org.fortiss.tooling.kernel.services.IActionService;
 import org.fortiss.tooling.kernel.services.IContextMenuService;
 import org.fortiss.tooling.kernel.services.IEditorService;
 import org.fortiss.tooling.kernel.services.INavigatorService;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 import org.fortiss.tooling.kernel.services.IPropertiesService;
 import org.fortiss.tooling.kernel.util.EObjectSelectionUtils;
 
@@ -78,15 +71,6 @@ public final class NavigatorViewPart extends ViewPart implements
 	/** Stores the TreeViewer. */
 	private TreeViewer viewer;
 
-	/** Stores the EmfStore workspace. */
-	private Workspace workspace;
-
-	/** Stores the workspace listener. */
-	private AdapterImpl workspaceListener;
-
-	/** Stores the project listener. */
-	private ProjectChangeObserver projectListener;
-
 	/** Stores the menu manager. */
 	private MenuManager menuManager;
 
@@ -101,107 +85,39 @@ public final class NavigatorViewPart extends ViewPart implements
 
 	/** Constructor. */
 	public NavigatorViewPart() {
-		workspace = WorkspaceManager.getInstance().getCurrentWorkspace();
-
-		createWorkspaceListener();
-		createProjectListener();
 
 		((NavigatorService) INavigatorService.INSTANCE)
 				.setNavigatorViewPart(this);
 	}
 
-	/** Creates the project listener. */
-	private void createProjectListener() {
-		projectListener = new ProjectChangeObserver() {
-
-			@Override
-			public void projectDeleted(Project project) {
-				updateUI.schedule();
-			}
-
-			@Override
-			public void notify(Notification notification, Project project,
-					EObject modelElement) {
-				updateUI.schedule();
-			}
-
-			@Override
-			public void modelElementRemoved(Project project,
-					EObject modelElement) {
-				updateUI.schedule();
-			}
-
-			@Override
-			public void modelElementAdded(Project project, EObject modelElement) {
-				updateUI.schedule();
-			}
-		};
-
-		for (ProjectSpace projectSpace : workspace.getProjectSpaces()) {
-			projectSpace.getProject().addProjectChangeObserver(projectListener);
-		}
-	}
-
-	/** Creates the workspace listener. */
-	private void createWorkspaceListener() {
-		workspaceListener = new AdapterImpl() {
-			@Override
-			public void notifyChanged(Notification msg) {
-				if ((msg.getFeatureID(Workspace.class)) == ModelPackage.WORKSPACE__PROJECT_SPACES) {
-					if (msg.getEventType() == Notification.ADD
-							&& ModelPackage.eINSTANCE.getProjectSpace()
-									.isInstance(msg.getNewValue())) {
-						ProjectSpace projectSpace = (ProjectSpace) msg
-								.getNewValue();
-						projectSpace.getProject().addProjectChangeObserver(
-								projectListener);
-					} else if (msg.getEventType() == Notification.REMOVE
-							&& ModelPackage.eINSTANCE.getProjectSpace()
-									.isInstance(msg.getOldValue())) {
-						ProjectSpace projectSpace = (ProjectSpace) msg
-								.getOldValue();
-						projectSpace.getProject().removeProjectChangeObserver(
-								projectListener);
-					}
-					updateUI.schedule();
-				}
-				super.notifyChanged(msg);
-			}
-
-		};
-		workspace.eAdapters().add(workspaceListener);
-	}
-
 	/** {@inheritDoc} */
 	@Override
 	public void createPartControl(Composite parent) {
 		viewer = new TreeViewer(parent, SWT.MULTI);
 
-		if (workspace != null) {
-			// NOTE that the order of this important. See also JDT package
-			// explorer.
-			IDecoratorManager decoratorManager = PlatformUI.getWorkbench()
-					.getDecoratorManager();
-			viewer.setLabelProvider(new DecoratingLabelProvider(
-					new NavigatorTreeLabelProvider(), decoratorManager
-							.getLabelDecorator()));
-			viewer.setContentProvider(new NavigatorTreeContentProvider());
+		// NOTE that the order of this important. See also JDT package
+		// explorer.
+		IDecoratorManager decoratorManager = PlatformUI.getWorkbench()
+				.getDecoratorManager();
+		viewer.setLabelProvider(new DecoratingLabelProvider(
+				new NavigatorTreeLabelProvider(), decoratorManager
+						.getLabelDecorator()));
+		viewer.setContentProvider(new NavigatorTreeContentProvider());
 
-			getSite().setSelectionProvider(viewer);
-			createContextMenu();
-			viewer.addSelectionChangedListener(this);
+		getSite().setSelectionProvider(viewer);
+		createContextMenu();
+		viewer.addSelectionChangedListener(this);
 
-			viewer.setInput(workspace);
+		viewer.setInput(IPersistencyService.INSTANCE);
 
-			viewer.addDoubleClickListener(this);
+		viewer.addDoubleClickListener(this);
 
-			IActionService.INSTANCE.registerGlobalActions(getViewSite());
+		IActionService.INSTANCE.registerGlobalActions(getViewSite());
 
-			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
-					.getSelectionService().addSelectionListener(this);
-		}
+		PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+				.getSelectionService().addSelectionListener(this);
 
-		// FIXME: whats that good for?
+		// FIXME (FH): whats that good for?
 		// if (viewer.getTree().getItems().length > 0) {
 		// setActiveECPProject(viewer.getTree().getItem(0).getData());
 		// viewer.getTree().select(viewer.getTree().getItem(0));
@@ -243,7 +159,6 @@ public final class NavigatorViewPart extends ViewPart implements
 	/** {@inheritDoc} */
 	@Override
 	public void dispose() {
-		workspace.eAdapters().remove(workspaceListener);
 		((NavigatorService) INavigatorService.INSTANCE)
 				.setNavigatorViewPart(null);
 
@@ -257,6 +172,7 @@ public final class NavigatorViewPart extends ViewPart implements
 	/** {@inheritDoc} */
 	@Override
 	public void doubleClick(DoubleClickEvent event) {
+		// delegate to the editor service
 		if (event.getSelection() instanceof IStructuredSelection) {
 			EObject element = EObjectSelectionUtils.getFirstElement(event
 					.getSelection());
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/properties/PropertiesAdapterFactory.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/properties/PropertiesAdapterFactory.java
index 836ce2931..d6a2d6cbf 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/properties/PropertiesAdapterFactory.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/properties/PropertiesAdapterFactory.java
@@ -19,8 +19,8 @@ package org.fortiss.tooling.kernel.internal.properties;
 
 import org.eclipse.core.runtime.IAdapterFactory;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.common.model.util.ModelUtil;
 import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 import org.fortiss.tooling.kernel.services.IPropertiesService;
 
 /**
@@ -40,7 +40,8 @@ public final class PropertiesAdapterFactory implements IAdapterFactory {
 		if (adapterType == ITabbedPropertySheetPageContributor.class
 				&& adaptableObject instanceof EObject) {
 			EObject modelElement = (EObject) adaptableObject;
-			if (ModelUtil.getProject(modelElement) != null) {
+			if (IPersistencyService.INSTANCE
+					.getTopLevelElementFor(modelElement) != null) {
 				return new ITabbedPropertySheetPageContributor() {
 
 					@Override
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/AutoUndoCommandStack.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/AutoUndoCommandStack.java
new file mode 100644
index 000000000..8bd3d86ea
--- /dev/null
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/AutoUndoCommandStack.java
@@ -0,0 +1,141 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2011 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.internal.storage.eclipse;
+
+import java.util.Map;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.transaction.ExceptionHandler;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.TransactionalCommandStack;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+
+/**
+ * This command stack warps a {@link TransactionalEditingDomain} and forwards
+ * all calls to its command stack. However all commands which are executed are
+ * wrapped in an AutoUndoCommand first.
+ * 
+ * @author hummelb
+ * @author $Author$
+ * @version $Rev$
+ * @levd.rating YELLOW Hash: 5D53FF5E73D3F0E9DFBD7F3CE61548D5
+ */
+public class AutoUndoCommandStack implements TransactionalCommandStack {
+
+	/** The underlying editing domain. */
+	private final TransactionalEditingDomain editingDomain;
+
+	/** The underlying command stack. */
+	private final TransactionalCommandStack commandStack;
+
+	/** Constructor. */
+	public AutoUndoCommandStack(TransactionalEditingDomain editingDomain) {
+		this.editingDomain = editingDomain;
+		commandStack = (TransactionalCommandStack) editingDomain
+				.getCommandStack();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void addCommandStackListener(CommandStackListener listener) {
+		commandStack.addCommandStackListener(listener);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public boolean canRedo() {
+		return commandStack.canRedo();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public boolean canUndo() {
+		return commandStack.canUndo();
+	}
+
+	/** {@inheritDoc} */
+	@SuppressWarnings("rawtypes")
+	@Override
+	public void execute(Command command, Map options)
+			throws InterruptedException, RollbackException {
+		commandStack.execute(
+				new EMFTransactionalCommand(command, editingDomain), options);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void execute(Command command) {
+		commandStack
+				.execute(new EMFTransactionalCommand(command, editingDomain));
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void flush() {
+		commandStack.flush();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ExceptionHandler getExceptionHandler() {
+		return commandStack.getExceptionHandler();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Command getMostRecentCommand() {
+		return commandStack.getMostRecentCommand();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Command getRedoCommand() {
+		return commandStack.getRedoCommand();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Command getUndoCommand() {
+		return commandStack.getUndoCommand();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void redo() {
+		commandStack.redo();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void removeCommandStackListener(CommandStackListener listener) {
+		commandStack.removeCommandStackListener(listener);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void setExceptionHandler(ExceptionHandler handler) {
+		commandStack.setExceptionHandler(handler);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void undo() {
+		commandStack.undo();
+	}
+}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMFTransactionalCommand.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMFTransactionalCommand.java
new file mode 100644
index 000000000..2fa2733fb
--- /dev/null
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMFTransactionalCommand.java
@@ -0,0 +1,182 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2011 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.internal.storage.eclipse;
+
+import java.util.Collection;
+
+import org.conqat.ide.commons.ui.logging.LoggingUtils;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CompoundCommand;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.RollbackException;
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
+import org.fortiss.tooling.kernel.ToolingKernelActivator;
+
+/**
+ * This class wraps another EMF command and makes sure that all execute methods
+ * ({@link #execute()}, {@link #undo()}, {@link #redo()}) are executed inside of
+ * a transaction. As a bonus the undo and redo methods are based on the
+ * transaction of the execute call (i.e. are coming for free).
+ * 
+ * @author hummelb
+ * @author $Author$
+ * @version $Rev$
+ * @levd.rating YELLOW Hash: 625F16187EE652EBF03196972D41AFE9
+ */
+public class EMFTransactionalCommand implements Command {
+
+	/** The wrapped command. */
+	private final Command inner;
+
+	/** The recording command used. */
+	private final RecordingCommand recordingCommand;
+
+	/** The editing domain. */
+	private final InternalTransactionalEditingDomain editingDomain;
+
+	/** Constructor. */
+	public EMFTransactionalCommand(Command command,
+			TransactionalEditingDomain editingDomain) {
+		inner = command;
+		recordingCommand = new RecordingCommand(editingDomain) {
+			@Override
+			protected void doExecute() {
+				inner.execute();
+			}
+		};
+		this.editingDomain = (InternalTransactionalEditingDomain) editingDomain;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void execute() {
+		runInTransaction(new Runnable() {
+			@Override
+			public void run() {
+				recordingCommand.execute();
+			}
+		});
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void redo() {
+		runInTransaction(new Runnable() {
+			@Override
+			public void run() {
+				recordingCommand.redo();
+			}
+		});
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void undo() {
+		runInTransaction(new Runnable() {
+			@Override
+			public void run() {
+				recordingCommand.undo();
+			}
+		});
+	}
+
+	/**
+	 * Executes the given runnable in a transaction.
+	 */
+	private void runInTransaction(Runnable runnable) {
+		Transaction tx = null;
+		try {
+			tx = editingDomain.startTransaction(false, null);
+			runnable.run();
+		} catch (InterruptedException e) {
+			LoggingUtils.error(ToolingKernelActivator.getDefault(),
+					"Had unexpected interruption in command execution!", e);
+		} finally {
+			if (tx != null) {
+				try {
+					tx.commit();
+				} catch (RollbackException e) {
+					// There is nothing we can do about.
+					// Maybe it even was intended, so ignore.
+				}
+			} else {
+				LoggingUtils.log(ToolingKernelActivator.getDefault(),
+						"Was not able to start transaction!", IStatus.ERROR);
+			}
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public boolean canExecute() {
+		return inner.canExecute();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public boolean canUndo() {
+		return recordingCommand.canUndo();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Collection<?> getAffectedObjects() {
+		return inner.getAffectedObjects();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getDescription() {
+		return inner.getDescription();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getLabel() {
+		return inner.getLabel();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Collection<?> getResult() {
+		return inner.getResult();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Command chain(Command command) {
+		if (command == null) {
+			return this;
+		}
+
+		final CompoundCommand result = new CompoundCommand();
+		result.append(this);
+		result.append(command);
+		return result;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void dispose() {
+		inner.dispose();
+		recordingCommand.dispose();
+	}
+}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/handler/ProjectModelElementHandler.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMultiContentsIterator.java
similarity index 50%
rename from org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/handler/ProjectModelElementHandler.java
rename to org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMultiContentsIterator.java
index d657e121d..6bd463b0e 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/handler/ProjectModelElementHandler.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EMultiContentsIterator.java
@@ -15,58 +15,73 @@ $Id$
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.internal.handler;
+package org.fortiss.tooling.kernel.internal.storage.eclipse;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collection;
+import java.util.Iterator;
 
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.client.model.WorkspaceManager;
-import org.eclipse.emf.emfstore.common.model.Project;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.fortiss.tooling.kernel.ToolingKernelActivator;
-import org.fortiss.tooling.kernel.base.HandlerBase;
-import org.fortiss.tooling.kernel.interfaces.IHandler;
-import org.fortiss.tooling.kernel.model.IProjectRootElement;
 
 /**
- * {@link IHandler} for {@link Project}s.
+ * An iterator class which is similar to the iterator returned from
+ * {@link EObject#eAllContents()}, but can be used on multiple objects and also
+ * includes the objects themselves.
  * 
- * @author hoelzlf
+ * @author hummelb
  * @author $Author$
  * @version $Rev$
- * @levd.rating RED Rev:
+ * @levd.rating GREEN Rev: 1794
  */
-public final class ProjectModelElementHandler extends HandlerBase<Project> {
+public class EMultiContentsIterator implements Iterator<EObject> {
 
-	/** {@inheritDoc} */
-	@Override
-	public String getName(Project element) {
-		return WorkspaceManager.getProjectSpace(element).getProjectName();
+	/** The objects to iterate on. */
+	private final EObject[] objects;
+
+	/** Current index into the array. */
+	private int currentIndex = 0;
+
+	/** Inner iterator. */
+	private Iterator<EObject> inner = null;
+
+	/** Constructor. */
+	public EMultiContentsIterator(EObject... objects) {
+		this.objects = objects;
 	}
 
-	/** {@inheritDoc} */
-	@Override
-	public String getDescription(Project element) {
-		return WorkspaceManager.getProjectSpace(element)
-				.getProjectDescription();
+	/** Constructor. */
+	public EMultiContentsIterator(Collection<EObject> objects) {
+		this.objects = objects.toArray(new EObject[objects.size()]);
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public ImageDescriptor getIconImageDescriptor() {
-		return ToolingKernelActivator.getImageDescriptor("icons/project.png");
+	public boolean hasNext() {
+		return currentIndex < objects.length;
 	}
 
 	/** {@inheritDoc} */
 	@Override
-	public List<EObject> getSubnodes(Project element) {
-		List<EObject> list = new ArrayList<EObject>();
-		for (EObject node : element.getModelElements()) {
-			if (node instanceof IProjectRootElement) {
-				list.add(node);
-			}
+	public EObject next() {
+		EObject result;
+		if (inner == null) {
+			result = objects[currentIndex];
+			inner = result.eAllContents();
+		} else {
+			result = inner.next();
 		}
-		return list;
+
+		// already check whether there is more to come
+		if (!inner.hasNext()) {
+			inner = null;
+			currentIndex++;
+		}
+
+		return result;
+	}
+
+	/** Removal is not supported. */
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException();
 	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java
new file mode 100644
index 000000000..992b4aa09
--- /dev/null
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java
@@ -0,0 +1,233 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2011 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.internal.storage.eclipse;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.conqat.ide.commons.ui.dialog.MessageUtils;
+import org.conqat.ide.commons.ui.logging.LoggingUtils;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.swt.widgets.Display;
+import org.fortiss.tooling.kernel.ToolingKernelActivator;
+import org.fortiss.tooling.kernel.interfaces.IStorageProvider;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
+
+/**
+ * This class implements the persistency service behavior for Eclipse file
+ * storage.
+ * 
+ * @author hoelzlf
+ * @author $Author$
+ * @version $Rev$
+ * @levd.rating RED Rev:
+ */
+public class EclipseResourceStorageProvider implements IStorageProvider,
+		IResourceChangeListener {
+	/** Cache of models loaded so far. */
+	private final Map<IFile, ModelContext> loadedContexts = new HashMap<IFile, ModelContext>();
+
+	/** Map from toplevel elements to context. */
+	private final Map<EObject, ModelContext> rootElementContexts = new IdentityHashMap<EObject, ModelContext>();
+
+	/** Constructor. */
+	public EclipseResourceStorageProvider() {
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
+		searchWorkspaceForModels();
+	}
+
+	/** Searches existing models in Eclipse project roots. */
+	private synchronized void searchWorkspaceForModels() {
+		for (IProject project : ResourcesPlugin.getWorkspace().getRoot()
+				.getProjects()) {
+			if (!project.isOpen()) {
+				continue;
+			}
+			try {
+				for (IResource res : project.members()) {
+					if (res instanceof IFile) {
+						IFile file = (IFile) res;
+						// TODO (FH): use an extension mechanism for this check
+						if (file.getFileExtension().equals("af3_20")) {
+							loadContext(file);
+						}
+					}
+				}
+			} catch (CoreException e) {
+				// ignore
+			} catch (IOException ioex) {
+				// ignore
+			}
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void resourceChanged(IResourceChangeEvent event) {
+		synchronized (this) {
+			if (event.getDelta() == null) {
+				return;
+			}
+			try {
+				event.getDelta().accept(new IResourceDeltaVisitor() {
+					@Override
+					public boolean visit(IResourceDelta delta) {
+						if ((delta.getFlags() & IResourceDelta.CONTENT) == 0) {
+							return true;
+						}
+
+						if (delta.getResource() instanceof IFile
+								&& isLoaded((IFile) delta.getResource())) {
+							if (delta.getKind() == IResourceDelta.REMOVED) {
+								unloadContext((IFile) delta.getResource());
+								// Refresh the top-level elements
+								IPersistencyService.INSTANCE
+										.refreshTopLevelElements(EclipseResourceStorageProvider.this);
+							} else if (delta.getKind() == IResourceDelta.CHANGED) {
+								// this also refreshes top-level elements
+								handleChange((IFile) delta.getResource());
+							}
+						}
+						return true;
+					}
+				});
+			} catch (final CoreException e) {
+				LoggingUtils.error(ToolingKernelActivator.getDefault(),
+						"Should not happen!", e);
+			}
+		}
+	}
+
+	/** Handles a change of the given file (which is actually managed). */
+	private void handleChange(final IFile file) {
+		final ModelContext context = loadedContexts.get(file);
+		if (!context.getLastChangeWasIntended()) {
+			Display.getDefault().asyncExec(new Runnable() {
+				@Override
+				public void run() {
+					final boolean reload = MessageUtils.askQuestion(
+							"Reload changed file?",
+							"The file "
+									+ file.getName()
+									+ " changed on disk. "
+									+ "Load these changes? "
+									+ "Note that loading the changes will discard all editors, "
+									+ "so all unsaved changes and the undo history will be lost. "
+									+ "However if you do not reload now, "
+									+ "the contents of the file will be overwritten "
+									+ "the next time you perform a save.");
+
+					if (reload) {
+						unloadContext(file);
+						try {
+							loadContext(file).setLastChangeWasIntended();
+
+							// perform touch to make sure the viewer does a
+							// refresh
+							file.touch(null);
+						} catch (final Exception e) {
+							LoggingUtils.error(
+									ToolingKernelActivator.getDefault(),
+									"Had an error during reloading the file!",
+									e);
+						}
+					}
+
+					// Refresh the top-level elements
+					IPersistencyService.INSTANCE
+							.refreshTopLevelElements(EclipseResourceStorageProvider.this);
+				}
+			});
+		}
+	}
+
+	/** Returns whether the given file has been loaded by this manager. */
+	public synchronized boolean isLoaded(IFile file) {
+		return loadedContexts.containsKey(file);
+	}
+
+	/** Loads a file and creates a new context from its contents. */
+	private ModelContext loadContext(IFile file) throws IOException {
+		ModelContext mc = new ModelContext(file);
+		loadedContexts.put(file, mc);
+		for (EObject top : mc.getTopLevelElements()) {
+			rootElementContexts.put(top, mc);
+		}
+		return mc;
+	}
+
+	/** Loads a file and creates a new context from its contents. */
+	private void unloadContext(IFile file) {
+		final ModelContext context = loadedContexts.remove(file);
+		if (context != null) {
+			for (EObject top : context.getTopLevelElements()) {
+				rootElementContexts.remove(top);
+			}
+			context.destroy();
+		}
+	}
+
+	/**
+	 * Returns the model context for the given model element. This operation is
+	 * implemented by traversing upwards along the parent hierarchy and checking
+	 * all known model contexts if they include the top-most element. If no
+	 * context is found, null is returned.
+	 */
+	private synchronized ModelContext getContext(EObject o) {
+		return rootElementContexts.get(EcoreUtil.getRootContainer(o));
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<EObject> getTopLevelElements() {
+		List<EObject> result = new ArrayList<EObject>();
+		result.addAll(rootElementContexts.keySet());
+		return result;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public CommandStack getCommandStack(EObject modelElement) {
+		ModelContext mc = getContext(modelElement);
+		if (mc != null) {
+			return mc.getTransactionalCommandStack();
+		}
+		return null;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void runAsCommand(EObject modelElement, Runnable runner) {
+		getContext(modelElement).runAsCommand(runner);
+	}
+}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
new file mode 100644
index 000000000..560cf3cc3
--- /dev/null
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/ModelContext.java
@@ -0,0 +1,390 @@
+/*--------------------------------------------------------------------------+
+$Id$
+|                                                                          |
+| Copyright 2011 ForTISS GmbH                     |
+|                                                                          |
+| Licensed under the Apache License, Version 2.0 (the "License");          |
+| you may not use this file except in compliance with the License.         |
+| You may obtain a copy of the License at                                  |
+|                                                                          |
+|    http://www.apache.org/licenses/LICENSE-2.0                            |
+|                                                                          |
+| Unless required by applicable law or agreed to in writing, software      |
+| distributed under the License is distributed on an "AS IS" BASIS,        |
+| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+| See the License for the specific language governing permissions and      |
+| limitations under the License.                                           |
++--------------------------------------------------------------------------*/
+package org.fortiss.tooling.kernel.internal.storage.eclipse;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.conqat.ide.commons.ui.logging.LoggingUtils;
+import org.conqat.lib.commons.collections.CollectionUtils;
+import org.conqat.lib.commons.collections.IdentityHashSet;
+import org.conqat.lib.commons.collections.UnmodifiableList;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.transaction.TransactionalCommandStack;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.ui.IEditorPart;
+import org.fortiss.tooling.kernel.ToolingKernelActivator;
+import org.fortiss.tooling.kernel.model.IIdLabeled;
+import org.fortiss.tooling.kernel.services.IModelElementService;
+import org.fortiss.tooling.kernel.util.EMFResourceUtils;
+
+/**
+ * The model context provides additional commands and hooks for a model.
+ * Additionally an editing domain is provided.
+ * 
+ * @author hummelb
+ * @author $Author$
+ * @version $Rev$
+ * @levd.rating YELLOW Rev: 1101
+ */
+class ModelContext {
+
+	/** The resource set we are using. */
+	private final ResourceSet rset;
+
+	/** The file this model is from. */
+	private final IFile file;
+
+	/** The resource containing the model. */
+	private final Resource r;
+
+	/** The editing domain used for this model. */
+	private final TransactionalEditingDomain editingDomain;
+
+	/** The transactional command stack. */
+	private final AutoUndoCommandStack transactionalCommandStack;
+
+	/**
+	 * Set of editors which depend on this context. These editors are closed
+	 * when the underlying file is deleted or changed.
+	 */
+	private final Set<IEditorPart> dependentEditors = new IdentityHashSet<IEditorPart>();
+
+	/** Flag for remembering whether the last change of the file was intended. */
+	private boolean lastChangeWasIntended = false;
+
+	/** The maximal ID used in this model (used to generate new IDs). */
+	private int maxId = -1;
+
+	/** Constructor. */
+	/* package */ModelContext(IFile file) throws IOException {
+		this.file = file;
+
+		editingDomain = TransactionalEditingDomain.Factory.INSTANCE
+				.createEditingDomain();
+		rset = editingDomain.getResourceSet();
+
+		r = rset.createResource(URI.createPlatformResourceURI(file
+				.getFullPath().toString(), true));
+		r.load(EMFResourceUtils.buildOptionsMap());
+
+		transactionalCommandStack = new AutoUndoCommandStack(editingDomain);
+
+		checkIDs();
+	}
+
+	/** Checks whether all IDs are present and updates {@link #maxId}. */
+	private void checkIDs() {
+		boolean hadMissing = false;
+		for (final Iterator<EObject> i = new EMultiContentsIterator(
+				getTopLevelElements()); i.hasNext();) {
+			final EObject eo = i.next();
+			if (eo instanceof IIdLabeled) {
+				if (((IIdLabeled) eo).getId() <= 0) {
+					hadMissing = true;
+				}
+				maxId = Math.max(maxId, ((IIdLabeled) eo).getId());
+			}
+		}
+		maxId = Math.max(0, maxId);
+		if (hadMissing) {
+			runAsCommand(new Runnable() {
+				@Override
+				public void run() {
+					generateMissingIDs();
+				}
+			});
+		}
+	}
+
+	/** Generates missing IDs. Must be called within transaction. */
+	private void generateMissingIDs() {
+		for (final Iterator<EObject> i = new EMultiContentsIterator(
+				getTopLevelElements()); i.hasNext();) {
+			final EObject eo = i.next();
+			if (eo instanceof IIdLabeled) {
+				if (((IIdLabeled) eo).getId() <= 0) {
+					((IIdLabeled) eo).setId((++maxId));
+				}
+			}
+		}
+	}
+
+	/**
+	 * Scans the given objects and sets up its IDs such that the uniqueness of
+	 * IDs will be maintained in this model even after it has been composed into
+	 * this model.
+	 */
+	/* package */void prepareIDsForCompose(EObject other) {
+		boolean needSmart = false;
+		for (final Iterator<EObject> i = new EMultiContentsIterator(other); i
+				.hasNext();) {
+			final EObject eo = i.next();
+			if (eo instanceof IIdLabeled) {
+				if (((IIdLabeled) eo).getId() <= 0) {
+					((IIdLabeled) eo).setId(++maxId);
+				} else {
+					needSmart = true;
+				}
+			}
+		}
+
+		if (needSmart) {
+			final Set<Integer> usedIDs = new HashSet<Integer>();
+			for (final Iterator<EObject> i = new EMultiContentsIterator(
+					getTopLevelElements()); i.hasNext();) {
+				final EObject eo = i.next();
+				if (eo instanceof IIdLabeled) {
+					usedIDs.add(((IIdLabeled) eo).getId());
+				}
+			}
+
+			for (final Iterator<EObject> i = new EMultiContentsIterator(other); i
+					.hasNext();) {
+				final EObject eo = i.next();
+				if (eo instanceof IIdLabeled) {
+					if (!usedIDs.add(((IIdLabeled) eo).getId())) {
+						final int newId = ++maxId;
+						((IIdLabeled) eo).setId(newId);
+						usedIDs.add(newId);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Add a dependent editor part which will be closed when this context
+	 * becomes invalid.
+	 */
+	/* package */void addDependentEditor(IEditorPart editor) {
+		dependentEditors.add(editor);
+	}
+
+	/** Removes an editor added via {@link #addDependentEditor(IEditorPart)}. */
+	/* package */void removeDependentEditor(IEditorPart editor) {
+		dependentEditors.remove(editor);
+	}
+
+	/** Destroys this context and closes all dependent editors. */
+	public void destroy() {
+		// discard changes
+		((BasicCommandStack) editingDomain.getCommandStack()).saveIsDone();
+
+		final List<IEditorPart> editors = new ArrayList<IEditorPart>(
+				dependentEditors);
+		dependentEditors.clear();
+
+		for (final IEditorPart editor : editors) {
+			editor.getSite().getShell().getDisplay().asyncExec(new Runnable() {
+				@Override
+				public void run() {
+					editor.getSite().getPage().closeEditor(editor, false);
+				}
+			});
+		}
+	}
+
+	/** Returns the top-level elements of this model. */
+	public UnmodifiableList<EObject> getTopLevelElements() {
+		return CollectionUtils.asUnmodifiable(r.getContents());
+	}
+
+	/** Returns the file associated with this model. */
+	public IFile getFile() {
+		return file;
+	}
+
+	/** Returns whether the model is dirty (i.e. if there are unsaved changes). */
+	public boolean isDirty() {
+		return ((BasicCommandStack) editingDomain.getCommandStack())
+				.isSaveNeeded();
+	}
+
+	/** Perform saving of the model. */
+	public synchronized void doSave(IProgressMonitor monitor)
+			throws IOException, CoreException {
+		monitor.beginTask("Saving...", 2);
+
+		// perform ID checking before safe to not produce inconsistent models
+		checkIDs();
+
+		// we use a two-state save process, as otherwise inconsistencies in the
+		// model can lead to partially written files which are unreadable and
+		// thus cause data loss.
+		final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+		r.save(bytes, EMFResourceUtils.buildOptionsMap());
+		monitor.worked(1);
+
+		setLastChangeWasIntended();
+		file.setContents(new ByteArrayInputStream(bytes.toByteArray()), false,
+				true, monitor);
+
+		monitor.worked(1);
+
+		((BasicCommandStack) editingDomain.getCommandStack()).saveIsDone();
+		performNotifyListeners(editingDomain.getCommandStack());
+
+		monitor.done();
+
+		// schedule actual marker creation as separate job
+		// we use a WorkspaceJob here since marker creation
+		// results in resource changed notifications that should
+		// be batched.
+		new WorkspaceJob("Create CCTS markers") {
+			@Override
+			public IStatus runInWorkspace(IProgressMonitor monitor) {
+				// TODO (FH): call marker service
+				// createMarkers();
+				return Status.OK_STATUS;
+			}
+		}.schedule();
+	}
+
+	/**
+	 * Returns whether the last change was caused by a save. This method has a
+	 * side effect! The {@link #lastChangeWasIntended} flag will be reset, so
+	 * this method should only be called once per change event.
+	 */
+	public synchronized boolean getLastChangeWasIntended() {
+		final boolean result = lastChangeWasIntended;
+		lastChangeWasIntended = false;
+		return result;
+	}
+
+	/** Sets the {@link #lastChangeWasIntended} flag to true. */
+	public synchronized void setLastChangeWasIntended() {
+		lastChangeWasIntended = true;
+	}
+
+	/**
+	 * Returns the editing domain of this model's context. Note that the command
+	 * stack contained in the returned editing domain is raw (i.e. does not deal
+	 * with transactions). Usually you should use the command stack returned
+	 * from {@link #getTransactionalCommandStack()}, unless you know what you
+	 * are doing.
+	 */
+	public TransactionalEditingDomain getEditingDomain() {
+		return editingDomain;
+	}
+
+	/**
+	 * Returns the command stack to be used, which automatically wraps all
+	 * commands in a transaction and provides easy undo/redo.
+	 */
+	public TransactionalCommandStack getTransactionalCommandStack() {
+		return transactionalCommandStack;
+	}
+
+	/** Runs the given runnable as a command. */
+	public void runAsCommand(final Runnable runnable) {
+		transactionalCommandStack.execute(new AbstractCommand() {
+
+			@Override
+			public boolean canExecute() {
+				return true;
+			}
+
+			@Override
+			public void execute() {
+				runnable.run();
+			}
+
+			@Override
+			public void redo() {
+				// we do nothing here, as redo is handled by our command stack.
+			}
+		});
+	}
+
+	/**
+	 * Returns the object from this context, whose qualified name is provided.
+	 * If none is found, null is returned. This method is relatively expensive
+	 * as the search is not efficient.
+	 */
+	/* package */EObject findElementByName(String qualifiedName) {
+		EObject result = null;
+		int lastPos = 0;
+
+		// TODO (FH): that is bad code!
+		final int l = qualifiedName.length();
+		OUTER: while (lastPos <= l) {
+			int sepPos = qualifiedName.indexOf("/", lastPos);
+			while (sepPos >= 0 && sepPos + 1 < l
+					&& qualifiedName.charAt(sepPos + 1) == '/') {
+				sepPos = qualifiedName.indexOf("/", sepPos + 2);
+			}
+			if (sepPos < 0) {
+				sepPos = l;
+			}
+
+			final String namePart = qualifiedName.substring(lastPos, sepPos);
+			lastPos = sepPos + 1;
+
+			List<EObject> children;
+			if (result == null) {
+				children = getTopLevelElements();
+			} else {
+				children = result.eContents();
+			}
+			for (final EObject e : children) {
+				if (namePart.equals(IModelElementService.INSTANCE
+						.getModelElementHandler(e).getName(e))) {
+					result = e;
+					continue OUTER;
+				}
+			}
+			return null;
+		}
+
+		return result;
+	}
+
+	/** Helper method for calling notifyListeners on the given stack. */
+	/* package */void performNotifyListeners(CommandStack commandStack) {
+		try {
+			Method notifyListenersMethod = BasicCommandStack.class
+					.getDeclaredMethod("notifyListeners");
+			notifyListenersMethod.setAccessible(true);
+			notifyListenersMethod.invoke(commandStack);
+		} catch (Exception e) {
+			LoggingUtils.error(ToolingKernelActivator.getDefault(),
+					"Notification after save failed!", e);
+		}
+	}
+
+}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IPersistencyService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IPersistencyService.java
index 6f90f1efc..923ebf32e 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IPersistencyService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IPersistencyService.java
@@ -17,11 +17,18 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.services;
 
+import java.util.List;
+
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.ecore.EObject;
+import org.fortiss.tooling.kernel.interfaces.IStorageProvider;
+import org.fortiss.tooling.kernel.interfaces.ITopLevelElementChangeListener;
 import org.fortiss.tooling.kernel.internal.PersistencyService;
 
 /**
- * The persistency service provides the access to the different persistency
- * options, namely an EMFStore or local XML files within an Eclipse project.
+ * The persistency service provides the transparent access to the different
+ * persistency options, namely an EMFStore or local XML files within an Eclipse
+ * project.
  * 
  * @author hoelzl
  * @author $Author$
@@ -33,5 +40,31 @@ public interface IPersistencyService {
 	/** Returns the singleton instance of the service. */
 	public static final IPersistencyService INSTANCE = new PersistencyService();
 
-	// TODO (FH): define
+	/**
+	 * Returns the list of top level {@link EObject}s provided by
+	 * {@link IStorageProvider}s.
+	 */
+	List<EObject> getTopLevelElements();
+
+	/**
+	 * Refreshes the list of top-level elements. This method should be called by
+	 * storage providers whenever their list of provided top-level elements
+	 * changes.
+	 */
+	void refreshTopLevelElements(IStorageProvider provider);
+
+	/** Adds a top-level element listener. */
+	void addTopLevelElementListener(ITopLevelElementChangeListener listener);
+
+	/** Removes a top-level element listener. */
+	void removeTopLevelElementListener(ITopLevelElementChangeListener listener);
+
+	/** Returns the top-level element for the given model element. */
+	EObject getTopLevelElementFor(EObject modelElement);
+
+	/** Returns the storage provider for the given model element. */
+	IStorageProvider getStorageProviderFor(EObject modelElement);
+
+	/** Returns the command stack for the given model element. */
+	CommandStack getCommandStack(EObject modelElement);
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/compose/ProjectCompositor.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EMFResourceUtils.java
similarity index 54%
rename from org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/compose/ProjectCompositor.java
rename to org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EMFResourceUtils.java
index dc8d0923f..b33b2da63 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/compose/ProjectCompositor.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EMFResourceUtils.java
@@ -15,36 +15,47 @@ $Id$
 | See the License for the specific language governing permissions and      |
 | limitations under the License.                                           |
 +--------------------------------------------------------------------------*/
-package org.fortiss.tooling.kernel.internal.compose;
+package org.fortiss.tooling.kernel.util;
 
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.common.model.Project;
-import org.fortiss.tooling.kernel.interfaces.ICompositionContext;
-import org.fortiss.tooling.kernel.interfaces.ICompositor;
-import org.fortiss.tooling.kernel.model.IProjectRootElement;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
 
 /**
- * {@link ICompositor} implementation for the {@link IProjectRootElement}s.
+ * Utility methods used for Eclipse resource storage.
  * 
  * @author hoelzlf
  * @author $Author$
  * @version $Rev$
  * @levd.rating RED Rev:
  */
-public final class ProjectCompositor implements ICompositor<Project> {
+public final class EMFResourceUtils {
+	/**
+	 * Stores the given EObject in the Eclipse workspace creating the given
+	 * IFile.
+	 */
+	public static void createNewEclipseWorkspaceProject(IFile file,
+			EObject topLevelElement) throws IOException {
 
-	/** {@inheritDoc} */
-	@Override
-	public boolean canCompose(Project container, EObject contained,
-			ICompositionContext context) {
-		return contained instanceof IProjectRootElement;
+		final Resource r = new ResourceSetImpl()
+				.createResource(URI.createPlatformResourceURI(file
+						.getFullPath().toString(), true));
+		r.getContents().add(topLevelElement);
+		r.save(buildOptionsMap());
 	}
 
-	/** {@inheritDoc} */
-	@Override
-	public boolean compose(Project container, EObject contained,
-			ICompositionContext context) {
-		container.addModelElement(contained);
-		return true;
+	/** Build the map of options used for IO of EMF models. */
+	public static Map<String, Object> buildOptionsMap() {
+		Map<String, Object> options = new HashMap<String, Object>();
+		options.put(XMLResource.OPTION_ENCODING, "UTF-8");
+		options.put(Resource.OPTION_ZIP, false);
+		return options;
 	}
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java
index cf11b33f3..68cb87f73 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java
@@ -17,14 +17,10 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.util;
 
-import org.conqat.ide.commons.ui.logging.LoggingUtils;
 import org.conqat.lib.commons.reflect.ReflectionUtils;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.emfstore.client.model.ProjectSpace;
-import org.eclipse.emf.emfstore.client.model.WorkspaceManager;
-import org.eclipse.emf.emfstore.common.model.Project;
-import org.fortiss.tooling.kernel.ToolingKernelActivator;
 import org.fortiss.tooling.kernel.model.IProjectRootElement;
+import org.fortiss.tooling.kernel.services.IPersistencyService;
 
 /**
  * Utility methods for accessing {@link IProjectRootElement}s.
@@ -36,27 +32,14 @@ import org.fortiss.tooling.kernel.model.IProjectRootElement;
  */
 public final class ProjectRootElementUtils {
 
-	/**
-	 * Returns the model element's ECP project or <code>null</code> .
-	 */
-	public static ProjectSpace getProjectSpace(EObject element) {
-		try {
-			return WorkspaceManager.getProjectSpace(element);
-		} catch (Exception e) {
-			LoggingUtils.error(ToolingKernelActivator.getDefault(),
-					"Unable to find ECP project!", e);
-		}
-		return null;
-	}
-
 	/**
 	 * Returns the instance of a project root element corresponding to the given
 	 * class.
 	 */
 	public static <T extends IProjectRootElement> T getRootElement(
 			EObject element, Class<T> clazz) {
-		Project project = getProjectSpace(element).getProject();
 		return ReflectionUtils.pickInstanceOf(clazz,
-				project.getAllModelElements());
+				IPersistencyService.INSTANCE.getTopLevelElementFor(element)
+						.eContents());
 	}
 }
-- 
GitLab