diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
index 24124dc..a5265ea 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
@@ -1,553 +1,552 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Simon McDuff - bug 201266
- *    Simon McDuff - bug 204890
- */
-package org.eclipse.emf.cdo.internal.common.revision.delta;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOWithID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevisable;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
-import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl;
-import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl;
-import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.change.ListChange;
-import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
-{
-  private EClass eClass;
-
-  private CDOID id;
-
-  private CDOBranch branch;
-
-  private int version;
-
-  private CDORevisable target;
-
-  private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
-
-  public CDORevisionDeltaImpl(CDORevision revision)
-  {
-    eClass = revision.getEClass();
-    id = revision.getID();
-    branch = revision.getBranch();
-    version = revision.getVersion();
-  }
-
-  public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
-  {
-    eClass = revisionDelta.getEClass();
-    id = revisionDelta.getID();
-    branch = revisionDelta.getBranch();
-    version = revisionDelta.getVersion();
-
-    if (copyFeatureDeltas)
-    {
-      for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
-      {
-        addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
-      }
-    }
-  }
-
-  public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
-  {
-    if (sourceRevision.getEClass() != targetRevision.getEClass())
-    {
-      throw new IllegalArgumentException();
-    }
-
-    eClass = sourceRevision.getEClass();
-    id = sourceRevision.getID();
-    branch = sourceRevision.getBranch();
-    version = sourceRevision.getVersion();
-    target = CDORevisionUtil.copyRevisable(targetRevision);
-
-    compare(sourceRevision, targetRevision);
-
-    CDORevisionData originData = sourceRevision.data();
-    CDORevisionData dirtyData = targetRevision.data();
-
-    Object dirtyContainerID = dirtyData.getContainerID();
-    if (dirtyContainerID instanceof CDOWithID)
-    {
-      dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
-    }
-
-    if (!compare(originData.getContainerID(), dirtyContainerID)
-        || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
-        || !compare(originData.getResourceID(), dirtyData.getResourceID()))
-    {
-      addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
-          dirtyData.getContainingFeatureID()));
-    }
-  }
-
-  public CDORevisionDeltaImpl(CDODataInput in) throws IOException
-  {
-    eClass = (EClass)in.readCDOClassifierRefAndResolve();
-    id = in.readCDOID();
-    branch = in.readCDOBranch();
-    version = in.readInt();
-    if (version < 0)
-    {
-      version = -version;
-      target = in.readCDORevisable();
-    }
-
-    int size = in.readInt();
-    for (int i = 0; i < size; i++)
-    {
-      CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
-      featureDeltas.put(featureDelta.getFeature(), featureDelta);
-    }
-  }
-
-  public void write(CDODataOutput out) throws IOException
-  {
-    out.writeCDOClassifierRef(eClass);
-    out.writeCDOID(id);
-    out.writeCDOBranch(branch);
-    if (target == null)
-    {
-      out.writeInt(version);
-    }
-    else
-    {
-      out.writeInt(-version);
-      out.writeCDORevisable(target);
-    }
-
-    out.writeInt(featureDeltas.size());
-    for (CDOFeatureDelta featureDelta : featureDeltas.values())
-    {
-      out.writeCDOFeatureDelta(eClass, featureDelta);
-    }
-  }
-
-  public EClass getEClass()
-  {
-    return eClass;
-  }
-
-  public CDOID getID()
-  {
-    return id;
-  }
-
-  public CDOBranch getBranch()
-  {
-    return branch;
-  }
-
-  public void setBranch(CDOBranch branch)
-  {
-    this.branch = branch;
-  }
-
-  public int getVersion()
-  {
-    return version;
-  }
-
-  public void setVersion(int version)
-  {
-    this.version = version;
-  }
-
-  public CDORevisable getTarget()
-  {
-    return target;
-  }
-
-  public void setTarget(CDORevisable target)
-  {
-    this.target = target;
-  }
-
-  public boolean isEmpty()
-  {
-    return featureDeltas.isEmpty();
-  }
-
-  public CDORevisionDelta copy()
-  {
-    return new CDORevisionDeltaImpl(this, true);
-  }
-
-  public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
-  {
-    return featureDeltas;
-  }
-
-  public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
-  {
-    return featureDeltas.get(feature);
-  }
-
-  public List<CDOFeatureDelta> getFeatureDeltas()
-  {
-    return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
-  }
-
-  public void apply(CDORevision revision)
-  {
-    for (CDOFeatureDelta featureDelta : featureDeltas.values())
-    {
-      ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
-    }
-  }
-
-  public void addFeatureDelta(CDOFeatureDelta delta)
-  {
-    if (delta instanceof CDOListFeatureDelta)
-    {
-      CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
-      for (CDOFeatureDelta childDelta : deltas.getListChanges())
-      {
-        addFeatureDelta(childDelta);
-      }
-    }
-    else
-    {
-      addSingleFeatureDelta(delta);
-    }
-  }
-
-  private void addSingleFeatureDelta(CDOFeatureDelta delta)
-  {
-    EStructuralFeature feature = delta.getFeature();
-    if (feature.isMany())
-    {
-      CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
-      if (listDelta == null)
-      {
-        listDelta = new CDOListFeatureDeltaImpl(feature);
-        featureDeltas.put(listDelta.getFeature(), listDelta);
-      }
-
-      // Remove all previous changes
-      if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
-      {
-        listDelta.getListChanges().clear();
-      }
-
-      listDelta.add(delta);
-    }
-    else
-    {
-      featureDeltas.put(feature, delta);
-    }
-  }
-
-  public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
-  {
-    boolean changed = false;
-    for (CDOFeatureDelta featureDelta : featureDeltas.values())
-    {
-      changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
-    }
-
-    return changed;
-  }
-
-  public void accept(CDOFeatureDeltaVisitor visitor)
-  {
-    for (CDOFeatureDelta featureDelta : featureDeltas.values())
-    {
-      ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
-    }
-  }
-
-  private void compare(CDORevision originRevision, CDORevision dirtyRevision)
-  {
-    CDORevisionData originData = originRevision.data();
-    CDORevisionData dirtyData = dirtyRevision.data();
-
-    for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
-    {
-      if (feature.isMany())
-      {
-        if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
-        {
-          addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
-        }
-        else
-        {
-          CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
-          final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
-
-          ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
-          {
-            @Override
-            public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
-            {
-              checkNoProxies(oldList);
-              checkNoProxies(newList);
-              super.analyzeLists(oldList, newList, listChanges);
-            }
-
-            @Override
-            protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
-                int index)
-            {
-              CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
-              changes.add(delta);
-              oldList.add(index, value);
-            }
-
-            @Override
-            protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
-                int index)
-            {
-              CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
-              // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
-              delta.setValue(oldList.get(index));
-              changes.add(delta);
-              oldList.remove(index);
-            }
-
-            @Override
-            protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
-                int index, int toIndex)
-            {
-              CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
-              // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
-              delta.setValue(oldList.get(index));
-              changes.add(delta);
-              oldList.move(toIndex, index);
-            }
-
-            private void checkNoProxies(EList<?> list)
-            {
-              for (Object element : list)
-              {
-                if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED)
-                {
-                  throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
-                }
-              }
-            }
-          };
-
-          CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
-          CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
-
-          analyzer.analyzeLists(originList, dirtyList, new NOOPList());
-          if (!changes.isEmpty())
-          {
-            featureDeltas.put(feature, listFeatureDelta);
-          }
-        }
-      }
-      else
-      {
-        Object originValue = originData.get(feature, 0);
-        Object dirtyValue = dirtyData.get(feature, 0);
-        if (!compare(originValue, dirtyValue))
-        {
-          if (dirtyValue == null)
-          {
-            addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
-          }
-          else
-          {
-            addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
-          }
-        }
-      }
-    }
-  }
-
-  private boolean compare(Object originValue, Object dirtyValue)
-  {
-    return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
-  }
-
-  @Override
-  public String toString()
-  {
-    return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
-        version, featureDeltas.values());
-  }
-
-  /**
-   * @author Eike Stepper
-   */
-  public static class NOOPList implements EList<ListChange>
-  {
-    private static final EList<ListChange> LIST = ECollections.emptyEList();
-
-    public NOOPList()
-    {
-    }
-
-    public int size()
-    {
-      return 0;
-    }
-
-    public boolean isEmpty()
-    {
-      return true;
-    }
-
-    public boolean contains(Object o)
-    {
-      return false;
-    }
-
-    public Iterator<ListChange> iterator()
-    {
-      return LIST.iterator();
-    }
-
-    public Object[] toArray()
-    {
-      return LIST.toArray();
-    }
-
-    public <T> T[] toArray(T[] a)
-    {
-      return LIST.toArray(a);
-    }
-
-    public boolean add(ListChange o)
-    {
-      return false;
-    }
-
-    public boolean remove(Object o)
-    {
-      return false;
-    }
-
-    public boolean containsAll(Collection<?> c)
-    {
-      return false;
-    }
-
-    public boolean addAll(Collection<? extends ListChange> c)
-    {
-      return false;
-    }
-
-    public boolean addAll(int index, Collection<? extends ListChange> c)
-    {
-      return false;
-    }
-
-    public boolean removeAll(Collection<?> c)
-    {
-      return false;
-    }
-
-    public boolean retainAll(Collection<?> c)
-    {
-      return false;
-    }
-
-    public void clear()
-    {
-    }
-
-    public ListChange get(int index)
-    {
-      return LIST.get(index);
-    }
-
-    public ListChange set(int index, ListChange element)
-    {
-      return null;
-    }
-
-    public void add(int index, ListChange element)
-    {
-    }
-
-    public ListChange remove(int index)
-    {
-      return null;
-    }
-
-    public int indexOf(Object o)
-    {
-      return LIST.indexOf(o);
-    }
-
-    public int lastIndexOf(Object o)
-    {
-      return LIST.lastIndexOf(o);
-    }
-
-    public ListIterator<ListChange> listIterator()
-    {
-      return LIST.listIterator();
-    }
-
-    public ListIterator<ListChange> listIterator(int index)
-    {
-      return LIST.listIterator(index);
-    }
-
-    public List<ListChange> subList(int fromIndex, int toIndex)
-    {
-      return LIST.subList(fromIndex, toIndex);
-    }
-
-    public void move(int newPosition, ListChange object)
-    {
-    }
-
-    public ListChange move(int newPosition, int oldPosition)
-    {
-      return null;
-    }
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Simon McDuff - bug 201266
+ *    Simon McDuff - bug 204890
+ */
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOWithID;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
+import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl;
+import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.change.ListChange;
+import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
+{
+  private EClass eClass;
+
+  private CDOID id;
+
+  private CDOBranch branch;
+
+  private int version;
+
+  private CDORevisable target;
+
+  private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
+
+  public CDORevisionDeltaImpl(CDORevision revision)
+  {
+    eClass = revision.getEClass();
+    id = revision.getID();
+    branch = revision.getBranch();
+    version = revision.getVersion();
+  }
+
+  public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
+  {
+    eClass = revisionDelta.getEClass();
+    id = revisionDelta.getID();
+    branch = revisionDelta.getBranch();
+    version = revisionDelta.getVersion();
+
+    if (copyFeatureDeltas)
+    {
+      for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
+      {
+        addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
+      }
+    }
+  }
+
+  public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
+  {
+    if (sourceRevision.getEClass() != targetRevision.getEClass())
+    {
+      throw new IllegalArgumentException();
+    }
+
+    eClass = sourceRevision.getEClass();
+    id = sourceRevision.getID();
+    branch = sourceRevision.getBranch();
+    version = sourceRevision.getVersion();
+    target = CDORevisionUtil.copyRevisable(targetRevision);
+
+    compare(sourceRevision, targetRevision);
+
+    CDORevisionData originData = sourceRevision.data();
+    CDORevisionData dirtyData = targetRevision.data();
+
+    Object dirtyContainerID = dirtyData.getContainerID();
+    if (dirtyContainerID instanceof CDOWithID)
+    {
+      dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
+    }
+
+    if (!compare(originData.getContainerID(), dirtyContainerID)
+        || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
+        || !compare(originData.getResourceID(), dirtyData.getResourceID()))
+    {
+      addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
+          dirtyData.getContainingFeatureID()));
+    }
+  }
+
+  public CDORevisionDeltaImpl(CDODataInput in) throws IOException
+  {
+    eClass = (EClass)in.readCDOClassifierRefAndResolve();
+    id = in.readCDOID();
+    branch = in.readCDOBranch();
+    version = in.readInt();
+    if (version < 0)
+    {
+      version = -version;
+      target = in.readCDORevisable();
+    }
+
+    int size = in.readInt();
+    for (int i = 0; i < size; i++)
+    {
+      CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
+      featureDeltas.put(featureDelta.getFeature(), featureDelta);
+    }
+  }
+
+  public void write(CDODataOutput out) throws IOException
+  {
+    out.writeCDOClassifierRef(eClass);
+    out.writeCDOID(id);
+    out.writeCDOBranch(branch);
+    if (target == null)
+    {
+      out.writeInt(version);
+    }
+    else
+    {
+      out.writeInt(-version);
+      out.writeCDORevisable(target);
+    }
+
+    out.writeInt(featureDeltas.size());
+    for (CDOFeatureDelta featureDelta : featureDeltas.values())
+    {
+      out.writeCDOFeatureDelta(eClass, featureDelta);
+    }
+  }
+
+  public EClass getEClass()
+  {
+    return eClass;
+  }
+
+  public CDOID getID()
+  {
+    return id;
+  }
+
+  public CDOBranch getBranch()
+  {
+    return branch;
+  }
+
+  public void setBranch(CDOBranch branch)
+  {
+    this.branch = branch;
+  }
+
+  public int getVersion()
+  {
+    return version;
+  }
+
+  public void setVersion(int version)
+  {
+    this.version = version;
+  }
+
+  public CDORevisable getTarget()
+  {
+    return target;
+  }
+
+  public void setTarget(CDORevisable target)
+  {
+    this.target = target;
+  }
+
+  public boolean isEmpty()
+  {
+    return featureDeltas.isEmpty();
+  }
+
+  public CDORevisionDelta copy()
+  {
+    return new CDORevisionDeltaImpl(this, true);
+  }
+
+  public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
+  {
+    return featureDeltas;
+  }
+
+  public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
+  {
+    return featureDeltas.get(feature);
+  }
+
+  public List<CDOFeatureDelta> getFeatureDeltas()
+  {
+    return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
+  }
+
+  public void apply(CDORevision revision)
+  {
+    for (CDOFeatureDelta featureDelta : featureDeltas.values())
+    {
+      ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
+    }
+  }
+
+  public void addFeatureDelta(CDOFeatureDelta delta)
+  {
+    if (delta instanceof CDOListFeatureDelta)
+    {
+      CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
+      for (CDOFeatureDelta childDelta : deltas.getListChanges())
+      {
+        addFeatureDelta(childDelta);
+      }
+    }
+    else
+    {
+      addSingleFeatureDelta(delta);
+    }
+  }
+
+  private void addSingleFeatureDelta(CDOFeatureDelta delta)
+  {
+    EStructuralFeature feature = delta.getFeature();
+    if (feature.isMany())
+    {
+      CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
+      if (listDelta == null)
+      {
+        listDelta = new CDOListFeatureDeltaImpl(feature);
+        featureDeltas.put(listDelta.getFeature(), listDelta);
+      }
+
+      // Remove all previous changes
+      if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
+      {
+        listDelta.getListChanges().clear();
+      }
+
+      listDelta.add(delta);
+    }
+    else
+    {
+      featureDeltas.put(feature, delta);
+    }
+  }
+
+  public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
+  {
+    boolean changed = false;
+    for (CDOFeatureDelta featureDelta : featureDeltas.values())
+    {
+      changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
+    }
+
+    return changed;
+  }
+
+  public void accept(CDOFeatureDeltaVisitor visitor)
+  {
+    for (CDOFeatureDelta featureDelta : featureDeltas.values())
+    {
+      ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
+    }
+  }
+
+  private void compare(CDORevision originRevision, CDORevision dirtyRevision)
+  {
+    CDORevisionData originData = originRevision.data();
+    CDORevisionData dirtyData = dirtyRevision.data();
+
+    for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
+    {
+      if (feature.isMany())
+      {
+        if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
+        {
+          addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
+        }
+        else
+        {
+          CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
+          final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
+
+          ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
+          {
+            @Override
+            public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
+            {
+              checkNoProxies(oldList);
+              checkNoProxies(newList);
+              super.analyzeLists(oldList, newList, listChanges);
+            }
+
+            @Override
+            protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
+                int index)
+            {
+              CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
+              changes.add(delta);
+              oldList.add(index, value);
+            }
+
+            @Override
+            protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+                int index)
+            {
+              CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
+              // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
+              delta.setValue(oldList.get(index));
+              changes.add(delta);
+              oldList.remove(index);
+            }
+
+            @Override
+            protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+                int index, int toIndex)
+            {
+              CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
+              // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
+              delta.setValue(oldList.get(index));
+              changes.add(delta);
+              oldList.move(toIndex, index);
+            }
+
+            private void checkNoProxies(EList<?> list)
+            {
+              for (Object element : list)
+              {
+                if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED)
+                {
+                  throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
+                }
+              }
+            }
+          };
+
+          CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
+          CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
+
+          analyzer.analyzeLists(originList, dirtyList, new NOOPList());
+          if (!changes.isEmpty())
+          {
+            featureDeltas.put(feature, listFeatureDelta);
+          }
+        }
+      }
+      else
+      {
+        Object originValue = originData.get(feature, 0);
+        Object dirtyValue = dirtyData.get(feature, 0);
+        if (!compare(originValue, dirtyValue))
+        {
+          if (dirtyValue == null)
+          {
+            addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
+          }
+          else
+          {
+            addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
+          }
+        }
+      }
+    }
+  }
+
+  private boolean compare(Object originValue, Object dirtyValue)
+  {
+    return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
+  }
+
+  @Override
+  public String toString()
+  {
+    return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
+        version, featureDeltas.values());
+  }
+
+  /**
+   * @author Eike Stepper
+   */
+  public static class NOOPList implements EList<ListChange>
+  {
+    private static final EList<ListChange> LIST = ECollections.emptyEList();
+
+    public NOOPList()
+    {
+    }
+
+    public int size()
+    {
+      return 0;
+    }
+
+    public boolean isEmpty()
+    {
+      return true;
+    }
+
+    public boolean contains(Object o)
+    {
+      return false;
+    }
+
+    public Iterator<ListChange> iterator()
+    {
+      return LIST.iterator();
+    }
+
+    public Object[] toArray()
+    {
+      return LIST.toArray();
+    }
+
+    public <T> T[] toArray(T[] a)
+    {
+      return LIST.toArray(a);
+    }
+
+    public boolean add(ListChange o)
+    {
+      return false;
+    }
+
+    public boolean remove(Object o)
+    {
+      return false;
+    }
+
+    public boolean containsAll(Collection<?> c)
+    {
+      return false;
+    }
+
+    public boolean addAll(Collection<? extends ListChange> c)
+    {
+      return false;
+    }
+
+    public boolean addAll(int index, Collection<? extends ListChange> c)
+    {
+      return false;
+    }
+
+    public boolean removeAll(Collection<?> c)
+    {
+      return false;
+    }
+
+    public boolean retainAll(Collection<?> c)
+    {
+      return false;
+    }
+
+    public void clear()
+    {
+    }
+
+    public ListChange get(int index)
+    {
+      return LIST.get(index);
+    }
+
+    public ListChange set(int index, ListChange element)
+    {
+      return null;
+    }
+
+    public void add(int index, ListChange element)
+    {
+    }
+
+    public ListChange remove(int index)
+    {
+      return null;
+    }
+
+    public int indexOf(Object o)
+    {
+      return LIST.indexOf(o);
+    }
+
+    public int lastIndexOf(Object o)
+    {
+      return LIST.lastIndexOf(o);
+    }
+
+    public ListIterator<ListChange> listIterator()
+    {
+      return LIST.listIterator();
+    }
+
+    public ListIterator<ListChange> listIterator(int index)
+    {
+      return LIST.listIterator(index);
+    }
+
+    public List<ListChange> subList(int fromIndex, int toIndex)
+    {
+      return LIST.subList(fromIndex, toIndex);
+    }
+
+    public void move(int newPosition, ListChange object)
+    {
+    }
+
+    public ListChange move(int newPosition, int oldPosition)
+    {
+      return null;
+    }
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
index 2608cd2..8853d5e 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
@@ -65,7 +65,6 @@
  */
 public abstract class BaseCDORevision extends AbstractCDORevision
 {
-
   private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, BaseCDORevision.class);
 
   private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, BaseCDORevision.class);
@@ -80,8 +79,12 @@
 
   private static final byte FROZEN_FLAG = 0x04;
 
+  private static final byte UNCHUNKED_FLAG = 0x08;
+
   private static final byte PERMISSION_MASK = 0x03;
 
+  private static final byte TRANSFER_MASK = PERMISSION_MASK | UNCHUNKED_FLAG;
+
   private CDOID id;
 
   private CDOBranchPoint branchPoint;
@@ -99,7 +102,7 @@
 
   private int containingFeatureID;
 
-  private transient byte flags = CDOPermission.WRITE.getBits();
+  private transient byte flags;
 
   /**
    * @since 3.0
@@ -130,7 +133,7 @@
     resourceID = source.resourceID;
     containerID = source.containerID;
     containingFeatureID = source.containingFeatureID;
-    flags = (byte)(source.flags & PERMISSION_MASK);
+    flags = (byte)(source.flags & TRANSFER_MASK);
   }
 
   /**
@@ -145,13 +148,13 @@
 
     readSystemValues(in);
 
-    byte permissionBits = (byte)(in.readByte() & PERMISSION_MASK);
-    if (permissionBits != CDOPermission.NONE.ordinal())
+    byte flagBits = (byte)(in.readByte() & TRANSFER_MASK);
+    if ((flagBits & PERMISSION_MASK) != CDOPermission.NONE.ordinal())
     {
       readValues(in);
     }
 
-    flags = permissionBits;
+    flags = flagBits;
 
     if (READING.isEnabled())
     {
@@ -203,7 +206,20 @@
 
     CDOPermissionProvider permissionProvider = out.getPermissionProvider();
     CDOPermission permission = permissionProvider.getPermission(this);
-    out.writeByte(permission.getBits());
+
+    int bits = flags & TRANSFER_MASK & ~PERMISSION_MASK;
+    bits |= permission.getBits();
+
+    if (referenceChunk == CDORevision.UNCHUNKED)
+    {
+      bits |= UNCHUNKED_FLAG;
+    }
+    else
+    {
+      bits &= ~UNCHUNKED_FLAG;
+    }
+
+    out.writeByte(bits);
 
     if (permission != CDOPermission.NONE)
     {
@@ -716,7 +732,7 @@
 
     if (isReadable())
     {
-      EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(getEClass());
+      EStructuralFeature[] features = getAllPersistentFeatures();
       for (int i = 0; i < features.length; i++)
       {
         EStructuralFeature feature = features[i];
@@ -732,6 +748,22 @@
     }
   }
 
+  /**
+   * @since 4.1
+   */
+  public boolean isUnchunked()
+  {
+    return (flags & UNCHUNKED_FLAG) != 0;
+  }
+
+  /**
+   * @since 4.1
+   */
+  public void setUnchunked()
+  {
+    flags |= UNCHUNKED_FLAG;
+  }
+
   protected Object getValue(int featureIndex)
   {
     checkReadable();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
index 031f06e..f743b2b 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
@@ -354,4 +354,20 @@
   {
     getDelegate().freeze();
   }
+
+  /**
+   * @since 4.1
+   */
+  public boolean isUnchunked()
+  {
+    return getDelegate().isUnchunked();
+  }
+
+  /**
+   * @since 4.1
+   */
+  public void setUnchunked()
+  {
+    getDelegate().setUnchunked();
+  }
 }
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
index 9d64683..985b397 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
@@ -126,4 +126,14 @@
    * @since 4.0
    */
   public void freeze();
+
+  /**
+   * @since 4.1
+   */
+  public boolean isUnchunked();
+
+  /**
+   * @since 4.1
+   */
+  public void setUnchunked();
 }
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java
index 72ffca1..7fa13aa 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java
@@ -279,6 +279,22 @@
     throw new UnsupportedOperationException(getExceptionMessage());
   }
 
+  /**
+   * @since 4.1
+   */
+  public boolean isUnchunked()
+  {
+    return true;
+  }
+
+  /**
+   * @since 4.1
+   */
+  public void setUnchunked()
+  {
+    // Do nothing
+  }
+
   private String getExceptionMessage()
   {
     return "Unsupported operation in " + this;
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
index 2ac02db..b3b1ca7 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
@@ -1,1124 +1,1117 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Stefan Winkler - major refactoring
- *    Stefan Winkler - 249610: [DB] Support external references (Implementation)
- *    Stefan Winkler - derived branch mapping from audit mapping
- *    Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
-import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 3.0
- */
-public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements
-    IClassMappingAuditSupport, IClassMappingDeltaSupport
-{
-  /**
-   * @author Stefan Winkler
-   */
-  private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
-  {
-    private IDBStoreAccessor accessor;
-
-    private long created;
-
-    private CDOID id;
-
-    private CDOBranch targetBranch;
-
-    private int oldVersion;
-
-    private int newVersion;
-
-    private InternalCDORevision newRevision;
-
-    public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created)
-    {
-      this.accessor = accessor;
-      this.created = created;
-      id = delta.getID();
-      oldVersion = delta.getVersion();
-
-      if (TRACER.isEnabled())
-      {
-        TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$
-      }
-
-      InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id);
-      newRevision = originalRevision.copy();
-      targetBranch = accessor.getTransaction().getBranch();
-      newRevision.adjustForCommit(targetBranch, created);
-
-      newVersion = newRevision.getVersion();
-
-      // process revision delta tree
-      delta.accept(this);
-
-      if (newVersion != CDORevision.FIRST_VERSION)
-      {
-        reviseOldRevision(accessor, id, delta.getBranch(), newRevision.getTimeStamp() - 1);
-      }
-
-      writeValues(accessor, newRevision);
-    }
-
-    public void visit(CDOMoveFeatureDelta delta)
-    {
-      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
-    }
-
-    public void visit(CDOAddFeatureDelta delta)
-    {
-      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
-    }
-
-    public void visit(CDORemoveFeatureDelta delta)
-    {
-      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
-    }
-
-    public void visit(CDOSetFeatureDelta delta)
-    {
-      delta.apply(newRevision);
-    }
-
-    public void visit(CDOUnsetFeatureDelta delta)
-    {
-      delta.apply(newRevision);
-    }
-
-    public void visit(CDOListFeatureDelta delta)
-    {
-      delta.apply(newRevision);
-      IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature());
-      listMapping.processDelta(accessor, id, targetBranch.getID(), oldVersion, newVersion, created, delta);
-    }
-
-    public void visit(CDOClearFeatureDelta delta)
-    {
-      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
-    }
-
-    public void visit(CDOContainerFeatureDelta delta)
-    {
-      delta.apply(newRevision);
-    }
-  }
-
-  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalBranchingClassMapping.class);
-
-  private String sqlInsertAttributes;
-
-  private String sqlSelectCurrentAttributes;
-
-  private String sqlSelectAllObjectIDs;
-
-  private String sqlSelectAttributesByTime;
-
-  private String sqlSelectAttributesByVersion;
-
-  private String sqlReviseAttributes;
-
-  private String sqlSelectForHandle;
-
-  private String sqlSelectForChangeSet;
-
-  private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
-  {
-    @Override
-    protected FeatureDeltaWriter initialValue()
-    {
-      return new FeatureDeltaWriter();
-    }
-  };
-
-  public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
-  {
-    super(mappingStrategy, eClass);
-
-    initSQLStrings();
-  }
-
-  @Override
-  protected IDBField addBranchingField(IDBTable table)
-  {
-    return table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
-  }
-
-  private void initSQLStrings()
-  {
-    Map<EStructuralFeature, String> unsettableFields = getUnsettableFields();
-    Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
-
-    // ----------- Select Revision ---------------------------
-    StringBuilder builder = new StringBuilder();
-
-    builder.append("SELECT "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
-
-    for (ITypeMapping singleMapping : getValueMappings())
-    {
-      builder.append(", "); //$NON-NLS-1$
-      builder.append(singleMapping.getField());
-    }
-
-    if (unsettableFields != null)
-    {
-      for (String fieldName : unsettableFields.values())
-      {
-        builder.append(", "); //$NON-NLS-1$
-        builder.append(fieldName);
-      }
-    }
-
-    if (listSizeFields != null)
-    {
-      for (String fieldName : listSizeFields.values())
-      {
-        builder.append(", "); //$NON-NLS-1$
-        builder.append(fieldName);
-      }
-    }
-
-    builder.append(" FROM "); //$NON-NLS-1$
-    builder.append(getTable());
-    builder.append(" WHERE "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append("=? AND "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append("=? AND ("); //$NON-NLS-1$
-    String sqlSelectAttributesPrefix = builder.toString();
-
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append("=0)"); //$NON-NLS-1$
-
-    sqlSelectCurrentAttributes = builder.toString();
-
-    builder = new StringBuilder(sqlSelectAttributesPrefix);
-
-    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-    builder.append("<=? AND ("); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append("=0 OR "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append(">=?))"); //$NON-NLS-1$
-
-    sqlSelectAttributesByTime = builder.toString();
-
-    builder = new StringBuilder(sqlSelectAttributesPrefix);
-
-    builder.append("ABS("); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
-    builder.append(")=?)"); //$NON-NLS-1$
-
-    sqlSelectAttributesByVersion = builder.toString();
-
-    // ----------- Insert Attributes -------------------------
-    builder = new StringBuilder();
-    builder.append("INSERT INTO "); //$NON-NLS-1$
-    builder.append(getTable());
-
-    builder.append("("); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
-
-    for (ITypeMapping singleMapping : getValueMappings())
-    {
-      builder.append(", "); //$NON-NLS-1$
-      builder.append(singleMapping.getField());
-    }
-
-    if (unsettableFields != null)
-    {
-      for (String fieldName : unsettableFields.values())
-      {
-        builder.append(", "); //$NON-NLS-1$
-        builder.append(fieldName);
-      }
-    }
-
-    if (listSizeFields != null)
-    {
-      for (String fieldName : listSizeFields.values())
-      {
-        builder.append(", "); //$NON-NLS-1$
-        builder.append(fieldName);
-      }
-    }
-
-    builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$
-
-    for (int i = 0; i < getValueMappings().size(); i++)
-    {
-      builder.append(", ?"); //$NON-NLS-1$
-    }
-
-    if (unsettableFields != null)
-    {
-      for (int i = 0; i < unsettableFields.size(); i++)
-      {
-        builder.append(", ?"); //$NON-NLS-1$
-      }
-    }
-
-    if (listSizeFields != null)
-    {
-      for (int i = 0; i < listSizeFields.size(); i++)
-      {
-        builder.append(", ?"); //$NON-NLS-1$
-      }
-    }
-
-    builder.append(")"); //$NON-NLS-1$
-    sqlInsertAttributes = builder.toString();
-
-    // ----------- Update to set revised ----------------
-    builder = new StringBuilder("UPDATE "); //$NON-NLS-1$
-    builder.append(getTable());
-    builder.append(" SET "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append("=? WHERE "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append("=? AND "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append("=? AND "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append("=0"); //$NON-NLS-1$
-    sqlReviseAttributes = builder.toString();
-
-    // ----------- Select all unrevised Object IDs ------
-    builder = new StringBuilder("SELECT "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append(" FROM "); //$NON-NLS-1$
-    builder.append(getTable());
-    builder.append(" WHERE "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-    builder.append("=0"); //$NON-NLS-1$
-    sqlSelectAllObjectIDs = builder.toString();
-
-    // ----------- Select all revisions (for handleRevision) ---
-    builder = new StringBuilder("SELECT "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
-    builder.append(", "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append(" FROM "); //$NON-NLS-1$
-    builder.append(getTable());
-    sqlSelectForHandle = builder.toString();
-
-    // ----------- Select all revisions (for handleRevision) ---
-    builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append(" FROM "); //$NON-NLS-1$
-    builder.append(getTable());
-    builder.append(" WHERE "); //$NON-NLS-1$
-    sqlSelectForChangeSet = builder.toString();
-  }
-
-  public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
-  {
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    long timeStamp = revision.getTimeStamp();
-    int branchID = revision.getBranch().getID();
-
-    try
-    {
-      if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
-      {
-        stmt = statementCache.getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
-        idHandler.setCDOID(stmt, 1, revision.getID());
-        stmt.setInt(2, branchID);
-        stmt.setLong(3, timeStamp);
-        stmt.setLong(4, timeStamp);
-      }
-      else
-      {
-        stmt = statementCache.getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
-        idHandler.setCDOID(stmt, 1, revision.getID());
-        stmt.setInt(2, branchID);
-      }
-
-      // Read singleval-attribute table always (even without modeled attributes!)
-      boolean success = readValuesFromStatement(stmt, revision, accessor);
-
-      // Read multival tables only if revision exists
-      if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION)
-      {
-        readLists(accessor, revision, listChunk);
-      }
-
-      return success;
-    }
-    catch (SQLException ex)
-    {
-      throw new DBException(ex);
-    }
-    finally
-    {
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
-  {
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    try
-    {
-      stmt = statementCache.getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
-      idHandler.setCDOID(stmt, 1, revision.getID());
-      stmt.setInt(2, revision.getBranch().getID());
-      stmt.setInt(3, revision.getVersion());
-
-      // Read singleval-attribute table always (even without modeled attributes!)
-      boolean success = readValuesFromStatement(stmt, revision, accessor);
-
-      // Read multival tables only if revision exists
-      if (success)
-      {
-        readLists(accessor, revision, listChunk);
-      }
-
-      return success;
-    }
-    catch (SQLException ex)
-    {
-      throw new DBException(ex);
-    }
-    finally
-    {
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
-      boolean exactMatch, CDOBranchPoint branchPoint)
-  {
-    EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
-
-    ITypeMapping nameValueMapping = getValueMapping(nameFeature);
-    if (nameValueMapping == null)
-    {
-      throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$
-    }
-
-    int branchID = branchPoint.getBranch().getID();
-    long timeStamp = branchPoint.getTimeStamp();
-
-    StringBuilder builder = new StringBuilder();
-    builder.append("SELECT "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_ID);
-    builder.append(" FROM "); //$NON-NLS-1$
-    builder.append(getTable());
-    builder.append(" WHERE "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
-    builder.append(">0 AND "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append("=? AND "); //$NON-NLS-1$
-    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
-    builder.append("=? AND "); //$NON-NLS-1$
-    builder.append(nameValueMapping.getField());
-    if (name == null)
-    {
-      builder.append(" IS NULL"); //$NON-NLS-1$
-    }
-    else
-    {
-      builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$
-    }
-
-    builder.append(" AND ("); //$NON-NLS-1$
-
-    if (timeStamp == CDORevision.UNSPECIFIED_DATE)
-    {
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("=0)"); //$NON-NLS-1$
-    }
-    else
-    {
-      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-      builder.append("<=? AND ("); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("=0 OR "); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append(">=?))"); //$NON-NLS-1$
-    }
-
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    try
-    {
-      int column = 1;
-
-      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
-      stmt.setInt(column++, branchID);
-      idHandler.setCDOID(stmt, column++, folderId);
-
-      if (name != null)
-      {
-        String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$
-        nameValueMapping.setValue(stmt, column++, queryName);
-      }
-
-      if (timeStamp != CDORevision.UNSPECIFIED_DATE)
-      {
-        stmt.setLong(column++, timeStamp);
-        stmt.setLong(column++, timeStamp);
-      }
-
-      if (TRACER.isEnabled())
-      {
-        TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$
-      }
-
-      return stmt;
-    }
-    catch (SQLException ex)
-    {
-      statementCache.releasePreparedStatement(stmt); // only release on error
-      throw new DBException(ex);
-    }
-  }
-
-  public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$
-    }
-
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    return statementCache.getPreparedStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH);
-  }
-
-  @Override
-  protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
-  {
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    try
-    {
-      int column = 1;
-      stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
-      idHandler.setCDOID(stmt, column++, revision.getID());
-      stmt.setInt(column++, revision.getVersion());
-      stmt.setInt(column++, revision.getBranch().getID());
-      stmt.setLong(column++, revision.getTimeStamp());
-      stmt.setLong(column++, revision.getRevised());
-      idHandler.setCDOID(stmt, column++, revision.getResourceID());
-      idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID());
-      stmt.setInt(column++, revision.getContainingFeatureID());
-
-      int isSetCol = column + getValueMappings().size();
-
-      for (ITypeMapping mapping : getValueMappings())
-      {
-        EStructuralFeature feature = mapping.getFeature();
-        if (feature.isUnsettable())
-        {
-          if (revision.getValue(feature) == null)
-          {
-            stmt.setBoolean(isSetCol++, false);
-
-            // also set value column to default value
-            mapping.setDefaultValue(stmt, column++);
-            continue;
-          }
-
-          stmt.setBoolean(isSetCol++, true);
-        }
-
-        mapping.setValueFromRevision(stmt, column++, revision);
-      }
-
-      Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
-      if (listSizeFields != null)
-      {
-        // isSetCol now points to the first listTableSize-column
-        column = isSetCol;
-
-        for (EStructuralFeature feature : listSizeFields.keySet())
-        {
-          CDOList list = revision.getList(feature);
-          stmt.setInt(column++, list.size());
-        }
-      }
-
-      DBUtil.update(stmt, true);
-    }
-    catch (SQLException e)
-    {
-      throw new DBException(e);
-    }
-    finally
-    {
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  @Override
-  protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp,
-      OMMonitor mon)
-  {
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    try
-    {
-      stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
-
-      int column = 1;
-      idHandler.setCDOID(stmt, column++, id);
-      stmt.setInt(column++, -version); // cdo_version
-      stmt.setInt(column++, branch.getID());
-      stmt.setLong(column++, timeStamp); // cdo_created
-      stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised
-      idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource
-      idHandler.setCDOID(stmt, column++, CDOID.NULL); // container
-      stmt.setInt(column++, 0); // containing feature ID
-
-      int isSetCol = column + getValueMappings().size();
-
-      for (ITypeMapping mapping : getValueMappings())
-      {
-        EStructuralFeature feature = mapping.getFeature();
-        if (feature.isUnsettable())
-        {
-          stmt.setBoolean(isSetCol++, false);
-        }
-
-        mapping.setDefaultValue(stmt, column++);
-      }
-
-      Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
-      if (listSizeFields != null)
-      {
-        // list size columns begin after isSet-columns
-        column = isSetCol;
-
-        for (int i = 0; i < listSizeFields.size(); i++)
-        {
-          stmt.setInt(column++, 0);
-        }
-      }
-
-      DBUtil.update(stmt, true);
-    }
-    catch (SQLException e)
-    {
-      throw new DBException(e);
-    }
-    finally
-    {
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  @Override
-  protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised)
-  {
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-
-    try
-    {
-      stmt = statementCache.getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
-
-      stmt.setLong(1, revised);
-      idHandler.setCDOID(stmt, 2, id);
-      stmt.setInt(3, branch.getID());
-
-      DBUtil.update(stmt, false); // No row affected if old revision from other branch!
-    }
-    catch (SQLException e)
-    {
-      throw new DBException(e);
-    }
-    finally
-    {
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  @Override
-  public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise,
-      OMMonitor monitor)
-  {
-    Async async = null;
-    monitor.begin(10);
-
-    try
-    {
-      try
-      {
-        async = monitor.forkAsync();
-        CDOID id = revision.getID();
-        if (mapType)
-        {
-          // put new objects into objectTypeMapper
-          long timeStamp = revision.getTimeStamp();
-          AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy();
-          mappingStrategy.putObjectType(accessor, timeStamp, id, getEClass());
-        }
-        else if (revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION)
-        {
-          // if revision is not the first one, revise the old revision
-          long revised = revision.getTimeStamp() - 1;
-          reviseOldRevision(accessor, id, revision.getBranch(), revised);
-          for (IListMapping mapping : getListMappings())
-          {
-            mapping.objectDetached(accessor, id, revised);
-          }
-        }
-      }
-      finally
-      {
-        if (async != null)
-        {
-          async.stop();
-        }
-      }
-
-      try
-      {
-        async = monitor.forkAsync();
-        if (revision.isResourceFolder() || revision.isResource())
-        {
-          checkDuplicateResources(accessor, revision);
-        }
-      }
-      finally
-      {
-        if (async != null)
-        {
-          async.stop();
-        }
-      }
-
-      try
-      {
-        // Write attribute table always (even without modeled attributes!)
-        async = monitor.forkAsync();
-        writeValues(accessor, revision);
-      }
-      finally
-      {
-        if (async != null)
-        {
-          async.stop();
-        }
-      }
-
-      try
-      {
-        // Write list tables only if they exist
-        async = monitor.forkAsync(7);
-        if (getListMappings() != null)
-        {
-          writeLists(accessor, revision);
-        }
-      }
-      finally
-      {
-        if (async != null)
-        {
-          async.stop();
-        }
-      }
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-
-  @Override
-  public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime,
-      CDORevisionHandler handler)
-  {
-    StringBuilder builder = new StringBuilder(sqlSelectForHandle);
-    boolean whereAppend = false;
-
-    if (branch != null)
-    {
-      // TODO: Prepare this string literal
-      builder.append(" WHERE "); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-      builder.append("=?"); //$NON-NLS-1$
-
-      whereAppend = true;
-    }
-
-    int timeParameters = 0;
-    if (timeStamp != CDOBranchPoint.INVALID_DATE)
-    {
-      if (exactTime)
-      {
-        if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
-        {
-          builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
-          builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-          builder.append("=?"); //$NON-NLS-1$
-          timeParameters = 1;
-        }
-      }
-      else
-      {
-        builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
-        if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
-        {
-          builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-          builder.append("<=? AND ("); //$NON-NLS-1$
-          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-          builder.append("=0 OR "); //$NON-NLS-1$
-          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-          builder.append(">=?)"); //$NON-NLS-1$
-          timeParameters = 2;
-        }
-        else
-        {
-          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-          builder.append("="); //$NON-NLS-1$
-          builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
-        }
-      }
-    }
-
-    IRepository repository = accessor.getStore().getRepository();
-    CDORevisionManager revisionManager = repository.getRevisionManager();
-    CDOBranchManager branchManager = repository.getBranchManager();
-
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-    ResultSet resultSet = null;
-
-    try
-    {
-      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
-
-      int column = 1;
-      if (branch != null)
-      {
-        stmt.setInt(column++, branch.getID());
-      }
-
-      for (int i = 0; i < timeParameters; i++)
-      {
-        stmt.setLong(column++, timeStamp);
-      }
-
-      resultSet = stmt.executeQuery();
-      while (resultSet.next())
-      {
-        CDOID id = idHandler.getCDOID(resultSet, 1);
-        int version = resultSet.getInt(2);
-
-        if (version >= CDOBranchVersion.FIRST_VERSION)
-        {
-          int branchID = resultSet.getInt(3);
-          CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version));
-          InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion,
-              CDORevision.UNCHUNKED, true);
-
-          if (!handler.handleRevision(revision))
-          {
-            break;
-          }
-        }
-        else
-        {
-          // Tell handler about detached IDs
-          InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0);
-          handler.handleRevision(revision);
-        }
-      }
-    }
-    catch (SQLException e)
-    {
-      throw new DBException(e);
-    }
-    finally
-    {
-      DBUtil.close(resultSet);
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  @Override
-  public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments)
-  {
-    StringBuilder builder = new StringBuilder(sqlSelectForChangeSet);
-    boolean isFirst = true;
-
-    for (int i = 0; i < segments.length; i++)
-    {
-      if (isFirst)
-      {
-        isFirst = false;
-      }
-      else
-      {
-        builder.append(" OR "); //$NON-NLS-1$
-      }
-
-      builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-      builder.append("=? AND "); //$NON-NLS-1$
-
-      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-      builder.append(">=?"); //$NON-NLS-1$
-      builder.append(" AND ("); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("<=? OR "); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("="); //$NON-NLS-1$
-      builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
-      builder.append(")"); //$NON-NLS-1$
-    }
-
-    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
-    IPreparedStatementCache statementCache = accessor.getStatementCache();
-    PreparedStatement stmt = null;
-    ResultSet resultSet = null;
-
-    Set<CDOID> result = new HashSet<CDOID>();
-
-    try
-    {
-      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
-      int column = 1;
-      for (CDOChangeSetSegment segment : segments)
-      {
-        stmt.setInt(column++, segment.getBranch().getID());
-        stmt.setLong(column++, segment.getTimeStamp());
-        stmt.setLong(column++, segment.getEndTime());
-      }
-
-      resultSet = stmt.executeQuery();
-      while (resultSet.next())
-      {
-        CDOID id = idHandler.getCDOID(resultSet, 1);
-        result.add(id);
-      }
-
-      return result;
-    }
-    catch (SQLException e)
-    {
-      throw new DBException(e);
-    }
-    finally
-    {
-      DBUtil.close(resultSet);
-      statementCache.releasePreparedStatement(stmt);
-    }
-  }
-
-  @Override
-  protected String getListXRefsWhere(QueryXRefsContext context)
-  {
-    StringBuilder builder = new StringBuilder();
-    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
-    builder.append("=");
-    builder.append(context.getBranch().getID());
-    builder.append(" AND (");
-
-    long timeStamp = context.getTimeStamp();
-    if (timeStamp == CDORevision.UNSPECIFIED_DATE)
-    {
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("=0)"); //$NON-NLS-1$
-    }
-    else
-    {
-      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
-      builder.append("<=");
-      builder.append(timeStamp);
-      builder.append(" AND ("); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append("=0 OR "); //$NON-NLS-1$
-      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
-      builder.append(">=");
-      builder.append(timeStamp);
-      builder.append("))"); //$NON-NLS-1$
-    }
-
-    return builder.toString();
-  }
-
-  public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
-      OMMonitor monitor)
-  {
-    monitor.begin();
-
-    try
-    {
-      if (accessor.getTransaction().getBranch() != delta.getBranch())
-      {
-        // new branch -> decide, if branch should be copied
-        if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch())
-        {
-          doCopyOnBranch(accessor, delta, created, monitor.fork());
-          return;
-        }
-      }
-
-      Async async = null;
-
-      try
-      {
-        async = monitor.forkAsync();
-        FeatureDeltaWriter writer = deltaWriter.get();
-        writer.process(accessor, delta, created);
-      }
-      finally
-      {
-        if (async != null)
-        {
-          async.stop();
-        }
-      }
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-
-  private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor)
-  {
-    monitor.begin(2);
-    try
-    {
-      InternalRepository repository = (InternalRepository)accessor.getStore().getRepository();
-
-      InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID());
-      if (oldRevision == null)
-      {
-        throw new IllegalStateException("Origin revision not found for " + delta);
-      }
-
-      // Make sure all chunks are loaded
-      for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(oldRevision.getEClass()))
-      {
-        if (feature.isMany())
-        {
-          repository.ensureChunk(oldRevision, feature, 0, oldRevision.getList(feature).size());
-        }
-      }
-
-      InternalCDORevision newRevision = oldRevision.copy();
-      newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created);
-      delta.apply(newRevision);
-      monitor.worked();
-      writeRevision(accessor, newRevision, false, true, monitor.fork());
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Stefan Winkler - major refactoring
+ *    Stefan Winkler - 249610: [DB] Support external references (Implementation)
+ *    Stefan Winkler - derived branch mapping from audit mapping
+ *    Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IIDHandler;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements
+    IClassMappingAuditSupport, IClassMappingDeltaSupport
+{
+  /**
+   * @author Stefan Winkler
+   */
+  private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
+  {
+    private IDBStoreAccessor accessor;
+
+    private long created;
+
+    private CDOID id;
+
+    private CDOBranch targetBranch;
+
+    private int oldVersion;
+
+    private int newVersion;
+
+    private InternalCDORevision newRevision;
+
+    public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created)
+    {
+      this.accessor = accessor;
+      this.created = created;
+      id = delta.getID();
+      oldVersion = delta.getVersion();
+
+      if (TRACER.isEnabled())
+      {
+        TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$
+      }
+
+      InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id);
+      newRevision = originalRevision.copy();
+      targetBranch = accessor.getTransaction().getBranch();
+      newRevision.adjustForCommit(targetBranch, created);
+
+      newVersion = newRevision.getVersion();
+
+      // process revision delta tree
+      delta.accept(this);
+
+      if (newVersion != CDORevision.FIRST_VERSION)
+      {
+        reviseOldRevision(accessor, id, delta.getBranch(), newRevision.getTimeStamp() - 1);
+      }
+
+      writeValues(accessor, newRevision);
+    }
+
+    public void visit(CDOMoveFeatureDelta delta)
+    {
+      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+    }
+
+    public void visit(CDOAddFeatureDelta delta)
+    {
+      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+    }
+
+    public void visit(CDORemoveFeatureDelta delta)
+    {
+      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+    }
+
+    public void visit(CDOSetFeatureDelta delta)
+    {
+      delta.apply(newRevision);
+    }
+
+    public void visit(CDOUnsetFeatureDelta delta)
+    {
+      delta.apply(newRevision);
+    }
+
+    public void visit(CDOListFeatureDelta delta)
+    {
+      delta.apply(newRevision);
+      IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature());
+      listMapping.processDelta(accessor, id, targetBranch.getID(), oldVersion, newVersion, created, delta);
+    }
+
+    public void visit(CDOClearFeatureDelta delta)
+    {
+      throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+    }
+
+    public void visit(CDOContainerFeatureDelta delta)
+    {
+      delta.apply(newRevision);
+    }
+  }
+
+  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalBranchingClassMapping.class);
+
+  private String sqlInsertAttributes;
+
+  private String sqlSelectCurrentAttributes;
+
+  private String sqlSelectAllObjectIDs;
+
+  private String sqlSelectAttributesByTime;
+
+  private String sqlSelectAttributesByVersion;
+
+  private String sqlReviseAttributes;
+
+  private String sqlSelectForHandle;
+
+  private String sqlSelectForChangeSet;
+
+  private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
+  {
+    @Override
+    protected FeatureDeltaWriter initialValue()
+    {
+      return new FeatureDeltaWriter();
+    }
+  };
+
+  public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+  {
+    super(mappingStrategy, eClass);
+
+    initSQLStrings();
+  }
+
+  @Override
+  protected IDBField addBranchingField(IDBTable table)
+  {
+    return table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
+  }
+
+  private void initSQLStrings()
+  {
+    Map<EStructuralFeature, String> unsettableFields = getUnsettableFields();
+    Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+
+    // ----------- Select Revision ---------------------------
+    StringBuilder builder = new StringBuilder();
+
+    builder.append("SELECT "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+    for (ITypeMapping singleMapping : getValueMappings())
+    {
+      builder.append(", "); //$NON-NLS-1$
+      builder.append(singleMapping.getField());
+    }
+
+    if (unsettableFields != null)
+    {
+      for (String fieldName : unsettableFields.values())
+      {
+        builder.append(", "); //$NON-NLS-1$
+        builder.append(fieldName);
+      }
+    }
+
+    if (listSizeFields != null)
+    {
+      for (String fieldName : listSizeFields.values())
+      {
+        builder.append(", "); //$NON-NLS-1$
+        builder.append(fieldName);
+      }
+    }
+
+    builder.append(" FROM "); //$NON-NLS-1$
+    builder.append(getTable());
+    builder.append(" WHERE "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append("=? AND "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append("=? AND ("); //$NON-NLS-1$
+    String sqlSelectAttributesPrefix = builder.toString();
+
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append("=0)"); //$NON-NLS-1$
+
+    sqlSelectCurrentAttributes = builder.toString();
+
+    builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+    builder.append("<=? AND ("); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append("=0 OR "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append(">=?))"); //$NON-NLS-1$
+
+    sqlSelectAttributesByTime = builder.toString();
+
+    builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+    builder.append("ABS("); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+    builder.append(")=?)"); //$NON-NLS-1$
+
+    sqlSelectAttributesByVersion = builder.toString();
+
+    // ----------- Insert Attributes -------------------------
+    builder = new StringBuilder();
+    builder.append("INSERT INTO "); //$NON-NLS-1$
+    builder.append(getTable());
+
+    builder.append("("); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+    for (ITypeMapping singleMapping : getValueMappings())
+    {
+      builder.append(", "); //$NON-NLS-1$
+      builder.append(singleMapping.getField());
+    }
+
+    if (unsettableFields != null)
+    {
+      for (String fieldName : unsettableFields.values())
+      {
+        builder.append(", "); //$NON-NLS-1$
+        builder.append(fieldName);
+      }
+    }
+
+    if (listSizeFields != null)
+    {
+      for (String fieldName : listSizeFields.values())
+      {
+        builder.append(", "); //$NON-NLS-1$
+        builder.append(fieldName);
+      }
+    }
+
+    builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$
+
+    for (int i = 0; i < getValueMappings().size(); i++)
+    {
+      builder.append(", ?"); //$NON-NLS-1$
+    }
+
+    if (unsettableFields != null)
+    {
+      for (int i = 0; i < unsettableFields.size(); i++)
+      {
+        builder.append(", ?"); //$NON-NLS-1$
+      }
+    }
+
+    if (listSizeFields != null)
+    {
+      for (int i = 0; i < listSizeFields.size(); i++)
+      {
+        builder.append(", ?"); //$NON-NLS-1$
+      }
+    }
+
+    builder.append(")"); //$NON-NLS-1$
+    sqlInsertAttributes = builder.toString();
+
+    // ----------- Update to set revised ----------------
+    builder = new StringBuilder("UPDATE "); //$NON-NLS-1$
+    builder.append(getTable());
+    builder.append(" SET "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append("=? WHERE "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append("=? AND "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append("=? AND "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append("=0"); //$NON-NLS-1$
+    sqlReviseAttributes = builder.toString();
+
+    // ----------- Select all unrevised Object IDs ------
+    builder = new StringBuilder("SELECT "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append(" FROM "); //$NON-NLS-1$
+    builder.append(getTable());
+    builder.append(" WHERE "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+    builder.append("=0"); //$NON-NLS-1$
+    sqlSelectAllObjectIDs = builder.toString();
+
+    // ----------- Select all revisions (for handleRevision) ---
+    builder = new StringBuilder("SELECT "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+    builder.append(", "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append(" FROM "); //$NON-NLS-1$
+    builder.append(getTable());
+    sqlSelectForHandle = builder.toString();
+
+    // ----------- Select all revisions (for handleRevision) ---
+    builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append(" FROM "); //$NON-NLS-1$
+    builder.append(getTable());
+    builder.append(" WHERE "); //$NON-NLS-1$
+    sqlSelectForChangeSet = builder.toString();
+  }
+
+  public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+  {
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    long timeStamp = revision.getTimeStamp();
+    int branchID = revision.getBranch().getID();
+
+    try
+    {
+      if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+      {
+        stmt = statementCache.getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
+        idHandler.setCDOID(stmt, 1, revision.getID());
+        stmt.setInt(2, branchID);
+        stmt.setLong(3, timeStamp);
+        stmt.setLong(4, timeStamp);
+      }
+      else
+      {
+        stmt = statementCache.getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+        idHandler.setCDOID(stmt, 1, revision.getID());
+        stmt.setInt(2, branchID);
+      }
+
+      // Read singleval-attribute table always (even without modeled attributes!)
+      boolean success = readValuesFromStatement(stmt, revision, accessor);
+
+      // Read multival tables only if revision exists
+      if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION)
+      {
+        readLists(accessor, revision, listChunk);
+      }
+
+      return success;
+    }
+    catch (SQLException ex)
+    {
+      throw new DBException(ex);
+    }
+    finally
+    {
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+  {
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    try
+    {
+      stmt = statementCache.getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
+      idHandler.setCDOID(stmt, 1, revision.getID());
+      stmt.setInt(2, revision.getBranch().getID());
+      stmt.setInt(3, revision.getVersion());
+
+      // Read singleval-attribute table always (even without modeled attributes!)
+      boolean success = readValuesFromStatement(stmt, revision, accessor);
+
+      // Read multival tables only if revision exists
+      if (success)
+      {
+        readLists(accessor, revision, listChunk);
+      }
+
+      return success;
+    }
+    catch (SQLException ex)
+    {
+      throw new DBException(ex);
+    }
+    finally
+    {
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+      boolean exactMatch, CDOBranchPoint branchPoint)
+  {
+    EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+    ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+    if (nameValueMapping == null)
+    {
+      throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$
+    }
+
+    int branchID = branchPoint.getBranch().getID();
+    long timeStamp = branchPoint.getTimeStamp();
+
+    StringBuilder builder = new StringBuilder();
+    builder.append("SELECT "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_ID);
+    builder.append(" FROM "); //$NON-NLS-1$
+    builder.append(getTable());
+    builder.append(" WHERE "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+    builder.append(">0 AND "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append("=? AND "); //$NON-NLS-1$
+    builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+    builder.append("=? AND "); //$NON-NLS-1$
+    builder.append(nameValueMapping.getField());
+    if (name == null)
+    {
+      builder.append(" IS NULL"); //$NON-NLS-1$
+    }
+    else
+    {
+      builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    builder.append(" AND ("); //$NON-NLS-1$
+
+    if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+    {
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("=0)"); //$NON-NLS-1$
+    }
+    else
+    {
+      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+      builder.append("<=? AND ("); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("=0 OR "); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append(">=?))"); //$NON-NLS-1$
+    }
+
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    try
+    {
+      int column = 1;
+
+      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
+      stmt.setInt(column++, branchID);
+      idHandler.setCDOID(stmt, column++, folderId);
+
+      if (name != null)
+      {
+        String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$
+        nameValueMapping.setValue(stmt, column++, queryName);
+      }
+
+      if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+      {
+        stmt.setLong(column++, timeStamp);
+        stmt.setLong(column++, timeStamp);
+      }
+
+      if (TRACER.isEnabled())
+      {
+        TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$
+      }
+
+      return stmt;
+    }
+    catch (SQLException ex)
+    {
+      statementCache.releasePreparedStatement(stmt); // only release on error
+      throw new DBException(ex);
+    }
+  }
+
+  public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$
+    }
+
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    return statementCache.getPreparedStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH);
+  }
+
+  @Override
+  protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+  {
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    try
+    {
+      int column = 1;
+      stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+      idHandler.setCDOID(stmt, column++, revision.getID());
+      stmt.setInt(column++, revision.getVersion());
+      stmt.setInt(column++, revision.getBranch().getID());
+      stmt.setLong(column++, revision.getTimeStamp());
+      stmt.setLong(column++, revision.getRevised());
+      idHandler.setCDOID(stmt, column++, revision.getResourceID());
+      idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID());
+      stmt.setInt(column++, revision.getContainingFeatureID());
+
+      int isSetCol = column + getValueMappings().size();
+
+      for (ITypeMapping mapping : getValueMappings())
+      {
+        EStructuralFeature feature = mapping.getFeature();
+        if (feature.isUnsettable())
+        {
+          if (revision.getValue(feature) == null)
+          {
+            stmt.setBoolean(isSetCol++, false);
+
+            // also set value column to default value
+            mapping.setDefaultValue(stmt, column++);
+            continue;
+          }
+
+          stmt.setBoolean(isSetCol++, true);
+        }
+
+        mapping.setValueFromRevision(stmt, column++, revision);
+      }
+
+      Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+      if (listSizeFields != null)
+      {
+        // isSetCol now points to the first listTableSize-column
+        column = isSetCol;
+
+        for (EStructuralFeature feature : listSizeFields.keySet())
+        {
+          CDOList list = revision.getList(feature);
+          stmt.setInt(column++, list.size());
+        }
+      }
+
+      DBUtil.update(stmt, true);
+    }
+    catch (SQLException e)
+    {
+      throw new DBException(e);
+    }
+    finally
+    {
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  @Override
+  protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp,
+      OMMonitor mon)
+  {
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    try
+    {
+      stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+      int column = 1;
+      idHandler.setCDOID(stmt, column++, id);
+      stmt.setInt(column++, -version); // cdo_version
+      stmt.setInt(column++, branch.getID());
+      stmt.setLong(column++, timeStamp); // cdo_created
+      stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised
+      idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource
+      idHandler.setCDOID(stmt, column++, CDOID.NULL); // container
+      stmt.setInt(column++, 0); // containing feature ID
+
+      int isSetCol = column + getValueMappings().size();
+
+      for (ITypeMapping mapping : getValueMappings())
+      {
+        EStructuralFeature feature = mapping.getFeature();
+        if (feature.isUnsettable())
+        {
+          stmt.setBoolean(isSetCol++, false);
+        }
+
+        mapping.setDefaultValue(stmt, column++);
+      }
+
+      Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+      if (listSizeFields != null)
+      {
+        // list size columns begin after isSet-columns
+        column = isSetCol;
+
+        for (int i = 0; i < listSizeFields.size(); i++)
+        {
+          stmt.setInt(column++, 0);
+        }
+      }
+
+      DBUtil.update(stmt, true);
+    }
+    catch (SQLException e)
+    {
+      throw new DBException(e);
+    }
+    finally
+    {
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  @Override
+  protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised)
+  {
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+
+    try
+    {
+      stmt = statementCache.getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
+
+      stmt.setLong(1, revised);
+      idHandler.setCDOID(stmt, 2, id);
+      stmt.setInt(3, branch.getID());
+
+      DBUtil.update(stmt, false); // No row affected if old revision from other branch!
+    }
+    catch (SQLException e)
+    {
+      throw new DBException(e);
+    }
+    finally
+    {
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  @Override
+  public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise,
+      OMMonitor monitor)
+  {
+    Async async = null;
+    monitor.begin(10);
+
+    try
+    {
+      try
+      {
+        async = monitor.forkAsync();
+        CDOID id = revision.getID();
+        if (mapType)
+        {
+          // put new objects into objectTypeMapper
+          long timeStamp = revision.getTimeStamp();
+          AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy();
+          mappingStrategy.putObjectType(accessor, timeStamp, id, getEClass());
+        }
+        else if (revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION)
+        {
+          // if revision is not the first one, revise the old revision
+          long revised = revision.getTimeStamp() - 1;
+          reviseOldRevision(accessor, id, revision.getBranch(), revised);
+          for (IListMapping mapping : getListMappings())
+          {
+            mapping.objectDetached(accessor, id, revised);
+          }
+        }
+      }
+      finally
+      {
+        if (async != null)
+        {
+          async.stop();
+        }
+      }
+
+      try
+      {
+        async = monitor.forkAsync();
+        if (revision.isResourceFolder() || revision.isResource())
+        {
+          checkDuplicateResources(accessor, revision);
+        }
+      }
+      finally
+      {
+        if (async != null)
+        {
+          async.stop();
+        }
+      }
+
+      try
+      {
+        // Write attribute table always (even without modeled attributes!)
+        async = monitor.forkAsync();
+        writeValues(accessor, revision);
+      }
+      finally
+      {
+        if (async != null)
+        {
+          async.stop();
+        }
+      }
+
+      try
+      {
+        // Write list tables only if they exist
+        async = monitor.forkAsync(7);
+        if (getListMappings() != null)
+        {
+          writeLists(accessor, revision);
+        }
+      }
+      finally
+      {
+        if (async != null)
+        {
+          async.stop();
+        }
+      }
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+
+  @Override
+  public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime,
+      CDORevisionHandler handler)
+  {
+    StringBuilder builder = new StringBuilder(sqlSelectForHandle);
+    boolean whereAppend = false;
+
+    if (branch != null)
+    {
+      // TODO: Prepare this string literal
+      builder.append(" WHERE "); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+      builder.append("=?"); //$NON-NLS-1$
+
+      whereAppend = true;
+    }
+
+    int timeParameters = 0;
+    if (timeStamp != CDOBranchPoint.INVALID_DATE)
+    {
+      if (exactTime)
+      {
+        if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+        {
+          builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
+          builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+          builder.append("=?"); //$NON-NLS-1$
+          timeParameters = 1;
+        }
+      }
+      else
+      {
+        builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
+        if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+        {
+          builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+          builder.append("<=? AND ("); //$NON-NLS-1$
+          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+          builder.append("=0 OR "); //$NON-NLS-1$
+          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+          builder.append(">=?)"); //$NON-NLS-1$
+          timeParameters = 2;
+        }
+        else
+        {
+          builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+          builder.append("="); //$NON-NLS-1$
+          builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
+        }
+      }
+    }
+
+    IRepository repository = accessor.getStore().getRepository();
+    CDORevisionManager revisionManager = repository.getRevisionManager();
+    CDOBranchManager branchManager = repository.getBranchManager();
+
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+    ResultSet resultSet = null;
+
+    try
+    {
+      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
+
+      int column = 1;
+      if (branch != null)
+      {
+        stmt.setInt(column++, branch.getID());
+      }
+
+      for (int i = 0; i < timeParameters; i++)
+      {
+        stmt.setLong(column++, timeStamp);
+      }
+
+      resultSet = stmt.executeQuery();
+      while (resultSet.next())
+      {
+        CDOID id = idHandler.getCDOID(resultSet, 1);
+        int version = resultSet.getInt(2);
+
+        if (version >= CDOBranchVersion.FIRST_VERSION)
+        {
+          int branchID = resultSet.getInt(3);
+          CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version));
+          InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion,
+              CDORevision.UNCHUNKED, true);
+
+          if (!handler.handleRevision(revision))
+          {
+            break;
+          }
+        }
+        else
+        {
+          // Tell handler about detached IDs
+          InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0);
+          handler.handleRevision(revision);
+        }
+      }
+    }
+    catch (SQLException e)
+    {
+      throw new DBException(e);
+    }
+    finally
+    {
+      DBUtil.close(resultSet);
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  @Override
+  public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments)
+  {
+    StringBuilder builder = new StringBuilder(sqlSelectForChangeSet);
+    boolean isFirst = true;
+
+    for (int i = 0; i < segments.length; i++)
+    {
+      if (isFirst)
+      {
+        isFirst = false;
+      }
+      else
+      {
+        builder.append(" OR "); //$NON-NLS-1$
+      }
+
+      builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+      builder.append("=? AND "); //$NON-NLS-1$
+
+      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+      builder.append(">=?"); //$NON-NLS-1$
+      builder.append(" AND ("); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("<=? OR "); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("="); //$NON-NLS-1$
+      builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
+      builder.append(")"); //$NON-NLS-1$
+    }
+
+    IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+    IPreparedStatementCache statementCache = accessor.getStatementCache();
+    PreparedStatement stmt = null;
+    ResultSet resultSet = null;
+
+    Set<CDOID> result = new HashSet<CDOID>();
+
+    try
+    {
+      stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
+      int column = 1;
+      for (CDOChangeSetSegment segment : segments)
+      {
+        stmt.setInt(column++, segment.getBranch().getID());
+        stmt.setLong(column++, segment.getTimeStamp());
+        stmt.setLong(column++, segment.getEndTime());
+      }
+
+      resultSet = stmt.executeQuery();
+      while (resultSet.next())
+      {
+        CDOID id = idHandler.getCDOID(resultSet, 1);
+        result.add(id);
+      }
+
+      return result;
+    }
+    catch (SQLException e)
+    {
+      throw new DBException(e);
+    }
+    finally
+    {
+      DBUtil.close(resultSet);
+      statementCache.releasePreparedStatement(stmt);
+    }
+  }
+
+  @Override
+  protected String getListXRefsWhere(QueryXRefsContext context)
+  {
+    StringBuilder builder = new StringBuilder();
+    builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+    builder.append("=");
+    builder.append(context.getBranch().getID());
+    builder.append(" AND (");
+
+    long timeStamp = context.getTimeStamp();
+    if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+    {
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("=0)"); //$NON-NLS-1$
+    }
+    else
+    {
+      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+      builder.append("<=");
+      builder.append(timeStamp);
+      builder.append(" AND ("); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append("=0 OR "); //$NON-NLS-1$
+      builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+      builder.append(">=");
+      builder.append(timeStamp);
+      builder.append("))"); //$NON-NLS-1$
+    }
+
+    return builder.toString();
+  }
+
+  public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
+      OMMonitor monitor)
+  {
+    monitor.begin();
+
+    try
+    {
+      if (accessor.getTransaction().getBranch() != delta.getBranch())
+      {
+        // new branch -> decide, if branch should be copied
+        if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch())
+        {
+          doCopyOnBranch(accessor, delta, created, monitor.fork());
+          return;
+        }
+      }
+
+      Async async = null;
+
+      try
+      {
+        async = monitor.forkAsync();
+        FeatureDeltaWriter writer = deltaWriter.get();
+        writer.process(accessor, delta, created);
+      }
+      finally
+      {
+        if (async != null)
+        {
+          async.stop();
+        }
+      }
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+
+  private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor)
+  {
+    monitor.begin(2);
+    try
+    {
+      InternalRepository repository = (InternalRepository)accessor.getStore().getRepository();
+
+      InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID());
+      if (oldRevision == null)
+      {
+        throw new IllegalStateException("Origin revision not found for " + delta);
+      }
+
+      // Make sure all chunks are loaded
+      repository.ensureChunks(oldRevision);
+
+      InternalCDORevision newRevision = oldRevision.copy();
+      newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created);
+      delta.apply(newRevision);
+      monitor.worked();
+      writeRevision(accessor, newRevision, false, true, monitor.fork());
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
index d65e8a6..9b89955 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
@@ -1,287 +1,542 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.internal.server;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
-import org.eclipse.emf.cdo.server.IQueryHandler;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
-import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
-import org.eclipse.emf.cdo.spi.server.InternalLockManager;
-import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
-import org.eclipse.emf.cdo.spi.server.InternalStore;
-
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public abstract class DelegatingRepository implements InternalRepository
-{
-  public DelegatingRepository()
-  {
-  }
-
-  protected abstract InternalRepository getDelegate();
-
-  public void addHandler(Handler handler)
-  {
-    getDelegate().addHandler(handler);
-  }
-
-  public void addListener(IListener listener)
-  {
-    getDelegate().addListener(listener);
-  }
-
-  public long[] createCommitTimeStamp(OMMonitor monitor)
-  {
-    return getDelegate().createCommitTimeStamp(monitor);
-  }
-
-  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
-      int chunkEnd)
-  {
-    return getDelegate().ensureChunk(revision, feature, chunkStart, chunkEnd);
-  }
-
-  public InternalCommitManager getCommitManager()
-  {
-    return getDelegate().getCommitManager();
-  }
-
-  public long getCreationTime()
-  {
-    return getDelegate().getCreationTime();
-  }
-
-  public Object[] getElements()
-  {
-    return getDelegate().getElements();
-  }
-
-  public long getLastCommitTimeStamp()
-  {
-    return getDelegate().getLastCommitTimeStamp();
-  }
-
-  public IListener[] getListeners()
-  {
-    return getDelegate().getListeners();
-  }
-
-  @Deprecated
-  public InternalLockManager getLockManager()
-  {
-    return getDelegate().getLockingManager();
-  }
-
-  public String getName()
-  {
-    return getDelegate().getName();
-  }
-
-  public InternalCDOPackageRegistry getPackageRegistry()
-  {
-    return getDelegate().getPackageRegistry();
-  }
-
-  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
-  {
-    return getDelegate().getPackageRegistry(considerCommitContext);
-  }
-
-  public Map<String, String> getProperties()
-  {
-    return getDelegate().getProperties();
-  }
-
-  public IQueryHandler getQueryHandler(CDOQueryInfo info)
-  {
-    return getDelegate().getQueryHandler(info);
-  }
-
-  public IQueryHandlerProvider getQueryHandlerProvider()
-  {
-    return getDelegate().getQueryHandlerProvider();
-  }
-
-  public InternalQueryManager getQueryManager()
-  {
-    return getDelegate().getQueryManager();
-  }
-
-  public InternalCDORevisionManager getRevisionManager()
-  {
-    return getDelegate().getRevisionManager();
-  }
-
-  public InternalSessionManager getSessionManager()
-  {
-    return getDelegate().getSessionManager();
-  }
-
-  public InternalStore getStore()
-  {
-    return getDelegate().getStore();
-  }
-
-  public String getUUID()
-  {
-    return getDelegate().getUUID();
-  }
-
-  public boolean hasListeners()
-  {
-    return getDelegate().hasListeners();
-  }
-
-  public boolean isEmpty()
-  {
-    return getDelegate().isEmpty();
-  }
-
-  public boolean isSupportingAudits()
-  {
-    return getDelegate().isSupportingAudits();
-  }
-
-  public boolean isSupportingBranches()
-  {
-    return getDelegate().isSupportingBranches();
-  }
-
-  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
-  {
-    return getDelegate().loadPackages(packageUnit);
-  }
-
-  public InternalCDOBranchManager getBranchManager()
-  {
-    return getDelegate().getBranchManager();
-  }
-
-  public void setBranchManager(InternalCDOBranchManager branchManager)
-  {
-    getDelegate().setBranchManager(branchManager);
-  }
-
-  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
-  {
-    return getDelegate().createBranch(branchID, branchInfo);
-  }
-
-  public BranchInfo loadBranch(int branchID)
-  {
-    return getDelegate().loadBranch(branchID);
-  }
-
-  public SubBranchInfo[] loadSubBranches(int branchID)
-  {
-    return getDelegate().loadSubBranches(branchID);
-  }
-
-  public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
-      int referenceChunk, int prefetchDepth)
-  {
-    return getDelegate().loadRevisions(infos, branchPoint, referenceChunk, prefetchDepth);
-  }
-
-  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
-  {
-    return getDelegate().loadRevisionByVersion(id, branchVersion, referenceChunk);
-  }
-
-  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
-      List<CDORevision> additionalRevisions)
-  {
-    getDelegate().notifyReadAccessHandlers(session, revisions, additionalRevisions);
-  }
-
-  public void notifyWriteAccessHandlers(ITransaction transaction, CommitContext commitContext, boolean beforeCommit,
-      OMMonitor monitor)
-  {
-    getDelegate().notifyWriteAccessHandlers(transaction, commitContext, beforeCommit, monitor);
-  }
-
-  public void removeHandler(Handler handler)
-  {
-    getDelegate().removeHandler(handler);
-  }
-
-  public void removeListener(IListener listener)
-  {
-    getDelegate().removeListener(listener);
-  }
-
-  public void setName(String name)
-  {
-    getDelegate().setName(name);
-  }
-
-  public void setProperties(Map<String, String> properties)
-  {
-    getDelegate().setProperties(properties);
-  }
-
-  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
-  {
-    getDelegate().setQueryHandlerProvider(queryHandlerProvider);
-  }
-
-  public void setRevisionManager(InternalCDORevisionManager revisionManager)
-  {
-    getDelegate().setRevisionManager(revisionManager);
-  }
-
-  public void setSessionManager(InternalSessionManager sessionManager)
-  {
-    getDelegate().setSessionManager(sessionManager);
-  }
-
-  public void setStore(InternalStore store)
-  {
-    getDelegate().setStore(store);
-  }
-
-  public long getTimeStamp()
-  {
-    return getDelegate().getTimeStamp();
-  }
-
-  public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
-  {
-    getDelegate().validateTimeStamp(timeStamp);
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
+import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
+import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
+import org.eclipse.emf.cdo.spi.server.InternalStore;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class DelegatingRepository implements InternalRepository
+{
+  public DelegatingRepository()
+  {
+  }
+
+  protected abstract InternalRepository getDelegate();
+
+  public void addHandler(Handler handler)
+  {
+    getDelegate().addHandler(handler);
+  }
+
+  public void addListener(IListener listener)
+  {
+    getDelegate().addListener(listener);
+  }
+
+  public long[] createCommitTimeStamp(OMMonitor monitor)
+  {
+    return getDelegate().createCommitTimeStamp(monitor);
+  }
+
+  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+      int chunkEnd)
+  {
+    return getDelegate().ensureChunk(revision, feature, chunkStart, chunkEnd);
+  }
+
+  public InternalCommitManager getCommitManager()
+  {
+    return getDelegate().getCommitManager();
+  }
+
+  public long getCreationTime()
+  {
+    return getDelegate().getCreationTime();
+  }
+
+  public Object[] getElements()
+  {
+    return getDelegate().getElements();
+  }
+
+  public long getLastCommitTimeStamp()
+  {
+    return getDelegate().getLastCommitTimeStamp();
+  }
+
+  public IListener[] getListeners()
+  {
+    return getDelegate().getListeners();
+  }
+
+  @Deprecated
+  public InternalLockManager getLockManager()
+  {
+    return getDelegate().getLockingManager();
+  }
+
+  public String getName()
+  {
+    return getDelegate().getName();
+  }
+
+  public InternalCDOPackageRegistry getPackageRegistry()
+  {
+    return getDelegate().getPackageRegistry();
+  }
+
+  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
+  {
+    return getDelegate().getPackageRegistry(considerCommitContext);
+  }
+
+  public Map<String, String> getProperties()
+  {
+    return getDelegate().getProperties();
+  }
+
+  public IQueryHandler getQueryHandler(CDOQueryInfo info)
+  {
+    return getDelegate().getQueryHandler(info);
+  }
+
+  public IQueryHandlerProvider getQueryHandlerProvider()
+  {
+    return getDelegate().getQueryHandlerProvider();
+  }
+
+  public InternalQueryManager getQueryManager()
+  {
+    return getDelegate().getQueryManager();
+  }
+
+  public InternalCDORevisionManager getRevisionManager()
+  {
+    return getDelegate().getRevisionManager();
+  }
+
+  public InternalSessionManager getSessionManager()
+  {
+    return getDelegate().getSessionManager();
+  }
+
+  public InternalStore getStore()
+  {
+    return getDelegate().getStore();
+  }
+
+  public String getUUID()
+  {
+    return getDelegate().getUUID();
+  }
+
+  public boolean hasListeners()
+  {
+    return getDelegate().hasListeners();
+  }
+
+  public boolean isEmpty()
+  {
+    return getDelegate().isEmpty();
+  }
+
+  public boolean isSupportingAudits()
+  {
+    return getDelegate().isSupportingAudits();
+  }
+
+  public boolean isSupportingBranches()
+  {
+    return getDelegate().isSupportingBranches();
+  }
+
+  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+  {
+    return getDelegate().loadPackages(packageUnit);
+  }
+
+  public InternalCDOBranchManager getBranchManager()
+  {
+    return getDelegate().getBranchManager();
+  }
+
+  public void setBranchManager(InternalCDOBranchManager branchManager)
+  {
+    getDelegate().setBranchManager(branchManager);
+  }
+
+  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
+  {
+    return getDelegate().createBranch(branchID, branchInfo);
+  }
+
+  public BranchInfo loadBranch(int branchID)
+  {
+    return getDelegate().loadBranch(branchID);
+  }
+
+  public SubBranchInfo[] loadSubBranches(int branchID)
+  {
+    return getDelegate().loadSubBranches(branchID);
+  }
+
+  public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+      int referenceChunk, int prefetchDepth)
+  {
+    return getDelegate().loadRevisions(infos, branchPoint, referenceChunk, prefetchDepth);
+  }
+
+  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
+  {
+    return getDelegate().loadRevisionByVersion(id, branchVersion, referenceChunk);
+  }
+
+  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+      List<CDORevision> additionalRevisions)
+  {
+    getDelegate().notifyReadAccessHandlers(session, revisions, additionalRevisions);
+  }
+
+  public void notifyWriteAccessHandlers(ITransaction transaction, CommitContext commitContext, boolean beforeCommit,
+      OMMonitor monitor)
+  {
+    getDelegate().notifyWriteAccessHandlers(transaction, commitContext, beforeCommit, monitor);
+  }
+
+  public void removeHandler(Handler handler)
+  {
+    getDelegate().removeHandler(handler);
+  }
+
+  public void removeListener(IListener listener)
+  {
+    getDelegate().removeListener(listener);
+  }
+
+  public void setName(String name)
+  {
+    getDelegate().setName(name);
+  }
+
+  public void setProperties(Map<String, String> properties)
+  {
+    getDelegate().setProperties(properties);
+  }
+
+  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
+  {
+    getDelegate().setQueryHandlerProvider(queryHandlerProvider);
+  }
+
+  public void setRevisionManager(InternalCDORevisionManager revisionManager)
+  {
+    getDelegate().setRevisionManager(revisionManager);
+  }
+
+  public void setSessionManager(InternalSessionManager sessionManager)
+  {
+    getDelegate().setSessionManager(sessionManager);
+  }
+
+  public void setStore(InternalStore store)
+  {
+    getDelegate().setStore(store);
+  }
+
+  public long getTimeStamp()
+  {
+    return getDelegate().getTimeStamp();
+  }
+
+  public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+  {
+    getDelegate().validateTimeStamp(timeStamp);
+  }
+
+  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
+  {
+    getDelegate().loadCommitInfos(branch, startTime, endTime, handler);
+  }
+
+  public CDOCommitData loadCommitData(long timeStamp)
+  {
+    return getDelegate().loadCommitData(timeStamp);
+  }
+
+  public Type getType()
+  {
+    return getDelegate().getType();
+  }
+
+  public State getState()
+  {
+    return getDelegate().getState();
+  }
+
+  public String getStoreType()
+  {
+    return getDelegate().getStoreType();
+  }
+
+  public Set<ObjectType> getObjectIDTypes()
+  {
+    return getDelegate().getObjectIDTypes();
+  }
+
+  public IDGenerationLocation getIDGenerationLocation()
+  {
+    return getDelegate().getIDGenerationLocation();
+  }
+
+  public CDOID getRootResourceID()
+  {
+    return getDelegate().getRootResourceID();
+  }
+
+  public Object processPackage(Object value)
+  {
+    return getDelegate().processPackage(value);
+  }
+
+  public boolean isSupportingEcore()
+  {
+    return getDelegate().isSupportingEcore();
+  }
+
+  public boolean isEnsuringReferentialIntegrity()
+  {
+    return getDelegate().isEnsuringReferentialIntegrity();
+  }
+
+  public void setType(Type type)
+  {
+    getDelegate().setType(type);
+  }
+
+  public long waitForCommit(long timeout)
+  {
+    return getDelegate().waitForCommit(timeout);
+  }
+
+  public void setState(State state)
+  {
+    getDelegate().setState(state);
+  }
+
+  public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
+  {
+    return getDelegate().loadBranches(startID, endID, branchHandler);
+  }
+
+  public Semaphore getPackageRegistryCommitLock()
+  {
+    return getDelegate().getPackageRegistryCommitLock();
+  }
+
+  public CDOCommitInfoHandler[] getCommitInfoHandlers()
+  {
+    return getDelegate().getCommitInfoHandlers();
+  }
+
+  public void addCommitInfoHandler(CDOCommitInfoHandler handler)
+  {
+    getDelegate().addCommitInfoHandler(handler);
+  }
+
+  public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
+  {
+    getDelegate().removeCommitInfoHandler(handler);
+  }
+
+  public InternalCDOCommitInfoManager getCommitInfoManager()
+  {
+    return getDelegate().getCommitInfoManager();
+  }
+
+  public Set<Handler> getHandlers()
+  {
+    return getDelegate().getHandlers();
+  }
+
+  public void setInitialPackages(EPackage... initialPackages)
+  {
+    getDelegate().setInitialPackages(initialPackages);
+  }
+
+  public InternalLockManager getLockingManager()
+  {
+    return getDelegate().getLockingManager();
+  }
+
+  public InternalCommitContext createCommitContext(InternalTransaction transaction)
+  {
+    return getDelegate().createCommitContext(transaction);
+  }
+
+  public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor)
+  {
+    return getDelegate().forceCommitTimeStamp(timestamp, monitor);
+  }
+
+  public void endCommit(long timeStamp)
+  {
+    getDelegate().endCommit(timeStamp);
+  }
+
+  public void failCommit(long timeStamp)
+  {
+    getDelegate().failCommit(timeStamp);
+  }
+
+  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
+  {
+    getDelegate().sendCommitNotification(sender, commitInfo);
+  }
+
+  public void setRootResourceID(CDOID rootResourceID)
+  {
+    getDelegate().setRootResourceID(rootResourceID);
+  }
+
+  public void setLastCommitTimeStamp(long commitTimeStamp)
+  {
+    getDelegate().setLastCommitTimeStamp(commitTimeStamp);
+  }
+
+  public void ensureChunks(InternalCDORevision revision)
+  {
+    getDelegate().ensureChunks(revision);
+  }
+
+  public void replicate(CDOReplicationContext context)
+  {
+    getDelegate().replicate(context);
+  }
+
+  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+      throws IOException
+  {
+    return getDelegate().replicateRaw(out, lastReplicatedBranchID, lastReplicatedCommitTime);
+  }
+
+  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
+  {
+    return getDelegate().getChangeSet(startPoint, endPoint);
+  }
+
+  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
+  {
+    return getDelegate().getMergeData(targetInfo, sourceInfo, targetBaseInfo, sourceBaseInfo, monitor);
+  }
+
+  public void queryLobs(List<byte[]> ids)
+  {
+    getDelegate().queryLobs(ids);
+  }
+
+  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
+  {
+    getDelegate().handleLobs(fromTime, toTime, handler);
+  }
+
+  public void loadLob(byte[] id, OutputStream out) throws IOException
+  {
+    getDelegate().loadLob(id, out);
+  }
+
+  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+      CDORevisionHandler handler)
+  {
+    getDelegate().handleRevisions(eClass, branch, exactBranch, timeStamp, exactTime, handler);
+  }
+
+  public boolean isSkipInitialization()
+  {
+    return getDelegate().isSkipInitialization();
+  }
+
+  public void setSkipInitialization(boolean skipInitialization)
+  {
+    getDelegate().setSkipInitialization(skipInitialization);
+  }
+
+  public void initSystemPackages()
+  {
+    getDelegate().initSystemPackages();
+  }
+
+  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
+  {
+    getDelegate().initMainBranch(branchManager, timeStamp);
+  }
+
+  public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
+      long timeout)
+  {
+    return getDelegate().lock(view, type, keys, recursive, timeout);
+  }
+
+  public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive)
+  {
+    return getDelegate().unlock(view, type, ids, recursive);
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index 669bf76..8347f99 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -1,1966 +1,2000 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Simon McDuff - bug 201266
- *    Simon McDuff - bug 233273
- *    Simon McDuff - bug 233490
- *    Stefan Winkler - changed order of determining audit and revision delta support.
- *    Andre Dietisheim - bug 256649
- */
-package org.eclipse.emf.cdo.internal.server;
-
-import org.eclipse.emf.cdo.common.CDOCommonView;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
-import org.eclipse.emf.cdo.common.id.CDOIDTemp;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
-import org.eclipse.emf.cdo.common.lock.CDOLockState;
-import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
-import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
-import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
-import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
-import org.eclipse.emf.cdo.internal.server.bundle.OM;
-import org.eclipse.emf.cdo.server.IQueryHandler;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreChunkReader;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.server.IView;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
-import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
-import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
-import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
-import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
-import org.eclipse.emf.cdo.spi.server.InternalLockManager;
-import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
-import org.eclipse.emf.cdo.spi.server.InternalStore;
-import org.eclipse.emf.cdo.spi.server.InternalTransaction;
-import org.eclipse.emf.cdo.spi.server.InternalView;
-
-import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
-
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
-import org.eclipse.net4j.util.StringUtil;
-import org.eclipse.net4j.util.WrappedException;
-import org.eclipse.net4j.util.collection.MoveableList;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
-import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
-import org.eclipse.net4j.util.container.Container;
-import org.eclipse.net4j.util.container.IPluginContainer;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.Monitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.transaction.TransactionException;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Semaphore;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class Repository extends Container<Object> implements InternalRepository
-{
-  private String name;
-
-  private String uuid;
-
-  private InternalStore store;
-
-  private Type type = Type.MASTER;
-
-  private State state = State.ONLINE;
-
-  private Map<String, String> properties;
-
-  private boolean supportingAudits;
-
-  private boolean supportingBranches;
-
-  private boolean supportingEcore;
-
-  private boolean ensuringReferentialIntegrity;
-
-  private IDGenerationLocation idGenerationLocation;
-
-  /**
-   * Must not be thread-bound to support XA commits.
-   */
-  private Semaphore packageRegistryCommitLock = new Semaphore(1);
-
-  private InternalCDOPackageRegistry packageRegistry;
-
-  private InternalCDOBranchManager branchManager;
-
-  private InternalCDORevisionManager revisionManager;
-
-  private InternalCDOCommitInfoManager commitInfoManager;
-
-  private InternalSessionManager sessionManager;
-
-  private InternalQueryManager queryManager;
-
-  private InternalCommitManager commitManager;
-
-  private InternalLockManager lockingManager;
-
-  private IQueryHandlerProvider queryHandlerProvider;
-
-  private List<ReadAccessHandler> readAccessHandlers = new ArrayList<ReadAccessHandler>();
-
-  private List<WriteAccessHandler> writeAccessHandlers = new ArrayList<WriteAccessHandler>();
-
-  private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>();
-
-  private EPackage[] initialPackages;
-
-  // Bugzilla 297940
-  private TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);
-
-  @ExcludeFromDump
-  private transient Object createBranchLock = new Object();
-
-  private boolean skipInitialization;
-
-  private CDOID rootResourceID;
-
-  public Repository()
-  {
-  }
-
-  public String getName()
-  {
-    return name;
-  }
-
-  public void setName(String name)
-  {
-    this.name = name;
-  }
-
-  public String getUUID()
-  {
-    if (uuid == null)
-    {
-      uuid = getProperties().get(Props.OVERRIDE_UUID);
-      if (uuid == null)
-      {
-        uuid = UUID.randomUUID().toString();
-      }
-      else if (uuid.length() == 0)
-      {
-        uuid = getName();
-      }
-    }
-
-    return uuid;
-  }
-
-  public InternalStore getStore()
-  {
-    return store;
-  }
-
-  public void setStore(InternalStore store)
-  {
-    this.store = store;
-  }
-
-  public Type getType()
-  {
-    return type;
-  }
-
-  public void setType(Type type)
-  {
-    checkArg(type, "type"); //$NON-NLS-1$
-    if (this.type != type)
-    {
-      changingType(this.type, type);
-    }
-  }
-
-  protected void changingType(Type oldType, Type newType)
-  {
-    type = newType;
-    fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
-
-    if (sessionManager != null)
-    {
-      sessionManager.sendRepositoryTypeNotification(oldType, newType);
-    }
-  }
-
-  public State getState()
-  {
-    return state;
-  }
-
-  public void setState(State state)
-  {
-    checkArg(state, "state"); //$NON-NLS-1$
-    if (this.state != state)
-    {
-      changingState(this.state, state);
-    }
-  }
-
-  protected void changingState(State oldState, State newState)
-  {
-    state = newState;
-    fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
-
-    if (sessionManager != null)
-    {
-      sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
-    }
-  }
-
-  public synchronized Map<String, String> getProperties()
-  {
-    if (properties == null)
-    {
-      properties = new HashMap<String, String>();
-    }
-
-    return properties;
-  }
-
-  public synchronized void setProperties(Map<String, String> properties)
-  {
-    this.properties = properties;
-  }
-
-  public boolean isSupportingAudits()
-  {
-    return supportingAudits;
-  }
-
-  public boolean isSupportingBranches()
-  {
-    return supportingBranches;
-  }
-
-  public boolean isSupportingEcore()
-  {
-    return supportingEcore;
-  }
-
-  public boolean isEnsuringReferentialIntegrity()
-  {
-    return ensuringReferentialIntegrity;
-  }
-
-  public IDGenerationLocation getIDGenerationLocation()
-  {
-    return idGenerationLocation;
-  }
-
-  public String getStoreType()
-  {
-    return store.getType();
-  }
-
-  public Set<CDOID.ObjectType> getObjectIDTypes()
-  {
-    return store.getObjectIDTypes();
-  }
-
-  public CDOID getRootResourceID()
-  {
-    return rootResourceID;
-  }
-
-  public void setRootResourceID(CDOID rootResourceID)
-  {
-    this.rootResourceID = rootResourceID;
-  }
-
-  public Object processPackage(Object value)
-  {
-    CDOFactoryImpl.prepareDynamicEPackage(value);
-    return value;
-  }
-
-  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
-  }
-
-  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
-  {
-    if (!isSupportingBranches())
-    {
-      throw new IllegalStateException("Branching is not supported by " + this);
-    }
-
-    long baseTimeStamp = branchInfo.getBaseTimeStamp();
-    if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
-    {
-      baseTimeStamp = getTimeStamp();
-      branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
-    }
-
-    synchronized (createBranchLock)
-    {
-      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-      return accessor.createBranch(branchID, branchInfo);
-    }
-  }
-
-  public BranchInfo loadBranch(int branchID)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.loadBranch(branchID);
-  }
-
-  public SubBranchInfo[] loadSubBranches(int branchID)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.loadSubBranches(branchID);
-  }
-
-  public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.loadBranches(startID, endID, branchHandler);
-  }
-
-  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    accessor.loadCommitInfos(branch, startTime, endTime, handler);
-  }
-
-  public CDOCommitData loadCommitData(long timeStamp)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.loadCommitData(timeStamp);
-  }
-
-  public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
-      int referenceChunk, int prefetchDepth)
-  {
-    for (RevisionInfo info : infos)
-    {
-      CDOID id = info.getID();
-      RevisionInfo.Type type = info.getType();
-      switch (type)
-      {
-      case AVAILABLE_NORMAL: // direct == false
-      {
-        RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
-        checkArg(availableInfo.isDirect() == false, "Load is not needed");
-        break;
-      }
-
-      case AVAILABLE_POINTER: // direct == false || target == null
-      {
-        RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
-        boolean needsTarget = !pointerInfo.hasTarget();
-        checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");
-
-        if (needsTarget)
-        {
-          CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
-          InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
-          PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo
-              .getAvailableBranchVersion().getBranch(), CDORevision.UNSPECIFIED_DATE, target);
-
-          info.setResult(target);
-          info.setSynthetic(pointer);
-          continue;
-        }
-
-        break;
-      }
-
-      case AVAILABLE_DETACHED: // direct == false
-      {
-        RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
-        checkArg(detachedInfo.isDirect() == false, "Load is not needed");
-        break;
-      }
-
-      case MISSING:
-      {
-        break;
-      }
-
-      default:
-        throw new IllegalStateException("Invalid revision info type: " + type);
-      }
-
-      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
-      if (revision == null)
-      {
-        if (isSupportingAudits())
-        {
-          // Case "Pointer"?
-          InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
-          if (target != null)
-          {
-            CDOBranch branch = branchPoint.getBranch();
-            long revised = loadRevisionRevised(id, branch);
-            PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
-            info.setSynthetic(pointer);
-          }
-
-          info.setResult(target);
-        }
-        else
-        {
-          DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id,
-              branchPoint.getBranch(), 0, CDORevision.UNSPECIFIED_DATE);
-          info.setSynthetic(detachedRevision);
-        }
-      }
-      else if (revision instanceof DetachedCDORevision)
-      {
-        DetachedCDORevision detached = (DetachedCDORevision)revision;
-        info.setSynthetic(detached);
-      }
-      else
-      {
-        revision.freeze();
-        info.setResult(revision);
-      }
-    }
-
-    return null;
-  }
-
-  private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk,
-      IStoreAccessor accessor)
-  {
-    CDOBranch branch = branchPoint.getBranch();
-    while (!branch.isMainBranch())
-    {
-      branchPoint = branch.getBase();
-      branch = branchPoint.getBranch();
-
-      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
-      if (revision != null)
-      {
-        revision.freeze();
-        return revision;
-      }
-    }
-
-    return null;
-  }
-
-  private long loadRevisionRevised(CDOID id, CDOBranch branch)
-  {
-    InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION),
-        CDORevision.UNCHUNKED);
-    if (revision != null)
-    {
-      return revision.getTimeStamp() - 1;
-    }
-
-    return CDORevision.UNSPECIFIED_DATE;
-  }
-
-  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
-  }
-
-  protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
-  {
-    EClass eClass = revision.getEClass();
-    EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
-    for (int i = 0; i < features.length; i++)
-    {
-      EStructuralFeature feature = features[i];
-      if (feature.isMany())
-      {
-        MoveableList<Object> list = revision.getList(feature);
-        int chunkEnd = Math.min(referenceChunk, list.size());
-        accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);
-      }
-    }
-  }
-
-  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
-      int chunkEnd)
-  {
-    MoveableList<Object> list = revision.getList(feature);
-    chunkEnd = Math.min(chunkEnd, list.size());
-    return ensureChunk(revision, feature, StoreThreadLocal.getAccessor(), list, chunkStart, chunkEnd);
-  }
-
-  protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature,
-      IStoreAccessor accessor, MoveableList<Object> list, int chunkStart, int chunkEnd)
-  {
-    IStoreChunkReader chunkReader = null;
-    int fromIndex = -1;
-    for (int j = chunkStart; j < chunkEnd; j++)
-    {
-      if (list.get(j) == InternalCDOList.UNINITIALIZED)
-      {
-        if (fromIndex == -1)
-        {
-          fromIndex = j;
-        }
-      }
-      else
-      {
-        if (fromIndex != -1)
-        {
-          if (chunkReader == null)
-          {
-            if (accessor == null)
-            {
-              accessor = StoreThreadLocal.getAccessor();
-            }
-
-            chunkReader = accessor.createChunkReader(revision, feature);
-          }
-
-          int toIndex = j;
-          if (fromIndex == toIndex - 1)
-          {
-            chunkReader.addSimpleChunk(fromIndex);
-          }
-          else
-          {
-            chunkReader.addRangedChunk(fromIndex, toIndex);
-          }
-
-          fromIndex = -1;
-        }
-      }
-    }
-
-    // Add last chunk
-    if (fromIndex != -1)
-    {
-      if (chunkReader == null)
-      {
-        if (accessor == null)
-        {
-          accessor = StoreThreadLocal.getAccessor();
-        }
-
-        chunkReader = accessor.createChunkReader(revision, feature);
-      }
-
-      int toIndex = chunkEnd;
-      if (fromIndex == toIndex - 1)
-      {
-        chunkReader.addSimpleChunk(fromIndex);
-      }
-      else
-      {
-        chunkReader.addRangedChunk(fromIndex, toIndex);
-      }
-    }
-
-    if (chunkReader != null)
-    {
-      InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;
-
-      List<Chunk> chunks = chunkReader.executeRead();
-      for (Chunk chunk : chunks)
-      {
-        int startIndex = chunk.getStartIndex();
-        for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
-        {
-          Object id = chunk.get(indexInChunk);
-          if (cdoList != null)
-          {
-            cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
-          }
-          else
-          {
-            list.set(startIndex + indexInChunk, id);
-          }
-        }
-      }
-    }
-
-    return accessor;
-  }
-
-  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
-  {
-    if (considerCommitContext)
-    {
-      IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
-      if (commitContext != null)
-      {
-        InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
-        if (contextualPackageRegistry != null)
-        {
-          return contextualPackageRegistry;
-        }
-      }
-    }
-
-    return packageRegistry;
-  }
-
-  public Semaphore getPackageRegistryCommitLock()
-  {
-    return packageRegistryCommitLock;
-  }
-
-  public InternalCDOPackageRegistry getPackageRegistry()
-  {
-    return getPackageRegistry(true);
-  }
-
-  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
-  {
-    checkInactive();
-    this.packageRegistry = packageRegistry;
-  }
-
-  public InternalSessionManager getSessionManager()
-  {
-    return sessionManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setSessionManager(InternalSessionManager sessionManager)
-  {
-    checkInactive();
-    this.sessionManager = sessionManager;
-  }
-
-  public InternalCDOBranchManager getBranchManager()
-  {
-    return branchManager;
-  }
-
-  public void setBranchManager(InternalCDOBranchManager branchManager)
-  {
-    checkInactive();
-    this.branchManager = branchManager;
-  }
-
-  public InternalCDOCommitInfoManager getCommitInfoManager()
-  {
-    return commitInfoManager;
-  }
-
-  public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
-  {
-    checkInactive();
-    this.commitInfoManager = commitInfoManager;
-  }
-
-  public InternalCDORevisionManager getRevisionManager()
-  {
-    return revisionManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setRevisionManager(InternalCDORevisionManager revisionManager)
-  {
-    checkInactive();
-    this.revisionManager = revisionManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public InternalQueryManager getQueryManager()
-  {
-    return queryManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setQueryManager(InternalQueryManager queryManager)
-  {
-    checkInactive();
-    this.queryManager = queryManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public InternalCommitManager getCommitManager()
-  {
-    return commitManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setCommitManager(InternalCommitManager commitManager)
-  {
-    checkInactive();
-    this.commitManager = commitManager;
-  }
-
-  /**
-   * @since 2.0
-   * @deprecated
-   */
-  @Deprecated
-  public InternalLockManager getLockManager()
-  {
-    return getLockingManager();
-  }
-
-  public InternalLockManager getLockingManager()
-  {
-    return lockingManager;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setLockingManager(InternalLockManager lockingManager)
-  {
-    checkInactive();
-    this.lockingManager = lockingManager;
-  }
-
-  public InternalCommitContext createCommitContext(InternalTransaction transaction)
-  {
-    return new TransactionCommitContext(transaction);
-  }
-
-  public long getLastCommitTimeStamp()
-  {
-    return timeStampAuthority.getLastFinishedTimeStamp();
-  }
-
-  public void setLastCommitTimeStamp(long lastCommitTimeStamp)
-  {
-    timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
-  }
-
-  public long waitForCommit(long timeout)
-  {
-    return timeStampAuthority.waitForCommit(timeout);
-  }
-
-  public long[] createCommitTimeStamp(OMMonitor monitor)
-  {
-    return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
-  }
-
-  public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
-  {
-    return timeStampAuthority.startCommit(override, monitor);
-  }
-
-  public void endCommit(long timestamp)
-  {
-    timeStampAuthority.endCommit(timestamp);
-  }
-
-  public void failCommit(long timestamp)
-  {
-    timeStampAuthority.failCommit(timestamp);
-  }
-
-  public CDOCommitInfoHandler[] getCommitInfoHandlers()
-  {
-    synchronized (commitInfoHandlers)
-    {
-      return commitInfoHandlers.toArray(new CDOCommitInfoHandler[commitInfoHandlers.size()]);
-    }
-  }
-
-  /**
-   * @since 4.0
-   */
-  public void addCommitInfoHandler(CDOCommitInfoHandler handler)
-  {
-    synchronized (commitInfoHandlers)
-    {
-      if (!commitInfoHandlers.contains(handler))
-      {
-        commitInfoHandlers.add(handler);
-      }
-    }
-  }
-
-  /**
-   * @since 4.0
-   */
-  public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
-  {
-    synchronized (commitInfoHandlers)
-    {
-      commitInfoHandlers.remove(handler);
-    }
-  }
-
-  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
-  {
-    sessionManager.sendCommitNotification(sender, commitInfo);
-
-    for (CDOCommitInfoHandler handler : getCommitInfoHandlers())
-    {
-      try
-      {
-        handler.handleCommitInfo(commitInfo);
-      }
-      catch (Exception ex)
-      {
-        OM.LOG.error(ex);
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public IQueryHandlerProvider getQueryHandlerProvider()
-  {
-    return queryHandlerProvider;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
-  {
-    this.queryHandlerProvider = queryHandlerProvider;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
-  {
-    String language = info.getQueryLanguage();
-    if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
-    {
-      return new ResourcesQueryHandler();
-    }
-
-    if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
-    {
-      return new XRefsQueryHandler();
-    }
-
-    IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
-    if (storeAccessor != null)
-    {
-      IQueryHandler handler = storeAccessor.getQueryHandler(info);
-      if (handler != null)
-      {
-        return handler;
-      }
-    }
-
-    if (queryHandlerProvider == null)
-    {
-      queryHandlerProvider = new ContainerQueryHandlerProvider(IPluginContainer.INSTANCE);
-    }
-
-    IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
-    if (handler != null)
-    {
-      return handler;
-    }
-
-    return null;
-  }
-
-  public Object[] getElements()
-  {
-    final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager,
-        commitManager, commitInfoManager, getLockingManager(), store };
-    return elements;
-  }
-
-  @Override
-  public boolean isEmpty()
-  {
-    return false;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public long getCreationTime()
-  {
-    return store.getCreationTime();
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
-  {
-    long creationTimeStamp = getCreationTime();
-    if (timeStamp < creationTimeStamp)
-    {
-      throw new IllegalArgumentException(
-          MessageFormat
-              .format(
-                  "timeStamp ({0}) < repository creation time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp))); //$NON-NLS-1$
-    }
-
-    long currentTimeStamp = getTimeStamp();
-    if (timeStamp > currentTimeStamp)
-    {
-      throw new IllegalArgumentException(
-          MessageFormat
-              .format(
-                  "timeStamp ({0}) > current time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp))); //$NON-NLS-1$
-    }
-  }
-
-  public long getTimeStamp()
-  {
-    return System.currentTimeMillis();
-  }
-
-  public Set<Handler> getHandlers()
-  {
-    Set<Handler> handlers = new HashSet<Handler>();
-
-    synchronized (readAccessHandlers)
-    {
-      handlers.addAll(readAccessHandlers);
-    }
-
-    synchronized (writeAccessHandlers)
-    {
-      handlers.addAll(writeAccessHandlers);
-    }
-
-    return handlers;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void addHandler(Handler handler)
-  {
-    if (handler instanceof ReadAccessHandler)
-    {
-      synchronized (readAccessHandlers)
-      {
-        if (!readAccessHandlers.contains(handler))
-        {
-          readAccessHandlers.add((ReadAccessHandler)handler);
-        }
-      }
-    }
-
-    if (handler instanceof WriteAccessHandler)
-    {
-      synchronized (writeAccessHandlers)
-      {
-        if (!writeAccessHandlers.contains(handler))
-        {
-          writeAccessHandlers.add((WriteAccessHandler)handler);
-        }
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void removeHandler(Handler handler)
-  {
-    if (handler instanceof ReadAccessHandler)
-    {
-      synchronized (readAccessHandlers)
-      {
-        readAccessHandlers.remove(handler);
-      }
-    }
-
-    if (handler instanceof WriteAccessHandler)
-    {
-      synchronized (writeAccessHandlers)
-      {
-        writeAccessHandlers.remove(handler);
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
-      List<CDORevision> additionalRevisions)
-  {
-    ReadAccessHandler[] handlers;
-    synchronized (readAccessHandlers)
-    {
-      int size = readAccessHandlers.size();
-      if (size == 0)
-      {
-        return;
-      }
-
-      handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
-    }
-
-    for (ReadAccessHandler handler : handlers)
-    {
-      // Do *not* protect against unchecked exceptions from handlers!
-      handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
-    }
-  }
-
-  public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
-      boolean beforeCommit, OMMonitor monitor)
-  {
-    WriteAccessHandler[] handlers;
-    synchronized (writeAccessHandlers)
-    {
-      int size = writeAccessHandlers.size();
-      if (size == 0)
-      {
-        return;
-      }
-
-      handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
-    }
-
-    try
-    {
-      monitor.begin(handlers.length);
-      for (WriteAccessHandler handler : handlers)
-      {
-        try
-        {
-          if (beforeCommit)
-          {
-            handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
-          }
-          else
-          {
-            handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
-          }
-        }
-        catch (RuntimeException ex)
-        {
-          if (!beforeCommit)
-          {
-            OM.LOG.error(ex);
-          }
-          else
-          {
-            // Do *not* protect against unchecked exceptions from handlers on before case!
-            throw ex;
-          }
-        }
-      }
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-
-  public void setInitialPackages(EPackage... initialPackages)
-  {
-    checkInactive();
-    this.initialPackages = initialPackages;
-  }
-
-  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
-      throws IOException
-  {
-    final int fromBranchID = lastReplicatedBranchID + 1;
-    final int toBranchID = getStore().getLastBranchID();
-
-    final long fromCommitTime = lastReplicatedCommitTime + 1L;
-    final long toCommitTime = getStore().getLastCommitTime();
-
-    out.writeInt(toBranchID);
-    out.writeLong(toCommitTime);
-
-    IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
-    accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
-
-    return new CDOReplicationInfo()
-    {
-      public int getLastReplicatedBranchID()
-      {
-        return toBranchID;
-      }
-
-      public long getLastReplicatedCommitTime()
-      {
-        return toCommitTime;
-      }
-
-      public String[] getLockAreaIDs()
-      {
-        return null; // TODO (CD) Raw replication of lockAreas
-      }
-    };
-  }
-
-  public void replicate(CDOReplicationContext context)
-  {
-    int startID = context.getLastReplicatedBranchID() + 1;
-    branchManager.getBranches(startID, 0, context);
-
-    long startTime = context.getLastReplicatedCommitTime();
-    commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
-
-    getLockingManager().getLockAreas(null, context);
-  }
-
-  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
-  {
-    CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);
-
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);
-
-    return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
-  }
-
-  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
-      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
-  {
-    CDOBranchPoint target = targetInfo.getBranchPoint();
-    CDOBranchPoint source = sourceInfo.getBranchPoint();
-
-    monitor.begin(5);
-
-    try
-    {
-      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-      Set<CDOID> ids = new HashSet<CDOID>();
-
-      if (targetBaseInfo == null && sourceBaseInfo == null)
-      {
-        if (CDOBranchUtil.isContainedBy(source, target))
-        {
-          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
-        }
-        else if (CDOBranchUtil.isContainedBy(target, source))
-        {
-          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
-        }
-        else
-        {
-          CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
-          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
-          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
-        }
-      }
-      else
-      {
-        CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
-
-        ids.addAll(accessor.readChangeSet(monitor.fork(),
-            CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target)));
-
-        ids.addAll(accessor.readChangeSet(monitor.fork(),
-            CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source)));
-      }
-
-      loadMergeData(ids, targetInfo, monitor.fork());
-      loadMergeData(ids, sourceInfo, monitor.fork());
-
-      if (targetBaseInfo != null)
-      {
-        loadMergeData(ids, targetBaseInfo, monitor.fork());
-      }
-
-      if (sourceBaseInfo != null)
-      {
-        loadMergeData(ids, sourceBaseInfo, monitor.fork());
-      }
-
-      return ids;
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-
-  private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
-  {
-    int size = ids.size();
-    monitor.begin(size);
-
-    try
-    {
-      CDOBranchPoint branchPoint = info.getBranchPoint();
-      for (CDOID id : ids)
-      {
-        if (info.containsRevision(id))
-        {
-          info.removeRevision(id);
-        }
-        else
-        {
-          InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
-          if (revision != null)
-          {
-            info.addRevision(revision);
-          }
-          else
-          {
-            info.removeRevision(id);
-          }
-        }
-
-        monitor.worked();
-      }
-    }
-    finally
-    {
-      monitor.done();
-    }
-  }
-
-  private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
-  {
-    InternalCDORevision revision = revisionManager.getRevision(id, branchPoint, CDORevision.UNCHUNKED,
-        CDORevision.DEPTH_NONE, true);
-    // if (revision == null || !ObjectUtil.equals(revision.getBranch(), branchPoint.getBranch()))
-    // {
-    // return null;
-    // }
-
-    return revision;
-  }
-
-  public void queryLobs(List<byte[]> ids)
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    accessor.queryLobs(ids);
-  }
-
-  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    accessor.handleLobs(fromTime, toTime, handler);
-  }
-
-  public void loadLob(byte[] id, OutputStream out) throws IOException
-  {
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    accessor.loadLob(id, out);
-  }
-
-  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
-      final CDORevisionHandler handler)
-  {
-    CDORevisionHandler wrapper = handler;
-    if (!exactBranch && !branch.isMainBranch())
-    {
-      if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
-      {
-        throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
-      }
-
-      wrapper = new CDORevisionHandler()
-      {
-        private Set<CDOID> handled = new HashSet<CDOID>();
-
-        public boolean handleRevision(CDORevision revision)
-        {
-          CDOID id = revision.getID();
-          if (handled.add(id))
-          {
-            return handler.handleRevision(revision);
-          }
-
-          return true;
-        }
-      };
-    }
-
-    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
-    while (branch != null)
-    {
-      accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
-      if (exactBranch)
-      {
-        break;
-      }
-
-      CDOBranchPoint base = branch.getBase();
-      branch = base.getBranch();
-      timeStamp = base.getTimeStamp();
-    }
-  }
-
-  public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
-      boolean isSupportingBranches)
-  {
-    List<Object> lockables = new ArrayList<Object>();
-    for (CDORevisionKey revKey : revisionKeys)
-    {
-      CDOID id = revKey.getID();
-      if (isSupportingBranches)
-      {
-        lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
-      }
-      else
-      {
-        lockables.add(id);
-      }
-    }
-    return lockables;
-  }
-
-  public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, boolean recursive,
-      long timeout)
-  {
-    List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
-    return lock(view, lockType, lockables, revKeys, recursive, timeout);
-  }
-
-  protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
-      List<CDORevisionKey> loadedRevs, boolean recursive, long timeout)
-  {
-    List<LockState<Object, IView>> newLockStates = null;
-    try
-    {
-      newLockStates = getLockingManager().lock2(true, type, view, lockables, recursive, timeout);
-    }
-    catch (TimeoutRuntimeException ex)
-    {
-      return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
-    }
-    catch (InterruptedException ex)
-    {
-      throw WrappedException.wrap(ex);
-    }
-
-    long[] requiredTimestamp = { 0L };
-    CDORevisionKey[] staleRevisionsArray = null;
-
-    try
-    {
-      staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
-    }
-    catch (IllegalArgumentException e)
-    {
-      getLockingManager().unlock2(true, type, view, lockables, recursive);
-      throw e;
-    }
-
-    // If some of the clients' revisions are stale and it has passiveUpdates disabled,
-    // then the locks are useless so we release them and report the stale revisions
-    //
-    InternalSession session = view.getSession();
-    boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
-    if (staleNoUpdate)
-    {
-      getLockingManager().unlock2(true, type, view, lockables, recursive);
-      return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
-          getTimeStamp());
-    }
-
-    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
-    sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
-
-    boolean waitForUpdate = staleRevisionsArray.length > 0;
-    return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
-        getTimeStamp());
-  }
-
-  private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
-      List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
-  {
-    List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
-    if (revisionKeys != null)
-    {
-      InternalCDORevisionManager revManager = getRevisionManager();
-      CDOBranch viewedBranch = view.getBranch();
-      for (CDORevisionKey revKey : revisionKeys)
-      {
-        CDOID id = revKey.getID();
-        InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), CDORevision.UNCHUNKED,
-            CDORevision.DEPTH_NONE, true);
-
-        if (rev == null)
-        {
-          throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
-              viewedBranch));
-        }
-
-        if (!revKey.equals(rev))
-        {
-          staleRevisions.add(revKey);
-          requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
-        }
-      }
-    }
-
-    // Convert the list to an array, to satisfy the API later
-    //
-    CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
-    staleRevisions.toArray(staleRevisionsArray);
-
-    return staleRevisionsArray;
-  }
-
-  private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
-  {
-    long timestamp = getTimeStamp();
-    CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
-        lockType, cdoLockStates);
-    getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
-  }
-
-  // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
-  public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
-  {
-    CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
-    int i = 0;
-
-    for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
-    {
-      CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
-      cdoLockStates[i++] = cdoLockState;
-    }
-
-    return cdoLockStates;
-  }
-
-  public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs, boolean recursive)
-  {
-    List<Object> unlockables = null;
-    if (objectIDs != null)
-    {
-      unlockables = new ArrayList<Object>(objectIDs.size());
-      CDOBranch branch = view.getBranch();
-      for (CDOID id : objectIDs)
-      {
-        Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
-        unlockables.add(key);
-      }
-    }
-
-    return doUnlock(view, lockType, unlockables, recursive);
-  }
-
-  protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables,
-      boolean recursive)
-  {
-    List<LockState<Object, IView>> newLockStates = null;
-    if (lockType == null) // Signals an unlock-all operation
-    {
-      newLockStates = getLockingManager().unlock2(true, view);
-    }
-    else
-    {
-      newLockStates = getLockingManager().unlock2(true, lockType, view, unlockables, recursive);
-    }
-
-    long timestamp = getTimeStamp();
-    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
-    sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
-
-    return new UnlockObjectsResult(cdoLockStates, timestamp);
-  }
-
-  @Override
-  public String toString()
-  {
-    return MessageFormat.format("Repository[{0}]", name); //$NON-NLS-1$
-  }
-
-  public boolean isSkipInitialization()
-  {
-    return skipInitialization;
-  }
-
-  public void setSkipInitialization(boolean skipInitialization)
-  {
-    this.skipInitialization = skipInitialization;
-  }
-
-  protected void initProperties()
-  {
-    String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
-    if (valueAudits != null)
-    {
-      supportingAudits = Boolean.valueOf(valueAudits);
-    }
-    else
-    {
-      supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
-    }
-
-    String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
-    if (valueBranches != null)
-    {
-      supportingBranches = Boolean.valueOf(valueBranches);
-    }
-    else
-    {
-      supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
-    }
-
-    String valueEcore = properties.get(Props.SUPPORTING_ECORE);
-    if (valueEcore != null)
-    {
-      supportingEcore = Boolean.valueOf(valueEcore);
-    }
-
-    String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
-    if (valueIntegrity != null)
-    {
-      ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
-    }
-
-    String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
-    if (valueIDLocation != null)
-    {
-      idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
-    }
-
-    if (idGenerationLocation == null)
-    {
-      idGenerationLocation = IDGenerationLocation.STORE;
-    }
-  }
-
-  public void initSystemPackages()
-  {
-    IStoreAccessor writer = store.getWriter(null);
-    StoreThreadLocal.setAccessor(writer);
-
-    try
-    {
-      List<InternalCDOPackageUnit> units = new ArrayList<InternalCDOPackageUnit>();
-      units.add(initSystemPackage(EcorePackage.eINSTANCE));
-      units.add(initSystemPackage(EresourcePackage.eINSTANCE));
-      units.add(initSystemPackage(EtypesPackage.eINSTANCE));
-
-      if (initialPackages != null)
-      {
-        for (EPackage initialPackage : initialPackages)
-        {
-          if (!packageRegistry.containsKey(initialPackage.getNsURI()))
-          {
-            units.add(initSystemPackage(initialPackage));
-          }
-        }
-      }
-
-      InternalCDOPackageUnit[] systemUnits = units.toArray(new InternalCDOPackageUnit[units.size()]);
-      writer.writePackageUnits(systemUnits, new Monitor());
-      writer.commit(new Monitor());
-    }
-    finally
-    {
-      StoreThreadLocal.release();
-    }
-  }
-
-  protected InternalCDOPackageUnit initSystemPackage(EPackage ePackage)
-  {
-    EMFUtil.registerPackage(ePackage, packageRegistry);
-    InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);
-
-    InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
-    packageUnit.setTimeStamp(store.getCreationTime());
-    packageUnit.setState(CDOPackageUnit.State.LOADED);
-    return packageUnit;
-  }
-
-  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
-  {
-    branchManager.initMainBranch(false, timeStamp);
-  }
-
-  protected void initRootResource()
-  {
-    CDOBranchPoint head = branchManager.getMainBranch().getHead();
-
-    CDORevisionFactory factory = getRevisionManager().getFactory();
-    InternalCDORevision rootResource = (InternalCDORevision)factory
-        .createRevision(EresourcePackage.Literals.CDO_RESOURCE);
-
-    rootResource.setBranchPoint(head);
-    rootResource.setContainerID(CDOID.NULL);
-    rootResource.setContainingFeatureID(0);
-
-    CDOID id = createRootResourceID();
-    rootResource.setID(id);
-    rootResource.setResourceID(id);
-
-    InternalSession session = getSessionManager().openSession(null);
-    InternalTransaction transaction = session.openTransaction(1, head);
-    InternalCommitContext commitContext = new TransactionCommitContext(transaction)
-    {
-      @Override
-      protected long[] createTimeStamp(OMMonitor monitor)
-      {
-        InternalRepository repository = getTransaction().getSession().getManager().getRepository();
-        return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
-      }
-
-      @Override
-      public String getUserID()
-      {
-        return SYSTEM_USER_ID;
-      }
-
-      @Override
-      public String getCommitComment()
-      {
-        return "<initialize>"; //$NON-NLS-1$
-      }
-    };
-
-    commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
-    commitContext.preWrite();
-
-    commitContext.write(new Monitor());
-    commitContext.commit(new Monitor());
-
-    String rollbackMessage = commitContext.getRollbackMessage();
-    if (rollbackMessage != null)
-    {
-      throw new TransactionException(rollbackMessage);
-    }
-
-    rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;
-
-    commitContext.postCommit(true);
-    session.close();
-  }
-
-  protected CDOID createRootResourceID()
-  {
-    if (getIDGenerationLocation() == IDGenerationLocation.STORE)
-    {
-      return CDOIDUtil.createTempObject(1);
-    }
-
-    return CDOIDGenerator.UUID.generateCDOID(null);
-  }
-
-  protected void readRootResource()
-  {
-    IStoreAccessor reader = store.getReader(null);
-    StoreThreadLocal.setAccessor(reader);
-
-    try
-    {
-      CDOBranchPoint head = branchManager.getMainBranch().getHead();
-      rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
-    }
-    finally
-    {
-      StoreThreadLocal.release();
-    }
-  }
-
-  protected void readPackageUnits()
-  {
-    IStoreAccessor reader = store.getReader(null);
-    StoreThreadLocal.setAccessor(reader);
-
-    try
-    {
-      Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
-      for (InternalCDOPackageUnit packageUnit : packageUnits)
-      {
-        packageRegistry.putPackageUnit(packageUnit);
-      }
-    }
-    finally
-    {
-      StoreThreadLocal.release();
-    }
-  }
-
-  @Override
-  protected void doBeforeActivate() throws Exception
-  {
-    super.doBeforeActivate();
-    checkState(store, "store"); //$NON-NLS-1$
-    checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
-    checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
-    checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
-    checkState(branchManager, "branchManager"); //$NON-NLS-1$
-    checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
-    checkState(queryManager, "queryManager"); //$NON-NLS-1$
-    checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
-    checkState(commitManager, "commitManager"); //$NON-NLS-1$
-    checkState(getLockingManager(), "lockingManager"); //$NON-NLS-1$
-
-    packageRegistry.setReplacingDescriptors(true);
-    packageRegistry.setPackageProcessor(this);
-    packageRegistry.setPackageLoader(this);
-
-    branchManager.setBranchLoader(this);
-    branchManager.setTimeProvider(this);
-
-    revisionManager.setRevisionLoader(this);
-    sessionManager.setRepository(this);
-    queryManager.setRepository(this);
-    commitInfoManager.setCommitInfoLoader(this);
-    commitManager.setRepository(this);
-    getLockingManager().setRepository(this);
-    store.setRepository(this);
-  }
-
-  @Override
-  protected void doActivate() throws Exception
-  {
-    super.doActivate();
-
-    initProperties();
-    if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
-    {
-      throw new IllegalStateException("Store can not handle client assigned IDs: " + store);
-    }
-
-    store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING
-        : IStore.RevisionTemporality.NONE);
-    store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING
-        : IStore.RevisionParallelism.NONE);
-    revisionManager.setSupportingAudits(supportingAudits);
-    revisionManager.setSupportingBranches(supportingBranches);
-
-    LifecycleUtil.activate(store);
-    LifecycleUtil.activate(packageRegistry);
-    LifecycleUtil.activate(sessionManager);
-    LifecycleUtil.activate(revisionManager);
-    LifecycleUtil.activate(branchManager);
-    LifecycleUtil.activate(queryManager);
-    LifecycleUtil.activate(commitInfoManager);
-    LifecycleUtil.activate(commitManager);
-    LifecycleUtil.activate(queryHandlerProvider);
-
-    if (!skipInitialization)
-    {
-      long lastCommitTimeStamp = Math.max(store.getCreationTime(), store.getLastCommitTime());
-      timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
-      initMainBranch(branchManager, lastCommitTimeStamp);
-
-      if (store.isFirstStart())
-      {
-        initSystemPackages();
-        initRootResource();
-      }
-      else
-      {
-        readPackageUnits();
-        readRootResource();
-      }
-
-      // This check does not work for CDOWorkspace:
-      // if (CDOIDUtil.isNull(rootResourceID))
-      // {
-      // throw new IllegalStateException("Root resource ID is null");
-      // }
-    }
-
-    LifecycleUtil.activate(getLockingManager()); // Needs an initialized main branch / branch manager
-  }
-
-  @Override
-  protected void doDeactivate() throws Exception
-  {
-    LifecycleUtil.deactivate(getLockingManager());
-    LifecycleUtil.deactivate(queryHandlerProvider);
-    LifecycleUtil.deactivate(commitManager);
-    LifecycleUtil.deactivate(commitInfoManager);
-    LifecycleUtil.deactivate(queryManager);
-    LifecycleUtil.deactivate(revisionManager);
-    LifecycleUtil.deactivate(sessionManager);
-    LifecycleUtil.deactivate(store);
-    LifecycleUtil.deactivate(branchManager);
-    LifecycleUtil.deactivate(packageRegistry);
-    super.doDeactivate();
-  }
-
-  /**
-   * @author Eike Stepper
-   * @since 2.0
-   */
-  public static class Default extends Repository
-  {
-    public Default()
-    {
-    }
-
-    @Override
-    protected void doBeforeActivate() throws Exception
-    {
-      if (getPackageRegistry(false) == null)
-      {
-        setPackageRegistry(createPackageRegistry());
-      }
-
-      if (getSessionManager() == null)
-      {
-        setSessionManager(createSessionManager());
-      }
-
-      if (getBranchManager() == null)
-      {
-        setBranchManager(createBranchManager());
-      }
-
-      if (getRevisionManager() == null)
-      {
-        setRevisionManager(createRevisionManager());
-      }
-
-      if (getQueryManager() == null)
-      {
-        setQueryManager(createQueryManager());
-      }
-
-      if (getCommitInfoManager() == null)
-      {
-        setCommitInfoManager(createCommitInfoManager());
-      }
-
-      if (getCommitManager() == null)
-      {
-        setCommitManager(createCommitManager());
-      }
-
-      if (getLockManager() == null)
-      {
-        setLockingManager(createLockManager());
-      }
-
-      super.doBeforeActivate();
-    }
-
-    protected InternalCDOPackageRegistry createPackageRegistry()
-    {
-      return new CDOPackageRegistryImpl();
-    }
-
-    protected InternalSessionManager createSessionManager()
-    {
-      return new SessionManager();
-    }
-
-    protected InternalCDOBranchManager createBranchManager()
-    {
-      return CDOBranchUtil.createBranchManager();
-    }
-
-    protected InternalCDORevisionManager createRevisionManager()
-    {
-      return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
-    }
-
-    protected InternalQueryManager createQueryManager()
-    {
-      return new QueryManager();
-    }
-
-    protected InternalCDOCommitInfoManager createCommitInfoManager()
-    {
-      return CDOCommitInfoUtil.createCommitInfoManager();
-    }
-
-    protected InternalCommitManager createCommitManager()
-    {
-      return new CommitManager();
-    }
-
-    @Deprecated
-    protected InternalLockManager createLockManager()
-    {
-      return createLockingManager();
-    }
-
-    public LockingManager createLockingManager()
-    {
-      return new LockingManager();
-    }
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Simon McDuff - bug 201266
+ *    Simon McDuff - bug 233273
+ *    Simon McDuff - bug 233490
+ *    Stefan Winkler - changed order of determining audit and revision delta support.
+ *    Andre Dietisheim - bug 256649
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
+import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.etypes.EtypesPackage;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IStore;
+import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreChunkReader;
+import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.server.IView;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
+import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
+import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
+import org.eclipse.emf.cdo.spi.server.InternalStore;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
+
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.MoveableList;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
+import org.eclipse.net4j.util.container.Container;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.monitor.Monitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class Repository extends Container<Object> implements InternalRepository
+{
+  private String name;
+
+  private String uuid;
+
+  private InternalStore store;
+
+  private Type type = Type.MASTER;
+
+  private State state = State.ONLINE;
+
+  private Map<String, String> properties;
+
+  private boolean supportingAudits;
+
+  private boolean supportingBranches;
+
+  private boolean supportingEcore;
+
+  private boolean ensuringReferentialIntegrity;
+
+  private IDGenerationLocation idGenerationLocation;
+
+  /**
+   * Must not be thread-bound to support XA commits.
+   */
+  private Semaphore packageRegistryCommitLock = new Semaphore(1);
+
+  private InternalCDOPackageRegistry packageRegistry;
+
+  private InternalCDOBranchManager branchManager;
+
+  private InternalCDORevisionManager revisionManager;
+
+  private InternalCDOCommitInfoManager commitInfoManager;
+
+  private InternalSessionManager sessionManager;
+
+  private InternalQueryManager queryManager;
+
+  private InternalCommitManager commitManager;
+
+  private InternalLockManager lockingManager;
+
+  private IQueryHandlerProvider queryHandlerProvider;
+
+  private List<ReadAccessHandler> readAccessHandlers = new ArrayList<ReadAccessHandler>();
+
+  private List<WriteAccessHandler> writeAccessHandlers = new ArrayList<WriteAccessHandler>();
+
+  private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>();
+
+  private EPackage[] initialPackages;
+
+  // Bugzilla 297940
+  private TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);
+
+  @ExcludeFromDump
+  private transient Object createBranchLock = new Object();
+
+  private boolean skipInitialization;
+
+  private CDOID rootResourceID;
+
+  public Repository()
+  {
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  public void setName(String name)
+  {
+    this.name = name;
+  }
+
+  public String getUUID()
+  {
+    if (uuid == null)
+    {
+      uuid = getProperties().get(Props.OVERRIDE_UUID);
+      if (uuid == null)
+      {
+        uuid = UUID.randomUUID().toString();
+      }
+      else if (uuid.length() == 0)
+      {
+        uuid = getName();
+      }
+    }
+
+    return uuid;
+  }
+
+  public InternalStore getStore()
+  {
+    return store;
+  }
+
+  public void setStore(InternalStore store)
+  {
+    this.store = store;
+  }
+
+  public Type getType()
+  {
+    return type;
+  }
+
+  public void setType(Type type)
+  {
+    checkArg(type, "type"); //$NON-NLS-1$
+    if (this.type != type)
+    {
+      changingType(this.type, type);
+    }
+  }
+
+  protected void changingType(Type oldType, Type newType)
+  {
+    type = newType;
+    fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
+
+    if (sessionManager != null)
+    {
+      sessionManager.sendRepositoryTypeNotification(oldType, newType);
+    }
+  }
+
+  public State getState()
+  {
+    return state;
+  }
+
+  public void setState(State state)
+  {
+    checkArg(state, "state"); //$NON-NLS-1$
+    if (this.state != state)
+    {
+      changingState(this.state, state);
+    }
+  }
+
+  protected void changingState(State oldState, State newState)
+  {
+    state = newState;
+    fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
+
+    if (sessionManager != null)
+    {
+      sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
+    }
+  }
+
+  public synchronized Map<String, String> getProperties()
+  {
+    if (properties == null)
+    {
+      properties = new HashMap<String, String>();
+    }
+
+    return properties;
+  }
+
+  public synchronized void setProperties(Map<String, String> properties)
+  {
+    this.properties = properties;
+  }
+
+  public boolean isSupportingAudits()
+  {
+    return supportingAudits;
+  }
+
+  public boolean isSupportingBranches()
+  {
+    return supportingBranches;
+  }
+
+  public boolean isSupportingEcore()
+  {
+    return supportingEcore;
+  }
+
+  public boolean isEnsuringReferentialIntegrity()
+  {
+    return ensuringReferentialIntegrity;
+  }
+
+  public IDGenerationLocation getIDGenerationLocation()
+  {
+    return idGenerationLocation;
+  }
+
+  public String getStoreType()
+  {
+    return store.getType();
+  }
+
+  public Set<CDOID.ObjectType> getObjectIDTypes()
+  {
+    return store.getObjectIDTypes();
+  }
+
+  public CDOID getRootResourceID()
+  {
+    return rootResourceID;
+  }
+
+  public void setRootResourceID(CDOID rootResourceID)
+  {
+    this.rootResourceID = rootResourceID;
+  }
+
+  public Object processPackage(Object value)
+  {
+    CDOFactoryImpl.prepareDynamicEPackage(value);
+    return value;
+  }
+
+  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
+  }
+
+  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
+  {
+    if (!isSupportingBranches())
+    {
+      throw new IllegalStateException("Branching is not supported by " + this);
+    }
+
+    long baseTimeStamp = branchInfo.getBaseTimeStamp();
+    if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+    {
+      baseTimeStamp = getTimeStamp();
+      branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
+    }
+
+    synchronized (createBranchLock)
+    {
+      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+      return accessor.createBranch(branchID, branchInfo);
+    }
+  }
+
+  public BranchInfo loadBranch(int branchID)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.loadBranch(branchID);
+  }
+
+  public SubBranchInfo[] loadSubBranches(int branchID)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.loadSubBranches(branchID);
+  }
+
+  public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.loadBranches(startID, endID, branchHandler);
+  }
+
+  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    accessor.loadCommitInfos(branch, startTime, endTime, handler);
+  }
+
+  public CDOCommitData loadCommitData(long timeStamp)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.loadCommitData(timeStamp);
+  }
+
+  public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+      int referenceChunk, int prefetchDepth)
+  {
+    for (RevisionInfo info : infos)
+    {
+      CDOID id = info.getID();
+      RevisionInfo.Type type = info.getType();
+      switch (type)
+      {
+      case AVAILABLE_NORMAL: // direct == false
+      {
+        RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
+        checkArg(availableInfo.isDirect() == false, "Load is not needed");
+        break;
+      }
+
+      case AVAILABLE_POINTER: // direct == false || target == null
+      {
+        RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
+        boolean needsTarget = !pointerInfo.hasTarget();
+        checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");
+
+        if (needsTarget)
+        {
+          CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
+          InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
+          PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo
+              .getAvailableBranchVersion().getBranch(), CDORevision.UNSPECIFIED_DATE, target);
+
+          info.setResult(target);
+          info.setSynthetic(pointer);
+          continue;
+        }
+
+        break;
+      }
+
+      case AVAILABLE_DETACHED: // direct == false
+      {
+        RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
+        checkArg(detachedInfo.isDirect() == false, "Load is not needed");
+        break;
+      }
+
+      case MISSING:
+      {
+        break;
+      }
+
+      default:
+        throw new IllegalStateException("Invalid revision info type: " + type);
+      }
+
+      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+      if (revision == null)
+      {
+        if (isSupportingAudits())
+        {
+          InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
+          if (target != null)
+          {
+            if (referenceChunk == CDORevision.UNCHUNKED)
+            {
+              target.setUnchunked();
+            }
+
+            CDOBranch branch = branchPoint.getBranch();
+            long revised = loadRevisionRevised(id, branch);
+            PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
+            info.setSynthetic(pointer);
+          }
+
+          info.setResult(target);
+        }
+        else
+        {
+          DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id,
+              branchPoint.getBranch(), 0, CDORevision.UNSPECIFIED_DATE);
+          info.setSynthetic(detachedRevision);
+        }
+      }
+      else if (revision instanceof DetachedCDORevision)
+      {
+        DetachedCDORevision detached = (DetachedCDORevision)revision;
+        info.setSynthetic(detached);
+      }
+      else
+      {
+        if (referenceChunk == CDORevision.UNCHUNKED)
+        {
+          revision.setUnchunked();
+        }
+
+        revision.freeze();
+        info.setResult(revision);
+      }
+    }
+
+    return null;
+  }
+
+  private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk,
+      IStoreAccessor accessor)
+  {
+    CDOBranch branch = branchPoint.getBranch();
+    while (!branch.isMainBranch())
+    {
+      branchPoint = branch.getBase();
+      branch = branchPoint.getBranch();
+
+      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+      if (revision != null)
+      {
+        revision.freeze();
+        return revision;
+      }
+    }
+
+    return null;
+  }
+
+  private long loadRevisionRevised(CDOID id, CDOBranch branch)
+  {
+    InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION),
+        CDORevision.UNCHUNKED);
+    if (revision != null)
+    {
+      return revision.getTimeStamp() - 1;
+    }
+
+    return CDORevision.UNSPECIFIED_DATE;
+  }
+
+  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
+  }
+
+  /**
+   * @deprecated Not used.
+   */
+  @Deprecated
+  protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
+  {
+    EClass eClass = revision.getEClass();
+    EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
+    for (int i = 0; i < features.length; i++)
+    {
+      EStructuralFeature feature = features[i];
+      if (feature.isMany())
+      {
+        MoveableList<Object> list = revision.getList(feature);
+        int chunkEnd = Math.min(referenceChunk, list.size());
+        accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);
+      }
+    }
+  }
+
+  public void ensureChunks(InternalCDORevision revision)
+  {
+    if (!revision.isUnchunked())
+    {
+      for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
+      {
+        if (feature.isMany())
+        {
+          ensureChunk(revision, feature, 0, revision.getList(feature).size());
+        }
+      }
+
+      revision.setUnchunked();
+    }
+  }
+
+  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+      int chunkEnd)
+  {
+    if (!revision.isUnchunked())
+    {
+      MoveableList<Object> list = revision.getList(feature);
+      chunkEnd = Math.min(chunkEnd, list.size());
+      return ensureChunk(revision, feature, StoreThreadLocal.getAccessor(), list, chunkStart, chunkEnd);
+    }
+
+    return null;
+  }
+
+  protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature,
+      IStoreAccessor accessor, MoveableList<Object> list, int chunkStart, int chunkEnd)
+  {
+    IStoreChunkReader chunkReader = null;
+    int fromIndex = -1;
+    for (int j = chunkStart; j < chunkEnd; j++)
+    {
+      if (list.get(j) == InternalCDOList.UNINITIALIZED)
+      {
+        if (fromIndex == -1)
+        {
+          fromIndex = j;
+        }
+      }
+      else
+      {
+        if (fromIndex != -1)
+        {
+          if (chunkReader == null)
+          {
+            if (accessor == null)
+            {
+              accessor = StoreThreadLocal.getAccessor();
+            }
+
+            chunkReader = accessor.createChunkReader(revision, feature);
+          }
+
+          int toIndex = j;
+          if (fromIndex == toIndex - 1)
+          {
+            chunkReader.addSimpleChunk(fromIndex);
+          }
+          else
+          {
+            chunkReader.addRangedChunk(fromIndex, toIndex);
+          }
+
+          fromIndex = -1;
+        }
+      }
+    }
+
+    // Add last chunk
+    if (fromIndex != -1)
+    {
+      if (chunkReader == null)
+      {
+        if (accessor == null)
+        {
+          accessor = StoreThreadLocal.getAccessor();
+        }
+
+        chunkReader = accessor.createChunkReader(revision, feature);
+      }
+
+      int toIndex = chunkEnd;
+      if (fromIndex == toIndex - 1)
+      {
+        chunkReader.addSimpleChunk(fromIndex);
+      }
+      else
+      {
+        chunkReader.addRangedChunk(fromIndex, toIndex);
+      }
+    }
+
+    if (chunkReader != null)
+    {
+      InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;
+
+      List<Chunk> chunks = chunkReader.executeRead();
+      for (Chunk chunk : chunks)
+      {
+        int startIndex = chunk.getStartIndex();
+        for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
+        {
+          Object id = chunk.get(indexInChunk);
+          if (cdoList != null)
+          {
+            cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
+          }
+          else
+          {
+            list.set(startIndex + indexInChunk, id);
+          }
+        }
+      }
+    }
+
+    return accessor;
+  }
+
+  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
+  {
+    if (considerCommitContext)
+    {
+      IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
+      if (commitContext != null)
+      {
+        InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
+        if (contextualPackageRegistry != null)
+        {
+          return contextualPackageRegistry;
+        }
+      }
+    }
+
+    return packageRegistry;
+  }
+
+  public Semaphore getPackageRegistryCommitLock()
+  {
+    return packageRegistryCommitLock;
+  }
+
+  public InternalCDOPackageRegistry getPackageRegistry()
+  {
+    return getPackageRegistry(true);
+  }
+
+  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
+  {
+    checkInactive();
+    this.packageRegistry = packageRegistry;
+  }
+
+  public InternalSessionManager getSessionManager()
+  {
+    return sessionManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setSessionManager(InternalSessionManager sessionManager)
+  {
+    checkInactive();
+    this.sessionManager = sessionManager;
+  }
+
+  public InternalCDOBranchManager getBranchManager()
+  {
+    return branchManager;
+  }
+
+  public void setBranchManager(InternalCDOBranchManager branchManager)
+  {
+    checkInactive();
+    this.branchManager = branchManager;
+  }
+
+  public InternalCDOCommitInfoManager getCommitInfoManager()
+  {
+    return commitInfoManager;
+  }
+
+  public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
+  {
+    checkInactive();
+    this.commitInfoManager = commitInfoManager;
+  }
+
+  public InternalCDORevisionManager getRevisionManager()
+  {
+    return revisionManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setRevisionManager(InternalCDORevisionManager revisionManager)
+  {
+    checkInactive();
+    this.revisionManager = revisionManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public InternalQueryManager getQueryManager()
+  {
+    return queryManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setQueryManager(InternalQueryManager queryManager)
+  {
+    checkInactive();
+    this.queryManager = queryManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public InternalCommitManager getCommitManager()
+  {
+    return commitManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setCommitManager(InternalCommitManager commitManager)
+  {
+    checkInactive();
+    this.commitManager = commitManager;
+  }
+
+  /**
+   * @since 2.0
+   * @deprecated
+   */
+  @Deprecated
+  public InternalLockManager getLockManager()
+  {
+    return getLockingManager();
+  }
+
+  public InternalLockManager getLockingManager()
+  {
+    return lockingManager;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setLockingManager(InternalLockManager lockingManager)
+  {
+    checkInactive();
+    this.lockingManager = lockingManager;
+  }
+
+  public InternalCommitContext createCommitContext(InternalTransaction transaction)
+  {
+    return new TransactionCommitContext(transaction);
+  }
+
+  public long getLastCommitTimeStamp()
+  {
+    return timeStampAuthority.getLastFinishedTimeStamp();
+  }
+
+  public void setLastCommitTimeStamp(long lastCommitTimeStamp)
+  {
+    timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+  }
+
+  public long waitForCommit(long timeout)
+  {
+    return timeStampAuthority.waitForCommit(timeout);
+  }
+
+  public long[] createCommitTimeStamp(OMMonitor monitor)
+  {
+    return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
+  }
+
+  public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
+  {
+    return timeStampAuthority.startCommit(override, monitor);
+  }
+
+  public void endCommit(long timestamp)
+  {
+    timeStampAuthority.endCommit(timestamp);
+  }
+
+  public void failCommit(long timestamp)
+  {
+    timeStampAuthority.failCommit(timestamp);
+  }
+
+  public CDOCommitInfoHandler[] getCommitInfoHandlers()
+  {
+    synchronized (commitInfoHandlers)
+    {
+      return commitInfoHandlers.toArray(new CDOCommitInfoHandler[commitInfoHandlers.size()]);
+    }
+  }
+
+  /**
+   * @since 4.0
+   */
+  public void addCommitInfoHandler(CDOCommitInfoHandler handler)
+  {
+    synchronized (commitInfoHandlers)
+    {
+      if (!commitInfoHandlers.contains(handler))
+      {
+        commitInfoHandlers.add(handler);
+      }
+    }
+  }
+
+  /**
+   * @since 4.0
+   */
+  public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
+  {
+    synchronized (commitInfoHandlers)
+    {
+      commitInfoHandlers.remove(handler);
+    }
+  }
+
+  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
+  {
+    sessionManager.sendCommitNotification(sender, commitInfo);
+
+    for (CDOCommitInfoHandler handler : getCommitInfoHandlers())
+    {
+      try
+      {
+        handler.handleCommitInfo(commitInfo);
+      }
+      catch (Exception ex)
+      {
+        OM.LOG.error(ex);
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public IQueryHandlerProvider getQueryHandlerProvider()
+  {
+    return queryHandlerProvider;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
+  {
+    this.queryHandlerProvider = queryHandlerProvider;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
+  {
+    String language = info.getQueryLanguage();
+    if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
+    {
+      return new ResourcesQueryHandler();
+    }
+
+    if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
+    {
+      return new XRefsQueryHandler();
+    }
+
+    IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
+    if (storeAccessor != null)
+    {
+      IQueryHandler handler = storeAccessor.getQueryHandler(info);
+      if (handler != null)
+      {
+        return handler;
+      }
+    }
+
+    if (queryHandlerProvider == null)
+    {
+      queryHandlerProvider = new ContainerQueryHandlerProvider(IPluginContainer.INSTANCE);
+    }
+
+    IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
+    if (handler != null)
+    {
+      return handler;
+    }
+
+    return null;
+  }
+
+  public Object[] getElements()
+  {
+    final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager,
+        commitManager, commitInfoManager, getLockingManager(), store };
+    return elements;
+  }
+
+  @Override
+  public boolean isEmpty()
+  {
+    return false;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public long getCreationTime()
+  {
+    return store.getCreationTime();
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+  {
+    long creationTimeStamp = getCreationTime();
+    if (timeStamp < creationTimeStamp)
+    {
+      throw new IllegalArgumentException(
+          MessageFormat
+              .format(
+                  "timeStamp ({0}) < repository creation time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp))); //$NON-NLS-1$
+    }
+
+    long currentTimeStamp = getTimeStamp();
+    if (timeStamp > currentTimeStamp)
+    {
+      throw new IllegalArgumentException(
+          MessageFormat
+              .format(
+                  "timeStamp ({0}) > current time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp))); //$NON-NLS-1$
+    }
+  }
+
+  public long getTimeStamp()
+  {
+    return System.currentTimeMillis();
+  }
+
+  public Set<Handler> getHandlers()
+  {
+    Set<Handler> handlers = new HashSet<Handler>();
+
+    synchronized (readAccessHandlers)
+    {
+      handlers.addAll(readAccessHandlers);
+    }
+
+    synchronized (writeAccessHandlers)
+    {
+      handlers.addAll(writeAccessHandlers);
+    }
+
+    return handlers;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void addHandler(Handler handler)
+  {
+    if (handler instanceof ReadAccessHandler)
+    {
+      synchronized (readAccessHandlers)
+      {
+        if (!readAccessHandlers.contains(handler))
+        {
+          readAccessHandlers.add((ReadAccessHandler)handler);
+        }
+      }
+    }
+
+    if (handler instanceof WriteAccessHandler)
+    {
+      synchronized (writeAccessHandlers)
+      {
+        if (!writeAccessHandlers.contains(handler))
+        {
+          writeAccessHandlers.add((WriteAccessHandler)handler);
+        }
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void removeHandler(Handler handler)
+  {
+    if (handler instanceof ReadAccessHandler)
+    {
+      synchronized (readAccessHandlers)
+      {
+        readAccessHandlers.remove(handler);
+      }
+    }
+
+    if (handler instanceof WriteAccessHandler)
+    {
+      synchronized (writeAccessHandlers)
+      {
+        writeAccessHandlers.remove(handler);
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+      List<CDORevision> additionalRevisions)
+  {
+    ReadAccessHandler[] handlers;
+    synchronized (readAccessHandlers)
+    {
+      int size = readAccessHandlers.size();
+      if (size == 0)
+      {
+        return;
+      }
+
+      handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
+    }
+
+    for (ReadAccessHandler handler : handlers)
+    {
+      // Do *not* protect against unchecked exceptions from handlers!
+      handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
+    }
+  }
+
+  public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
+      boolean beforeCommit, OMMonitor monitor)
+  {
+    WriteAccessHandler[] handlers;
+    synchronized (writeAccessHandlers)
+    {
+      int size = writeAccessHandlers.size();
+      if (size == 0)
+      {
+        return;
+      }
+
+      handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
+    }
+
+    try
+    {
+      monitor.begin(handlers.length);
+      for (WriteAccessHandler handler : handlers)
+      {
+        try
+        {
+          if (beforeCommit)
+          {
+            handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
+          }
+          else
+          {
+            handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
+          }
+        }
+        catch (RuntimeException ex)
+        {
+          if (!beforeCommit)
+          {
+            OM.LOG.error(ex);
+          }
+          else
+          {
+            // Do *not* protect against unchecked exceptions from handlers on before case!
+            throw ex;
+          }
+        }
+      }
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+
+  public void setInitialPackages(EPackage... initialPackages)
+  {
+    checkInactive();
+    this.initialPackages = initialPackages;
+  }
+
+  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+      throws IOException
+  {
+    final int fromBranchID = lastReplicatedBranchID + 1;
+    final int toBranchID = getStore().getLastBranchID();
+
+    final long fromCommitTime = lastReplicatedCommitTime + 1L;
+    final long toCommitTime = getStore().getLastCommitTime();
+
+    out.writeInt(toBranchID);
+    out.writeLong(toCommitTime);
+
+    IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
+    accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
+
+    return new CDOReplicationInfo()
+    {
+      public int getLastReplicatedBranchID()
+      {
+        return toBranchID;
+      }
+
+      public long getLastReplicatedCommitTime()
+      {
+        return toCommitTime;
+      }
+
+      public String[] getLockAreaIDs()
+      {
+        return null; // TODO (CD) Raw replication of lockAreas
+      }
+    };
+  }
+
+  public void replicate(CDOReplicationContext context)
+  {
+    int startID = context.getLastReplicatedBranchID() + 1;
+    branchManager.getBranches(startID, 0, context);
+
+    long startTime = context.getLastReplicatedCommitTime();
+    commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
+
+    getLockingManager().getLockAreas(null, context);
+  }
+
+  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
+  {
+    CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);
+
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);
+
+    return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
+  }
+
+  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
+  {
+    CDOBranchPoint target = targetInfo.getBranchPoint();
+    CDOBranchPoint source = sourceInfo.getBranchPoint();
+
+    monitor.begin(5);
+
+    try
+    {
+      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+      Set<CDOID> ids = new HashSet<CDOID>();
+
+      if (targetBaseInfo == null && sourceBaseInfo == null)
+      {
+        if (CDOBranchUtil.isContainedBy(source, target))
+        {
+          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
+        }
+        else if (CDOBranchUtil.isContainedBy(target, source))
+        {
+          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
+        }
+        else
+        {
+          CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
+          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
+          ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
+        }
+      }
+      else
+      {
+        CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
+
+        ids.addAll(accessor.readChangeSet(monitor.fork(),
+            CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target)));
+
+        ids.addAll(accessor.readChangeSet(monitor.fork(),
+            CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source)));
+      }
+
+      loadMergeData(ids, targetInfo, monitor.fork());
+      loadMergeData(ids, sourceInfo, monitor.fork());
+
+      if (targetBaseInfo != null)
+      {
+        loadMergeData(ids, targetBaseInfo, monitor.fork());
+      }
+
+      if (sourceBaseInfo != null)
+      {
+        loadMergeData(ids, sourceBaseInfo, monitor.fork());
+      }
+
+      return ids;
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+
+  private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
+  {
+    int size = ids.size();
+    monitor.begin(size);
+
+    try
+    {
+      CDOBranchPoint branchPoint = info.getBranchPoint();
+      for (CDOID id : ids)
+      {
+        if (info.containsRevision(id))
+        {
+          info.removeRevision(id);
+        }
+        else
+        {
+          InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
+          if (revision != null)
+          {
+            info.addRevision(revision);
+          }
+          else
+          {
+            info.removeRevision(id);
+          }
+        }
+
+        monitor.worked();
+      }
+    }
+    finally
+    {
+      monitor.done();
+    }
+  }
+
+  private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
+  {
+    InternalCDORevision revision = revisionManager.getRevision(id, branchPoint, CDORevision.UNCHUNKED,
+        CDORevision.DEPTH_NONE, true);
+    // if (revision == null || !ObjectUtil.equals(revision.getBranch(), branchPoint.getBranch()))
+    // {
+    // return null;
+    // }
+
+    return revision;
+  }
+
+  public void queryLobs(List<byte[]> ids)
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    accessor.queryLobs(ids);
+  }
+
+  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    accessor.handleLobs(fromTime, toTime, handler);
+  }
+
+  public void loadLob(byte[] id, OutputStream out) throws IOException
+  {
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    accessor.loadLob(id, out);
+  }
+
+  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+      final CDORevisionHandler handler)
+  {
+    CDORevisionHandler wrapper = handler;
+    if (!exactBranch && !branch.isMainBranch())
+    {
+      if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+      {
+        throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
+      }
+
+      wrapper = new CDORevisionHandler()
+      {
+        private Set<CDOID> handled = new HashSet<CDOID>();
+
+        public boolean handleRevision(CDORevision revision)
+        {
+          CDOID id = revision.getID();
+          if (handled.add(id))
+          {
+            return handler.handleRevision(revision);
+          }
+
+          return true;
+        }
+      };
+    }
+
+    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+    while (branch != null)
+    {
+      accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
+      if (exactBranch)
+      {
+        break;
+      }
+
+      CDOBranchPoint base = branch.getBase();
+      branch = base.getBranch();
+      timeStamp = base.getTimeStamp();
+    }
+  }
+
+  public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
+      boolean isSupportingBranches)
+  {
+    List<Object> lockables = new ArrayList<Object>();
+    for (CDORevisionKey revKey : revisionKeys)
+    {
+      CDOID id = revKey.getID();
+      if (isSupportingBranches)
+      {
+        lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
+      }
+      else
+      {
+        lockables.add(id);
+      }
+    }
+    return lockables;
+  }
+
+  public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, boolean recursive,
+      long timeout)
+  {
+    List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
+    return lock(view, lockType, lockables, revKeys, recursive, timeout);
+  }
+
+  protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
+      List<CDORevisionKey> loadedRevs, boolean recursive, long timeout)
+  {
+    List<LockState<Object, IView>> newLockStates = null;
+    try
+    {
+      newLockStates = getLockingManager().lock2(true, type, view, lockables, recursive, timeout);
+    }
+    catch (TimeoutRuntimeException ex)
+    {
+      return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
+    }
+    catch (InterruptedException ex)
+    {
+      throw WrappedException.wrap(ex);
+    }
+
+    long[] requiredTimestamp = { 0L };
+    CDORevisionKey[] staleRevisionsArray = null;
+
+    try
+    {
+      staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
+    }
+    catch (IllegalArgumentException e)
+    {
+      getLockingManager().unlock2(true, type, view, lockables, recursive);
+      throw e;
+    }
+
+    // If some of the clients' revisions are stale and it has passiveUpdates disabled,
+    // then the locks are useless so we release them and report the stale revisions
+    //
+    InternalSession session = view.getSession();
+    boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
+    if (staleNoUpdate)
+    {
+      getLockingManager().unlock2(true, type, view, lockables, recursive);
+      return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
+          getTimeStamp());
+    }
+
+    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+    sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
+
+    boolean waitForUpdate = staleRevisionsArray.length > 0;
+    return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
+        getTimeStamp());
+  }
+
+  private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
+      List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
+  {
+    List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
+    if (revisionKeys != null)
+    {
+      InternalCDORevisionManager revManager = getRevisionManager();
+      CDOBranch viewedBranch = view.getBranch();
+      for (CDORevisionKey revKey : revisionKeys)
+      {
+        CDOID id = revKey.getID();
+        InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), CDORevision.UNCHUNKED,
+            CDORevision.DEPTH_NONE, true);
+
+        if (rev == null)
+        {
+          throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
+              viewedBranch));
+        }
+
+        if (!revKey.equals(rev))
+        {
+          staleRevisions.add(revKey);
+          requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
+        }
+      }
+    }
+
+    // Convert the list to an array, to satisfy the API later
+    //
+    CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
+    staleRevisions.toArray(staleRevisionsArray);
+
+    return staleRevisionsArray;
+  }
+
+  private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
+  {
+    long timestamp = getTimeStamp();
+    CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
+        lockType, cdoLockStates);
+    getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
+  }
+
+  // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
+  public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
+  {
+    CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
+    int i = 0;
+
+    for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
+    {
+      CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
+      cdoLockStates[i++] = cdoLockState;
+    }
+
+    return cdoLockStates;
+  }
+
+  public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs, boolean recursive)
+  {
+    List<Object> unlockables = null;
+    if (objectIDs != null)
+    {
+      unlockables = new ArrayList<Object>(objectIDs.size());
+      CDOBranch branch = view.getBranch();
+      for (CDOID id : objectIDs)
+      {
+        Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
+        unlockables.add(key);
+      }
+    }
+
+    return doUnlock(view, lockType, unlockables, recursive);
+  }
+
+  protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables,
+      boolean recursive)
+  {
+    List<LockState<Object, IView>> newLockStates = null;
+    if (lockType == null) // Signals an unlock-all operation
+    {
+      newLockStates = getLockingManager().unlock2(true, view);
+    }
+    else
+    {
+      newLockStates = getLockingManager().unlock2(true, lockType, view, unlockables, recursive);
+    }
+
+    long timestamp = getTimeStamp();
+    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+    sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
+
+    return new UnlockObjectsResult(cdoLockStates, timestamp);
+  }
+
+  @Override
+  public String toString()
+  {
+    return MessageFormat.format("Repository[{0}]", name); //$NON-NLS-1$
+  }
+
+  public boolean isSkipInitialization()
+  {
+    return skipInitialization;
+  }
+
+  public void setSkipInitialization(boolean skipInitialization)
+  {
+    this.skipInitialization = skipInitialization;
+  }
+
+  protected void initProperties()
+  {
+    String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
+    if (valueAudits != null)
+    {
+      supportingAudits = Boolean.valueOf(valueAudits);
+    }
+    else
+    {
+      supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
+    }
+
+    String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
+    if (valueBranches != null)
+    {
+      supportingBranches = Boolean.valueOf(valueBranches);
+    }
+    else
+    {
+      supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
+    }
+
+    String valueEcore = properties.get(Props.SUPPORTING_ECORE);
+    if (valueEcore != null)
+    {
+      supportingEcore = Boolean.valueOf(valueEcore);
+    }
+
+    String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
+    if (valueIntegrity != null)
+    {
+      ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
+    }
+
+    String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
+    if (valueIDLocation != null)
+    {
+      idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
+    }
+
+    if (idGenerationLocation == null)
+    {
+      idGenerationLocation = IDGenerationLocation.STORE;
+    }
+  }
+
+  public void initSystemPackages()
+  {
+    IStoreAccessor writer = store.getWriter(null);
+    StoreThreadLocal.setAccessor(writer);
+
+    try
+    {
+      List<InternalCDOPackageUnit> units = new ArrayList<InternalCDOPackageUnit>();
+      units.add(initSystemPackage(EcorePackage.eINSTANCE));
+      units.add(initSystemPackage(EresourcePackage.eINSTANCE));
+      units.add(initSystemPackage(EtypesPackage.eINSTANCE));
+
+      if (initialPackages != null)
+      {
+        for (EPackage initialPackage : initialPackages)
+        {
+          if (!packageRegistry.containsKey(initialPackage.getNsURI()))
+          {
+            units.add(initSystemPackage(initialPackage));
+          }
+        }
+      }
+
+      InternalCDOPackageUnit[] systemUnits = units.toArray(new InternalCDOPackageUnit[units.size()]);
+      writer.writePackageUnits(systemUnits, new Monitor());
+      writer.commit(new Monitor());
+    }
+    finally
+    {
+      StoreThreadLocal.release();
+    }
+  }
+
+  protected InternalCDOPackageUnit initSystemPackage(EPackage ePackage)
+  {
+    EMFUtil.registerPackage(ePackage, packageRegistry);
+    InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);
+
+    InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
+    packageUnit.setTimeStamp(store.getCreationTime());
+    packageUnit.setState(CDOPackageUnit.State.LOADED);
+    return packageUnit;
+  }
+
+  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
+  {
+    branchManager.initMainBranch(false, timeStamp);
+  }
+
+  protected void initRootResource()
+  {
+    CDOBranchPoint head = branchManager.getMainBranch().getHead();
+
+    CDORevisionFactory factory = getRevisionManager().getFactory();
+    InternalCDORevision rootResource = (InternalCDORevision)factory
+        .createRevision(EresourcePackage.Literals.CDO_RESOURCE);
+
+    rootResource.setBranchPoint(head);
+    rootResource.setContainerID(CDOID.NULL);
+    rootResource.setContainingFeatureID(0);
+
+    CDOID id = createRootResourceID();
+    rootResource.setID(id);
+    rootResource.setResourceID(id);
+
+    InternalSession session = getSessionManager().openSession(null);
+    InternalTransaction transaction = session.openTransaction(1, head);
+    InternalCommitContext commitContext = new TransactionCommitContext(transaction)
+    {
+      @Override
+      protected long[] createTimeStamp(OMMonitor monitor)
+      {
+        InternalRepository repository = getTransaction().getSession().getManager().getRepository();
+        return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
+      }
+
+      @Override
+      public String getUserID()
+      {
+        return SYSTEM_USER_ID;
+      }
+
+      @Override
+      public String getCommitComment()
+      {
+        return "<initialize>"; //$NON-NLS-1$
+      }
+    };
+
+    commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
+    commitContext.preWrite();
+
+    commitContext.write(new Monitor());
+    commitContext.commit(new Monitor());
+
+    String rollbackMessage = commitContext.getRollbackMessage();
+    if (rollbackMessage != null)
+    {
+      throw new TransactionException(rollbackMessage);
+    }
+
+    rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;
+
+    commitContext.postCommit(true);
+    session.close();
+  }
+
+  protected CDOID createRootResourceID()
+  {
+    if (getIDGenerationLocation() == IDGenerationLocation.STORE)
+    {
+      return CDOIDUtil.createTempObject(1);
+    }
+
+    return CDOIDGenerator.UUID.generateCDOID(null);
+  }
+
+  protected void readRootResource()
+  {
+    IStoreAccessor reader = store.getReader(null);
+    StoreThreadLocal.setAccessor(reader);
+
+    try
+    {
+      CDOBranchPoint head = branchManager.getMainBranch().getHead();
+      rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
+    }
+    finally
+    {
+      StoreThreadLocal.release();
+    }
+  }
+
+  protected void readPackageUnits()
+  {
+    IStoreAccessor reader = store.getReader(null);
+    StoreThreadLocal.setAccessor(reader);
+
+    try
+    {
+      Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
+      for (InternalCDOPackageUnit packageUnit : packageUnits)
+      {
+        packageRegistry.putPackageUnit(packageUnit);
+      }
+    }
+    finally
+    {
+      StoreThreadLocal.release();
+    }
+  }
+
+  @Override
+  protected void doBeforeActivate() throws Exception
+  {
+    super.doBeforeActivate();
+    checkState(store, "store"); //$NON-NLS-1$
+    checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
+    checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
+    checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
+    checkState(branchManager, "branchManager"); //$NON-NLS-1$
+    checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
+    checkState(queryManager, "queryManager"); //$NON-NLS-1$
+    checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
+    checkState(commitManager, "commitManager"); //$NON-NLS-1$
+    checkState(getLockingManager(), "lockingManager"); //$NON-NLS-1$
+
+    packageRegistry.setReplacingDescriptors(true);
+    packageRegistry.setPackageProcessor(this);
+    packageRegistry.setPackageLoader(this);
+
+    branchManager.setBranchLoader(this);
+    branchManager.setTimeProvider(this);
+
+    revisionManager.setRevisionLoader(this);
+    sessionManager.setRepository(this);
+    queryManager.setRepository(this);
+    commitInfoManager.setCommitInfoLoader(this);
+    commitManager.setRepository(this);
+    getLockingManager().setRepository(this);
+    store.setRepository(this);
+  }
+
+  @Override
+  protected void doActivate() throws Exception
+  {
+    super.doActivate();
+
+    initProperties();
+    if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
+    {
+      throw new IllegalStateException("Store can not handle client assigned IDs: " + store);
+    }
+
+    store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING
+        : IStore.RevisionTemporality.NONE);
+    store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING
+        : IStore.RevisionParallelism.NONE);
+    revisionManager.setSupportingAudits(supportingAudits);
+    revisionManager.setSupportingBranches(supportingBranches);
+
+    LifecycleUtil.activate(store);
+    LifecycleUtil.activate(packageRegistry);
+    LifecycleUtil.activate(sessionManager);
+    LifecycleUtil.activate(revisionManager);
+    LifecycleUtil.activate(branchManager);
+    LifecycleUtil.activate(queryManager);
+    LifecycleUtil.activate(commitInfoManager);
+    LifecycleUtil.activate(commitManager);
+    LifecycleUtil.activate(queryHandlerProvider);
+
+    if (!skipInitialization)
+    {
+      long lastCommitTimeStamp = Math.max(store.getCreationTime(), store.getLastCommitTime());
+      timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+      initMainBranch(branchManager, lastCommitTimeStamp);
+
+      if (store.isFirstStart())
+      {
+        initSystemPackages();
+        initRootResource();
+      }
+      else
+      {
+        readPackageUnits();
+        readRootResource();
+      }
+
+      // This check does not work for CDOWorkspace:
+      // if (CDOIDUtil.isNull(rootResourceID))
+      // {
+      // throw new IllegalStateException("Root resource ID is null");
+      // }
+    }
+
+    LifecycleUtil.activate(getLockingManager()); // Needs an initialized main branch / branch manager
+  }
+
+  @Override
+  protected void doDeactivate() throws Exception
+  {
+    LifecycleUtil.deactivate(getLockingManager());
+    LifecycleUtil.deactivate(queryHandlerProvider);
+    LifecycleUtil.deactivate(commitManager);
+    LifecycleUtil.deactivate(commitInfoManager);
+    LifecycleUtil.deactivate(queryManager);
+    LifecycleUtil.deactivate(revisionManager);
+    LifecycleUtil.deactivate(sessionManager);
+    LifecycleUtil.deactivate(store);
+    LifecycleUtil.deactivate(branchManager);
+    LifecycleUtil.deactivate(packageRegistry);
+    super.doDeactivate();
+  }
+
+  /**
+   * @author Eike Stepper
+   * @since 2.0
+   */
+  public static class Default extends Repository
+  {
+    public Default()
+    {
+    }
+
+    @Override
+    protected void doBeforeActivate() throws Exception
+    {
+      if (getPackageRegistry(false) == null)
+      {
+        setPackageRegistry(createPackageRegistry());
+      }
+
+      if (getSessionManager() == null)
+      {
+        setSessionManager(createSessionManager());
+      }
+
+      if (getBranchManager() == null)
+      {
+        setBranchManager(createBranchManager());
+      }
+
+      if (getRevisionManager() == null)
+      {
+        setRevisionManager(createRevisionManager());
+      }
+
+      if (getQueryManager() == null)
+      {
+        setQueryManager(createQueryManager());
+      }
+
+      if (getCommitInfoManager() == null)
+      {
+        setCommitInfoManager(createCommitInfoManager());
+      }
+
+      if (getCommitManager() == null)
+      {
+        setCommitManager(createCommitManager());
+      }
+
+      if (getLockManager() == null)
+      {
+        setLockingManager(createLockManager());
+      }
+
+      super.doBeforeActivate();
+    }
+
+    protected InternalCDOPackageRegistry createPackageRegistry()
+    {
+      return new CDOPackageRegistryImpl();
+    }
+
+    protected InternalSessionManager createSessionManager()
+    {
+      return new SessionManager();
+    }
+
+    protected InternalCDOBranchManager createBranchManager()
+    {
+      return CDOBranchUtil.createBranchManager();
+    }
+
+    protected InternalCDORevisionManager createRevisionManager()
+    {
+      return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
+    }
+
+    protected InternalQueryManager createQueryManager()
+    {
+      return new QueryManager();
+    }
+
+    protected InternalCDOCommitInfoManager createCommitInfoManager()
+    {
+      return CDOCommitInfoUtil.createCommitInfoManager();
+    }
+
+    protected InternalCommitManager createCommitManager()
+    {
+      return new CommitManager();
+    }
+
+    @Deprecated
+    protected InternalLockManager createLockManager()
+    {
+      return createLockingManager();
+    }
+
+    public LockingManager createLockingManager()
+    {
+      return new LockingManager();
+    }
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
index 2644eae..a7c41b8 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
@@ -26,7 +26,6 @@
 import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
 import org.eclipse.emf.cdo.common.lock.CDOLockState;
 import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
 import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
 import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
 import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
@@ -1038,13 +1037,7 @@
     }
 
     // Make sure all chunks are loaded
-    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(oldRevision.getEClass()))
-    {
-      if (feature.isMany())
-      {
-        repository.ensureChunk(oldRevision, feature, 0, oldRevision.getList(feature).size());
-      }
-    }
+    repository.ensureChunks(oldRevision);
 
     InternalCDORevision newRevision = oldRevision.copy();
     newRevision.adjustForCommit(branch, timeStamp);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
index 55ad08c..07bf2e1 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
@@ -1,319 +1,301 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Simon McDuff - bug 233490
- */
-package org.eclipse.emf.cdo.internal.server;
-
-import org.eclipse.emf.cdo.common.CDOCommonView;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalView;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.options.IOptionsContainer;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.text.MessageFormat;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class View extends Lifecycle implements InternalView, CDOCommonView.Options
-{
-  private InternalSession session;
-
-  private final int viewID;
-
-  private final int sessionID; // Needed here so we can compute the hashCode even after session becomes null due to
-                               // deactivation!
-
-  private CDOBranchPoint branchPoint;
-
-  private String durableLockingID;
-
-  private InternalRepository repository;
-
-  private Set<CDOID> changeSubscriptionIDs = new HashSet<CDOID>();
-
-  private boolean lockNotificationsEnabled;
-
-  /**
-   * @since 2.0
-   */
-  public View(InternalSession session, int viewID, CDOBranchPoint branchPoint)
-  {
-    this.session = session;
-    this.viewID = viewID;
-    sessionID = session.getSessionID();
-
-    repository = session.getManager().getRepository();
-    setBranchPoint(branchPoint);
-  }
-
-  public InternalSession getSession()
-  {
-    return session;
-  }
-
-  public int getSessionID()
-  {
-    return session.getSessionID();
-  }
-
-  public int getViewID()
-  {
-    return viewID;
-  }
-
-  public CDOBranch getBranch()
-  {
-    return branchPoint.getBranch();
-  }
-
-  public long getTimeStamp()
-  {
-    return branchPoint.getTimeStamp();
-  }
-
-  public boolean isReadOnly()
-  {
-    return true;
-  }
-
-  public boolean isDurableView()
-  {
-    return durableLockingID != null;
-  }
-
-  public String getDurableLockingID()
-  {
-    return durableLockingID;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public InternalRepository getRepository()
-  {
-    checkOpen();
-    return repository;
-  }
-
-  public InternalCDORevision getRevision(CDOID id)
-  {
-    CDORevisionManager revisionManager = repository.getRevisionManager();
-    return (InternalCDORevision)revisionManager.getRevision(id, this, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE,
-        true);
-  }
-
-  public void changeTarget(CDOBranchPoint branchPoint, List<CDOID> invalidObjects,
-      List<CDORevisionDelta> allChangedObjects, List<CDOID> allDetachedObjects)
-  {
-    List<CDORevision> oldRevisions = getRevisions(invalidObjects);
-    setBranchPoint(branchPoint);
-    List<CDORevision> newRevisions = getRevisions(invalidObjects);
-
-    Iterator<CDORevision> it = newRevisions.iterator();
-    for (CDORevision oldRevision : oldRevisions)
-    {
-      CDORevision newRevision = it.next();
-      if (newRevision == null)
-      {
-        allDetachedObjects.add(oldRevision.getID());
-      }
-      else if (newRevision != oldRevision)
-      {
-        // Fix for Bugzilla 369646: ensure that revisions are fully loaded
-        ensureRevisionChunks((InternalCDORevision)newRevision);
-        ensureRevisionChunks((InternalCDORevision)oldRevision);
-
-        CDORevisionDelta delta = newRevision.compare(oldRevision);
-        allChangedObjects.add(delta);
-      }
-    }
-  }
-
-  // TODO: Eike can this be put in the Repository class?
-  /**
-   * Make sure that all lists of the given revision are fully loaded.
-   */
-  private void ensureRevisionChunks(InternalCDORevision revision)
-  {
-    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
-    {
-      if (feature.isMany())
-      {
-        getRepository().ensureChunk(revision, feature, 0, revision.getList(feature).size());
-      }
-    }
-  }
-
-  private List<CDORevision> getRevisions(List<CDOID> ids)
-  {
-    return repository.getRevisionManager().getRevisions(ids, branchPoint, CDORevision.UNCHUNKED,
-        CDORevision.DEPTH_NONE, true);
-  }
-
-  public void setBranchPoint(CDOBranchPoint branchPoint)
-  {
-    checkOpen();
-    long timeStamp = branchPoint.getTimeStamp();
-    branchPoint = branchPoint.getBranch().getPoint(timeStamp);
-    validateTimeStamp(timeStamp);
-    this.branchPoint = branchPoint;
-  }
-
-  protected void validateTimeStamp(long timeStamp) throws IllegalArgumentException
-  {
-    if (timeStamp != UNSPECIFIED_DATE)
-    {
-      repository.validateTimeStamp(timeStamp);
-    }
-  }
-
-  public void setDurableLockingID(String durableLockingID)
-  {
-    this.durableLockingID = durableLockingID;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public synchronized void subscribe(CDOID id)
-  {
-    checkOpen();
-    changeSubscriptionIDs.add(id);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public synchronized void unsubscribe(CDOID id)
-  {
-    checkOpen();
-    changeSubscriptionIDs.remove(id);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public synchronized boolean hasSubscription(CDOID id)
-  {
-    checkOpen();
-    return changeSubscriptionIDs.contains(id);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public synchronized void clearChangeSubscription()
-  {
-    checkOpen();
-    changeSubscriptionIDs.clear();
-  }
-
-  @Override
-  public int hashCode()
-  {
-    return ObjectUtil.hashCode(sessionID, viewID);
-  }
-
-  @Override
-  public String toString()
-  {
-    int sessionID = session == null ? 0 : session.getSessionID();
-    return MessageFormat.format("{0}[{1}:{2}]", getClassName(), sessionID, viewID); //$NON-NLS-1$
-  }
-
-  protected String getClassName()
-  {
-    return "View"; //$NON-NLS-1$
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void close()
-  {
-    deactivate();
-  }
-
-  @Override
-  protected void doDeactivate() throws Exception
-  {
-    if (!isClosed())
-    {
-      session.viewClosed(this);
-    }
-
-    super.doDeactivate();
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void doClose()
-  {
-    clearChangeSubscription();
-    changeSubscriptionIDs = null;
-    session = null;
-    repository = null;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public boolean isClosed()
-  {
-    return repository == null;
-  }
-
-  private void checkOpen()
-  {
-    if (isClosed())
-    {
-      throw new IllegalStateException("View closed"); //$NON-NLS-1$
-    }
-  }
-
-  public IOptionsContainer getContainer()
-  {
-    return this;
-  }
-
-  public Options options()
-  {
-    return this;
-  }
-
-  public boolean isLockNotificationEnabled()
-  {
-    return lockNotificationsEnabled;
-  }
-
-  public void setLockNotificationEnabled(boolean enable)
-  {
-    lockNotificationsEnabled = enable;
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Simon McDuff - bug 233490
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.options.IOptionsContainer;
+
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public class View extends Lifecycle implements InternalView, CDOCommonView.Options
+{
+  private InternalSession session;
+
+  private final int viewID;
+
+  private final int sessionID; // Needed here so we can compute the hashCode even after session becomes null due to
+                               // deactivation!
+
+  private CDOBranchPoint branchPoint;
+
+  private String durableLockingID;
+
+  private InternalRepository repository;
+
+  private Set<CDOID> changeSubscriptionIDs = new HashSet<CDOID>();
+
+  private boolean lockNotificationsEnabled;
+
+  /**
+   * @since 2.0
+   */
+  public View(InternalSession session, int viewID, CDOBranchPoint branchPoint)
+  {
+    this.session = session;
+    this.viewID = viewID;
+    sessionID = session.getSessionID();
+
+    repository = session.getManager().getRepository();
+    setBranchPoint(branchPoint);
+  }
+
+  public InternalSession getSession()
+  {
+    return session;
+  }
+
+  public int getSessionID()
+  {
+    return session.getSessionID();
+  }
+
+  public int getViewID()
+  {
+    return viewID;
+  }
+
+  public CDOBranch getBranch()
+  {
+    return branchPoint.getBranch();
+  }
+
+  public long getTimeStamp()
+  {
+    return branchPoint.getTimeStamp();
+  }
+
+  public boolean isReadOnly()
+  {
+    return true;
+  }
+
+  public boolean isDurableView()
+  {
+    return durableLockingID != null;
+  }
+
+  public String getDurableLockingID()
+  {
+    return durableLockingID;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public InternalRepository getRepository()
+  {
+    checkOpen();
+    return repository;
+  }
+
+  public InternalCDORevision getRevision(CDOID id)
+  {
+    CDORevisionManager revisionManager = repository.getRevisionManager();
+    return (InternalCDORevision)revisionManager.getRevision(id, this, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE,
+        true);
+  }
+
+  public void changeTarget(CDOBranchPoint branchPoint, List<CDOID> invalidObjects,
+      List<CDORevisionDelta> allChangedObjects, List<CDOID> allDetachedObjects)
+  {
+    List<CDORevision> oldRevisions = getRevisions(invalidObjects);
+    setBranchPoint(branchPoint);
+    List<CDORevision> newRevisions = getRevisions(invalidObjects);
+
+    Iterator<CDORevision> it = newRevisions.iterator();
+    for (CDORevision oldRevision : oldRevisions)
+    {
+      CDORevision newRevision = it.next();
+      if (newRevision == null)
+      {
+        allDetachedObjects.add(oldRevision.getID());
+      }
+      else if (newRevision != oldRevision)
+      {
+        // Fix for Bugzilla 369646: ensure that revisions are fully loaded
+        repository.ensureChunks((InternalCDORevision)newRevision);
+        repository.ensureChunks((InternalCDORevision)oldRevision);
+
+        CDORevisionDelta delta = newRevision.compare(oldRevision);
+        allChangedObjects.add(delta);
+      }
+    }
+  }
+
+  private List<CDORevision> getRevisions(List<CDOID> ids)
+  {
+    return repository.getRevisionManager().getRevisions(ids, branchPoint, CDORevision.UNCHUNKED,
+        CDORevision.DEPTH_NONE, true);
+  }
+
+  public void setBranchPoint(CDOBranchPoint branchPoint)
+  {
+    checkOpen();
+    long timeStamp = branchPoint.getTimeStamp();
+    branchPoint = branchPoint.getBranch().getPoint(timeStamp);
+    validateTimeStamp(timeStamp);
+    this.branchPoint = branchPoint;
+  }
+
+  protected void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+  {
+    if (timeStamp != UNSPECIFIED_DATE)
+    {
+      repository.validateTimeStamp(timeStamp);
+    }
+  }
+
+  public void setDurableLockingID(String durableLockingID)
+  {
+    this.durableLockingID = durableLockingID;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public synchronized void subscribe(CDOID id)
+  {
+    checkOpen();
+    changeSubscriptionIDs.add(id);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public synchronized void unsubscribe(CDOID id)
+  {
+    checkOpen();
+    changeSubscriptionIDs.remove(id);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public synchronized boolean hasSubscription(CDOID id)
+  {
+    checkOpen();
+    return changeSubscriptionIDs.contains(id);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public synchronized void clearChangeSubscription()
+  {
+    checkOpen();
+    changeSubscriptionIDs.clear();
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return ObjectUtil.hashCode(sessionID, viewID);
+  }
+
+  @Override
+  public String toString()
+  {
+    int sessionID = session == null ? 0 : session.getSessionID();
+    return MessageFormat.format("{0}[{1}:{2}]", getClassName(), sessionID, viewID); //$NON-NLS-1$
+  }
+
+  protected String getClassName()
+  {
+    return "View"; //$NON-NLS-1$
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void close()
+  {
+    deactivate();
+  }
+
+  @Override
+  protected void doDeactivate() throws Exception
+  {
+    if (!isClosed())
+    {
+      session.viewClosed(this);
+    }
+
+    super.doDeactivate();
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void doClose()
+  {
+    clearChangeSubscription();
+    changeSubscriptionIDs = null;
+    session = null;
+    repository = null;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public boolean isClosed()
+  {
+    return repository == null;
+  }
+
+  private void checkOpen()
+  {
+    if (isClosed())
+    {
+      throw new IllegalStateException("View closed"); //$NON-NLS-1$
+    }
+  }
+
+  public IOptionsContainer getContainer()
+  {
+    return this;
+  }
+
+  public Options options()
+  {
+    return this;
+  }
+
+  public boolean isLockNotificationEnabled()
+  {
+    return lockNotificationsEnabled;
+  }
+
+  public void setLockNotificationEnabled(boolean enable)
+  {
+    lockNotificationsEnabled = enable;
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
index 562881a..a3c6524 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
@@ -1,240 +1,245 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.spi.server;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager.CommitInfoLoader;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageProcessor;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager.RevisionLoader;
-
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Semaphore;
-
-/**
- * @author Eike Stepper
- * @since 3.0
- * @noextend This interface is not intended to be extended by clients.
- * @noimplement This interface is not intended to be implemented by clients.
- */
-public interface InternalRepository extends IRepository, PackageProcessor, PackageLoader, BranchLoader, RevisionLoader,
-    CommitInfoLoader
-{
-  public void setName(String name);
-
-  public void setType(Type type);
-
-  public void setState(State state);
-
-  public InternalStore getStore();
-
-  public void setStore(InternalStore store);
-
-  public void setProperties(Map<String, String> properties);
-
-  public InternalCDOBranchManager getBranchManager();
-
-  public void setBranchManager(InternalCDOBranchManager branchManager);
-
-  /**
-   * @since 4.1
-   */
-  public Semaphore getPackageRegistryCommitLock();
-
-  /**
-   * Same as calling {@link #getPackageRegistry(boolean) getPackageRegistry(true)}.
-   */
-  public InternalCDOPackageRegistry getPackageRegistry();
-
-  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext);
-
-  public InternalCDORevisionManager getRevisionManager();
-
-  public void setRevisionManager(InternalCDORevisionManager revisionManager);
-
-  public InternalCDOCommitInfoManager getCommitInfoManager();
-
-  public InternalSessionManager getSessionManager();
-
-  public void setSessionManager(InternalSessionManager sessionManager);
-
-  /**
-   * @deprecated As of 4.1 use {@link #getLockingManager()}.
-   */
-  @Deprecated
-  public InternalLockManager getLockManager();
-
-  /**
-   * @since 4.1
-   */
-  public InternalLockManager getLockingManager();
-
-  public InternalQueryManager getQueryManager();
-
-  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider);
-
-  public InternalCommitManager getCommitManager();
-
-  public InternalCommitContext createCommitContext(InternalTransaction transaction);
-
-  /**
-   * Returns a commit time stamp that is guaranteed to be unique in this repository. At index 1 of the returned
-   * <code>long</code> array is the previous commit time.
-   * 
-   * @since 4.0
-   */
-  public long[] createCommitTimeStamp(OMMonitor monitor);
-
-  /**
-   * Like {@link #createCommitTimeStamp(OMMonitor)}, but forces the repository to use the timestamp value passed in as
-   * the argument. This should be called only to force the timestamp of the first commit of a new repository to be equal
-   * to its creation time.
-   * 
-   * @since 4.0
-   */
-  public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor);
-
-  /**
-   * Notifies the repository of the completion of a commit. The value passed in must be a value obtained earlier through
-   * {@link #createCommitTimeStamp(OMMonitor)}
-   * 
-   * @since 4.0
-   */
-  public void endCommit(long timeStamp);
-
-  /**
-   * Notifies the repository of the failure of a commit. The value passed in must be a value obtained earlier through
-   * {@link #createCommitTimeStamp(OMMonitor)}
-   * 
-   * @since 4.0
-   */
-  public void failCommit(long timeStamp);
-
-  /**
-   * @since 4.0
-   */
-  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo);
-
-  public void setRootResourceID(CDOID rootResourceID);
-
-  /**
-   * @since 4.0
-   */
-  public void setLastCommitTimeStamp(long commitTimeStamp);
-
-  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
-      int chunkEnd);
-
-  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
-      List<CDORevision> additionalRevisions);
-
-  public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
-      boolean beforeCommit, OMMonitor monitor);
-
-  public void replicate(CDOReplicationContext context);
-
-  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
-      throws IOException;
-
-  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint);
-
-  /**
-   * @since 4.0
-   */
-  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
-      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor);
-
-  /**
-   * @since 4.0
-   */
-  public void queryLobs(List<byte[]> ids);
-
-  /**
-   * @since 4.0
-   */
-  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException;
-
-  /**
-   * @since 4.0
-   */
-  public void loadLob(byte[] id, OutputStream out) throws IOException;
-
-  /**
-   * @since 4.0
-   */
-  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
-      CDORevisionHandler handler);
-
-  /**
-   * @since 4.0
-   */
-  public boolean isSkipInitialization();
-
-  /**
-   * @since 4.0
-   */
-  public void setSkipInitialization(boolean skipInitialization);
-
-  /**
-   * @since 4.0
-   */
-  public void initSystemPackages();
-
-  /**
-   * @since 4.0
-   */
-  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp);
-
-  /**
-   * @since 4.1
-   */
-  public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
-      long timeout);
-
-  /**
-   * @since 4.1
-   */
-  public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive);
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager.CommitInfoLoader;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageProcessor;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager.RevisionLoader;
+
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface InternalRepository extends IRepository, PackageProcessor, PackageLoader, BranchLoader, RevisionLoader,
+    CommitInfoLoader
+{
+  public void setName(String name);
+
+  public void setType(Type type);
+
+  public void setState(State state);
+
+  public InternalStore getStore();
+
+  public void setStore(InternalStore store);
+
+  public void setProperties(Map<String, String> properties);
+
+  public InternalCDOBranchManager getBranchManager();
+
+  public void setBranchManager(InternalCDOBranchManager branchManager);
+
+  /**
+   * @since 4.1
+   */
+  public Semaphore getPackageRegistryCommitLock();
+
+  /**
+   * Same as calling {@link #getPackageRegistry(boolean) getPackageRegistry(true)}.
+   */
+  public InternalCDOPackageRegistry getPackageRegistry();
+
+  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext);
+
+  public InternalCDORevisionManager getRevisionManager();
+
+  public void setRevisionManager(InternalCDORevisionManager revisionManager);
+
+  public InternalCDOCommitInfoManager getCommitInfoManager();
+
+  public InternalSessionManager getSessionManager();
+
+  public void setSessionManager(InternalSessionManager sessionManager);
+
+  /**
+   * @deprecated As of 4.1 use {@link #getLockingManager()}.
+   */
+  @Deprecated
+  public InternalLockManager getLockManager();
+
+  /**
+   * @since 4.1
+   */
+  public InternalLockManager getLockingManager();
+
+  public InternalQueryManager getQueryManager();
+
+  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider);
+
+  public InternalCommitManager getCommitManager();
+
+  public InternalCommitContext createCommitContext(InternalTransaction transaction);
+
+  /**
+   * Returns a commit time stamp that is guaranteed to be unique in this repository. At index 1 of the returned
+   * <code>long</code> array is the previous commit time.
+   *
+   * @since 4.0
+   */
+  public long[] createCommitTimeStamp(OMMonitor monitor);
+
+  /**
+   * Like {@link #createCommitTimeStamp(OMMonitor)}, but forces the repository to use the timestamp value passed in as
+   * the argument. This should be called only to force the timestamp of the first commit of a new repository to be equal
+   * to its creation time.
+   *
+   * @since 4.0
+   */
+  public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor);
+
+  /**
+   * Notifies the repository of the completion of a commit. The value passed in must be a value obtained earlier through
+   * {@link #createCommitTimeStamp(OMMonitor)}
+   *
+   * @since 4.0
+   */
+  public void endCommit(long timeStamp);
+
+  /**
+   * Notifies the repository of the failure of a commit. The value passed in must be a value obtained earlier through
+   * {@link #createCommitTimeStamp(OMMonitor)}
+   *
+   * @since 4.0
+   */
+  public void failCommit(long timeStamp);
+
+  /**
+   * @since 4.0
+   */
+  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo);
+
+  public void setRootResourceID(CDOID rootResourceID);
+
+  /**
+   * @since 4.0
+   */
+  public void setLastCommitTimeStamp(long commitTimeStamp);
+
+  /**
+   * @since 4.1
+   */
+  public void ensureChunks(InternalCDORevision revision);
+
+  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+      int chunkEnd);
+
+  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+      List<CDORevision> additionalRevisions);
+
+  public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
+      boolean beforeCommit, OMMonitor monitor);
+
+  public void replicate(CDOReplicationContext context);
+
+  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+      throws IOException;
+
+  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint);
+
+  /**
+   * @since 4.0
+   */
+  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor);
+
+  /**
+   * @since 4.0
+   */
+  public void queryLobs(List<byte[]> ids);
+
+  /**
+   * @since 4.0
+   */
+  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException;
+
+  /**
+   * @since 4.0
+   */
+  public void loadLob(byte[] id, OutputStream out) throws IOException;
+
+  /**
+   * @since 4.0
+   */
+  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+      CDORevisionHandler handler);
+
+  /**
+   * @since 4.0
+   */
+  public boolean isSkipInitialization();
+
+  /**
+   * @since 4.0
+   */
+  public void setSkipInitialization(boolean skipInitialization);
+
+  /**
+   * @since 4.0
+   */
+  public void initSystemPackages();
+
+  /**
+   * @since 4.0
+   */
+  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp);
+
+  /**
+   * @since 4.1
+   */
+  public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
+      long timeout);
+
+  /**
+   * @since 4.1
+   */
+  public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive);
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
index 6693793..2fdbe2e 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingTest.java
@@ -1,366 +1,366 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- */
-package org.eclipse.emf.cdo.tests;
-
-import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.session.CDOSession;
-import org.eclipse.emf.cdo.tests.model1.Customer;
-import org.eclipse.emf.cdo.tests.model1.SalesOrder;
-import org.eclipse.emf.cdo.tests.model5.GenListOfInt;
-import org.eclipse.emf.cdo.tests.model5.Model5Factory;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.util.CommitException;
-import org.eclipse.emf.cdo.view.CDOView;
-
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EObject;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * @author Eike Stepper
- */
-public class ChunkingTest extends AbstractCDOTest
-{
-  public void testReadNative() throws Exception
-  {
-    {
-      CDOSession session = openSession();
-      CDOTransaction transaction = session.openTransaction();
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      Customer customer = getModel1Factory().createCustomer();
-      customer.setName("customer");
-      resource.getContents().add(customer);
-
-      for (int i = 0; i < 100; i++)
-      {
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        salesOrder.setCustomer(customer);
-        resource.getContents().add(salesOrder);
-      }
-
-      transaction.commit();
-    }
-
-    clearCache(getRepository().getRevisionManager());
-
-    // ************************************************************* //
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    CDOTransaction transaction = session.openTransaction();
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    Customer customer = (Customer)resource.getContents().get(0);
-    EList<SalesOrder> salesOrders = customer.getSalesOrders();
-    int i = 0;
-    for (Iterator<SalesOrder> it = salesOrders.iterator(); it.hasNext();)
-    {
-      msg(i++);
-      SalesOrder salesOrder = it.next();
-      msg(salesOrder);
-    }
-  }
-
-  public void testWriteNative() throws Exception
-  {
-    {
-      CDOSession session = openSession();
-      CDOTransaction transaction = session.openTransaction();
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      Customer customer = getModel1Factory().createCustomer();
-      customer.setName("customer");
-      resource.getContents().add(customer);
-
-      for (int i = 0; i < 100; i++)
-      {
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        salesOrder.setCustomer(customer);
-        resource.getContents().add(salesOrder);
-      }
-
-      transaction.commit();
-    }
-
-    clearCache(getRepository().getRevisionManager());
-
-    // ************************************************************* //
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    CDOTransaction transaction = session.openTransaction();
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    Customer customer = (Customer)resource.getContents().get(0);
-    EList<SalesOrder> salesOrders = customer.getSalesOrders();
-    for (int i = 50; i < 70; i++)
-    {
-      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-      salesOrder.setId(i + 1000);
-      resource.getContents().add(salesOrder);
-      salesOrders.set(i, salesOrder);
-    }
-
-    transaction.commit();
-  }
-
-  public void testChunkWithTemporaryObject() throws Exception
-  {
-    {
-      CDOSession session = openSession();
-      CDOTransaction transaction = session.openTransaction();
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      Customer customer = getModel1Factory().createCustomer();
-      customer.setName("customer");
-      resource.getContents().add(customer);
-
-      transaction.commit();
-    }
-
-    clearCache(getRepository().getRevisionManager());
-
-    // ************************************************************* //
-
-    CDOSession session = openSession();
-    CDOTransaction transaction = session.openTransaction();
-    transaction.options().setRevisionPrefetchingPolicy(CDOUtil.createRevisionPrefetchingPolicy(10));
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    Customer customer = getModel1Factory().createCustomer();
-    customer.setName("customer");
-    resource.getContents().add(customer);
-    for (EObject element : resource.getContents())
-    {
-      msg(element);
-    }
-
-    transaction.commit();
-  }
-
-  public void testReadAfterUpdateBeforeCommit() throws Exception
-  {
-    {
-      CDOSession session = openSession();
-      CDOTransaction transaction = session.openTransaction();
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      for (int i = 0; i < 100; i++)
-      {
-        msg("Creating salesOrder" + i);
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        resource.getContents().add(salesOrder);
-      }
-
-      transaction.commit();
-    }
-
-    clearCache(getRepository().getRevisionManager());
-    // ************************************************************* //
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    CDOTransaction transaction = session.openTransaction();
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    for (int i = 50; i < 70; i++)
-    {
-      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-      salesOrder.setId(i + 1000);
-      resource.getContents().add(i, salesOrder);
-    }
-
-    for (int i = 70; i < 120; i++)
-    {
-      SalesOrder saleOrders = (SalesOrder)resource.getContents().get(i);
-      assertEquals(i - 20, saleOrders.getId());
-    }
-
-    transaction.commit();
-  }
-
-  public void testReadAfterUpdateAfterCommit() throws Exception
-  {
-    {
-      CDOSession session = openSession();
-      CDOTransaction transaction = session.openTransaction();
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      for (int i = 0; i < 100; i++)
-      {
-        msg("Creating salesOrder" + i);
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        resource.getContents().add(salesOrder);
-      }
-
-      transaction.commit();
-    }
-
-    clearCache(getRepository().getRevisionManager());
-    // ************************************************************* //
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    msg("Creating resource");
-    CDOTransaction transaction = session.openTransaction();
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    for (int i = 50; i < 70; i++)
-    {
-      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-      salesOrder.setId(i + 1000);
-      resource.getContents().add(i, salesOrder);
-    }
-
-    transaction.commit();
-
-    for (int i = 70; i < 120; i++)
-    {
-      SalesOrder saleOrders = (SalesOrder)resource.getContents().get(i);
-      assertEquals(i - 20, saleOrders.getId());
-    }
-  }
-
-  private static final String RESOURCE_PATH = "/test";
-
-  public void testPartiallyLoadedAdd() throws CommitException
-  {
-    createInitialList();
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
-    CDOTransaction tx = session.openTransaction();
-    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
-
-    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
-    list.getElements().add(9);
-
-    tx.commit();
-    tx.close();
-    session.close();
-    clearCache(getRepository().getRevisionManager());
-
-    testListResult(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-  }
-
-  public void testPartiallyLoadedAddAtIndex() throws CommitException
-  {
-    createInitialList();
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
-    CDOTransaction tx = session.openTransaction();
-    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
-
-    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
-    list.getElements().add(5, 9);
-
-    tx.commit();
-    tx.close();
-    session.close();
-    clearCache(getRepository().getRevisionManager());
-
-    testListResult(0, 1, 2, 3, 4, 9, 5, 6, 7, 8);
-  }
-
-  public void testPartiallyLoadedSet() throws CommitException
-  {
-    createInitialList();
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
-    CDOTransaction tx = session.openTransaction();
-    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
-
-    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
-    list.getElements().set(5, 9);
-
-    tx.commit();
-    tx.close();
-    session.close();
-    clearCache(getRepository().getRevisionManager());
-
-    testListResult(0, 1, 2, 3, 4, 9, 6, 7, 8);
-  }
-
-  public void testPartiallyLoadedRemoveIndex() throws CommitException
-  {
-    createInitialList();
-
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
-    CDOTransaction tx = session.openTransaction();
-    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
-
-    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
-    list.getElements().remove(5);
-
-    tx.commit();
-    tx.close();
-    session.close();
-    clearCache(getRepository().getRevisionManager());
-
-    testListResult(0, 1, 2, 3, 4, 6, 7, 8);
-  }
-
-  private void createInitialList() throws CommitException
-  {
-    CDOSession session = openSession();
-    CDOTransaction tx = session.openTransaction();
-    CDOResource resource = tx.createResource(getResourcePath(RESOURCE_PATH));
-
-    GenListOfInt list = Model5Factory.eINSTANCE.createGenListOfInt();
-
-    list.getElements().addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8));
-
-    resource.getContents().add(list);
-
-    tx.commit();
-    tx.close();
-    session.close();
-
-    clearCache(getRepository().getRevisionManager());
-  }
-
-  private void testListResult(Integer... expected)
-  {
-    List<Integer> expectedList = Arrays.asList(expected);
-
-    CDOSession session = openSession();
-    CDOView view = session.openView();
-    CDOResource resource = view.getResource(getResourcePath(RESOURCE_PATH));
-
-    EList<Integer> actualList = ((GenListOfInt)resource.getContents().get(0)).getElements();
-
-    assertEquals("List sizes differ", expectedList.size(), actualList.size());
-
-    for (int index = 0; index < expectedList.size(); index++)
-    {
-      assertEquals("Entry at index " + index + " differs", expectedList.get(index), actualList.get(index));
-    }
-
-    view.close();
-    session.close();
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.tests.model1.Customer;
+import org.eclipse.emf.cdo.tests.model1.SalesOrder;
+import org.eclipse.emf.cdo.tests.model5.GenListOfInt;
+import org.eclipse.emf.cdo.tests.model5.Model5Factory;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.net4j.util.io.IOUtil;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public class ChunkingTest extends AbstractCDOTest
+{
+  public void testReadNative() throws Exception
+  {
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      Customer customer = getModel1Factory().createCustomer();
+      customer.setName("customer");
+      resource.getContents().add(customer);
+
+      for (int i = 0; i < 100; i++)
+      {
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        salesOrder.setCustomer(customer);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+      session.close();
+    }
+
+    clearCache(getRepository().getRevisionManager());
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    Customer customer = (Customer)resource.getContents().get(0);
+    EList<SalesOrder> salesOrders = customer.getSalesOrders();
+    int i = 0;
+    for (Iterator<SalesOrder> it = salesOrders.iterator(); it.hasNext();)
+    {
+      IOUtil.OUT().println(i++);
+      SalesOrder salesOrder = it.next();
+      IOUtil.OUT().println(salesOrder);
+    }
+  }
+
+  public void testWriteNative() throws Exception
+  {
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      Customer customer = getModel1Factory().createCustomer();
+      customer.setName("customer");
+      resource.getContents().add(customer);
+
+      for (int i = 0; i < 100; i++)
+      {
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        salesOrder.setCustomer(customer);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+      session.close();
+    }
+
+    clearCache(getRepository().getRevisionManager());
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    Customer customer = (Customer)resource.getContents().get(0);
+    EList<SalesOrder> salesOrders = customer.getSalesOrders();
+    for (int i = 50; i < 70; i++)
+    {
+      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+      salesOrder.setId(i + 1000);
+      resource.getContents().add(salesOrder);
+      salesOrders.set(i, salesOrder);
+    }
+
+    transaction.commit();
+  }
+
+  public void testChunkWithTemporaryObject() throws Exception
+  {
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      Customer customer = getModel1Factory().createCustomer();
+      customer.setName("customer");
+      resource.getContents().add(customer);
+
+      transaction.commit();
+    }
+
+    clearCache(getRepository().getRevisionManager());
+
+    // ************************************************************* //
+
+    CDOSession session = openSession();
+    CDOTransaction transaction = session.openTransaction();
+    transaction.options().setRevisionPrefetchingPolicy(CDOUtil.createRevisionPrefetchingPolicy(10));
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    Customer customer = getModel1Factory().createCustomer();
+    customer.setName("customer");
+    resource.getContents().add(customer);
+    for (EObject element : resource.getContents())
+    {
+      msg(element);
+    }
+
+    transaction.commit();
+  }
+
+  public void testReadAfterUpdateBeforeCommit() throws Exception
+  {
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      for (int i = 0; i < 100; i++)
+      {
+        msg("Creating salesOrder" + i);
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+    }
+
+    clearCache(getRepository().getRevisionManager());
+    // ************************************************************* //
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    for (int i = 50; i < 70; i++)
+    {
+      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+      salesOrder.setId(i + 1000);
+      resource.getContents().add(i, salesOrder);
+    }
+
+    for (int i = 70; i < 120; i++)
+    {
+      SalesOrder saleOrders = (SalesOrder)resource.getContents().get(i);
+      assertEquals(i - 20, saleOrders.getId());
+    }
+
+    transaction.commit();
+  }
+
+  public void testReadAfterUpdateAfterCommit() throws Exception
+  {
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      for (int i = 0; i < 100; i++)
+      {
+        msg("Creating salesOrder" + i);
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+    }
+
+    clearCache(getRepository().getRevisionManager());
+    // ************************************************************* //
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    msg("Creating resource");
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    for (int i = 50; i < 70; i++)
+    {
+      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+      salesOrder.setId(i + 1000);
+      resource.getContents().add(i, salesOrder);
+    }
+
+    transaction.commit();
+
+    for (int i = 70; i < 120; i++)
+    {
+      SalesOrder saleOrders = (SalesOrder)resource.getContents().get(i);
+      assertEquals(i - 20, saleOrders.getId());
+    }
+  }
+
+  private static final String RESOURCE_PATH = "/test";
+
+  public void testPartiallyLoadedAdd() throws CommitException
+  {
+    createInitialList();
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+    CDOTransaction tx = session.openTransaction();
+    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
+
+    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+    list.getElements().add(9);
+
+    tx.commit();
+    tx.close();
+    session.close();
+    clearCache(getRepository().getRevisionManager());
+
+    testListResult(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+  }
+
+  public void testPartiallyLoadedAddAtIndex() throws CommitException
+  {
+    createInitialList();
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+    CDOTransaction tx = session.openTransaction();
+    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
+
+    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+    list.getElements().add(5, 9);
+
+    tx.commit();
+    tx.close();
+    session.close();
+    clearCache(getRepository().getRevisionManager());
+
+    testListResult(0, 1, 2, 3, 4, 9, 5, 6, 7, 8);
+  }
+
+  public void testPartiallyLoadedSet() throws CommitException
+  {
+    createInitialList();
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+    CDOTransaction tx = session.openTransaction();
+    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
+
+    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+    list.getElements().set(5, 9);
+
+    tx.commit();
+    tx.close();
+    session.close();
+    clearCache(getRepository().getRevisionManager());
+
+    testListResult(0, 1, 2, 3, 4, 9, 6, 7, 8);
+  }
+
+  public void testPartiallyLoadedRemoveIndex() throws CommitException
+  {
+    createInitialList();
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(3, 1));
+    CDOTransaction tx = session.openTransaction();
+    CDOResource resource = tx.getResource(getResourcePath(RESOURCE_PATH));
+
+    GenListOfInt list = (GenListOfInt)resource.getContents().get(0);
+    list.getElements().remove(5);
+
+    tx.commit();
+    tx.close();
+    session.close();
+    clearCache(getRepository().getRevisionManager());
+
+    testListResult(0, 1, 2, 3, 4, 6, 7, 8);
+  }
+
+  private void createInitialList() throws CommitException
+  {
+    CDOSession session = openSession();
+    CDOTransaction tx = session.openTransaction();
+    CDOResource resource = tx.createResource(getResourcePath(RESOURCE_PATH));
+
+    GenListOfInt list = Model5Factory.eINSTANCE.createGenListOfInt();
+
+    list.getElements().addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8));
+
+    resource.getContents().add(list);
+
+    tx.commit();
+    tx.close();
+    session.close();
+
+    clearCache(getRepository().getRevisionManager());
+  }
+
+  private void testListResult(Integer... expected)
+  {
+    List<Integer> expectedList = Arrays.asList(expected);
+
+    CDOSession session = openSession();
+    CDOView view = session.openView();
+    CDOResource resource = view.getResource(getResourcePath(RESOURCE_PATH));
+
+    EList<Integer> actualList = ((GenListOfInt)resource.getContents().get(0)).getElements();
+
+    assertEquals("List sizes differ", expectedList.size(), actualList.size());
+
+    for (int index = 0; index < expectedList.size(); index++)
+    {
+      assertEquals("Entry at index " + index + " differs", expectedList.get(index), actualList.get(index));
+    }
+
+    view.close();
+    session.close();
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java
index cddd109..c7b0997 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ChunkingWithMEMTest.java
@@ -1,150 +1,129 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Simon McDuff - initial API and implementation
- *    Eike Stepper - maintenance
- */
-package org.eclipse.emf.cdo.tests;
-
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.session.CDOSession;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.tests.model1.Customer;
-import org.eclipse.emf.cdo.tests.model1.SalesOrder;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
-import org.eclipse.emf.cdo.util.CDOUtil;
-
-import org.eclipse.emf.common.util.EList;
-
-import java.util.Iterator;
-
-/**
- * @author Simon McDuff
- */
-public class ChunkingWithMEMTest extends AbstractCDOTest
-{
-  public void testReadNative() throws Exception
-  {
-    CDORevision revisionToRemove = null;
-
-    {
-      msg("Opening session");
-      CDOSession session = openSession();
-
-      msg("Attaching transaction");
-      CDOTransaction transaction = session.openTransaction();
-
-      msg("Creating resource");
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      msg("Creating customer");
-      Customer customer = getModel1Factory().createCustomer();
-      customer.setName("customer");
-      resource.getContents().add(customer);
-      revisionToRemove = CDOUtil.getCDOObject(customer).cdoRevision();
-      for (int i = 0; i < 100; i++)
-      {
-        msg("Creating salesOrder" + i);
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        salesOrder.setCustomer(customer);
-        resource.getContents().add(salesOrder);
-      }
-
-      msg("Committing");
-      transaction.commit();
-      session.close();
-    }
-
-    InternalCDORevisionManager revisionManager = getRepository().getRevisionManager();
-    revisionManager.getCache().removeRevision(revisionToRemove.getID(), revisionToRemove);
-
-    msg("Opening session");
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    msg("Attaching transaction");
-    CDOTransaction transaction = session.openTransaction();
-    msg("Loading resource");
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    Customer customer = (Customer)resource.getContents().get(0);
-    EList<SalesOrder> salesOrders = customer.getSalesOrders();
-    int i = 0;
-    for (Iterator<SalesOrder> it = salesOrders.iterator(); it.hasNext();)
-    {
-      msg(i++);
-      SalesOrder salesOrder = it.next();
-      msg(salesOrder);
-    }
-
-    session.close();
-  }
-
-  public void testWriteNative() throws Exception
-  {
-    CDORevision revisionToRemove = null;
-
-    {
-      msg("Opening session");
-      CDOSession session = openSession();
-
-      msg("Attaching transaction");
-      CDOTransaction transaction = session.openTransaction();
-
-      msg("Creating resource");
-      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
-
-      msg("Creating customer");
-      Customer customer = getModel1Factory().createCustomer();
-      customer.setName("customer");
-      resource.getContents().add(customer);
-
-      for (int i = 0; i < 100; i++)
-      {
-        msg("Creating salesOrder" + i);
-        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-        salesOrder.setId(i);
-        salesOrder.setCustomer(customer);
-        resource.getContents().add(salesOrder);
-      }
-
-      msg("Committing");
-      transaction.commit();
-      revisionToRemove = CDOUtil.getCDOObject(customer).cdoRevision();
-      session.close();
-    }
-
-    InternalCDORevisionManager revisionManager = getRepository().getRevisionManager();
-    revisionManager.getCache().removeRevision(revisionToRemove.getID(), revisionToRemove);
-
-    msg("Opening session");
-    CDOSession session = openSession();
-    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
-
-    msg("Attaching transaction");
-    CDOTransaction transaction = session.openTransaction();
-
-    msg("Loading resource");
-    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
-
-    Customer customer = (Customer)resource.getContents().get(0);
-    EList<SalesOrder> salesOrders = customer.getSalesOrders();
-    for (int i = 50; i < 70; i++)
-    {
-      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
-      salesOrder.setId(i + 1000);
-      resource.getContents().add(salesOrder);
-      salesOrders.set(i, salesOrder);
-    }
-
-    transaction.commit();
-    session.close();
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Simon McDuff - initial API and implementation
+ *    Eike Stepper - maintenance
+ */
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.tests.model1.Customer;
+import org.eclipse.emf.cdo.tests.model1.SalesOrder;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+
+import org.eclipse.net4j.util.io.IOUtil;
+
+import org.eclipse.emf.common.util.EList;
+
+import java.util.Iterator;
+
+/**
+ * @author Simon McDuff
+ */
+public class ChunkingWithMEMTest extends AbstractCDOTest
+{
+  public void testReadNative() throws Exception
+  {
+    CDORevision revisionToRemove = null;
+
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      Customer customer = getModel1Factory().createCustomer();
+      customer.setName("customer");
+      resource.getContents().add(customer);
+
+      revisionToRemove = CDOUtil.getCDOObject(customer).cdoRevision();
+
+      for (int i = 0; i < 100; i++)
+      {
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        salesOrder.setCustomer(customer);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+      session.close();
+    }
+
+    InternalCDORevisionManager revisionManager = getRepository().getRevisionManager();
+    revisionManager.getCache().removeRevision(revisionToRemove.getID(), revisionToRemove);
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    Customer customer = (Customer)resource.getContents().get(0);
+    EList<SalesOrder> salesOrders = customer.getSalesOrders();
+    int i = 0;
+    for (Iterator<SalesOrder> it = salesOrders.iterator(); it.hasNext();)
+    {
+      IOUtil.OUT().println(i++);
+      SalesOrder salesOrder = it.next();
+      IOUtil.OUT().println(salesOrder);
+    }
+  }
+
+  public void testWriteNative() throws Exception
+  {
+    CDORevision revisionToRemove = null;
+
+    {
+      CDOSession session = openSession();
+      CDOTransaction transaction = session.openTransaction();
+      CDOResource resource = transaction.createResource(getResourcePath("/test1"));
+
+      Customer customer = getModel1Factory().createCustomer();
+      customer.setName("customer");
+      resource.getContents().add(customer);
+
+      for (int i = 0; i < 100; i++)
+      {
+        SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+        salesOrder.setId(i);
+        salesOrder.setCustomer(customer);
+        resource.getContents().add(salesOrder);
+      }
+
+      transaction.commit();
+      revisionToRemove = CDOUtil.getCDOObject(customer).cdoRevision();
+      session.close();
+    }
+
+    InternalCDORevisionManager revisionManager = getRepository().getRevisionManager();
+    revisionManager.getCache().removeRevision(revisionToRemove.getID(), revisionToRemove);
+
+    CDOSession session = openSession();
+    session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(10, 10));
+
+    CDOTransaction transaction = session.openTransaction();
+    CDOResource resource = transaction.getResource(getResourcePath("/test1"));
+
+    Customer customer = (Customer)resource.getContents().get(0);
+    EList<SalesOrder> salesOrders = customer.getSalesOrders();
+    for (int i = 50; i < 70; i++)
+    {
+      SalesOrder salesOrder = getModel1Factory().createSalesOrder();
+      salesOrder.setId(i + 1000);
+      resource.getContents().add(salesOrder);
+      salesOrders.set(i, salesOrder);
+    }
+
+    transaction.commit();
+    session.close();
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
index 2db4c85..b62afba 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_369646_Test.java
@@ -16,6 +16,7 @@
 import org.eclipse.emf.cdo.tests.AbstractCDOTest;
 import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
 import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
+import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
 import org.eclipse.emf.cdo.tests.model1.Category;
 import org.eclipse.emf.cdo.transaction.CDOTransaction;
 import org.eclipse.emf.cdo.util.CDOUtil;
@@ -31,9 +32,9 @@
  * @author Eike Stepper
  */
 @CleanRepositoriesBefore
+@Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
 public class Bugzilla_369646_Test extends AbstractCDOTest
 {
-  @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
   public void testSetBranchWithSubBranches() throws Exception
   {
     // Note: as of bug 369646, this fails with DBStore and range-based branching mapping strategy.
@@ -50,20 +51,19 @@
     res.getContents().add(c);
     transaction.commit();
 
-    // create two cascading branches
+    // Create two cascading branches
     CDOBranch sub1 = transaction.getBranch().createBranch("sub1");
     CDOBranch sub2 = sub1.createBranch("sub2");
 
-    // now delete the contents in the sub2 branch
+    // Now delete the contents in the sub2 branch
     transaction.setBranch(sub2);
     res.getContents().remove(0);
     transaction.commit();
 
-    // and now try to switch the transaction to the parent branch
+    // And now try to switch the transaction to the parent branch
     transaction.setBranch(sub1);
   }
 
-  @Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
   public void testSetBranchWithPCL() throws Exception
   {
     {
@@ -85,32 +85,32 @@
 
       transaction.commit();
 
-      // create a branch
+      // Create a branch
       CDOBranch sub1 = transaction.getBranch().createBranch("sub1");
       transaction.setBranch(sub1);
 
-      // modify list in branch
+      // Modify list in branch
       cat.getCategories().remove(3);
       cat.getCategories().remove(7);
 
-      // commit
+      // Commit
       transaction.commit();
       session.close();
     }
 
-    // now clear the cache on server
+    // Now clear the cache on server
     clearCache(getRepository().getRevisionManager());
 
-    // open a new session with PCL enabled
+    // Open a new session with PCL enabled
     CDOSession session = openSession();
     session.options().setCollectionLoadingPolicy(CDOUtil.createCollectionLoadingPolicy(1, 1));
 
-    // load the categroy in the resource (is now partially loaded)
+    // Load the categroy in the resource (is now partially loaded)
     CDOView view = session.openView();
     CDOResource res = view.getResource(getResourcePath("/test"));
     Category cat = (Category)res.getContents().get(0);
 
-    // and switch view target
+    // And switch view target
     view.setBranch(view.getBranch().getBranches()[0]);
     IOUtil.OUT().println("Result: " + cat.getCategories());
   }
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
index b9fef39..ce4235b 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java
@@ -1,1632 +1,1633 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Simon McDuff - maintenance
- */
-package org.eclipse.emf.internal.cdo;
-
-import org.eclipse.emf.cdo.CDOLock;
-import org.eclipse.emf.cdo.CDOObject;
-import org.eclipse.emf.cdo.CDOState;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lock.CDOLockState;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.view.CDOView;
-
-import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.messages.Messages;
-import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.NotificationChain;
-import org.eclipse.emf.common.util.BasicEList;
-import org.eclipse.emf.common.util.BasicEMap;
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
-import org.eclipse.emf.ecore.impl.ENotificationImpl;
-import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.Resource.Internal;
-import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
-import org.eclipse.emf.ecore.util.EcoreEList;
-import org.eclipse.emf.ecore.util.EcoreEMap;
-import org.eclipse.emf.ecore.util.FeatureMap;
-import org.eclipse.emf.ecore.util.FeatureMapUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.spi.cdo.CDOStore;
-import org.eclipse.emf.spi.cdo.FSMUtil;
-import org.eclipse.emf.spi.cdo.InternalCDOLoadable;
-import org.eclipse.emf.spi.cdo.InternalCDOObject;
-import org.eclipse.emf.spi.cdo.InternalCDOView;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * The base class of all <em>native</em> {@link CDOObject objects}.
- * 
- * @author Eike Stepper
- */
-public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObject
-{
-  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.class);
-
-  private CDOID id;
-
-  private CDOState state;
-
-  private InternalCDOView view;
-
-  private InternalCDORevision revision;
-
-  /**
-   * CDO uses this list instead of eSettings for transient objects. EMF uses eSettings as cache. CDO deactivates the
-   * cache but EMF still used eSettings to store list wrappers. CDO needs another place to store the real list with the
-   * actual data (transient mode) and accessible through EStore. This allows CDO to always use the same instance of the
-   * list wrapper.
-   */
-  private transient Object[] cdoSettings;
-
-  public CDOObjectImpl()
-  {
-    state = CDOState.TRANSIENT;
-    eContainer = null;
-    cdoSettings = null;
-  }
-
-  public CDOID cdoID()
-  {
-    return id;
-  }
-
-  public CDOState cdoState()
-  {
-    return state;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public InternalCDORevision cdoRevision()
-  {
-    return revision;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public InternalCDOView cdoView()
-  {
-    return view;
-  }
-
-  public CDOResourceImpl cdoResource()
-  {
-    Resource resource = eResource();
-    if (resource instanceof CDOResourceImpl)
-    {
-      return (CDOResourceImpl)resource;
-    }
-
-    return null;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public CDOResourceImpl cdoDirectResource()
-  {
-    Resource.Internal resource = eDirectResource();
-    if (resource instanceof CDOResourceImpl)
-    {
-      return (CDOResourceImpl)resource;
-    }
-
-    return null;
-  }
-
-  /**
-   * @since 3.0
-   */
-  public void cdoPrefetch(int depth)
-  {
-    view.prefetchRevisions(id, depth);
-  }
-
-  public void cdoReload()
-  {
-    CDOStateMachine.INSTANCE.reload(this);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public boolean cdoConflict()
-  {
-    return FSMUtil.isConflict(this);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public boolean cdoInvalid()
-  {
-    return FSMUtil.isInvalid(this);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public CDOLock cdoReadLock()
-  {
-    return createLock(this, LockType.READ);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public CDOLock cdoWriteLock()
-  {
-    return createLock(this, LockType.WRITE);
-  }
-
-  /**
-   * @since 4.1
-   */
-  public CDOLock cdoWriteOption()
-  {
-    return createLock(this, LockType.OPTION);
-  }
-
-  /**
-   * @since 4.1
-   */
-  public CDOLockState cdoLockState()
-  {
-    return getLockState(this);
-  }
-
-  public void cdoInternalSetID(CDOID id)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Setting ID: {0}", id); //$NON-NLS-1$
-    }
-
-    this.id = id;
-  }
-
-  public CDOState cdoInternalSetState(CDOState state)
-  {
-    CDOState oldState = this.state;
-    if (oldState != state)
-    {
-      if (TRACER.isEnabled())
-      {
-        TRACER.format("Setting state {0} for {1}", state, this); //$NON-NLS-1$
-      }
-
-      this.state = state;
-      if (view != null)
-      {
-        view.handleObjectStateChanged(this, oldState, state);
-      }
-
-      return oldState;
-    }
-
-    return null;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void cdoInternalSetRevision(CDORevision revision)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$
-    }
-
-    this.revision = (InternalCDORevision)revision;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void cdoInternalSetView(CDOView view)
-  {
-    this.view = (InternalCDOView)view;
-    if (this.view != null)
-    {
-      eSetStore(this.view.getStore());
-    }
-    else
-    {
-      eSetStore(null);
-    }
-  }
-
-  public void cdoInternalSetResource(CDOResource resource)
-  {
-    throw new UnsupportedOperationException();
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void cdoInternalPreLoad()
-  {
-    // Do nothing
-  }
-
-  public void cdoInternalPostLoad()
-  {
-    // Reset EMAP objects
-    if (eSettings != null)
-    {
-      // Make sure transient features are kept but persisted values are not cached.
-      EClass eClass = eClass();
-      for (int i = 0; i < eClass.getFeatureCount(); i++)
-      {
-        EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
-
-        // We need to keep the existing list if possible.
-        if (EMFUtil.isPersistent(eFeature) && eSettings[i] instanceof InternalCDOLoadable)
-        {
-          ((InternalCDOLoadable)eSettings[i]).cdoInternalPostLoad();
-        }
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void cdoInternalPostInvalidate()
-  {
-    // Do nothing
-  }
-
-  public void cdoInternalPostAttach()
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Populating revision for {0}", this); //$NON-NLS-1$
-    }
-
-    revision.setContainerID(eContainer == null ? CDOID.NULL : view.convertObjectToID(eContainer, true));
-    revision.setContainingFeatureID(eContainerFeatureID);
-
-    Resource directResource = eDirectResource();
-    if (directResource instanceof CDOResource)
-    {
-      CDOResource cdoResource = (CDOResource)directResource;
-      revision.setResourceID(cdoResource.cdoID());
-    }
-
-    if (cdoSettings != null)
-    {
-      EClass eClass = eClass();
-      for (int i = 0; i < eClass.getFeatureCount(); i++)
-      {
-        EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
-        if (EMFUtil.isPersistent(eFeature))
-        {
-          instanceToRevisionFeature(view, this, eFeature, cdoSettings[i]);
-        }
-      }
-
-      cdoSettings = null;
-    }
-  }
-
-  /**
-   * It is really important for accessing the data to go through {@link #cdoStore()}. {@link #eStore()} will redirect
-   * you to the transient data.
-   * 
-   * @since 2.0
-   */
-  public void cdoInternalPostDetach(boolean remote)
-  {
-    if (remote)
-    {
-      // Do nothing
-      return;
-    }
-
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Depopulating revision for {0}", this); //$NON-NLS-1$
-    }
-
-    CDOStore store = cdoStore();
-    super.eSetDirectResource((Resource.Internal)store.getResource(this));
-    eContainer = store.getContainer(this);
-    eContainerFeatureID = store.getContainingFeatureID(this);
-
-    // Ensure that the internal eSettings array is initialized;
-    resetSettings();
-
-    EClass eClass = eClass();
-    for (int i = 0; i < eClass.getFeatureCount(); i++)
-    {
-      EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
-      if (EMFUtil.isPersistent(eFeature))
-      {
-        revisionToInstanceFeature(this, revision, eFeature);
-      }
-    }
-  }
-
-  /**
-   * @since 3.0
-   */
-  public void cdoInternalPostRollback()
-  {
-    // Do nothing
-  }
-
-  public void cdoInternalPreCommit()
-  {
-    // Do nothing
-  }
-
-  public InternalEObject cdoInternalInstance()
-  {
-    return this;
-  }
-
-  public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID)
-  {
-    return eDynamicFeature(dynamicFeatureID);
-  }
-
-  /**
-   * @since 2.0
-   */
-  @Override
-  public synchronized EList<Adapter> eAdapters()
-  {
-    if (eAdapters == null)
-    {
-      // TODO Adjust for EObjectEAdapterList (see bug #247130)
-      eAdapters = new EAdapterList<Adapter>(this)
-      {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        protected void didAdd(int index, Adapter newObject)
-        {
-          if (view == null || view.isActive())
-          {
-            super.didAdd(index, newObject);
-            if (!FSMUtil.isTransient(CDOObjectImpl.this))
-            {
-              view.handleAddAdapter(CDOObjectImpl.this, newObject);
-            }
-          }
-        }
-
-        @Override
-        protected void didRemove(int index, Adapter oldObject)
-        {
-          if (view == null || view.isActive())
-          {
-            super.didRemove(index, oldObject);
-            if (!FSMUtil.isTransient(CDOObjectImpl.this))
-            {
-              view.handleRemoveAdapter(CDOObjectImpl.this, oldObject);
-            }
-          }
-        }
-      };
-    }
-
-    return eAdapters;
-  }
-
-  /**
-   * @since 2.0
-   */
-  @Override
-  public Resource.Internal eDirectResource()
-  {
-    if (FSMUtil.isTransient(this))
-    {
-      return super.eDirectResource();
-    }
-
-    return (Resource.Internal)cdoStore().getResource(this);
-  }
-
-  @Override
-  public Resource.Internal eInternalResource()
-  {
-    if (FSMUtil.isInvalid(this))
-    {
-      return null;
-    }
-
-    return super.eInternalResource();
-  }
-
-  @Override
-  public Object dynamicGet(int dynamicFeatureID)
-  {
-    Object result = eSettings[dynamicFeatureID];
-    if (result == null)
-    {
-      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
-      if (EMFUtil.isPersistent(eStructuralFeature))
-      {
-        if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
-        {
-          eSettings[dynamicFeatureID] = result = createFeatureMap(eStructuralFeature);
-        }
-        else if (eStructuralFeature.isMany())
-        {
-          eSettings[dynamicFeatureID] = result = createList(eStructuralFeature);
-        }
-        else
-        {
-          result = eStore().get(this, eStructuralFeature, EStore.NO_INDEX);
-          if (eIsCaching())
-          {
-            eSettings[dynamicFeatureID] = result;
-          }
-        }
-      }
-    }
-
-    return result;
-  }
-
-  @Override
-  public void dynamicSet(int dynamicFeatureID, Object value)
-  {
-    EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
-    if (!EMFUtil.isPersistent(eStructuralFeature))
-    {
-      eSettings[dynamicFeatureID] = value;
-    }
-    else
-    {
-      eStore().set(this, eStructuralFeature, EStore.NO_INDEX, value);
-      if (eIsCaching())
-      {
-        eSettings[dynamicFeatureID] = value;
-      }
-    }
-  }
-
-  @Override
-  public void dynamicUnset(int dynamicFeatureID)
-  {
-    EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
-    if (!EMFUtil.isPersistent(eStructuralFeature))
-    {
-      eSettings[dynamicFeatureID] = null;
-    }
-    else
-    {
-      eStore().unset(this, eDynamicFeature(dynamicFeatureID));
-      if (eIsCaching())
-      {
-        eSettings[dynamicFeatureID] = null;
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  @Override
-  protected boolean eDynamicIsSet(int dynamicFeatureID, EStructuralFeature eFeature)
-  {
-    if (dynamicFeatureID < 0)
-    {
-      return eOpenIsSet(eFeature);
-    }
-
-    if (EMFUtil.isPersistent(eFeature))
-    {
-      return eStore().isSet(this, eFeature);
-    }
-
-    return eSettingDelegate(eFeature).dynamicIsSet(this, eSettings(), dynamicFeatureID);
-  }
-
-  /**
-   * @since 2.0
-   */
-  @Override
-  public EStore eStore()
-  {
-    if (FSMUtil.isTransient(this))
-    {
-      return CDOStoreSettingsImpl.INSTANCE;
-    }
-
-    return cdoStore();
-  }
-
-  @Override
-  public InternalEObject eInternalContainer()
-  {
-    InternalEObject container;
-    if (FSMUtil.isTransient(this))
-    {
-      container = eContainer;
-    }
-    else
-    {
-      // Delegate to CDOStore
-      container = cdoStore().getContainer(this);
-    }
-
-    return container;
-  }
-
-  @Override
-  public int eContainerFeatureID()
-  {
-    if (FSMUtil.isTransient(this))
-    {
-      return eContainerFeatureID;
-    }
-
-    // Delegate to CDOStore
-    return cdoStore().getContainingFeatureID(this);
-  }
-
-  /**
-   * Code took from {@link BasicEObjectImpl#eBasicSetContainer} and modify it to detect when object are moved in the
-   * same context. (E.g.: An object is moved from resA to resB. resA and resB belongs to the same CDORepositoryInfo.
-   * Without this special handling, a detach and newObject will be generated for the object moved)
-   * 
-   * @since 2.0
-   */
-  @Override
-  public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
-      NotificationChain msgs)
-  {
-    boolean isResourceRoot = this instanceof CDOResource && ((CDOResource)this).isRoot();
-
-    InternalEObject oldContainer = eInternalContainer();
-    Resource.Internal oldResource = eDirectResource();
-    Resource.Internal newResource = null;
-    if (oldResource != null)
-    {
-      if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
-      {
-        msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
-        eSetDirectResource(null);
-        newResource = newContainer.eInternalResource();
-      }
-      else
-      {
-        oldResource = null;
-      }
-    }
-    else
-    {
-      if (oldContainer != null)
-      {
-        oldResource = oldContainer.eInternalResource();
-      }
-
-      if (newContainer != null)
-      {
-        newResource = newContainer.eInternalResource();
-      }
-    }
-
-    CDOView oldView = view;
-    CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
-        : null;
-
-    boolean moved = oldView != null && oldView == newView;
-    if (!moved && oldResource != null && !isResourceRoot)
-    {
-      oldResource.detached(this);
-    }
-
-    int oldContainerFeatureID = eContainerFeatureID();
-    eBasicSetContainer(newContainer, newContainerFeatureID);
-
-    if (!moved && oldResource != newResource && newResource != null)
-    {
-      newResource.attached(this);
-    }
-
-    if (eNotificationRequired())
-    {
-      if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
-      {
-        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
-            oldContainer, null);
-        if (msgs == null)
-        {
-          msgs = notification;
-        }
-        else
-        {
-          msgs.add(notification);
-        }
-      }
-
-      if (newContainerFeatureID >= 0)
-      {
-        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
-            oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
-        if (msgs == null)
-        {
-          msgs = notification;
-        }
-        else
-        {
-          msgs.add(notification);
-        }
-      }
-    }
-
-    return msgs;
-  }
-
-  /**
-   * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
-   * context.
-   * 
-   * @since 2.0
-   */
-  @Override
-  public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
-  {
-    Resource.Internal oldResource = eDirectResource();
-
-    CDOView oldView = view;
-    CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;
-
-    boolean isSameView;
-    if (state == CDOState.NEW)
-    {
-      isSameView = false;
-    }
-    else
-    {
-      isSameView = oldView != null && oldView == newView;
-    }
-
-    if (oldResource != null)
-    {
-      notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);
-
-      // When setting the resource to null we assume that detach has already been called in the resource implementation
-      if (!isSameView && resource != null)
-      {
-        oldResource.detached(this);
-      }
-    }
-
-    InternalEObject oldContainer = eInternalContainer();
-    if (oldContainer != null && !isSameView)
-    {
-      if (eContainmentFeature().isResolveProxies())
-      {
-        Resource.Internal oldContainerResource = oldContainer.eInternalResource();
-        if (oldContainerResource != null)
-        {
-          // If we're not setting a new resource, attach it to the old container's resource.
-          if (resource == null)
-          {
-            oldContainerResource.attached(this);
-          }
-
-          // If we didn't detach it from an old resource already, detach it from the old container's resource.
-          //
-          else if (oldResource == null)
-          {
-            oldContainerResource.detached(this);
-          }
-        }
-      }
-      else
-      {
-        notifications = eBasicRemoveFromContainer(notifications);
-        notifications = eBasicSetContainer(null, -1, notifications);
-      }
-    }
-
-    eSetDirectResource(resource);
-
-    return notifications;
-  }
-
-  /**
-   * Specializing the behaviour of {@link #hashCode()} is not permitted as per {@link EObject} specification.
-   */
-  @Override
-  public final int hashCode()
-  {
-    return super.hashCode();
-  }
-
-  /**
-   * Specializing the behaviour of {@link #equals(Object)} is not permitted as per {@link EObject} specification.
-   */
-  @Override
-  public final boolean equals(Object obj)
-  {
-    return super.equals(obj);
-  }
-
-  @Override
-  public String toString()
-  {
-    if (id == null)
-    {
-      return eClass().getName() + "?"; //$NON-NLS-1$
-    }
-
-    return eClass().getName() + "@" + id; //$NON-NLS-1$
-  }
-
-  /**
-   * @since 2.0
-   */
-  protected Object[] cdoSettings()
-  {
-    if (cdoSettings == null)
-    {
-      int size = eClass().getFeatureCount() - eStaticFeatureCount();
-      if (size == 0)
-      {
-        cdoSettings = ENO_SETTINGS;
-      }
-      else
-      {
-        cdoSettings = new Object[size];
-      }
-    }
-
-    return cdoSettings;
-  }
-
-  /**
-   * @since 2.0
-   */
-  protected Object[] cdoBasicSettings()
-  {
-    return cdoSettings;
-  }
-
-  @Override
-  protected FeatureMap createFeatureMap(EStructuralFeature eStructuralFeature)
-  {
-    return new CDOStoreFeatureMap(eStructuralFeature);
-  }
-
-  /**
-   * @since 4.1
-   */
-  protected CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature)
-  {
-    return new CDOStoreEcoreEMap(eStructuralFeature);
-  }
-
-  /**
-   * @since 4.1
-   */
-  protected CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature)
-  {
-    return new CDOStoreUnorderedEList<Object>(eStructuralFeature);
-  }
-
-  @Override
-  protected EList<?> createList(EStructuralFeature eStructuralFeature)
-  {
-    if (isMap(eStructuralFeature))
-    {
-      return createMap(eStructuralFeature);
-    }
-
-    if (!eStructuralFeature.isOrdered())
-    {
-      return createUnorderedList(eStructuralFeature);
-    }
-
-    return super.createList(eStructuralFeature);
-  }
-
-  private boolean isMap(EStructuralFeature eStructuralFeature)
-  {
-    // Answer from Christian Damus:
-    // Java ensures that string constants are interned, so this is actually
-    // more efficient than .equals() and it's correct
-    return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$
-  }
-
-  @Override
-  protected void eInitializeContainer()
-  {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  protected void eSetDirectResource(Internal resource)
-  {
-    if (FSMUtil.isTransient(this))
-    {
-      super.eSetDirectResource(resource);
-    }
-    else if (resource instanceof CDOResourceImpl || resource == null)
-    {
-      cdoStore().setContainer(this, (CDOResourceImpl)resource, eInternalContainer(), eContainerFeatureID());
-    }
-    else
-    {
-      throw new IllegalArgumentException(Messages.getString("CDOObjectImpl.8")); //$NON-NLS-1$
-    }
-  }
-
-  /**
-   * Don't cache non-transient features in this CDOObject's {@link #eSettings()}.
-   */
-  @Override
-  protected boolean eIsCaching()
-  {
-    return false;
-  }
-
-  @Override
-  protected void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID); //$NON-NLS-1$
-    }
-
-    if (FSMUtil.isTransient(this))
-    {
-      super.eBasicSetContainer(newEContainer, newContainerFeatureID);
-    }
-    else
-    {
-      cdoStore().setContainer(this, cdoDirectResource(), newEContainer, newContainerFeatureID);
-    }
-  }
-
-  private CDOStore cdoStore()
-  {
-    return view.getStore();
-  }
-
-  private void resetSettings()
-  {
-    cdoSettings = null;
-    cdoSettings();
-  }
-
-  /**
-   * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
-   * was not {@link CDOState#NEW}.
-   */
-  private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
-  {
-    if (object != null)
-    {
-      InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(object);
-      if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
-      {
-        if (feature.isMany())
-        {
-          int index = cdoObject.eStore().indexOf(cdoObject, feature, instance.cdoID());
-
-          // TODO Simon Log an error in the new view.getErrors() in the case we are not able to find the object.
-          // Cannot throw an exception, the detach process is too far.
-          if (index != -1)
-          {
-            cdoObject.eStore().set(cdoObject, feature, index, instance);
-          }
-        }
-        else
-        {
-          cdoObject.eStore().set(cdoObject, feature, 0, instance);
-        }
-      }
-      else
-      {
-        if (feature.isResolveProxies())
-        {
-          // We should not trigger events. But we have no choice :-(.
-          if (feature.isMany())
-          {
-            @SuppressWarnings("unchecked")
-            InternalEList<Object> list = (InternalEList<Object>)object.eGet(feature);
-            int index = list.indexOf(instance);
-            if (index != -1)
-            {
-              list.set(index, instance);
-            }
-          }
-          else
-          {
-            object.eSet(feature, instance);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public static void revisionToInstanceFeature(InternalCDOObject instance, InternalCDORevision revision,
-      EStructuralFeature eFeature)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Depopulating feature {0}", eFeature); //$NON-NLS-1$
-    }
-
-    EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature;
-    InternalCDOView view = instance.cdoView();
-    EReference oppositeReference = view.isObjectNew(instance.cdoID()) ? null : internalFeature.getEOpposite();
-
-    CDOStore cdoStore = view.getStore();
-    EStore eStore = instance.eStore();
-
-    if (eFeature.isMany())
-    {
-      int size = cdoStore.size(instance, eFeature);
-      for (int index = 0; index < size; index++)
-      {
-        // Do not trigger events
-        // Do not trigger inverse updates
-        Object object = cdoStore.get(instance, eFeature, index);
-        eStore.add(instance, eFeature, index, object);
-        if (oppositeReference != null)
-        {
-          adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
-        }
-      }
-    }
-    else
-    {
-      Object object = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
-      eStore.set(instance, eFeature, EStore.NO_INDEX, object);
-      if (oppositeReference != null)
-      {
-        adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
-      }
-    }
-  }
-
-  /**
-   * @since 3.0
-   */
-  public static void instanceToRevisionFeature(InternalCDOView view, InternalCDOObject object,
-      EStructuralFeature feature, Object setting)
-  {
-    if (TRACER.isEnabled())
-    {
-      TRACER.format("Populating feature {0}", feature); //$NON-NLS-1$
-    }
-
-    CDOStore cdoStore = view.getStore();
-    InternalCDORevision revision = object.cdoRevision();
-
-    if (feature.isMany())
-    {
-      if (setting != null)
-      {
-        int index = 0;
-        @SuppressWarnings("unchecked")
-        EList<Object> list = (EList<Object>)setting;
-        for (Object value : list)
-        {
-          value = cdoStore.convertToCDO(object, feature, value);
-          revision.add(feature, index++, value);
-        }
-      }
-    }
-    else
-    {
-      setting = cdoStore.convertToCDO(object, feature, setting);
-      revision.set(feature, 0, setting);
-    }
-  }
-
-  /**
-   * @since 4.1
-   */
-  public static CDOLock createLock(InternalCDOObject object, LockType type)
-  {
-    if (FSMUtil.isTransient(object))
-    {
-      throw new IllegalStateException("Call CDOView.lockObjects() for transient object " + object);
-    }
-
-    return new CDOLockImpl(object, type);
-  }
-
-  /**
-   * @since 4.1
-   */
-  public static CDOLockState getLockState(InternalCDOObject object)
-  {
-    if (!FSMUtil.isTransient(object))
-    {
-      InternalCDOView view = object.cdoView();
-      CDOID id = object.cdoID();
-
-      return view.getLockStates(Collections.singletonList(id))[0];
-    }
-
-    return null;
-  }
-
-  /**
-   * For internal use only.
-   * 
-   * @author Simon McDuff
-   * @since 2.0
-   */
-  public static class CDOStoreSettingsImpl implements InternalEObject.EStore
-  {
-    public static CDOStoreSettingsImpl INSTANCE = new CDOStoreSettingsImpl();
-
-    private CDOStoreSettingsImpl()
-    {
-    }
-
-    protected Object getValue(InternalEObject eObject, int dynamicFeatureID)
-    {
-      Object value = ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID];
-      return value;
-    }
-
-    protected EList<Object> getValueAsList(InternalEObject eObject, int dynamicFeatureID)
-    {
-      @SuppressWarnings("unchecked")
-      EList<Object> result = (EList<Object>)getValue(eObject, dynamicFeatureID);
-      if (result == null)
-      {
-        result = new BasicEList<Object>();
-        ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID] = result;
-      }
-
-      return result;
-    }
-
-    protected Object setValue(InternalEObject eObject, int dynamicFeatureID, Object newValue)
-    {
-      Object settings[] = ((CDOObjectImpl)eObject).cdoSettings();
-      Object oldSetting = settings[dynamicFeatureID];
-      settings[dynamicFeatureID] = newValue;
-      return oldSetting;
-    }
-
-    protected int eDynamicFeatureID(InternalEObject eObject, EStructuralFeature feature)
-    {
-      return ((CDOObjectImpl)eObject).eDynamicFeatureID(feature);
-    }
-
-    public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      if (index != NO_INDEX)
-      {
-        return getValueAsList(eObject, dynamicFeatureID).get(index);
-      }
-
-      return getValue(eObject, dynamicFeatureID);
-    }
-
-    public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      if (index != NO_INDEX)
-      {
-        return getValueAsList(eObject, dynamicFeatureID).set(index, value);
-      }
-
-      return setValue(eObject, dynamicFeatureID, value);
-    }
-
-    public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      getValueAsList(eObject, dynamicFeatureID).add(index, value);
-    }
-
-    public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).remove(index);
-    }
-
-    public Object move(InternalEObject eObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).move(targetIndex, sourceIndex);
-    }
-
-    public void clear(InternalEObject eObject, EStructuralFeature feature)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      if (feature.isMany())
-      {
-        getValueAsList(eObject, dynamicFeatureID).clear();
-      }
-
-      setValue(eObject, dynamicFeatureID, null);
-    }
-
-    public int size(InternalEObject eObject, EStructuralFeature feature)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).size();
-    }
-
-    public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).indexOf(value);
-    }
-
-    public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).lastIndexOf(value);
-    }
-
-    public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).toArray();
-    }
-
-    public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] array)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).toArray(array);
-    }
-
-    public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).isEmpty();
-    }
-
-    public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).contains(value);
-    }
-
-    public int hashCode(InternalEObject eObject, EStructuralFeature feature)
-    {
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return getValueAsList(eObject, dynamicFeatureID).hashCode();
-    }
-
-    public InternalEObject getContainer(InternalEObject eObject)
-    {
-      return null;
-    }
-
-    public EStructuralFeature getContainingFeature(InternalEObject eObject)
-    {
-      throw new UnsupportedOperationException("Should never be called");
-    }
-
-    public EObject create(EClass eClass)
-    {
-      return new EStoreEObjectImpl(eClass, this);
-    }
-
-    public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
-    {
-      if (!feature.isUnsettable())
-      {
-        if (feature.isMany())
-        {
-          @SuppressWarnings("unchecked")
-          InternalEList<Object> list = (InternalEList<Object>)eObject.eGet(feature);
-          return list != null && !list.isEmpty();
-        }
-
-        return !ObjectUtil.equals(eObject.eGet(feature), feature.getDefaultValue());
-      }
-
-      Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
-      if (settings == null)
-      {
-        return false;
-      }
-
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      return settings[dynamicFeatureID] != null;
-    }
-
-    public void unset(InternalEObject eObject, EStructuralFeature feature)
-    {
-      Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
-      if (settings == null)
-      {
-        // Is already unset
-        return;
-      }
-
-      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
-      if (feature.isUnsettable())
-      {
-        settings[dynamicFeatureID] = null;
-      }
-      else
-      {
-        settings[dynamicFeatureID] = feature.getDefaultValue();
-      }
-    }
-  }
-
-  /**
-   * @author Eike Stepper
-   * @since 4.1
-   */
-  public class CDOStoreEcoreEMap extends EcoreEMap<Object, Object> implements InternalCDOLoadable
-  {
-    private static final long serialVersionUID = 1L;
-
-    public CDOStoreEcoreEMap(EStructuralFeature eStructuralFeature)
-    {
-      super((EClass)eStructuralFeature.getEType(), BasicEMap.Entry.class, null);
-      delegateEList = new BasicEStoreEList<BasicEMap.Entry<Object, Object>>(CDOObjectImpl.this, eStructuralFeature)
-      {
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public void unset()
-        {
-          super.unset();
-          doClear();
-        }
-
-        @Override
-        protected void didAdd(int index, BasicEMap.Entry<Object, Object> newObject)
-        {
-          CDOStoreEcoreEMap.this.doPut(newObject);
-        }
-
-        @Override
-        protected void didSet(int index, BasicEMap.Entry<Object, Object> newObject,
-            BasicEMap.Entry<Object, Object> oldObject)
-        {
-          didRemove(index, oldObject);
-          didAdd(index, newObject);
-        }
-
-        @Override
-        protected void didRemove(int index, BasicEMap.Entry<Object, Object> oldObject)
-        {
-          CDOStoreEcoreEMap.this.doRemove(oldObject);
-        }
-
-        @Override
-        protected void didClear(int size, Object[] oldObjects)
-        {
-          CDOStoreEcoreEMap.this.doClear();
-        }
-
-        @Override
-        protected void didMove(int index, BasicEMap.Entry<Object, Object> movedObject, int oldIndex)
-        {
-          CDOStoreEcoreEMap.this.doMove(movedObject);
-        }
-      };
-
-      size = delegateEList.size();
-    }
-
-    private void checkListForReading()
-    {
-      if (!FSMUtil.isTransient(CDOObjectImpl.this))
-      {
-        CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
-      }
-    }
-
-    /**
-     * Ensures that the entry data is created and is populated with contents of the delegate list.
-     */
-    @Override
-    protected synchronized void ensureEntryDataExists()
-    {
-      checkListForReading();
-      super.ensureEntryDataExists();
-    }
-
-    @Override
-    public int size()
-    {
-      checkListForReading();
-      return size;
-    }
-
-    @Override
-    public boolean isEmpty()
-    {
-      checkListForReading();
-      return size == 0;
-    }
-
-    @Override
-    public boolean contains(Object object)
-    {
-      checkListForReading();
-      return super.contains(object);
-    }
-
-    @Override
-    public boolean containsAll(Collection<?> collection)
-    {
-      checkListForReading();
-      return super.containsAll(collection);
-    }
-
-    @Override
-    public boolean containsKey(Object key)
-    {
-      checkListForReading();
-      return super.containsKey(key);
-    }
-
-    @Override
-    public boolean containsValue(Object value)
-    {
-      checkListForReading();
-      return super.containsValue(value);
-    }
-
-    public void cdoInternalPostLoad()
-    {
-      entryData = null;
-      size = delegateEList.size();
-    }
-
-    public void cdoInternalPreLoad()
-    {
-    }
-  }
-
-  /**
-   * @author Andras Peteri
-   * @since 4.1
-   */
-  public class CDOStoreUnorderedEList<E> extends BasicEStoreEList<E>
-  {
-    private static final long serialVersionUID = 1L;
-
-    public CDOStoreUnorderedEList(EStructuralFeature feature)
-    {
-      super(CDOObjectImpl.this, feature);
-    }
-
-    @Override
-    public E remove(int index)
-    {
-      boolean oldObjectIsLast = index == size() - 1;
-      E oldObject = super.remove(index);
-
-      if (!oldObjectIsLast)
-      {
-        move(index, size() - 1);
-      }
-
-      return oldObject;
-    }
-  }
-
-  /**
-   * TODO Remove this when EMF has fixed bug 197487
-   * 
-   * @author Eike Stepper
-   */
-  public class CDOStoreFeatureMap extends DelegatingFeatureMap
-  {
-    private static final long serialVersionUID = 1L;
-
-    public CDOStoreFeatureMap(EStructuralFeature eStructuralFeature)
-    {
-      super(CDOObjectImpl.this, eStructuralFeature);
-    }
-
-    @Override
-    protected List<FeatureMap.Entry> delegateList()
-    {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public EStructuralFeature getEStructuralFeature()
-    {
-      return eStructuralFeature;
-    }
-
-    @Override
-    protected void delegateAdd(int index, Entry object)
-    {
-      eStore().add(owner, eStructuralFeature, index, object);
-    }
-
-    @Override
-    protected void delegateAdd(Entry object)
-    {
-      delegateAdd(delegateSize(), object);
-    }
-
-    @Override
-    protected List<FeatureMap.Entry> delegateBasicList()
-    {
-      int size = delegateSize();
-      if (size == 0)
-      {
-        return ECollections.emptyEList();
-      }
-
-      Object[] data = cdoStore().toArray(owner, eStructuralFeature);
-      return new EcoreEList.UnmodifiableEList<FeatureMap.Entry>(owner, eStructuralFeature, data.length, data);
-    }
-
-    @Override
-    protected void delegateClear()
-    {
-      eStore().clear(owner, eStructuralFeature);
-    }
-
-    @Override
-    protected boolean delegateContains(Object object)
-    {
-      return eStore().contains(owner, eStructuralFeature, object);
-    }
-
-    @Override
-    protected boolean delegateContainsAll(Collection<?> collection)
-    {
-      for (Object o : collection)
-      {
-        if (!delegateContains(o))
-        {
-          return false;
-        }
-      }
-
-      return true;
-    }
-
-    @Override
-    protected Entry delegateGet(int index)
-    {
-      return (Entry)eStore().get(owner, eStructuralFeature, index);
-    }
-
-    @Override
-    protected int delegateHashCode()
-    {
-      return eStore().hashCode(owner, eStructuralFeature);
-    }
-
-    @Override
-    protected int delegateIndexOf(Object object)
-    {
-      return eStore().indexOf(owner, eStructuralFeature, object);
-    }
-
-    @Override
-    protected boolean delegateIsEmpty()
-    {
-      return eStore().isEmpty(owner, eStructuralFeature);
-    }
-
-    @Override
-    protected Iterator<FeatureMap.Entry> delegateIterator()
-    {
-      return iterator();
-    }
-
-    @Override
-    protected int delegateLastIndexOf(Object object)
-    {
-      return eStore().lastIndexOf(owner, eStructuralFeature, object);
-    }
-
-    @Override
-    protected ListIterator<FeatureMap.Entry> delegateListIterator()
-    {
-      return listIterator();
-    }
-
-    @Override
-    protected Entry delegateRemove(int index)
-    {
-      return (Entry)eStore().remove(owner, eStructuralFeature, index);
-    }
-
-    @Override
-    protected Entry delegateSet(int index, Entry object)
-    {
-      return (Entry)eStore().set(owner, eStructuralFeature, index, object);
-    }
-
-    @Override
-    protected int delegateSize()
-    {
-      return eStore().size(owner, eStructuralFeature);
-    }
-
-    @Override
-    protected Object[] delegateToArray()
-    {
-      return eStore().toArray(owner, eStructuralFeature);
-    }
-
-    @Override
-    protected <T> T[] delegateToArray(T[] array)
-    {
-      return eStore().toArray(owner, eStructuralFeature, array);
-    }
-
-    @Override
-    protected Entry delegateMove(int targetIndex, int sourceIndex)
-    {
-      return (Entry)eStore().move(owner, eStructuralFeature, targetIndex, sourceIndex);
-    }
-
-    @Override
-    protected String delegateToString()
-    {
-      StringBuffer stringBuffer = new StringBuffer();
-      stringBuffer.append("["); //$NON-NLS-1$
-      for (int i = 0, size = size(); i < size;)
-      {
-        Object value = delegateGet(i);
-        stringBuffer.append(String.valueOf(value));
-        if (++i < size)
-        {
-          stringBuffer.append(", "); //$NON-NLS-1$
-        }
-      }
-
-      stringBuffer.append("]"); //$NON-NLS-1$
-      return stringBuffer.toString();
-    }
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Simon McDuff - maintenance
+ */
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOLock;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.messages.Messages;
+import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Internal;
+import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
+import org.eclipse.emf.ecore.util.EcoreEList;
+import org.eclipse.emf.ecore.util.EcoreEMap;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.spi.cdo.CDOStore;
+import org.eclipse.emf.spi.cdo.FSMUtil;
+import org.eclipse.emf.spi.cdo.InternalCDOLoadable;
+import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * The base class of all <em>native</em> {@link CDOObject objects}.
+ *
+ * @author Eike Stepper
+ */
+public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObject
+{
+  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.class);
+
+  private CDOID id;
+
+  private CDOState state;
+
+  private InternalCDOView view;
+
+  private InternalCDORevision revision;
+
+  /**
+   * CDO uses this list instead of eSettings for transient objects. EMF uses eSettings as cache. CDO deactivates the
+   * cache but EMF still used eSettings to store list wrappers. CDO needs another place to store the real list with the
+   * actual data (transient mode) and accessible through EStore. This allows CDO to always use the same instance of the
+   * list wrapper.
+   */
+  private transient Object[] cdoSettings;
+
+  public CDOObjectImpl()
+  {
+    state = CDOState.TRANSIENT;
+    eContainer = null;
+    cdoSettings = null;
+  }
+
+  public CDOID cdoID()
+  {
+    return id;
+  }
+
+  public CDOState cdoState()
+  {
+    return state;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public InternalCDORevision cdoRevision()
+  {
+    return revision;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public InternalCDOView cdoView()
+  {
+    return view;
+  }
+
+  public CDOResourceImpl cdoResource()
+  {
+    Resource resource = eResource();
+    if (resource instanceof CDOResourceImpl)
+    {
+      return (CDOResourceImpl)resource;
+    }
+
+    return null;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public CDOResourceImpl cdoDirectResource()
+  {
+    Resource.Internal resource = eDirectResource();
+    if (resource instanceof CDOResourceImpl)
+    {
+      return (CDOResourceImpl)resource;
+    }
+
+    return null;
+  }
+
+  /**
+   * @since 3.0
+   */
+  public void cdoPrefetch(int depth)
+  {
+    view.prefetchRevisions(id, depth);
+  }
+
+  public void cdoReload()
+  {
+    CDOStateMachine.INSTANCE.reload(this);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public boolean cdoConflict()
+  {
+    return FSMUtil.isConflict(this);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public boolean cdoInvalid()
+  {
+    return FSMUtil.isInvalid(this);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public CDOLock cdoReadLock()
+  {
+    return createLock(this, LockType.READ);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public CDOLock cdoWriteLock()
+  {
+    return createLock(this, LockType.WRITE);
+  }
+
+  /**
+   * @since 4.1
+   */
+  public CDOLock cdoWriteOption()
+  {
+    return createLock(this, LockType.OPTION);
+  }
+
+  /**
+   * @since 4.1
+   */
+  public CDOLockState cdoLockState()
+  {
+    return getLockState(this);
+  }
+
+  public void cdoInternalSetID(CDOID id)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Setting ID: {0}", id); //$NON-NLS-1$
+    }
+
+    this.id = id;
+  }
+
+  public CDOState cdoInternalSetState(CDOState state)
+  {
+    CDOState oldState = this.state;
+    if (oldState != state)
+    {
+      if (TRACER.isEnabled())
+      {
+        TRACER.format("Setting state {0} for {1}", state, this); //$NON-NLS-1$
+      }
+
+      this.state = state;
+      if (view != null)
+      {
+        view.handleObjectStateChanged(this, oldState, state);
+      }
+
+      return oldState;
+    }
+
+    return null;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void cdoInternalSetRevision(CDORevision revision)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$
+    }
+
+    this.revision = (InternalCDORevision)revision;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void cdoInternalSetView(CDOView view)
+  {
+    this.view = (InternalCDOView)view;
+    if (this.view != null)
+    {
+      eSetStore(this.view.getStore());
+    }
+    else
+    {
+      eSetStore(null);
+    }
+  }
+
+  public void cdoInternalSetResource(CDOResource resource)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void cdoInternalPreLoad()
+  {
+    // Do nothing
+  }
+
+  public void cdoInternalPostLoad()
+  {
+    // Reset EMAP objects
+    if (eSettings != null)
+    {
+      // Make sure transient features are kept but persisted values are not cached.
+      EClass eClass = eClass();
+      for (int i = 0; i < eClass.getFeatureCount(); i++)
+      {
+        EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+
+        // We need to keep the existing list if possible.
+        if (EMFUtil.isPersistent(eFeature) && eSettings[i] instanceof InternalCDOLoadable)
+        {
+          ((InternalCDOLoadable)eSettings[i]).cdoInternalPostLoad();
+        }
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void cdoInternalPostInvalidate()
+  {
+    // Do nothing
+  }
+
+  public void cdoInternalPostAttach()
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Populating revision for {0}", this); //$NON-NLS-1$
+    }
+
+    revision.setContainerID(eContainer == null ? CDOID.NULL : view.convertObjectToID(eContainer, true));
+    revision.setContainingFeatureID(eContainerFeatureID);
+
+    Resource directResource = eDirectResource();
+    if (directResource instanceof CDOResource)
+    {
+      CDOResource cdoResource = (CDOResource)directResource;
+      revision.setResourceID(cdoResource.cdoID());
+    }
+
+    if (cdoSettings != null)
+    {
+      EClass eClass = eClass();
+      for (int i = 0; i < eClass.getFeatureCount(); i++)
+      {
+        EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+        if (EMFUtil.isPersistent(eFeature))
+        {
+          instanceToRevisionFeature(view, this, eFeature, cdoSettings[i]);
+        }
+      }
+
+      cdoRevision().setUnchunked();
+      cdoSettings = null;
+    }
+  }
+
+  /**
+   * It is really important for accessing the data to go through {@link #cdoStore()}. {@link #eStore()} will redirect
+   * you to the transient data.
+   *
+   * @since 2.0
+   */
+  public void cdoInternalPostDetach(boolean remote)
+  {
+    if (remote)
+    {
+      // Do nothing
+      return;
+    }
+
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Depopulating revision for {0}", this); //$NON-NLS-1$
+    }
+
+    CDOStore store = cdoStore();
+    super.eSetDirectResource((Resource.Internal)store.getResource(this));
+    eContainer = store.getContainer(this);
+    eContainerFeatureID = store.getContainingFeatureID(this);
+
+    // Ensure that the internal eSettings array is initialized;
+    resetSettings();
+
+    EClass eClass = eClass();
+    for (int i = 0; i < eClass.getFeatureCount(); i++)
+    {
+      EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+      if (EMFUtil.isPersistent(eFeature))
+      {
+        revisionToInstanceFeature(this, revision, eFeature);
+      }
+    }
+  }
+
+  /**
+   * @since 3.0
+   */
+  public void cdoInternalPostRollback()
+  {
+    // Do nothing
+  }
+
+  public void cdoInternalPreCommit()
+  {
+    // Do nothing
+  }
+
+  public InternalEObject cdoInternalInstance()
+  {
+    return this;
+  }
+
+  public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID)
+  {
+    return eDynamicFeature(dynamicFeatureID);
+  }
+
+  /**
+   * @since 2.0
+   */
+  @Override
+  public synchronized EList<Adapter> eAdapters()
+  {
+    if (eAdapters == null)
+    {
+      // TODO Adjust for EObjectEAdapterList (see bug #247130)
+      eAdapters = new EAdapterList<Adapter>(this)
+      {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void didAdd(int index, Adapter newObject)
+        {
+          if (view == null || view.isActive())
+          {
+            super.didAdd(index, newObject);
+            if (!FSMUtil.isTransient(CDOObjectImpl.this))
+            {
+              view.handleAddAdapter(CDOObjectImpl.this, newObject);
+            }
+          }
+        }
+
+        @Override
+        protected void didRemove(int index, Adapter oldObject)
+        {
+          if (view == null || view.isActive())
+          {
+            super.didRemove(index, oldObject);
+            if (!FSMUtil.isTransient(CDOObjectImpl.this))
+            {
+              view.handleRemoveAdapter(CDOObjectImpl.this, oldObject);
+            }
+          }
+        }
+      };
+    }
+
+    return eAdapters;
+  }
+
+  /**
+   * @since 2.0
+   */
+  @Override
+  public Resource.Internal eDirectResource()
+  {
+    if (FSMUtil.isTransient(this))
+    {
+      return super.eDirectResource();
+    }
+
+    return (Resource.Internal)cdoStore().getResource(this);
+  }
+
+  @Override
+  public Resource.Internal eInternalResource()
+  {
+    if (FSMUtil.isInvalid(this))
+    {
+      return null;
+    }
+
+    return super.eInternalResource();
+  }
+
+  @Override
+  public Object dynamicGet(int dynamicFeatureID)
+  {
+    Object result = eSettings[dynamicFeatureID];
+    if (result == null)
+    {
+      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+      if (EMFUtil.isPersistent(eStructuralFeature))
+      {
+        if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
+        {
+          eSettings[dynamicFeatureID] = result = createFeatureMap(eStructuralFeature);
+        }
+        else if (eStructuralFeature.isMany())
+        {
+          eSettings[dynamicFeatureID] = result = createList(eStructuralFeature);
+        }
+        else
+        {
+          result = eStore().get(this, eStructuralFeature, EStore.NO_INDEX);
+          if (eIsCaching())
+          {
+            eSettings[dynamicFeatureID] = result;
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+
+  @Override
+  public void dynamicSet(int dynamicFeatureID, Object value)
+  {
+    EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+    if (!EMFUtil.isPersistent(eStructuralFeature))
+    {
+      eSettings[dynamicFeatureID] = value;
+    }
+    else
+    {
+      eStore().set(this, eStructuralFeature, EStore.NO_INDEX, value);
+      if (eIsCaching())
+      {
+        eSettings[dynamicFeatureID] = value;
+      }
+    }
+  }
+
+  @Override
+  public void dynamicUnset(int dynamicFeatureID)
+  {
+    EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+    if (!EMFUtil.isPersistent(eStructuralFeature))
+    {
+      eSettings[dynamicFeatureID] = null;
+    }
+    else
+    {
+      eStore().unset(this, eDynamicFeature(dynamicFeatureID));
+      if (eIsCaching())
+      {
+        eSettings[dynamicFeatureID] = null;
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  @Override
+  protected boolean eDynamicIsSet(int dynamicFeatureID, EStructuralFeature eFeature)
+  {
+    if (dynamicFeatureID < 0)
+    {
+      return eOpenIsSet(eFeature);
+    }
+
+    if (EMFUtil.isPersistent(eFeature))
+    {
+      return eStore().isSet(this, eFeature);
+    }
+
+    return eSettingDelegate(eFeature).dynamicIsSet(this, eSettings(), dynamicFeatureID);
+  }
+
+  /**
+   * @since 2.0
+   */
+  @Override
+  public EStore eStore()
+  {
+    if (FSMUtil.isTransient(this))
+    {
+      return CDOStoreSettingsImpl.INSTANCE;
+    }
+
+    return cdoStore();
+  }
+
+  @Override
+  public InternalEObject eInternalContainer()
+  {
+    InternalEObject container;
+    if (FSMUtil.isTransient(this))
+    {
+      container = eContainer;
+    }
+    else
+    {
+      // Delegate to CDOStore
+      container = cdoStore().getContainer(this);
+    }
+
+    return container;
+  }
+
+  @Override
+  public int eContainerFeatureID()
+  {
+    if (FSMUtil.isTransient(this))
+    {
+      return eContainerFeatureID;
+    }
+
+    // Delegate to CDOStore
+    return cdoStore().getContainingFeatureID(this);
+  }
+
+  /**
+   * Code took from {@link BasicEObjectImpl#eBasicSetContainer} and modify it to detect when object are moved in the
+   * same context. (E.g.: An object is moved from resA to resB. resA and resB belongs to the same CDORepositoryInfo.
+   * Without this special handling, a detach and newObject will be generated for the object moved)
+   *
+   * @since 2.0
+   */
+  @Override
+  public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
+      NotificationChain msgs)
+  {
+    boolean isResourceRoot = this instanceof CDOResource && ((CDOResource)this).isRoot();
+
+    InternalEObject oldContainer = eInternalContainer();
+    Resource.Internal oldResource = eDirectResource();
+    Resource.Internal newResource = null;
+    if (oldResource != null)
+    {
+      if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
+      {
+        msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
+        eSetDirectResource(null);
+        newResource = newContainer.eInternalResource();
+      }
+      else
+      {
+        oldResource = null;
+      }
+    }
+    else
+    {
+      if (oldContainer != null)
+      {
+        oldResource = oldContainer.eInternalResource();
+      }
+
+      if (newContainer != null)
+      {
+        newResource = newContainer.eInternalResource();
+      }
+    }
+
+    CDOView oldView = view;
+    CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
+        : null;
+
+    boolean moved = oldView != null && oldView == newView;
+    if (!moved && oldResource != null && !isResourceRoot)
+    {
+      oldResource.detached(this);
+    }
+
+    int oldContainerFeatureID = eContainerFeatureID();
+    eBasicSetContainer(newContainer, newContainerFeatureID);
+
+    if (!moved && oldResource != newResource && newResource != null)
+    {
+      newResource.attached(this);
+    }
+
+    if (eNotificationRequired())
+    {
+      if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
+      {
+        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
+            oldContainer, null);
+        if (msgs == null)
+        {
+          msgs = notification;
+        }
+        else
+        {
+          msgs.add(notification);
+        }
+      }
+
+      if (newContainerFeatureID >= 0)
+      {
+        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
+            oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
+        if (msgs == null)
+        {
+          msgs = notification;
+        }
+        else
+        {
+          msgs.add(notification);
+        }
+      }
+    }
+
+    return msgs;
+  }
+
+  /**
+   * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
+   * context.
+   *
+   * @since 2.0
+   */
+  @Override
+  public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
+  {
+    Resource.Internal oldResource = eDirectResource();
+
+    CDOView oldView = view;
+    CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;
+
+    boolean isSameView;
+    if (state == CDOState.NEW)
+    {
+      isSameView = false;
+    }
+    else
+    {
+      isSameView = oldView != null && oldView == newView;
+    }
+
+    if (oldResource != null)
+    {
+      notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);
+
+      // When setting the resource to null we assume that detach has already been called in the resource implementation
+      if (!isSameView && resource != null)
+      {
+        oldResource.detached(this);
+      }
+    }
+
+    InternalEObject oldContainer = eInternalContainer();
+    if (oldContainer != null && !isSameView)
+    {
+      if (eContainmentFeature().isResolveProxies())
+      {
+        Resource.Internal oldContainerResource = oldContainer.eInternalResource();
+        if (oldContainerResource != null)
+        {
+          // If we're not setting a new resource, attach it to the old container's resource.
+          if (resource == null)
+          {
+            oldContainerResource.attached(this);
+          }
+
+          // If we didn't detach it from an old resource already, detach it from the old container's resource.
+          //
+          else if (oldResource == null)
+          {
+            oldContainerResource.detached(this);
+          }
+        }
+      }
+      else
+      {
+        notifications = eBasicRemoveFromContainer(notifications);
+        notifications = eBasicSetContainer(null, -1, notifications);
+      }
+    }
+
+    eSetDirectResource(resource);
+
+    return notifications;
+  }
+
+  /**
+   * Specializing the behaviour of {@link #hashCode()} is not permitted as per {@link EObject} specification.
+   */
+  @Override
+  public final int hashCode()
+  {
+    return super.hashCode();
+  }
+
+  /**
+   * Specializing the behaviour of {@link #equals(Object)} is not permitted as per {@link EObject} specification.
+   */
+  @Override
+  public final boolean equals(Object obj)
+  {
+    return super.equals(obj);
+  }
+
+  @Override
+  public String toString()
+  {
+    if (id == null)
+    {
+      return eClass().getName() + "?"; //$NON-NLS-1$
+    }
+
+    return eClass().getName() + "@" + id; //$NON-NLS-1$
+  }
+
+  /**
+   * @since 2.0
+   */
+  protected Object[] cdoSettings()
+  {
+    if (cdoSettings == null)
+    {
+      int size = eClass().getFeatureCount() - eStaticFeatureCount();
+      if (size == 0)
+      {
+        cdoSettings = ENO_SETTINGS;
+      }
+      else
+      {
+        cdoSettings = new Object[size];
+      }
+    }
+
+    return cdoSettings;
+  }
+
+  /**
+   * @since 2.0
+   */
+  protected Object[] cdoBasicSettings()
+  {
+    return cdoSettings;
+  }
+
+  @Override
+  protected FeatureMap createFeatureMap(EStructuralFeature eStructuralFeature)
+  {
+    return new CDOStoreFeatureMap(eStructuralFeature);
+  }
+
+  /**
+   * @since 4.1
+   */
+  protected CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature)
+  {
+    return new CDOStoreEcoreEMap(eStructuralFeature);
+  }
+
+  /**
+   * @since 4.1
+   */
+  protected CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature)
+  {
+    return new CDOStoreUnorderedEList<Object>(eStructuralFeature);
+  }
+
+  @Override
+  protected EList<?> createList(EStructuralFeature eStructuralFeature)
+  {
+    if (isMap(eStructuralFeature))
+    {
+      return createMap(eStructuralFeature);
+    }
+
+    if (!eStructuralFeature.isOrdered())
+    {
+      return createUnorderedList(eStructuralFeature);
+    }
+
+    return super.createList(eStructuralFeature);
+  }
+
+  private boolean isMap(EStructuralFeature eStructuralFeature)
+  {
+    // Answer from Christian Damus:
+    // Java ensures that string constants are interned, so this is actually
+    // more efficient than .equals() and it's correct
+    return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$
+  }
+
+  @Override
+  protected void eInitializeContainer()
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  protected void eSetDirectResource(Internal resource)
+  {
+    if (FSMUtil.isTransient(this))
+    {
+      super.eSetDirectResource(resource);
+    }
+    else if (resource instanceof CDOResourceImpl || resource == null)
+    {
+      cdoStore().setContainer(this, (CDOResourceImpl)resource, eInternalContainer(), eContainerFeatureID());
+    }
+    else
+    {
+      throw new IllegalArgumentException(Messages.getString("CDOObjectImpl.8")); //$NON-NLS-1$
+    }
+  }
+
+  /**
+   * Don't cache non-transient features in this CDOObject's {@link #eSettings()}.
+   */
+  @Override
+  protected boolean eIsCaching()
+  {
+    return false;
+  }
+
+  @Override
+  protected void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID); //$NON-NLS-1$
+    }
+
+    if (FSMUtil.isTransient(this))
+    {
+      super.eBasicSetContainer(newEContainer, newContainerFeatureID);
+    }
+    else
+    {
+      cdoStore().setContainer(this, cdoDirectResource(), newEContainer, newContainerFeatureID);
+    }
+  }
+
+  private CDOStore cdoStore()
+  {
+    return view.getStore();
+  }
+
+  private void resetSettings()
+  {
+    cdoSettings = null;
+    cdoSettings();
+  }
+
+  /**
+   * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
+   * was not {@link CDOState#NEW}.
+   */
+  private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
+  {
+    if (object != null)
+    {
+      InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(object);
+      if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
+      {
+        if (feature.isMany())
+        {
+          int index = cdoObject.eStore().indexOf(cdoObject, feature, instance.cdoID());
+
+          // TODO Simon Log an error in the new view.getErrors() in the case we are not able to find the object.
+          // Cannot throw an exception, the detach process is too far.
+          if (index != -1)
+          {
+            cdoObject.eStore().set(cdoObject, feature, index, instance);
+          }
+        }
+        else
+        {
+          cdoObject.eStore().set(cdoObject, feature, 0, instance);
+        }
+      }
+      else
+      {
+        if (feature.isResolveProxies())
+        {
+          // We should not trigger events. But we have no choice :-(.
+          if (feature.isMany())
+          {
+            @SuppressWarnings("unchecked")
+            InternalEList<Object> list = (InternalEList<Object>)object.eGet(feature);
+            int index = list.indexOf(instance);
+            if (index != -1)
+            {
+              list.set(index, instance);
+            }
+          }
+          else
+          {
+            object.eSet(feature, instance);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public static void revisionToInstanceFeature(InternalCDOObject instance, InternalCDORevision revision,
+      EStructuralFeature eFeature)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Depopulating feature {0}", eFeature); //$NON-NLS-1$
+    }
+
+    EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature;
+    InternalCDOView view = instance.cdoView();
+    EReference oppositeReference = view.isObjectNew(instance.cdoID()) ? null : internalFeature.getEOpposite();
+
+    CDOStore cdoStore = view.getStore();
+    EStore eStore = instance.eStore();
+
+    if (eFeature.isMany())
+    {
+      int size = cdoStore.size(instance, eFeature);
+      for (int index = 0; index < size; index++)
+      {
+        // Do not trigger events
+        // Do not trigger inverse updates
+        Object object = cdoStore.get(instance, eFeature, index);
+        eStore.add(instance, eFeature, index, object);
+        if (oppositeReference != null)
+        {
+          adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+        }
+      }
+    }
+    else
+    {
+      Object object = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
+      eStore.set(instance, eFeature, EStore.NO_INDEX, object);
+      if (oppositeReference != null)
+      {
+        adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+      }
+    }
+  }
+
+  /**
+   * @since 3.0
+   */
+  public static void instanceToRevisionFeature(InternalCDOView view, InternalCDOObject object,
+      EStructuralFeature feature, Object setting)
+  {
+    if (TRACER.isEnabled())
+    {
+      TRACER.format("Populating feature {0}", feature); //$NON-NLS-1$
+    }
+
+    CDOStore cdoStore = view.getStore();
+    InternalCDORevision revision = object.cdoRevision();
+
+    if (feature.isMany())
+    {
+      if (setting != null)
+      {
+        int index = 0;
+        @SuppressWarnings("unchecked")
+        EList<Object> list = (EList<Object>)setting;
+        for (Object value : list)
+        {
+          value = cdoStore.convertToCDO(object, feature, value);
+          revision.add(feature, index++, value);
+        }
+      }
+    }
+    else
+    {
+      setting = cdoStore.convertToCDO(object, feature, setting);
+      revision.set(feature, 0, setting);
+    }
+  }
+
+  /**
+   * @since 4.1
+   */
+  public static CDOLock createLock(InternalCDOObject object, LockType type)
+  {
+    if (FSMUtil.isTransient(object))
+    {
+      throw new IllegalStateException("Call CDOView.lockObjects() for transient object " + object);
+    }
+
+    return new CDOLockImpl(object, type);
+  }
+
+  /**
+   * @since 4.1
+   */
+  public static CDOLockState getLockState(InternalCDOObject object)
+  {
+    if (!FSMUtil.isTransient(object))
+    {
+      InternalCDOView view = object.cdoView();
+      CDOID id = object.cdoID();
+
+      return view.getLockStates(Collections.singletonList(id))[0];
+    }
+
+    return null;
+  }
+
+  /**
+   * For internal use only.
+   *
+   * @author Simon McDuff
+   * @since 2.0
+   */
+  public static class CDOStoreSettingsImpl implements InternalEObject.EStore
+  {
+    public static CDOStoreSettingsImpl INSTANCE = new CDOStoreSettingsImpl();
+
+    private CDOStoreSettingsImpl()
+    {
+    }
+
+    protected Object getValue(InternalEObject eObject, int dynamicFeatureID)
+    {
+      Object value = ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID];
+      return value;
+    }
+
+    protected EList<Object> getValueAsList(InternalEObject eObject, int dynamicFeatureID)
+    {
+      @SuppressWarnings("unchecked")
+      EList<Object> result = (EList<Object>)getValue(eObject, dynamicFeatureID);
+      if (result == null)
+      {
+        result = new BasicEList<Object>();
+        ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID] = result;
+      }
+
+      return result;
+    }
+
+    protected Object setValue(InternalEObject eObject, int dynamicFeatureID, Object newValue)
+    {
+      Object settings[] = ((CDOObjectImpl)eObject).cdoSettings();
+      Object oldSetting = settings[dynamicFeatureID];
+      settings[dynamicFeatureID] = newValue;
+      return oldSetting;
+    }
+
+    protected int eDynamicFeatureID(InternalEObject eObject, EStructuralFeature feature)
+    {
+      return ((CDOObjectImpl)eObject).eDynamicFeatureID(feature);
+    }
+
+    public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      if (index != NO_INDEX)
+      {
+        return getValueAsList(eObject, dynamicFeatureID).get(index);
+      }
+
+      return getValue(eObject, dynamicFeatureID);
+    }
+
+    public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      if (index != NO_INDEX)
+      {
+        return getValueAsList(eObject, dynamicFeatureID).set(index, value);
+      }
+
+      return setValue(eObject, dynamicFeatureID, value);
+    }
+
+    public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      getValueAsList(eObject, dynamicFeatureID).add(index, value);
+    }
+
+    public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).remove(index);
+    }
+
+    public Object move(InternalEObject eObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).move(targetIndex, sourceIndex);
+    }
+
+    public void clear(InternalEObject eObject, EStructuralFeature feature)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      if (feature.isMany())
+      {
+        getValueAsList(eObject, dynamicFeatureID).clear();
+      }
+
+      setValue(eObject, dynamicFeatureID, null);
+    }
+
+    public int size(InternalEObject eObject, EStructuralFeature feature)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).size();
+    }
+
+    public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).indexOf(value);
+    }
+
+    public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).lastIndexOf(value);
+    }
+
+    public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).toArray();
+    }
+
+    public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] array)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).toArray(array);
+    }
+
+    public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).isEmpty();
+    }
+
+    public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).contains(value);
+    }
+
+    public int hashCode(InternalEObject eObject, EStructuralFeature feature)
+    {
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return getValueAsList(eObject, dynamicFeatureID).hashCode();
+    }
+
+    public InternalEObject getContainer(InternalEObject eObject)
+    {
+      return null;
+    }
+
+    public EStructuralFeature getContainingFeature(InternalEObject eObject)
+    {
+      throw new UnsupportedOperationException("Should never be called");
+    }
+
+    public EObject create(EClass eClass)
+    {
+      return new EStoreEObjectImpl(eClass, this);
+    }
+
+    public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
+    {
+      if (!feature.isUnsettable())
+      {
+        if (feature.isMany())
+        {
+          @SuppressWarnings("unchecked")
+          InternalEList<Object> list = (InternalEList<Object>)eObject.eGet(feature);
+          return list != null && !list.isEmpty();
+        }
+
+        return !ObjectUtil.equals(eObject.eGet(feature), feature.getDefaultValue());
+      }
+
+      Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
+      if (settings == null)
+      {
+        return false;
+      }
+
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      return settings[dynamicFeatureID] != null;
+    }
+
+    public void unset(InternalEObject eObject, EStructuralFeature feature)
+    {
+      Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
+      if (settings == null)
+      {
+        // Is already unset
+        return;
+      }
+
+      int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+      if (feature.isUnsettable())
+      {
+        settings[dynamicFeatureID] = null;
+      }
+      else
+      {
+        settings[dynamicFeatureID] = feature.getDefaultValue();
+      }
+    }
+  }
+
+  /**
+   * @author Eike Stepper
+   * @since 4.1
+   */
+  public class CDOStoreEcoreEMap extends EcoreEMap<Object, Object> implements InternalCDOLoadable
+  {
+    private static final long serialVersionUID = 1L;
+
+    public CDOStoreEcoreEMap(EStructuralFeature eStructuralFeature)
+    {
+      super((EClass)eStructuralFeature.getEType(), BasicEMap.Entry.class, null);
+      delegateEList = new BasicEStoreEList<BasicEMap.Entry<Object, Object>>(CDOObjectImpl.this, eStructuralFeature)
+      {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public void unset()
+        {
+          super.unset();
+          doClear();
+        }
+
+        @Override
+        protected void didAdd(int index, BasicEMap.Entry<Object, Object> newObject)
+        {
+          CDOStoreEcoreEMap.this.doPut(newObject);
+        }
+
+        @Override
+        protected void didSet(int index, BasicEMap.Entry<Object, Object> newObject,
+            BasicEMap.Entry<Object, Object> oldObject)
+        {
+          didRemove(index, oldObject);
+          didAdd(index, newObject);
+        }
+
+        @Override
+        protected void didRemove(int index, BasicEMap.Entry<Object, Object> oldObject)
+        {
+          CDOStoreEcoreEMap.this.doRemove(oldObject);
+        }
+
+        @Override
+        protected void didClear(int size, Object[] oldObjects)
+        {
+          CDOStoreEcoreEMap.this.doClear();
+        }
+
+        @Override
+        protected void didMove(int index, BasicEMap.Entry<Object, Object> movedObject, int oldIndex)
+        {
+          CDOStoreEcoreEMap.this.doMove(movedObject);
+        }
+      };
+
+      size = delegateEList.size();
+    }
+
+    private void checkListForReading()
+    {
+      if (!FSMUtil.isTransient(CDOObjectImpl.this))
+      {
+        CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
+      }
+    }
+
+    /**
+     * Ensures that the entry data is created and is populated with contents of the delegate list.
+     */
+    @Override
+    protected synchronized void ensureEntryDataExists()
+    {
+      checkListForReading();
+      super.ensureEntryDataExists();
+    }
+
+    @Override
+    public int size()
+    {
+      checkListForReading();
+      return size;
+    }
+
+    @Override
+    public boolean isEmpty()
+    {
+      checkListForReading();
+      return size == 0;
+    }
+
+    @Override
+    public boolean contains(Object object)
+    {
+      checkListForReading();
+      return super.contains(object);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> collection)
+    {
+      checkListForReading();
+      return super.containsAll(collection);
+    }
+
+    @Override
+    public boolean containsKey(Object key)
+    {
+      checkListForReading();
+      return super.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value)
+    {
+      checkListForReading();
+      return super.containsValue(value);
+    }
+
+    public void cdoInternalPostLoad()
+    {
+      entryData = null;
+      size = delegateEList.size();
+    }
+
+    public void cdoInternalPreLoad()
+    {
+    }
+  }
+
+  /**
+   * @author Andras Peteri
+   * @since 4.1
+   */
+  public class CDOStoreUnorderedEList<E> extends BasicEStoreEList<E>
+  {
+    private static final long serialVersionUID = 1L;
+
+    public CDOStoreUnorderedEList(EStructuralFeature feature)
+    {
+      super(CDOObjectImpl.this, feature);
+    }
+
+    @Override
+    public E remove(int index)
+    {
+      boolean oldObjectIsLast = index == size() - 1;
+      E oldObject = super.remove(index);
+
+      if (!oldObjectIsLast)
+      {
+        move(index, size() - 1);
+      }
+
+      return oldObject;
+    }
+  }
+
+  /**
+   * TODO Remove this when EMF has fixed bug 197487
+   *
+   * @author Eike Stepper
+   */
+  public class CDOStoreFeatureMap extends DelegatingFeatureMap
+  {
+    private static final long serialVersionUID = 1L;
+
+    public CDOStoreFeatureMap(EStructuralFeature eStructuralFeature)
+    {
+      super(CDOObjectImpl.this, eStructuralFeature);
+    }
+
+    @Override
+    protected List<FeatureMap.Entry> delegateList()
+    {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public EStructuralFeature getEStructuralFeature()
+    {
+      return eStructuralFeature;
+    }
+
+    @Override
+    protected void delegateAdd(int index, Entry object)
+    {
+      eStore().add(owner, eStructuralFeature, index, object);
+    }
+
+    @Override
+    protected void delegateAdd(Entry object)
+    {
+      delegateAdd(delegateSize(), object);
+    }
+
+    @Override
+    protected List<FeatureMap.Entry> delegateBasicList()
+    {
+      int size = delegateSize();
+      if (size == 0)
+      {
+        return ECollections.emptyEList();
+      }
+
+      Object[] data = cdoStore().toArray(owner, eStructuralFeature);
+      return new EcoreEList.UnmodifiableEList<FeatureMap.Entry>(owner, eStructuralFeature, data.length, data);
+    }
+
+    @Override
+    protected void delegateClear()
+    {
+      eStore().clear(owner, eStructuralFeature);
+    }
+
+    @Override
+    protected boolean delegateContains(Object object)
+    {
+      return eStore().contains(owner, eStructuralFeature, object);
+    }
+
+    @Override
+    protected boolean delegateContainsAll(Collection<?> collection)
+    {
+      for (Object o : collection)
+      {
+        if (!delegateContains(o))
+        {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    @Override
+    protected Entry delegateGet(int index)
+    {
+      return (Entry)eStore().get(owner, eStructuralFeature, index);
+    }
+
+    @Override
+    protected int delegateHashCode()
+    {
+      return eStore().hashCode(owner, eStructuralFeature);
+    }
+
+    @Override
+    protected int delegateIndexOf(Object object)
+    {
+      return eStore().indexOf(owner, eStructuralFeature, object);
+    }
+
+    @Override
+    protected boolean delegateIsEmpty()
+    {
+      return eStore().isEmpty(owner, eStructuralFeature);
+    }
+
+    @Override
+    protected Iterator<FeatureMap.Entry> delegateIterator()
+    {
+      return iterator();
+    }
+
+    @Override
+    protected int delegateLastIndexOf(Object object)
+    {
+      return eStore().lastIndexOf(owner, eStructuralFeature, object);
+    }
+
+    @Override
+    protected ListIterator<FeatureMap.Entry> delegateListIterator()
+    {
+      return listIterator();
+    }
+
+    @Override
+    protected Entry delegateRemove(int index)
+    {
+      return (Entry)eStore().remove(owner, eStructuralFeature, index);
+    }
+
+    @Override
+    protected Entry delegateSet(int index, Entry object)
+    {
+      return (Entry)eStore().set(owner, eStructuralFeature, index, object);
+    }
+
+    @Override
+    protected int delegateSize()
+    {
+      return eStore().size(owner, eStructuralFeature);
+    }
+
+    @Override
+    protected Object[] delegateToArray()
+    {
+      return eStore().toArray(owner, eStructuralFeature);
+    }
+
+    @Override
+    protected <T> T[] delegateToArray(T[] array)
+    {
+      return eStore().toArray(owner, eStructuralFeature, array);
+    }
+
+    @Override
+    protected Entry delegateMove(int targetIndex, int sourceIndex)
+    {
+      return (Entry)eStore().move(owner, eStructuralFeature, targetIndex, sourceIndex);
+    }
+
+    @Override
+    protected String delegateToString()
+    {
+      StringBuffer stringBuffer = new StringBuffer();
+      stringBuffer.append("["); //$NON-NLS-1$
+      for (int i = 0, size = size(); i < size;)
+      {
+        Object value = delegateGet(i);
+        stringBuffer.append(String.valueOf(value));
+        if (++i < size)
+        {
+          stringBuffer.append(", "); //$NON-NLS-1$
+        }
+      }
+
+      stringBuffer.append("]"); //$NON-NLS-1$
+      return stringBuffer.toString();
+    }
+  }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
index 1d93cab..36e51eb 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
@@ -331,6 +331,8 @@
     {
       instanceToRevisionFeature(feature, packageRegistry);
     }
+
+    revision.setUnchunked();
   }
 
   protected void instanceToRevisionContainment()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index f8541bf..708f06e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -1,1849 +1,1859 @@
-/*
- * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
- * 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:
- *    Eike Stepper - initial API and implementation
- *    Simon McDuff - bug 226778
- *    Simon McDuff - bug 230832
- *    Simon McDuff - bug 233490
- *    Simon McDuff - bug 213402
- *    Victor Roldan Betancort - maintenance
- */
-package org.eclipse.emf.internal.cdo.session;
-
-import org.eclipse.emf.cdo.common.CDOCommonRepository;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.commit.CDOChangeKind;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
-import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
-import org.eclipse.emf.cdo.common.lob.CDOLobStore;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
-import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
-import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevisable;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
-import org.eclipse.emf.cdo.common.util.CDOException;
-import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
-import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOMoveFeatureDeltaImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl;
-import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
-import org.eclipse.emf.cdo.session.CDORepositoryInfo;
-import org.eclipse.emf.cdo.session.CDOSession;
-import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
-import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
-import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
-import org.eclipse.emf.cdo.spi.common.CDOLobStoreImpl;
-import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.common.revision.CDOFeatureDeltaVisitorImpl;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
-import org.eclipse.emf.cdo.view.CDOView;
-
-import org.eclipse.emf.internal.cdo.analyzer.NOOPFetchRuleManager;
-import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.messages.Messages;
-import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
-import org.eclipse.emf.internal.cdo.session.remote.CDORemoteSessionManagerImpl;
-import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
-import org.eclipse.net4j.util.WrappedException;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.concurrent.IRWLockManager;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.concurrent.IRWOLockManager;
-import org.eclipse.net4j.util.concurrent.QueueRunner;
-import org.eclipse.net4j.util.concurrent.RWOLockManager;
-import org.eclipse.net4j.util.event.Event;
-import org.eclipse.net4j.util.event.EventUtil;
-import org.eclipse.net4j.util.event.IEvent;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.event.Notifier;
-import org.eclipse.net4j.util.io.IOUtil;
-import org.eclipse.net4j.util.lifecycle.ILifecycle;
-import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.log.OMLogger;
-import org.eclipse.net4j.util.options.OptionsEvent;
-
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.RefreshSessionResult;
-import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager;
-import org.eclipse.emf.spi.cdo.InternalCDOSession;
-import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
-import org.eclipse.emf.spi.cdo.InternalCDOView;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public abstract class CDOSessionImpl extends CDOTransactionContainerImpl implements InternalCDOSession
-{
-  private ExceptionHandler exceptionHandler;
-
-  private CDOIDGenerator idGenerator;
-
-  private InternalCDOPackageRegistry packageRegistry;
-
-  private InternalCDOBranchManager branchManager;
-
-  private InternalCDORevisionManager revisionManager;
-
-  private InternalCDOCommitInfoManager commitInfoManager;
-
-  private CDOSessionProtocol sessionProtocol;
-
-  @ExcludeFromDump
-  private IListener sessionProtocolListener = new LifecycleEventAdapter()
-  {
-    @Override
-    protected void onDeactivated(ILifecycle lifecycle)
-    {
-      sessionProtocolDeactivated();
-    }
-  };
-
-  private int sessionID;
-
-  private String userID;
-
-  private long lastUpdateTime;
-
-  @ExcludeFromDump
-  private LastUpdateTimeLock lastUpdateTimeLock = new LastUpdateTimeLock();
-
-  private CDOSession.Options options = createOptions();
-
-  private OutOfSequenceInvalidations outOfSequenceInvalidations = new OutOfSequenceInvalidations();
-
-  private QueueRunner invalidationRunner;
-
-  private CDORepositoryInfo repositoryInfo;
-
-  private CDOFetchRuleManager fetchRuleManager;
-
-  private IRWOLockManager<CDOSessionImpl, Object> lockManager = new RWOLockManager<CDOSessionImpl, Object>();
-
-  @ExcludeFromDump
-  private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this);
-
-  private boolean mainBranchLocal;
-
-  private CDOAuthenticator authenticator;
-
-  private InternalCDORemoteSessionManager remoteSessionManager;
-
-  /**
-   * A map to track for every object that was committed since this session's last refresh, onto what CDOBranchPoint it
-   * was committed. (Used only for sticky transactions, see bug 290032 - Sticky views.)
-   */
-  private Map<CDOID, CDOBranchPoint> committedSinceLastRefresh = new HashMap<CDOID, CDOBranchPoint>();
-
-  static
-  {
-    // Ensure that these 3 packages are registered with the global package registry in stand-alone
-    EcorePackage.eINSTANCE.getClass();
-    EresourcePackage.eINSTANCE.getClass();
-    EtypesPackage.eINSTANCE.getClass();
-  }
-
-  public CDOSessionImpl()
-  {
-  }
-
-  public CDORepositoryInfo getRepositoryInfo()
-  {
-    return repositoryInfo;
-  }
-
-  public void setRepositoryInfo(CDORepositoryInfo repositoryInfo)
-  {
-    this.repositoryInfo = repositoryInfo;
-  }
-
-  public int getSessionID()
-  {
-    return sessionID;
-  }
-
-  public void setSessionID(int sessionID)
-  {
-    this.sessionID = sessionID;
-  }
-
-  public String getUserID()
-  {
-    return userID;
-  }
-
-  public void setUserID(String userID)
-  {
-    this.userID = userID;
-  }
-
-  public ExceptionHandler getExceptionHandler()
-  {
-    return exceptionHandler;
-  }
-
-  public void setExceptionHandler(ExceptionHandler exceptionHandler)
-  {
-    checkInactive();
-    this.exceptionHandler = exceptionHandler;
-  }
-
-  public CDOIDGenerator getIDGenerator()
-  {
-    return idGenerator;
-  }
-
-  public void setIDGenerator(CDOIDGenerator idGenerator)
-  {
-    checkInactive();
-    this.idGenerator = idGenerator;
-  }
-
-  public InternalCDOPackageRegistry getPackageRegistry()
-  {
-    return packageRegistry;
-  }
-
-  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
-  {
-    this.packageRegistry = packageRegistry;
-  }
-
-  public InternalCDOBranchManager getBranchManager()
-  {
-    return branchManager;
-  }
-
-  public void setBranchManager(InternalCDOBranchManager branchManager)
-  {
-    checkInactive();
-    this.branchManager = branchManager;
-  }
-
-  public InternalCDORevisionManager getRevisionManager()
-  {
-    return revisionManager;
-  }
-
-  public void setRevisionManager(InternalCDORevisionManager revisionManager)
-  {
-    checkInactive();
-    this.revisionManager = revisionManager;
-  }
-
-  public InternalCDOCommitInfoManager getCommitInfoManager()
-  {
-    return commitInfoManager;
-  }
-
-  public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
-  {
-    checkInactive();
-    this.commitInfoManager = commitInfoManager;
-  }
-
-  public CDOSessionProtocol getSessionProtocol()
-  {
-    return sessionProtocol;
-  }
-
-  public void setSessionProtocol(CDOSessionProtocol sessionProtocol)
-  {
-    checkInactive();
-    if (exceptionHandler == null)
-    {
-      this.sessionProtocol = sessionProtocol;
-    }
-    else
-    {
-      if (this.sessionProtocol instanceof DelegatingSessionProtocol)
-      {
-        ((DelegatingSessionProtocol)this.sessionProtocol).setDelegate(sessionProtocol);
-      }
-      else
-      {
-        this.sessionProtocol = new DelegatingSessionProtocol(sessionProtocol, exceptionHandler);
-      }
-    }
-  }
-
-  /**
-   * @since 3.0
-   */
-  public CDOFetchRuleManager getFetchRuleManager()
-  {
-    return fetchRuleManager;
-  }
-
-  /**
-   * @since 3.0
-   */
-  public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
-  {
-    if (fetchRuleManager == null)
-    {
-      fetchRuleManager = new NOOPFetchRuleManager()
-      {
-        public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
-        {
-          return options().getCollectionLoadingPolicy();
-        }
-      };
-    }
-
-    this.fetchRuleManager = fetchRuleManager;
-  }
-
-  public CDOAuthenticator getAuthenticator()
-  {
-    return authenticator;
-  }
-
-  public void setAuthenticator(CDOAuthenticator authenticator)
-  {
-    this.authenticator = authenticator;
-  }
-
-  public boolean isMainBranchLocal()
-  {
-    return mainBranchLocal;
-  }
-
-  public void setMainBranchLocal(boolean mainBranchLocal)
-  {
-    this.mainBranchLocal = mainBranchLocal;
-  }
-
-  public InternalCDORemoteSessionManager getRemoteSessionManager()
-  {
-    return remoteSessionManager;
-  }
-
-  public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager)
-  {
-    this.remoteSessionManager = remoteSessionManager;
-  }
-
-  public CDOLobStore getLobStore()
-  {
-    final CDOLobStore cache = options().getLobCache();
-    return new CDOLobStore.Delegating()
-    {
-      @Override
-      public InputStream getBinary(final CDOLobInfo info) throws IOException
-      {
-        for (;;)
-        {
-          try
-          {
-            return super.getBinary(info);
-          }
-          catch (FileNotFoundException couldNotBeRead)
-          {
-            try
-            {
-              loadBinary(info);
-            }
-            catch (FileNotFoundException couldNotBeCreated)
-            {
-              // Try to read again
-            }
-          }
-        }
-      }
-
-      @Override
-      public Reader getCharacter(CDOLobInfo info) throws IOException
-      {
-        for (;;)
-        {
-          try
-          {
-            return super.getCharacter(info);
-          }
-          catch (FileNotFoundException couldNotBeRead)
-          {
-            try
-            {
-              loadCharacter(info);
-            }
-            catch (FileNotFoundException couldNotBeCreated)
-            {
-              // Try to read again
-            }
-          }
-        }
-      }
-
-      private void loadBinary(final CDOLobInfo info) throws IOException
-      {
-        final File file = getDelegate().getBinaryFile(info.getID());
-        final FileOutputStream out = new FileOutputStream(file);
-
-        loadLobAsync(info, new Runnable()
-        {
-          public void run()
-          {
-            try
-            {
-              getSessionProtocol().loadLob(info, out);
-            }
-            catch (Throwable t)
-            {
-              OM.LOG.error(t);
-              IOUtil.delete(file);
-            }
-          }
-        });
-      }
-
-      private void loadCharacter(final CDOLobInfo info) throws IOException
-      {
-        final File file = getDelegate().getCharacterFile(info.getID());
-        final FileWriter out = new FileWriter(file);
-
-        loadLobAsync(info, new Runnable()
-        {
-          public void run()
-          {
-            try
-            {
-              getSessionProtocol().loadLob(info, out);
-            }
-            catch (Throwable t)
-            {
-              OM.LOG.error(t);
-              IOUtil.delete(file);
-            }
-          }
-        });
-      }
-
-      @Override
-      protected CDOLobStore getDelegate()
-      {
-        return cache;
-      }
-    };
-  }
-
-  protected void loadLobAsync(CDOLobInfo info, Runnable runnable)
-  {
-    new Thread(runnable, "LobLoader").start();
-  }
-
-  public void close()
-  {
-    LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
-  }
-
-  /**
-   * @since 2.0
-   */
-  public boolean isClosed()
-  {
-    return !isActive();
-  }
-
-  /**
-   * @since 2.0
-   */
-  public CDOSession.Options options()
-  {
-    return options;
-  }
-
-  /**
-   * @since 2.0
-   */
-  protected CDOSession.Options createOptions()
-  {
-    return new OptionsImpl();
-  }
-
-  public Object processPackage(Object value)
-  {
-    CDOFactoryImpl.prepareDynamicEPackage(value);
-    return value;
-  }
-
-  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
-  {
-    if (packageUnit.getOriginalType().isGenerated())
-    {
-      if (!options().isGeneratedPackageEmulationEnabled())
-      {
-        throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit)); //$NON-NLS-1$
-      }
-    }
-
-    return getSessionProtocol().loadPackages(packageUnit);
-  }
-
-  public void acquireAtomicRequestLock(Object key)
-  {
-    try
-    {
-      lockManager.lock(LockType.WRITE, key, this, IRWLockManager.WAIT);
-    }
-    catch (InterruptedException ex)
-    {
-      throw WrappedException.wrap(ex);
-    }
-  }
-
-  public void releaseAtomicRequestLock(Object key)
-  {
-    lockManager.unlock(LockType.WRITE, key, singletonCollection);
-  }
-
-  @Override
-  protected void initViewSynced(InternalCDOView view)
-  {
-    view.setSession(this);
-    view.setLastUpdateTime(getLastUpdateTime());
-  }
-
-  @Override
-  protected CDOBranch getMainBranch()
-  {
-    return getBranchManager().getMainBranch();
-  }
-
-  /**
-   * @since 2.0
-   */
-  public long refresh()
-  {
-    checkActive();
-    if (options().isPassiveUpdateEnabled())
-    {
-      return CDOBranchPoint.UNSPECIFIED_DATE;
-    }
-
-    return refresh(false);
-  }
-
-  private long refresh(boolean enablePassiveUpdates)
-  {
-    Map<CDOBranch, List<InternalCDOView>> views = new HashMap<CDOBranch, List<InternalCDOView>>();
-    Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions = new HashMap<CDOBranch, Map<CDOID, InternalCDORevision>>();
-    collectViewedRevisions(views, viewedRevisions);
-    cleanupRevisionCache(viewedRevisions);
-
-    CDOSessionProtocol sessionProtocol = getSessionProtocol();
-    long lastUpdateTime = getLastUpdateTime();
-    int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
-
-    RefreshSessionResult result = sessionProtocol.refresh(lastUpdateTime, viewedRevisions, initialChunkSize,
-        enablePassiveUpdates);
-
-    setLastUpdateTime(result.getLastUpdateTime());
-    registerPackageUnits(result.getPackageUnits());
-
-    for (Entry<CDOBranch, List<InternalCDOView>> entry : views.entrySet())
-    {
-      CDOBranch branch = entry.getKey();
-      List<InternalCDOView> branchViews = entry.getValue();
-      processRefreshSessionResult(result, branch, branchViews, viewedRevisions);
-    }
-
-    return result.getLastUpdateTime();
-  }
-
-  public void processRefreshSessionResult(RefreshSessionResult result, CDOBranch branch,
-      List<InternalCDOView> branchViews, Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
-  {
-    Map<CDOID, InternalCDORevision> oldRevisions = viewedRevisions.get(branch);
-
-    List<CDORevisionKey> changedObjects = new ArrayList<CDORevisionKey>();
-    List<InternalCDORevision> newRevisions = result.getChangedObjects(branch);
-    for (InternalCDORevision newRevision : newRevisions)
-    {
-      getRevisionManager().addRevision(newRevision);
-
-      InternalCDORevision oldRevision = oldRevisions.get(newRevision.getID());
-      InternalCDORevisionDelta delta = newRevision.compare(oldRevision);
-      changedObjects.add(delta);
-    }
-
-    List<CDOIDAndVersion> detachedObjects = result.getDetachedObjects(branch);
-    for (CDOIDAndVersion detachedObject : detachedObjects)
-    {
-      getRevisionManager().reviseLatest(detachedObject.getID(), branch);
-    }
-
-    for (InternalCDOView view : branchViews)
-    {
-      view.invalidate(view.getBranch(), result.getLastUpdateTime(), changedObjects, detachedObjects, oldRevisions,
-          false);
-    }
-  }
-
-  private void collectViewedRevisions(Map<CDOBranch, List<InternalCDOView>> views,
-      Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
-  {
-    for (InternalCDOView view : getViews())
-    {
-      if (view.getTimeStamp() == CDOView.UNSPECIFIED_DATE)
-      {
-        CDOBranch branch = view.getBranch();
-        Map<CDOID, InternalCDORevision> revisions = viewedRevisions.get(branch);
-        boolean needNewMap = revisions == null;
-        if (needNewMap)
-        {
-          revisions = new HashMap<CDOID, InternalCDORevision>();
-        }
-
-        view.collectViewedRevisions(revisions);
-        if (!revisions.isEmpty())
-        {
-          List<InternalCDOView> list = views.get(branch);
-          if (list == null)
-          {
-            list = new ArrayList<InternalCDOView>();
-            views.put(branch, list);
-          }
-
-          list.add(view);
-
-          if (needNewMap)
-          {
-            viewedRevisions.put(branch, revisions);
-          }
-        }
-      }
-    }
-  }
-
-  private void cleanupRevisionCache(Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
-  {
-    Set<InternalCDORevision> set = new HashSet<InternalCDORevision>();
-    for (Map<CDOID, InternalCDORevision> revisions : viewedRevisions.values())
-    {
-      for (InternalCDORevision revision : revisions.values())
-      {
-        set.add(revision);
-      }
-    }
-
-    InternalCDORevisionCache cache = getRevisionManager().getCache();
-    List<CDORevision> currentRevisions = cache.getCurrentRevisions();
-    for (CDORevision revision : currentRevisions)
-    {
-      if (!set.contains(revision))
-      {
-        cache.removeRevision(revision.getID(), revision);
-      }
-    }
-  }
-
-  public long getLastUpdateTime()
-  {
-    synchronized (lastUpdateTimeLock)
-    {
-      return lastUpdateTime;
-    }
-  }
-
-  public void setLastUpdateTime(long lastUpdateTime)
-  {
-    synchronized (lastUpdateTimeLock)
-    {
-      if (this.lastUpdateTime < lastUpdateTime)
-      {
-        this.lastUpdateTime = lastUpdateTime;
-      }
-
-      lastUpdateTimeLock.notifyAll();
-    }
-  }
-
-  public void waitForUpdate(long updateTime)
-  {
-    waitForUpdate(updateTime, NO_TIMEOUT);
-  }
-
-  public boolean waitForUpdate(long updateTime, long timeoutMillis)
-  {
-    long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
-    InternalCDOView views[] = getViews();
-    if (views.length > 0)
-    {
-      for (CDOView view : views)
-      {
-        long viewTimeoutMillis = timeoutMillis == NO_TIMEOUT ? NO_TIMEOUT : end - System.currentTimeMillis();
-        boolean ok = view.waitForUpdate(updateTime, viewTimeoutMillis);
-        if (!ok)
-        {
-          return false;
-        }
-      }
-
-      return true;
-    }
-
-    // Session without views
-    for (;;)
-    {
-      synchronized (lastUpdateTimeLock)
-      {
-        if (lastUpdateTime >= updateTime)
-        {
-          return true;
-        }
-
-        long now = System.currentTimeMillis();
-        if (now >= end)
-        {
-          return false;
-        }
-
-        try
-        {
-          lastUpdateTimeLock.wait(end - now);
-        }
-        catch (InterruptedException ex)
-        {
-          throw WrappedException.wrap(ex);
-        }
-      }
-    }
-  }
-
-  /**
-   * @since 3.0
-   */
-  public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
-  {
-    CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
-    return policy.resolveProxy(revision, feature, accessIndex, serverIndex);
-  }
-
-  /**
-   * @since 4.0
-   */
-  public void resolveAllElementProxies(CDORevision revision)
-  {
-    CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
-    for (EStructuralFeature feature : revision.getEClass().getEAllStructuralFeatures())
-    {
-      if (feature instanceof EReference)
-      {
-        EReference reference = (EReference)feature;
-        if (reference.isMany() && EMFUtil.isPersistent(reference))
-        {
-          CDOList list = ((InternalCDORevision)revision).getList(reference);
-          for (Iterator<Object> it = list.iterator(); it.hasNext();)
-          {
-            Object element = it.next();
-            if (element instanceof CDOElementProxy)
-            {
-              policy.resolveAllProxies(revision, reference);
-              break;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  public void handleRepositoryTypeChanged(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
-  {
-    fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
-  }
-
-  public void handleRepositoryStateChanged(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
-  {
-    fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
-  }
-
-  public void handleBranchNotification(InternalCDOBranch branch)
-  {
-    getBranchManager().handleBranchCreated(branch);
-  }
-
-  public void handleCommitNotification(CDOCommitInfo commitInfo)
-  {
-    try
-    {
-      registerPackageUnits(commitInfo.getNewPackageUnits());
-      invalidate(commitInfo, null);
-    }
-    catch (RuntimeException ex)
-    {
-      if (isActive())
-      {
-        OM.LOG.error(ex);
-      }
-      else
-      {
-        OM.LOG.info(Messages.getString("CDOSessionImpl.2")); //$NON-NLS-1$
-      }
-    }
-  }
-
-  public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
-  {
-    for (InternalCDOView view : getViews())
-    {
-      if (view != sender)
-      {
-        view.handleLockNotification(sender, lockChangeInfo);
-      }
-    }
-
-    fireEvent(new LocksChangedEvent(sender, lockChangeInfo));
-  }
-
-  private void registerPackageUnits(List<CDOPackageUnit> packageUnits)
-  {
-    InternalCDOPackageRegistry packageRegistry = getPackageRegistry();
-    for (CDOPackageUnit newPackageUnit : packageUnits)
-    {
-      packageRegistry.putPackageUnit((InternalCDOPackageUnit)newPackageUnit);
-    }
-  }
-
-  private Map<CDOID, InternalCDORevision> reviseRevisions(CDOCommitInfo commitInfo)
-  {
-    Map<CDOID, InternalCDORevision> oldRevisions = null;
-    CDOBranch newBranch = commitInfo.getBranch();
-    long timeStamp = commitInfo.getTimeStamp();
-    InternalCDORevisionManager revisionManager = getRevisionManager();
-
-    // Cache new revisions
-    for (CDOIDAndVersion key : commitInfo.getNewObjects())
-    {
-      if (key instanceof InternalCDORevision)
-      {
-        InternalCDORevision newRevision = (InternalCDORevision)key;
-        revisionManager.addRevision(newRevision);
-      }
-    }
-
-    // Apply deltas and cache the resulting new revisions, if possible...
-    for (CDORevisionKey key : commitInfo.getChangedObjects())
-    {
-      // Add old values to revision deltas.
-      if (key instanceof CDORevisionDelta)
-      {
-        final CDORevisionDelta revisionDelta = (CDORevisionDelta)key;
-        final CDORevision oldRevision = revisionManager.getRevisionByVersion(revisionDelta.getID(), revisionDelta,
-            CDORevision.UNCHUNKED, false);
-
-        if (oldRevision != null)
-        {
-          CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitorImpl()
-          {
-            private List<Object> workList;
-
-            @Override
-            public void visit(CDOAddFeatureDelta delta)
-            {
-              workList.add(delta.getIndex(), delta.getValue());
-            }
-
-            @Override
-            public void visit(CDOClearFeatureDelta delta)
-            {
-              workList.clear();
-            }
-
-            @Override
-            public void visit(CDOListFeatureDelta deltas)
-            {
-              @SuppressWarnings("unchecked")
-              List<Object> list = (List<Object>)((InternalCDORevision)oldRevision).getValue(deltas.getFeature());
-              if (list != null)
-              {
-                workList = new ArrayList<Object>(list);
-                super.visit(deltas);
-              }
-            }
-
-            @Override
-            public void visit(CDOMoveFeatureDelta delta)
-            {
-              Object value = workList.get(delta.getOldPosition());
-              ((CDOMoveFeatureDeltaImpl)delta).setValue(value);
-              ECollections.move(workList, delta.getNewPosition(), delta.getOldPosition());
-            }
-
-            @Override
-            public void visit(CDORemoveFeatureDelta delta)
-            {
-              Object oldValue = workList.remove(delta.getIndex());
-              ((CDOSingleValueFeatureDeltaImpl)delta).setValue(oldValue);
-            }
-
-            @Override
-            public void visit(CDOSetFeatureDelta delta)
-            {
-              EStructuralFeature feature = delta.getFeature();
-              Object value = null;
-              if (feature.isMany())
-              {
-                value = workList.set(delta.getIndex(), delta.getValue());
-              }
-              else
-              {
-                value = ((InternalCDORevision)oldRevision).getValue(feature);
-              }
-
-              ((CDOSetFeatureDeltaImpl)delta).setOldValue(value);
-            }
-          };
-
-          for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas())
-          {
-            featureDelta.accept(visitor);
-          }
-        }
-      }
-
-      CDOID id = key.getID();
-      Pair<InternalCDORevision, InternalCDORevision> pair = createNewRevision(key, commitInfo);
-      if (pair != null)
-      {
-        InternalCDORevision newRevision = pair.getElement2();
-        revisionManager.addRevision(newRevision);
-        if (oldRevisions == null)
-        {
-          oldRevisions = new HashMap<CDOID, InternalCDORevision>();
-        }
-
-        InternalCDORevision oldRevision = pair.getElement1();
-        oldRevisions.put(id, oldRevision);
-      }
-      else
-      {
-        // ... otherwise try to revise old revision if it is in the same branch
-        if (ObjectUtil.equals(key.getBranch(), newBranch))
-        {
-          revisionManager.reviseVersion(id, key, timeStamp);
-        }
-      }
-    }
-
-    // Revise old revisions
-    for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
-    {
-      CDOID id = key.getID();
-      int version = key.getVersion();
-      if (version == CDOBranchVersion.UNSPECIFIED_VERSION)
-      {
-        revisionManager.reviseLatest(id, newBranch);
-      }
-      else
-      {
-        CDOBranchVersion branchVersion = newBranch.getVersion(version);
-        revisionManager.reviseVersion(id, branchVersion, timeStamp);
-      }
-    }
-
-    return oldRevisions;
-  }
-
-  private Pair<InternalCDORevision, InternalCDORevision> createNewRevision(CDORevisionKey potentialDelta,
-      CDOCommitInfo commitInfo)
-  {
-    if (potentialDelta instanceof CDORevisionDelta)
-    {
-      CDORevisionDelta delta = (CDORevisionDelta)potentialDelta;
-      CDOID id = delta.getID();
-
-      InternalCDORevisionManager revisionManager = getRevisionManager();
-      InternalCDORevision oldRevision = revisionManager.getRevisionByVersion(id, potentialDelta, CDORevision.UNCHUNKED,
-          false);
-      if (oldRevision != null)
-      {
-        InternalCDORevision newRevision = oldRevision.copy();
-        newRevision.adjustForCommit(commitInfo.getBranch(), commitInfo.getTimeStamp());
-
-        CDORevisable target = delta.getTarget();
-        if (target != null)
-        {
-          newRevision.setVersion(target.getVersion());
-        }
-
-        delta.apply(newRevision);
-        newRevision.freeze();
-        return new Pair<InternalCDORevision, InternalCDORevision>(oldRevision, newRevision);
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
-  {
-    long previousTimeStamp = commitInfo.getPreviousTimeStamp();
-    long lastUpdateTime = getLastUpdateTime();
-
-    if (previousTimeStamp < lastUpdateTime)
-    {
-      previousTimeStamp = lastUpdateTime;
-    }
-
-    synchronized (outOfSequenceInvalidations)
-    {
-      outOfSequenceInvalidations.put(previousTimeStamp, new Pair<CDOCommitInfo, InternalCDOTransaction>(commitInfo,
-          sender));
-    }
-
-    long nextPreviousTimeStamp = lastUpdateTime;
-    for (;;)
-    {
-      synchronized (outOfSequenceInvalidations)
-      {
-        Pair<CDOCommitInfo, InternalCDOTransaction> currentPair = outOfSequenceInvalidations
-            .remove(nextPreviousTimeStamp);
-
-        // If we don't have the invalidation that follows the last one we processed,
-        // then there is nothing we can do right now
-        if (currentPair == null)
-        {
-          break;
-        }
-
-        final CDOCommitInfo currentCommitInfo = currentPair.getElement1();
-        final InternalCDOTransaction currentSender = currentPair.getElement2();
-        nextPreviousTimeStamp = currentCommitInfo.getTimeStamp();
-
-        if (sender == null)
-        {
-          QueueRunner invalidationRunner = getInvalidationRunner();
-          invalidationRunner.addWork(new Runnable()
-          {
-            public void run()
-            {
-              invalidateOrdered(currentCommitInfo, currentSender);
-            }
-          });
-        }
-        else
-        {
-          invalidateOrdered(currentCommitInfo, currentSender);
-        }
-      }
-    }
-  }
-
-  /**
-   * This method is synchronized on outOfSequenceInvalidations by the caller!
-   */
-  private QueueRunner getInvalidationRunner()
-  {
-    if (invalidationRunner == null)
-    {
-      invalidationRunner = new QueueRunner();
-      invalidationRunner.activate();
-    }
-
-    return invalidationRunner;
-  }
-
-  private void invalidateOrdered(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
-  {
-    Map<CDOID, InternalCDORevision> oldRevisions = null;
-    boolean success = commitInfo.getBranch() != null;
-    if (success)
-    {
-      oldRevisions = reviseRevisions(commitInfo);
-    }
-
-    if (options.isPassiveUpdateEnabled())
-    {
-      setLastUpdateTime(commitInfo.getTimeStamp());
-    }
-
-    if (success)
-    {
-      fireInvalidationEvent(sender, commitInfo);
-    }
-
-    for (InternalCDOView view : getViews())
-    {
-      if (view != sender)
-      {
-        invalidateView(commitInfo, view, oldRevisions);
-      }
-      else
-      {
-        view.setLastUpdateTime(commitInfo.getTimeStamp());
-      }
-    }
-  }
-
-  private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view,
-      Map<CDOID, InternalCDORevision> oldRevisions)
-  {
-    try
-    {
-      CDOBranch branch = commitInfo.getBranch();
-      long lastUpdateTime = commitInfo.getTimeStamp();
-      List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
-      List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
-      view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true);
-    }
-    catch (RuntimeException ex)
-    {
-      if (view.isActive())
-      {
-        OM.LOG.error(ex);
-      }
-      else
-      {
-        OM.LOG.info(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
-      }
-    }
-  }
-
-  /**
-   * @since 2.0
-   */
-  public void fireInvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
-  {
-    fireEvent(new InvalidationEvent(sender, commitInfo));
-  }
-
-  @Override
-  public String toString()
-  {
-    String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); //$NON-NLS-1$
-    return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$
-  }
-
-  public CDOBranchPoint getCommittedSinceLastRefresh(CDOID id)
-  {
-    if (isSticky())
-    {
-      return committedSinceLastRefresh.get(id);
-    }
-
-    return null;
-  }
-
-  public void setCommittedSinceLastRefresh(CDOID id, CDOBranchPoint branchPoint)
-  {
-    if (isSticky())
-    {
-      committedSinceLastRefresh.put(id, branchPoint);
-    }
-  }
-
-  public void clearCommittedSinceLastRefresh()
-  {
-    if (isSticky())
-    {
-      committedSinceLastRefresh.clear();
-    }
-  }
-
-  public boolean isSticky()
-  {
-    return !options().isPassiveUpdateEnabled() && getRepositoryInfo().isSupportingAudits();
-  }
-
-  public CDOChangeSetData compareRevisions(CDOBranchPoint source, CDOBranchPoint target)
-  {
-    long now = getLastUpdateTime();
-
-    if (target.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
-    {
-      target = target.getBranch().getPoint(now);
-    }
-
-    if (source.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
-    {
-      source = source.getBranch().getPoint(now);
-    }
-
-    CDORevisionAvailabilityInfo targetInfo = createRevisionAvailabilityInfo(target);
-    CDORevisionAvailabilityInfo sourceInfo = createRevisionAvailabilityInfo(source);
-
-    Set<CDOID> ids = sessionProtocol.loadMergeData(targetInfo, sourceInfo, null, null);
-
-    cacheRevisions(targetInfo);
-    cacheRevisions(sourceInfo);
-
-    return CDORevisionUtil.createChangeSetData(ids, sourceInfo, targetInfo);
-  }
-
-  public CDORevisionAvailabilityInfo createRevisionAvailabilityInfo(CDOBranchPoint branchPoint)
-  {
-    CDORevisionAvailabilityInfo info = new CDORevisionAvailabilityInfo(branchPoint);
-
-    InternalCDORevisionManager revisionManager = getRevisionManager();
-    InternalCDORevisionCache cache = revisionManager.getCache();
-
-    List<CDORevision> revisions = cache.getRevisions(branchPoint);
-    for (CDORevision revision : revisions)
-    {
-      if (revision instanceof PointerCDORevision)
-      {
-        PointerCDORevision pointer = (PointerCDORevision)revision;
-        CDOBranchVersion target = pointer.getTarget();
-        if (target != null)
-        {
-          revision = cache.getRevisionByVersion(pointer.getID(), target);
-        }
-      }
-      else if (revision instanceof DetachedCDORevision)
-      {
-        revision = null;
-      }
-
-      if (revision != null)
-      {
-        resolveAllElementProxies(revision);
-        info.addRevision(revision);
-      }
-    }
-
-    return info;
-  }
-
-  public void cacheRevisions(CDORevisionAvailabilityInfo info)
-  {
-    InternalCDORevisionManager revisionManager = getRevisionManager();
-    CDOBranch branch = info.getBranchPoint().getBranch();
-    for (CDORevisionKey key : info.getAvailableRevisions().values())
-    {
-      CDORevision revision = (CDORevision)key;
-      revisionManager.addRevision(revision);
-
-      if (!ObjectUtil.equals(revision.getBranch(), branch))
-      {
-        CDOID id = revision.getID();
-        CDORevision firstRevision = revisionManager.getCache().getRevisionByVersion(id,
-            branch.getVersion(CDOBranchVersion.FIRST_VERSION));
-        if (firstRevision != null)
-        {
-          long revised = firstRevision.getTimeStamp() - 1L;
-          CDOBranchVersion target = CDOBranchUtil.copyBranchVersion(revision);
-          PointerCDORevision pointer = new PointerCDORevision(revision.getEClass(), id, branch, revised, target);
-          revisionManager.addRevision(pointer);
-        }
-      }
-    }
-  }
-
-  @Override
-  protected void doActivate() throws Exception
-  {
-    super.doActivate();
-
-    InternalCDORemoteSessionManager remoteSessionManager = new CDORemoteSessionManagerImpl();
-    remoteSessionManager.setLocalSession(this);
-    setRemoteSessionManager(remoteSessionManager);
-    remoteSessionManager.activate();
-
-    checkState(sessionProtocol, "sessionProtocol"); //$NON-NLS-1$
-    checkState(remoteSessionManager, "remoteSessionManager"); //$NON-NLS-1$
-  }
-
-  @Override
-  protected void doDeactivate() throws Exception
-  {
-    super.doDeactivate();
-
-    LifecycleUtil.deactivate(invalidationRunner);
-    outOfSequenceInvalidations.clear();
-
-    unhookSessionProtocol();
-
-    CDORemoteSessionManager remoteSessionManager = getRemoteSessionManager();
-    setRemoteSessionManager(null);
-    LifecycleUtil.deactivate(remoteSessionManager);
-
-    CDOSessionProtocol sessionProtocol = getSessionProtocol();
-    LifecycleUtil.deactivate(sessionProtocol);
-    setSessionProtocol(null);
-  }
-
-  /**
-   * Makes this session start listening to its protocol
-   */
-  protected CDOSessionProtocol hookSessionProtocol()
-  {
-    EventUtil.addListener(sessionProtocol, sessionProtocolListener);
-    return sessionProtocol;
-  }
-
-  /**
-   * Makes this session stop listening to its protocol
-   */
-  protected void unhookSessionProtocol()
-  {
-    EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
-  }
-
-  protected void sessionProtocolDeactivated()
-  {
-    deactivate();
-  }
-
-  /**
-   * A separate class for better monitor debugging.
-   * 
-   * @author Eike Stepper
-   */
-  private static final class LastUpdateTimeLock
-  {
-  }
-
-  /**
-   * @author Eike Stepper
-   */
-  private static final class OutOfSequenceInvalidations extends
-      HashMap<Long, Pair<CDOCommitInfo, InternalCDOTransaction>>
-  {
-    private static final long serialVersionUID = 1L;
-  }
-
-  /**
-   * @author Eike Stepper
-   * @since 2.0
-   */
-  protected class OptionsImpl extends Notifier implements Options
-  {
-    private boolean generatedPackageEmulationEnabled;
-
-    private boolean passiveUpdateEnabled = true;
-
-    private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
-
-    private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
-
-    private CDOCollectionLoadingPolicy collectionLoadingPolicy;
-
-    private CDOLobStore lobCache = CDOLobStoreImpl.INSTANCE;
-
-    public OptionsImpl()
-    {
-      setCollectionLoadingPolicy(null); // Init default
-    }
-
-    public CDOSession getContainer()
-    {
-      return CDOSessionImpl.this;
-    }
-
-    public boolean isGeneratedPackageEmulationEnabled()
-    {
-      return generatedPackageEmulationEnabled;
-    }
-
-    public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled)
-    {
-      this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
-      if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled)
-      {
-        this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
-        // TODO Check inconsistent state if switching off?
-
-        IListener[] listeners = getListeners();
-        if (listeners != null)
-        {
-          fireEvent(new GeneratedPackageEmulationEventImpl(), listeners);
-        }
-      }
-    }
-
-    public boolean isPassiveUpdateEnabled()
-    {
-      return passiveUpdateEnabled;
-    }
-
-    public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
-    {
-      if (this.passiveUpdateEnabled != passiveUpdateEnabled)
-      {
-        this.passiveUpdateEnabled = passiveUpdateEnabled;
-        CDOSessionProtocol protocol = getSessionProtocol();
-        if (protocol != null)
-        {
-          if (passiveUpdateEnabled)
-          {
-            refresh(true);
-          }
-          else
-          {
-            protocol.disablePassiveUpdate();
-          }
-
-          IListener[] listeners = getListeners();
-          if (listeners != null)
-          {
-            fireEvent(new PassiveUpdateEventImpl(!passiveUpdateEnabled, passiveUpdateEnabled, passiveUpdateMode,
-                passiveUpdateMode), listeners);
-          }
-        }
-      }
-    }
-
-    public PassiveUpdateMode getPassiveUpdateMode()
-    {
-      return passiveUpdateMode;
-    }
-
-    public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
-    {
-      checkArg(passiveUpdateMode, "passiveUpdateMode"); //$NON-NLS-1$
-      if (this.passiveUpdateMode != passiveUpdateMode)
-      {
-        PassiveUpdateMode oldMode = this.passiveUpdateMode;
-        this.passiveUpdateMode = passiveUpdateMode;
-        CDOSessionProtocol protocol = getSessionProtocol();
-        if (protocol != null)
-        {
-          protocol.setPassiveUpdateMode(passiveUpdateMode);
-
-          IListener[] listeners = getListeners();
-          if (listeners != null)
-          {
-            fireEvent(
-                new PassiveUpdateEventImpl(passiveUpdateEnabled, passiveUpdateEnabled, oldMode, passiveUpdateMode),
-                listeners);
-          }
-        }
-      }
-    }
-
-    public LockNotificationMode getLockNotificationMode()
-    {
-      return lockNotificationMode;
-    }
-
-    public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
-    {
-      checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$
-      if (this.lockNotificationMode != lockNotificationMode)
-      {
-        LockNotificationMode oldMode = this.lockNotificationMode;
-        this.lockNotificationMode = lockNotificationMode;
-        CDOSessionProtocol protocol = getSessionProtocol();
-        if (protocol != null)
-        {
-          protocol.setLockNotificationMode(lockNotificationMode);
-
-          IListener[] listeners = getListeners();
-          if (listeners != null)
-          {
-            fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners);
-          }
-        }
-      }
-      this.lockNotificationMode = lockNotificationMode;
-    }
-
-    public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
-    {
-      synchronized (this)
-      {
-        return collectionLoadingPolicy;
-      }
-    }
-
-    public void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
-    {
-      if (policy == null)
-      {
-        policy = CDOUtil.createCollectionLoadingPolicy(CDORevision.UNCHUNKED, CDORevision.UNCHUNKED);
-      }
-
-      CDOSession oldSession = policy.getSession();
-      if (oldSession != null)
-      {
-        throw new IllegalArgumentException("Policy is already associated with " + oldSession);
-      }
-
-      policy.setSession(CDOSessionImpl.this);
-
-      IListener[] listeners = getListeners();
-      IEvent event = null;
-
-      synchronized (this)
-      {
-        if (collectionLoadingPolicy != policy)
-        {
-          collectionLoadingPolicy = policy;
-          if (listeners != null)
-          {
-            event = new CollectionLoadingPolicyEventImpl();
-          }
-        }
-      }
-
-      if (event != null)
-      {
-        fireEvent(event, listeners);
-      }
-    }
-
-    public CDOLobStore getLobCache()
-    {
-      synchronized (this)
-      {
-        return lobCache;
-      }
-    }
-
-    public void setLobCache(CDOLobStore cache)
-    {
-      if (cache == null)
-      {
-        cache = CDOLobStoreImpl.INSTANCE;
-      }
-
-      IListener[] listeners = getListeners();
-      IEvent event = null;
-
-      synchronized (this)
-      {
-        if (lobCache != cache)
-        {
-          lobCache = cache;
-          if (listeners != null)
-          {
-            event = new LobCacheEventImpl();
-          }
-        }
-      }
-
-      if (event != null)
-      {
-        fireEvent(event, listeners);
-      }
-    }
-
-    /**
-     * @author Eike Stepper
-     */
-    private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements
-        GeneratedPackageEmulationEvent
-    {
-      private static final long serialVersionUID = 1L;
-
-      public GeneratedPackageEmulationEventImpl()
-      {
-        super(OptionsImpl.this);
-      }
-    }
-
-    /**
-     * @author Eike Stepper
-     */
-    private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
-    {
-      private static final long serialVersionUID = 1L;
-
-      private boolean oldEnabled;
-
-      private boolean newEnabled;
-
-      private PassiveUpdateMode oldMode;
-
-      private PassiveUpdateMode newMode;
-
-      public PassiveUpdateEventImpl(boolean oldEnabled, boolean newEnabled, PassiveUpdateMode oldMode,
-          PassiveUpdateMode newMode)
-      {
-        super(OptionsImpl.this);
-        this.oldEnabled = oldEnabled;
-        this.newEnabled = newEnabled;
-        this.oldMode = oldMode;
-        this.newMode = newMode;
-      }
-
-      public boolean getOldEnabled()
-      {
-        return oldEnabled;
-      }
-
-      public boolean getNewEnabled()
-      {
-        return newEnabled;
-      }
-
-      public PassiveUpdateMode getOldMode()
-      {
-        return oldMode;
-      }
-
-      public PassiveUpdateMode getNewMode()
-      {
-        return newMode;
-      }
-    }
-
-    /**
-     * @author Caspar De Groot
-     */
-    private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent
-    {
-      private static final long serialVersionUID = 1L;
-
-      private LockNotificationMode oldMode, newMode;
-
-      public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode)
-      {
-        super(OptionsImpl.this);
-        this.oldMode = oldMode;
-        this.newMode = newMode;
-      }
-
-      public LockNotificationMode getOldMode()
-      {
-        return oldMode;
-      }
-
-      public LockNotificationMode getNewMode()
-      {
-        return newMode;
-      }
-    }
-
-    /**
-     * @author Eike Stepper
-     */
-    private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
-    {
-      private static final long serialVersionUID = 1L;
-
-      public CollectionLoadingPolicyEventImpl()
-      {
-        super(OptionsImpl.this);
-      }
-    }
-
-    /**
-     * @author Eike Stepper
-     */
-    private final class LobCacheEventImpl extends OptionsEvent implements LobCacheEvent
-    {
-      private static final long serialVersionUID = 1L;
-
-      public LobCacheEventImpl()
-      {
-        super(OptionsImpl.this);
-      }
-    }
-  }
-
-  /**
-   * @author Eike Stepper
-   */
-  private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
-  {
-    private static final long serialVersionUID = 1L;
-
-    private InternalCDOTransaction sender;
-
-    private CDOCommitInfo commitInfo;
-
-    public InvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
-    {
-      super(CDOSessionImpl.this);
-      this.sender = sender;
-      this.commitInfo = commitInfo;
-    }
-
-    @Override
-    public CDOSession getSource()
-    {
-      return (CDOSession)super.getSource();
-    }
-
-    public CDOCommitInfoManager getCommitInfoManager()
-    {
-      return commitInfo.getCommitInfoManager();
-    }
-
-    public CDOTransaction getLocalTransaction()
-    {
-      return sender;
-    }
-
-    @Deprecated
-    public InternalCDOView getView()
-    {
-      return sender;
-    }
-
-    public boolean isRemote()
-    {
-      return sender == null;
-    }
-
-    public CDOBranch getBranch()
-    {
-      return commitInfo.getBranch();
-    }
-
-    public long getTimeStamp()
-    {
-      return commitInfo.getTimeStamp();
-    }
-
-    public long getPreviousTimeStamp()
-    {
-      return commitInfo.getPreviousTimeStamp();
-    }
-
-    public String getUserID()
-    {
-      return commitInfo.getUserID();
-    }
-
-    public String getComment()
-    {
-      return commitInfo.getComment();
-    }
-
-    public boolean isEmpty()
-    {
-      return false;
-    }
-
-    public CDOChangeSetData copy()
-    {
-      return commitInfo.copy();
-    }
-
-    public void merge(CDOChangeSetData changeSetData)
-    {
-      commitInfo.merge(changeSetData);
-    }
-
-    public List<CDOPackageUnit> getNewPackageUnits()
-    {
-      return commitInfo.getNewPackageUnits();
-    }
-
-    public List<CDOIDAndVersion> getNewObjects()
-    {
-      return commitInfo.getNewObjects();
-    }
-
-    public List<CDORevisionKey> getChangedObjects()
-    {
-      return commitInfo.getChangedObjects();
-    }
-
-    public List<CDOIDAndVersion> getDetachedObjects()
-    {
-      return commitInfo.getDetachedObjects();
-    }
-
-    public Map<CDOID, CDOChangeKind> getChangeKinds()
-    {
-      return commitInfo.getChangeKinds();
-    }
-
-    public CDOChangeKind getChangeKind(CDOID id)
-    {
-      return commitInfo.getChangeKind(id);
-    }
-
-    @Override
-    public String toString()
-    {
-      return "CDOSessionInvalidationEvent[" + commitInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
-    }
-  }
-
-  /**
-   * @author Caspar De Groot
-   * @since 4.1
-   */
-  private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOSessionLocksChangedEvent
-  {
-    private static final long serialVersionUID = 1L;
-
-    public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
-    {
-      super(CDOSessionImpl.this, sender, lockChangeInfo);
-    }
-
-    @Override
-    public CDOSession getSource()
-    {
-      return (CDOSession)super.getSource();
-    }
-  }
-}
+/*
+ * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others.
+ * 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:
+ *    Eike Stepper - initial API and implementation
+ *    Simon McDuff - bug 226778
+ *    Simon McDuff - bug 230832
+ *    Simon McDuff - bug 233490
+ *    Simon McDuff - bug 213402
+ *    Victor Roldan Betancort - maintenance
+ */
+package org.eclipse.emf.internal.cdo.session;
+
+import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeKind;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
+import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
+import org.eclipse.emf.cdo.common.lob.CDOLobStore;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
+import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
+import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.CDOException;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.etypes.EtypesPackage;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOMoveFeatureDeltaImpl;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl;
+import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
+import org.eclipse.emf.cdo.session.CDORepositoryInfo;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
+import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
+import org.eclipse.emf.cdo.spi.common.CDOLobStoreImpl;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.CDOFeatureDeltaVisitorImpl;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.internal.cdo.analyzer.NOOPFetchRuleManager;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.messages.Messages;
+import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
+import org.eclipse.emf.internal.cdo.session.remote.CDORemoteSessionManagerImpl;
+import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.IRWOLockManager;
+import org.eclipse.net4j.util.concurrent.QueueRunner;
+import org.eclipse.net4j.util.concurrent.RWOLockManager;
+import org.eclipse.net4j.util.event.Event;
+import org.eclipse.net4j.util.event.EventUtil;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.event.Notifier;
+import org.eclipse.net4j.util.io.IOUtil;
+import org.eclipse.net4j.util.lifecycle.ILifecycle;
+import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.options.OptionsEvent;
+
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.RefreshSessionResult;
+import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager;
+import org.eclipse.emf.spi.cdo.InternalCDOSession;
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOSessionImpl extends CDOTransactionContainerImpl implements InternalCDOSession
+{
+  private ExceptionHandler exceptionHandler;
+
+  private CDOIDGenerator idGenerator;
+
+  private InternalCDOPackageRegistry packageRegistry;
+
+  private InternalCDOBranchManager branchManager;
+
+  private InternalCDORevisionManager revisionManager;
+
+  private InternalCDOCommitInfoManager commitInfoManager;
+
+  private CDOSessionProtocol sessionProtocol;
+
+  @ExcludeFromDump
+  private IListener sessionProtocolListener = new LifecycleEventAdapter()
+  {
+    @Override
+    protected void onDeactivated(ILifecycle lifecycle)
+    {
+      sessionProtocolDeactivated();
+    }
+  };
+
+  private int sessionID;
+
+  private String userID;
+
+  private long lastUpdateTime;
+
+  @ExcludeFromDump
+  private LastUpdateTimeLock lastUpdateTimeLock = new LastUpdateTimeLock();
+
+  private CDOSession.Options options = createOptions();
+
+  private OutOfSequenceInvalidations outOfSequenceInvalidations = new OutOfSequenceInvalidations();
+
+  private QueueRunner invalidationRunner;
+
+  private CDORepositoryInfo repositoryInfo;
+
+  private CDOFetchRuleManager fetchRuleManager;
+
+  private IRWOLockManager<CDOSessionImpl, Object> lockManager = new RWOLockManager<CDOSessionImpl, Object>();
+
+  @ExcludeFromDump
+  private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this);
+
+  private boolean mainBranchLocal;
+
+  private CDOAuthenticator authenticator;
+
+  private InternalCDORemoteSessionManager remoteSessionManager;
+
+  /**
+   * A map to track for every object that was committed since this session's last refresh, onto what CDOBranchPoint it
+   * was committed. (Used only for sticky transactions, see bug 290032 - Sticky views.)
+   */
+  private Map<CDOID, CDOBranchPoint> committedSinceLastRefresh = new HashMap<CDOID, CDOBranchPoint>();
+
+  static
+  {
+    // Ensure that these 3 packages are registered with the global package registry in stand-alone
+    EcorePackage.eINSTANCE.getClass();
+    EresourcePackage.eINSTANCE.getClass();
+    EtypesPackage.eINSTANCE.getClass();
+  }
+
+  public CDOSessionImpl()
+  {
+  }
+
+  public CDORepositoryInfo getRepositoryInfo()
+  {
+    return repositoryInfo;
+  }
+
+  public void setRepositoryInfo(CDORepositoryInfo repositoryInfo)
+  {
+    this.repositoryInfo = repositoryInfo;
+  }
+
+  public int getSessionID()
+  {
+    return sessionID;
+  }
+
+  public void setSessionID(int sessionID)
+  {
+    this.sessionID = sessionID;
+  }
+
+  public String getUserID()
+  {
+    return userID;
+  }
+
+  public void setUserID(String userID)
+  {
+    this.userID = userID;
+  }
+
+  public ExceptionHandler getExceptionHandler()
+  {
+    return exceptionHandler;
+  }
+
+  public void setExceptionHandler(ExceptionHandler exceptionHandler)
+  {
+    checkInactive();
+    this.exceptionHandler = exceptionHandler;
+  }
+
+  public CDOIDGenerator getIDGenerator()
+  {
+    return idGenerator;
+  }
+
+  public void setIDGenerator(CDOIDGenerator idGenerator)
+  {
+    checkInactive();
+    this.idGenerator = idGenerator;
+  }
+
+  public InternalCDOPackageRegistry getPackageRegistry()
+  {
+    return packageRegistry;
+  }
+
+  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
+  {
+    this.packageRegistry = packageRegistry;
+  }
+
+  public InternalCDOBranchManager getBranchManager()
+  {
+    return branchManager;
+  }
+
+  public void setBranchManager(InternalCDOBranchManager branchManager)
+  {
+    checkInactive();
+    this.branchManager = branchManager;
+  }
+
+  public InternalCDORevisionManager getRevisionManager()
+  {
+    return revisionManager;
+  }
+
+  public void setRevisionManager(InternalCDORevisionManager revisionManager)
+  {
+    checkInactive();
+    this.revisionManager = revisionManager;
+  }
+
+  public InternalCDOCommitInfoManager getCommitInfoManager()
+  {
+    return commitInfoManager;
+  }
+
+  public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
+  {
+    checkInactive();
+    this.commitInfoManager = commitInfoManager;
+  }
+
+  public CDOSessionProtocol getSessionProtocol()
+  {
+    return sessionProtocol;
+  }
+
+  public void setSessionProtocol(CDOSessionProtocol sessionProtocol)
+  {
+    checkInactive();
+    if (exceptionHandler == null)
+    {
+      this.sessionProtocol = sessionProtocol;
+    }
+    else
+    {
+      if (this.sessionProtocol instanceof DelegatingSessionProtocol)
+      {
+        ((DelegatingSessionProtocol)this.sessionProtocol).setDelegate(sessionProtocol);
+      }
+      else
+      {
+        this.sessionProtocol = new DelegatingSessionProtocol(sessionProtocol, exceptionHandler);
+      }
+    }
+  }
+
+  /**
+   * @since 3.0
+   */
+  public CDOFetchRuleManager getFetchRuleManager()
+  {
+    return fetchRuleManager;
+  }
+
+  /**
+   * @since 3.0
+   */
+  public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
+  {
+    if (fetchRuleManager == null)
+    {
+      fetchRuleManager = new NOOPFetchRuleManager()
+      {
+        public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
+        {
+          return options().getCollectionLoadingPolicy();
+        }
+      };
+    }
+
+    this.fetchRuleManager = fetchRuleManager;
+  }
+
+  public CDOAuthenticator getAuthenticator()
+  {
+    return authenticator;
+  }
+
+  public void setAuthenticator(CDOAuthenticator authenticator)
+  {
+    this.authenticator = authenticator;
+  }
+
+  public boolean isMainBranchLocal()
+  {
+    return mainBranchLocal;
+  }
+
+  public void setMainBranchLocal(boolean mainBranchLocal)
+  {
+    this.mainBranchLocal = mainBranchLocal;
+  }
+
+  public InternalCDORemoteSessionManager getRemoteSessionManager()
+  {
+    return remoteSessionManager;
+  }
+
+  public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager)
+  {
+    this.remoteSessionManager = remoteSessionManager;
+  }
+
+  public CDOLobStore getLobStore()
+  {
+    final CDOLobStore cache = options().getLobCache();
+    return new CDOLobStore.Delegating()
+    {
+      @Override
+      public InputStream getBinary(final CDOLobInfo info) throws IOException
+      {
+        for (;;)
+        {
+          try
+          {
+            return super.getBinary(info);
+          }
+          catch (FileNotFoundException couldNotBeRead)
+          {
+            try
+            {
+              loadBinary(info);
+            }
+            catch (FileNotFoundException couldNotBeCreated)
+            {
+              // Try to read again
+            }
+          }
+        }
+      }
+
+      @Override
+      public Reader getCharacter(CDOLobInfo info) throws IOException
+      {
+        for (;;)
+        {
+          try
+          {
+            return super.getCharacter(info);
+          }
+          catch (FileNotFoundException couldNotBeRead)
+          {
+            try
+            {
+              loadCharacter(info);
+            }
+            catch (FileNotFoundException couldNotBeCreated)
+            {
+              // Try to read again
+            }
+          }
+        }
+      }
+
+      private void loadBinary(final CDOLobInfo info) throws IOException
+      {
+        final File file = getDelegate().getBinaryFile(info.getID());
+        final FileOutputStream out = new FileOutputStream(file);
+
+        loadLobAsync(info, new Runnable()
+        {
+          public void run()
+          {
+            try
+            {
+              getSessionProtocol().loadLob(info, out);
+            }
+            catch (Throwable t)
+            {
+              OM.LOG.error(t);
+              IOUtil.delete(file);
+            }
+          }
+        });
+      }
+
+      private void loadCharacter(final CDOLobInfo info) throws IOException
+      {
+        final File file = getDelegate().getCharacterFile(info.getID());
+        final FileWriter out = new FileWriter(file);
+
+        loadLobAsync(info, new Runnable()
+        {
+          public void run()
+          {
+            try
+            {
+              getSessionProtocol().loadLob(info, out);
+            }
+            catch (Throwable t)
+            {
+              OM.LOG.error(t);
+              IOUtil.delete(file);
+            }
+          }
+        });
+      }
+
+      @Override
+      protected CDOLobStore getDelegate()
+      {
+        return cache;
+      }
+    };
+  }
+
+  protected void loadLobAsync(CDOLobInfo info, Runnable runnable)
+  {
+    new Thread(runnable, "LobLoader").start();
+  }
+
+  public void close()
+  {
+    LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
+  }
+
+  /**
+   * @since 2.0
+   */
+  public boolean isClosed()
+  {
+    return !isActive();
+  }
+
+  /**
+   * @since 2.0
+   */
+  public CDOSession.Options options()
+  {
+    return options;
+  }
+
+  /**
+   * @since 2.0
+   */
+  protected CDOSession.Options createOptions()
+  {
+    return new OptionsImpl();
+  }
+
+  public Object processPackage(Object value)
+  {
+    CDOFactoryImpl.prepareDynamicEPackage(value);
+    return value;
+  }
+
+  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+  {
+    if (packageUnit.getOriginalType().isGenerated())
+    {
+      if (!options().isGeneratedPackageEmulationEnabled())
+      {
+        throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit)); //$NON-NLS-1$
+      }
+    }
+
+    return getSessionProtocol().loadPackages(packageUnit);
+  }
+
+  public void acquireAtomicRequestLock(Object key)
+  {
+    try
+    {
+      lockManager.lock(LockType.WRITE, key, this, IRWLockManager.WAIT);
+    }
+    catch (InterruptedException ex)
+    {
+      throw WrappedException.wrap(ex);
+    }
+  }
+
+  public void releaseAtomicRequestLock(Object key)
+  {
+    lockManager.unlock(LockType.WRITE, key, singletonCollection);
+  }
+
+  @Override
+  protected void initViewSynced(InternalCDOView view)
+  {
+    view.setSession(this);
+    view.setLastUpdateTime(getLastUpdateTime());
+  }
+
+  @Override
+  protected CDOBranch getMainBranch()
+  {
+    return getBranchManager().getMainBranch();
+  }
+
+  /**
+   * @since 2.0
+   */
+  public long refresh()
+  {
+    checkActive();
+    if (options().isPassiveUpdateEnabled())
+    {
+      return CDOBranchPoint.UNSPECIFIED_DATE;
+    }
+
+    return refresh(false);
+  }
+
+  private long refresh(boolean enablePassiveUpdates)
+  {
+    Map<CDOBranch, List<InternalCDOView>> views = new HashMap<CDOBranch, List<InternalCDOView>>();
+    Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions = new HashMap<CDOBranch, Map<CDOID, InternalCDORevision>>();
+    collectViewedRevisions(views, viewedRevisions);
+    cleanupRevisionCache(viewedRevisions);
+
+    CDOSessionProtocol sessionProtocol = getSessionProtocol();
+    long lastUpdateTime = getLastUpdateTime();
+    int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
+
+    RefreshSessionResult result = sessionProtocol.refresh(lastUpdateTime, viewedRevisions, initialChunkSize,
+        enablePassiveUpdates);
+
+    setLastUpdateTime(result.getLastUpdateTime());
+    registerPackageUnits(result.getPackageUnits());
+
+    for (Entry<CDOBranch, List<InternalCDOView>> entry : views.entrySet())
+    {
+      CDOBranch branch = entry.getKey();
+      List<InternalCDOView> branchViews = entry.getValue();
+      processRefreshSessionResult(result, branch, branchViews, viewedRevisions);
+    }
+
+    return result.getLastUpdateTime();
+  }
+
+  public void processRefreshSessionResult(RefreshSessionResult result, CDOBranch branch,
+      List<InternalCDOView> branchViews, Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+  {
+    Map<CDOID, InternalCDORevision> oldRevisions = viewedRevisions.get(branch);
+
+    List<CDORevisionKey> changedObjects = new ArrayList<CDORevisionKey>();
+    List<InternalCDORevision> newRevisions = result.getChangedObjects(branch);
+    for (InternalCDORevision newRevision : newRevisions)
+    {
+      getRevisionManager().addRevision(newRevision);
+
+      InternalCDORevision oldRevision = oldRevisions.get(newRevision.getID());
+      InternalCDORevisionDelta delta = newRevision.compare(oldRevision);
+      changedObjects.add(delta);
+    }
+
+    List<CDOIDAndVersion> detachedObjects = result.getDetachedObjects(branch);
+    for (CDOIDAndVersion detachedObject : detachedObjects)
+    {
+      getRevisionManager().reviseLatest(detachedObject.getID(), branch);
+    }
+
+    for (InternalCDOView view : branchViews)
+    {
+      view.invalidate(view.getBranch(), result.getLastUpdateTime(), changedObjects, detachedObjects, oldRevisions,
+          false);
+    }
+  }
+
+  private void collectViewedRevisions(Map<CDOBranch, List<InternalCDOView>> views,
+      Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+  {
+    for (InternalCDOView view : getViews())
+    {
+      if (view.getTimeStamp() == CDOView.UNSPECIFIED_DATE)
+      {
+        CDOBranch branch = view.getBranch();
+        Map<CDOID, InternalCDORevision> revisions = viewedRevisions.get(branch);
+        boolean needNewMap = revisions == null;
+        if (needNewMap)
+        {
+          revisions = new HashMap<CDOID, InternalCDORevision>();
+        }
+
+        view.collectViewedRevisions(revisions);
+        if (!revisions.isEmpty())
+        {
+          List<InternalCDOView> list = views.get(branch);
+          if (list == null)
+          {
+            list = new ArrayList<InternalCDOView>();
+            views.put(branch, list);
+          }
+
+          list.add(view);
+
+          if (needNewMap)
+          {
+            viewedRevisions.put(branch, revisions);
+          }
+        }
+      }
+    }
+  }
+
+  private void cleanupRevisionCache(Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+  {
+    Set<InternalCDORevision> set = new HashSet<InternalCDORevision>();
+    for (Map<CDOID, InternalCDORevision> revisions : viewedRevisions.values())
+    {
+      for (InternalCDORevision revision : revisions.values())
+      {
+        set.add(revision);
+      }
+    }
+
+    InternalCDORevisionCache cache = getRevisionManager().getCache();
+    List<CDORevision> currentRevisions = cache.getCurrentRevisions();
+    for (CDORevision revision : currentRevisions)
+    {
+      if (!set.contains(revision))
+      {
+        cache.removeRevision(revision.getID(), revision);
+      }
+    }
+  }
+
+  public long getLastUpdateTime()
+  {
+    synchronized (lastUpdateTimeLock)
+    {
+      return lastUpdateTime;
+    }
+  }
+
+  public void setLastUpdateTime(long lastUpdateTime)
+  {
+    synchronized (lastUpdateTimeLock)
+    {
+      if (this.lastUpdateTime < lastUpdateTime)
+      {
+        this.lastUpdateTime = lastUpdateTime;
+      }
+
+      lastUpdateTimeLock.notifyAll();
+    }
+  }
+
+  public void waitForUpdate(long updateTime)
+  {
+    waitForUpdate(updateTime, NO_TIMEOUT);
+  }
+
+  public boolean waitForUpdate(long updateTime, long timeoutMillis)
+  {
+    long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
+    InternalCDOView views[] = getViews();
+    if (views.length > 0)
+    {
+      for (CDOView view : views)
+      {
+        long viewTimeoutMillis = timeoutMillis == NO_TIMEOUT ? NO_TIMEOUT : end - System.currentTimeMillis();
+        boolean ok = view.waitForUpdate(updateTime, viewTimeoutMillis);
+        if (!ok)
+        {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    // Session without views
+    for (;;)
+    {
+      synchronized (lastUpdateTimeLock)
+      {
+        if (lastUpdateTime >= updateTime)
+        {
+          return true;
+        }
+
+        long now = System.currentTimeMillis();
+        if (now >= end)
+        {
+          return false;
+        }
+
+        try
+        {
+          lastUpdateTimeLock.wait(end - now);
+        }
+        catch (InterruptedException ex)
+        {
+          throw WrappedException.wrap(ex);
+        }
+      }
+    }
+  }
+
+  /**
+   * @since 3.0
+   */
+  public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
+  {
+    if (!((InternalCDORevision)revision).isUnchunked())
+    {
+      CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
+      return policy.resolveProxy(revision, feature, accessIndex, serverIndex);
+    }
+
+    return revision.data().get(feature, accessIndex);
+  }
+
+  /**
+   * @since 4.0
+   */
+  public void resolveAllElementProxies(CDORevision revision)
+  {
+    if (!((InternalCDORevision)revision).isUnchunked())
+    {
+      CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
+      for (EStructuralFeature feature : revision.getEClass().getEAllStructuralFeatures())
+      {
+        if (feature instanceof EReference)
+        {
+          EReference reference = (EReference)feature;
+          if (reference.isMany() && EMFUtil.isPersistent(reference))
+          {
+            CDOList list = ((InternalCDORevision)revision).getList(reference);
+            for (Iterator<Object> it = list.iterator(); it.hasNext();)
+            {
+              Object element = it.next();
+              if (element instanceof CDOElementProxy)
+              {
+                policy.resolveAllProxies(revision, reference);
+                break;
+              }
+            }
+          }
+        }
+      }
+
+      ((InternalCDORevision)revision).setUnchunked();
+    }
+  }
+
+  public void handleRepositoryTypeChanged(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
+  {
+    fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
+  }
+
+  public void handleRepositoryStateChanged(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
+  {
+    fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
+  }
+
+  public void handleBranchNotification(InternalCDOBranch branch)
+  {
+    getBranchManager().handleBranchCreated(branch);
+  }
+
+  public void handleCommitNotification(CDOCommitInfo commitInfo)
+  {
+    try
+    {
+      registerPackageUnits(commitInfo.getNewPackageUnits());
+      invalidate(commitInfo, null);
+    }
+    catch (RuntimeException ex)
+    {
+      if (isActive())
+      {
+        OM.LOG.error(ex);
+      }
+      else
+      {
+        OM.LOG.info(Messages.getString("CDOSessionImpl.2")); //$NON-NLS-1$
+      }
+    }
+  }
+
+  public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
+  {
+    for (InternalCDOView view : getViews())
+    {
+      if (view != sender)
+      {
+        view.handleLockNotification(sender, lockChangeInfo);
+      }
+    }
+
+    fireEvent(new LocksChangedEvent(sender, lockChangeInfo));
+  }
+
+  private void registerPackageUnits(List<CDOPackageUnit> packageUnits)
+  {
+    InternalCDOPackageRegistry packageRegistry = getPackageRegistry();
+    for (CDOPackageUnit newPackageUnit : packageUnits)
+    {
+      packageRegistry.putPackageUnit((InternalCDOPackageUnit)newPackageUnit);
+    }
+  }
+
+  private Map<CDOID, InternalCDORevision> reviseRevisions(CDOCommitInfo commitInfo)
+  {
+    Map<CDOID, InternalCDORevision> oldRevisions = null;
+    CDOBranch newBranch = commitInfo.getBranch();
+    long timeStamp = commitInfo.getTimeStamp();
+    InternalCDORevisionManager revisionManager = getRevisionManager();
+
+    // Cache new revisions
+    for (CDOIDAndVersion key : commitInfo.getNewObjects())
+    {
+      if (key instanceof InternalCDORevision)
+      {
+        InternalCDORevision newRevision = (InternalCDORevision)key;
+        revisionManager.addRevision(newRevision);
+      }
+    }
+
+    // Apply deltas and cache the resulting new revisions, if possible...
+    for (CDORevisionKey key : commitInfo.getChangedObjects())
+    {
+      // Add old values to revision deltas.
+      if (key instanceof CDORevisionDelta)
+      {
+        final CDORevisionDelta revisionDelta = (CDORevisionDelta)key;
+        final CDORevision oldRevision = revisionManager.getRevisionByVersion(revisionDelta.getID(), revisionDelta,
+            CDORevision.UNCHUNKED, false);
+
+        if (oldRevision != null)
+        {
+          CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitorImpl()
+          {
+            private List<Object> workList;
+
+            @Override
+            public void visit(CDOAddFeatureDelta delta)
+            {
+              workList.add(delta.getIndex(), delta.getValue());
+            }
+
+            @Override
+            public void visit(CDOClearFeatureDelta delta)
+            {
+              workList.clear();
+            }
+
+            @Override
+            public void visit(CDOListFeatureDelta deltas)
+            {
+              @SuppressWarnings("unchecked")
+              List<Object> list = (List<Object>)((InternalCDORevision)oldRevision).getValue(deltas.getFeature());
+              if (list != null)
+              {
+                workList = new ArrayList<Object>(list);
+                super.visit(deltas);
+              }
+            }
+
+            @Override
+            public void visit(CDOMoveFeatureDelta delta)
+            {
+              Object value = workList.get(delta.getOldPosition());
+              ((CDOMoveFeatureDeltaImpl)delta).setValue(value);
+              ECollections.move(workList, delta.getNewPosition(), delta.getOldPosition());
+            }
+
+            @Override
+            public void visit(CDORemoveFeatureDelta delta)
+            {
+              Object oldValue = workList.remove(delta.getIndex());
+              ((CDOSingleValueFeatureDeltaImpl)delta).setValue(oldValue);
+            }
+
+            @Override
+            public void visit(CDOSetFeatureDelta delta)
+            {
+              EStructuralFeature feature = delta.getFeature();
+              Object value = null;
+              if (feature.isMany())
+              {
+                value = workList.set(delta.getIndex(), delta.getValue());
+              }
+              else
+              {
+                value = ((InternalCDORevision)oldRevision).getValue(feature);
+              }
+
+              ((CDOSetFeatureDeltaImpl)delta).setOldValue(value);
+            }
+          };
+
+          for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas())
+          {
+            featureDelta.accept(visitor);
+          }
+        }
+      }
+
+      CDOID id = key.getID();
+      Pair<InternalCDORevision, InternalCDORevision> pair = createNewRevision(key, commitInfo);
+      if (pair != null)
+      {
+        InternalCDORevision newRevision = pair.getElement2();
+        revisionManager.addRevision(newRevision);
+        if (oldRevisions == null)
+        {
+          oldRevisions = new HashMap<CDOID, InternalCDORevision>();
+        }
+
+        InternalCDORevision oldRevision = pair.getElement1();
+        oldRevisions.put(id, oldRevision);
+      }
+      else
+      {
+        // ... otherwise try to revise old revision if it is in the same branch
+        if (ObjectUtil.equals(key.getBranch(), newBranch))
+        {
+          revisionManager.reviseVersion(id, key, timeStamp);
+        }
+      }
+    }
+
+    // Revise old revisions
+    for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
+    {
+      CDOID id = key.getID();
+      int version = key.getVersion();
+      if (version == CDOBranchVersion.UNSPECIFIED_VERSION)
+      {
+        revisionManager.reviseLatest(id, newBranch);
+      }
+      else
+      {
+        CDOBranchVersion branchVersion = newBranch.getVersion(version);
+        revisionManager.reviseVersion(id, branchVersion, timeStamp);
+      }
+    }
+
+    return oldRevisions;
+  }
+
+  private Pair<InternalCDORevision, InternalCDORevision> createNewRevision(CDORevisionKey potentialDelta,
+      CDOCommitInfo commitInfo)
+  {
+    if (potentialDelta instanceof CDORevisionDelta)
+    {
+      CDORevisionDelta delta = (CDORevisionDelta)potentialDelta;
+      CDOID id = delta.getID();
+
+      InternalCDORevisionManager revisionManager = getRevisionManager();
+      InternalCDORevision oldRevision = revisionManager.getRevisionByVersion(id, potentialDelta, CDORevision.UNCHUNKED,
+          false);
+      if (oldRevision != null)
+      {
+        InternalCDORevision newRevision = oldRevision.copy();
+        newRevision.adjustForCommit(commitInfo.getBranch(), commitInfo.getTimeStamp());
+
+        CDORevisable target = delta.getTarget();
+        if (target != null)
+        {
+          newRevision.setVersion(target.getVersion());
+        }
+
+        delta.apply(newRevision);
+        newRevision.freeze();
+        return new Pair<InternalCDORevision, InternalCDORevision>(oldRevision, newRevision);
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
+  {
+    long previousTimeStamp = commitInfo.getPreviousTimeStamp();
+    long lastUpdateTime = getLastUpdateTime();
+
+    if (previousTimeStamp < lastUpdateTime)
+    {
+      previousTimeStamp = lastUpdateTime;
+    }
+
+    synchronized (outOfSequenceInvalidations)
+    {
+      outOfSequenceInvalidations.put(previousTimeStamp, new Pair<CDOCommitInfo, InternalCDOTransaction>(commitInfo,
+          sender));
+    }
+
+    long nextPreviousTimeStamp = lastUpdateTime;
+    for (;;)
+    {
+      synchronized (outOfSequenceInvalidations)
+      {
+        Pair<CDOCommitInfo, InternalCDOTransaction> currentPair = outOfSequenceInvalidations
+            .remove(nextPreviousTimeStamp);
+
+        // If we don't have the invalidation that follows the last one we processed,
+        // then there is nothing we can do right now
+        if (currentPair == null)
+        {
+          break;
+        }
+
+        final CDOCommitInfo currentCommitInfo = currentPair.getElement1();
+        final InternalCDOTransaction currentSender = currentPair.getElement2();
+        nextPreviousTimeStamp = currentCommitInfo.getTimeStamp();
+
+        if (sender == null)
+        {
+          QueueRunner invalidationRunner = getInvalidationRunner();
+          invalidationRunner.addWork(new Runnable()
+          {
+            public void run()
+            {
+              invalidateOrdered(currentCommitInfo, currentSender);
+            }
+          });
+        }
+        else
+        {
+          invalidateOrdered(currentCommitInfo, currentSender);
+        }
+      }
+    }
+  }
+
+  /**
+   * This method is synchronized on outOfSequenceInvalidations by the caller!
+   */
+  private QueueRunner getInvalidationRunner()
+  {
+    if (invalidationRunner == null)
+    {
+      invalidationRunner = new QueueRunner();
+      invalidationRunner.activate();
+    }
+
+    return invalidationRunner;
+  }
+
+  private void invalidateOrdered(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
+  {
+    Map<CDOID, InternalCDORevision> oldRevisions = null;
+    boolean success = commitInfo.getBranch() != null;
+    if (success)
+    {
+      oldRevisions = reviseRevisions(commitInfo);
+    }
+
+    if (options.isPassiveUpdateEnabled())
+    {
+      setLastUpdateTime(commitInfo.getTimeStamp());
+    }
+
+    if (success)
+    {
+      fireInvalidationEvent(sender, commitInfo);
+    }
+
+    for (InternalCDOView view : getViews())
+    {
+      if (view != sender)
+      {
+        invalidateView(commitInfo, view, oldRevisions);
+      }
+      else
+      {
+        view.setLastUpdateTime(commitInfo.getTimeStamp());
+      }
+    }
+  }
+
+  private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view,
+      Map<CDOID, InternalCDORevision> oldRevisions)
+  {
+    try
+    {
+      CDOBranch branch = commitInfo.getBranch();
+      long lastUpdateTime = commitInfo.getTimeStamp();
+      List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
+      List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
+      view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true);
+    }
+    catch (RuntimeException ex)
+    {
+      if (view.isActive())
+      {
+        OM.LOG.error(ex);
+      }
+      else
+      {
+        OM.LOG.info(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
+      }
+    }
+  }
+
+  /**
+   * @since 2.0
+   */
+  public void fireInvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
+  {
+    fireEvent(new InvalidationEvent(sender, commitInfo));
+  }
+
+  @Override
+  public String toString()
+  {
+    String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); //$NON-NLS-1$
+    return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$
+  }
+
+  public CDOBranchPoint getCommittedSinceLastRefresh(CDOID id)
+  {
+    if (isSticky())
+    {
+      return committedSinceLastRefresh.get(id);
+    }
+
+    return null;
+  }
+
+  public void setCommittedSinceLastRefresh(CDOID id, CDOBranchPoint branchPoint)
+  {
+    if (isSticky())
+    {
+      committedSinceLastRefresh.put(id, branchPoint);
+    }
+  }
+
+  public void clearCommittedSinceLastRefresh()
+  {
+    if (isSticky())
+    {
+      committedSinceLastRefresh.clear();
+    }
+  }
+
+  public boolean isSticky()
+  {
+    return !options().isPassiveUpdateEnabled() && getRepositoryInfo().isSupportingAudits();
+  }
+
+  public CDOChangeSetData compareRevisions(CDOBranchPoint source, CDOBranchPoint target)
+  {
+    long now = getLastUpdateTime();
+
+    if (target.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
+    {
+      target = target.getBranch().getPoint(now);
+    }
+
+    if (source.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
+    {
+      source = source.getBranch().getPoint(now);
+    }
+
+    CDORevisionAvailabilityInfo targetInfo = createRevisionAvailabilityInfo(target);
+    CDORevisionAvailabilityInfo sourceInfo = createRevisionAvailabilityInfo(source);
+
+    Set<CDOID> ids = sessionProtocol.loadMergeData(targetInfo, sourceInfo, null, null);
+
+    cacheRevisions(targetInfo);
+    cacheRevisions(sourceInfo);
+
+    return CDORevisionUtil.createChangeSetData(ids, sourceInfo, targetInfo);
+  }
+
+  public CDORevisionAvailabilityInfo createRevisionAvailabilityInfo(CDOBranchPoint branchPoint)
+  {
+    CDORevisionAvailabilityInfo info = new CDORevisionAvailabilityInfo(branchPoint);
+
+    InternalCDORevisionManager revisionManager = getRevisionManager();
+    InternalCDORevisionCache cache = revisionManager.getCache();
+
+    List<CDORevision> revisions = cache.getRevisions(branchPoint);
+    for (CDORevision revision : revisions)
+    {
+      if (revision instanceof PointerCDORevision)
+      {
+        PointerCDORevision pointer = (PointerCDORevision)revision;
+        CDOBranchVersion target = pointer.getTarget();
+        if (target != null)
+        {
+          revision = cache.getRevisionByVersion(pointer.getID(), target);
+        }
+      }
+      else if (revision instanceof DetachedCDORevision)
+      {
+        revision = null;
+      }
+
+      if (revision != null)
+      {
+        resolveAllElementProxies(revision);
+        info.addRevision(revision);
+      }
+    }
+
+    return info;
+  }
+
+  public void cacheRevisions(CDORevisionAvailabilityInfo info)
+  {
+    InternalCDORevisionManager revisionManager = getRevisionManager();
+    CDOBranch branch = info.getBranchPoint().getBranch();
+    for (CDORevisionKey key : info.getAvailableRevisions().values())
+    {
+      CDORevision revision = (CDORevision)key;
+      revisionManager.addRevision(revision);
+
+      if (!ObjectUtil.equals(revision.getBranch(), branch))
+      {
+        CDOID id = revision.getID();
+        CDORevision firstRevision = revisionManager.getCache().getRevisionByVersion(id,
+            branch.getVersion(CDOBranchVersion.FIRST_VERSION));
+        if (firstRevision != null)
+        {
+          long revised = firstRevision.getTimeStamp() - 1L;
+          CDOBranchVersion target = CDOBranchUtil.copyBranchVersion(revision);
+          PointerCDORevision pointer = new PointerCDORevision(revision.getEClass(), id, branch, revised, target);
+          revisionManager.addRevision(pointer);
+        }
+      }
+    }
+  }
+
+  @Override
+  protected void doActivate() throws Exception
+  {
+    super.doActivate();
+
+    InternalCDORemoteSessionManager remoteSessionManager = new CDORemoteSessionManagerImpl();
+    remoteSessionManager.setLocalSession(this);
+    setRemoteSessionManager(remoteSessionManager);
+    remoteSessionManager.activate();
+
+    checkState(sessionProtocol, "sessionProtocol"); //$NON-NLS-1$
+    checkState(remoteSessionManager, "remoteSessionManager"); //$NON-NLS-1$
+  }
+
+  @Override
+  protected void doDeactivate() throws Exception
+  {
+    super.doDeactivate();
+
+    LifecycleUtil.deactivate(invalidationRunner);
+    outOfSequenceInvalidations.clear();
+
+    unhookSessionProtocol();
+
+    CDORemoteSessionManager remoteSessionManager = getRemoteSessionManager();
+    setRemoteSessionManager(null);
+    LifecycleUtil.deactivate(remoteSessionManager);
+
+    CDOSessionProtocol sessionProtocol = getSessionProtocol();
+    LifecycleUtil.deactivate(sessionProtocol);
+    setSessionProtocol(null);
+  }
+
+  /**
+   * Makes this session start listening to its protocol
+   */
+  protected CDOSessionProtocol hookSessionProtocol()
+  {
+    EventUtil.addListener(sessionProtocol, sessionProtocolListener);
+    return sessionProtocol;
+  }
+
+  /**
+   * Makes this session stop listening to its protocol
+   */
+  protected void unhookSessionProtocol()
+  {
+    EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
+  }
+
+  protected void sessionProtocolDeactivated()
+  {
+    deactivate();
+  }
+
+  /**
+   * A separate class for better monitor debugging.
+   *
+   * @author Eike Stepper
+   */
+  private static final class LastUpdateTimeLock
+  {
+  }
+
+  /**
+   * @author Eike Stepper
+   */
+  private static final class OutOfSequenceInvalidations extends
+      HashMap<Long, Pair<CDOCommitInfo, InternalCDOTransaction>>
+  {
+    private static final long serialVersionUID = 1L;
+  }
+
+  /**
+   * @author Eike Stepper
+   * @since 2.0
+   */
+  protected class OptionsImpl extends Notifier implements Options
+  {
+    private boolean generatedPackageEmulationEnabled;
+
+    private boolean passiveUpdateEnabled = true;
+
+    private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
+
+    private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
+
+    private CDOCollectionLoadingPolicy collectionLoadingPolicy;
+
+    private CDOLobStore lobCache = CDOLobStoreImpl.INSTANCE;
+
+    public OptionsImpl()
+    {
+      setCollectionLoadingPolicy(null); // Init default
+    }
+
+    public CDOSession getContainer()
+    {
+      return CDOSessionImpl.this;
+    }
+
+    public boolean isGeneratedPackageEmulationEnabled()
+    {
+      return generatedPackageEmulationEnabled;
+    }
+
+    public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled)
+    {
+      this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
+      if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled)
+      {
+        this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
+        // TODO Check inconsistent state if switching off?
+
+        IListener[] listeners = getListeners();
+        if (listeners != null)
+        {
+          fireEvent(new GeneratedPackageEmulationEventImpl(), listeners);
+        }
+      }
+    }
+
+    public boolean isPassiveUpdateEnabled()
+    {
+      return passiveUpdateEnabled;
+    }
+
+    public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
+    {
+      if (this.passiveUpdateEnabled != passiveUpdateEnabled)
+      {
+        this.passiveUpdateEnabled = passiveUpdateEnabled;
+        CDOSessionProtocol protocol = getSessionProtocol();
+        if (protocol != null)
+        {
+          if (passiveUpdateEnabled)
+          {
+            refresh(true);
+          }
+          else
+          {
+            protocol.disablePassiveUpdate();
+          }
+
+          IListener[] listeners = getListeners();
+          if (listeners != null)
+          {
+            fireEvent(new PassiveUpdateEventImpl(!passiveUpdateEnabled, passiveUpdateEnabled, passiveUpdateMode,
+                passiveUpdateMode), listeners);
+          }
+        }
+      }
+    }
+
+    public PassiveUpdateMode getPassiveUpdateMode()
+    {
+      return passiveUpdateMode;
+    }
+
+    public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
+    {
+      checkArg(passiveUpdateMode, "passiveUpdateMode"); //$NON-NLS-1$
+      if (this.passiveUpdateMode != passiveUpdateMode)
+      {
+        PassiveUpdateMode oldMode = this.passiveUpdateMode;
+        this.passiveUpdateMode = passiveUpdateMode;
+        CDOSessionProtocol protocol = getSessionProtocol();
+        if (protocol != null)
+        {
+          protocol.setPassiveUpdateMode(passiveUpdateMode);
+
+          IListener[] listeners = getListeners();
+          if (listeners != null)
+          {
+            fireEvent(
+                new PassiveUpdateEventImpl(passiveUpdateEnabled, passiveUpdateEnabled, oldMode, passiveUpdateMode),
+                listeners);
+          }
+        }
+      }
+    }
+
+    public LockNotificationMode getLockNotificationMode()
+    {
+      return lockNotificationMode;
+    }
+
+    public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
+    {
+      checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$
+      if (this.lockNotificationMode != lockNotificationMode)
+      {
+        LockNotificationMode oldMode = this.lockNotificationMode;
+        this.lockNotificationMode = lockNotificationMode;
+        CDOSessionProtocol protocol = getSessionProtocol();
+        if (protocol != null)
+        {
+          protocol.setLockNotificationMode(lockNotificationMode);
+
+          IListener[] listeners = getListeners();
+          if (listeners != null)
+          {
+            fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners);
+          }
+        }
+      }
+      this.lockNotificationMode = lockNotificationMode;
+    }
+
+    public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
+    {
+      synchronized (this)
+      {
+        return collectionLoadingPolicy;
+      }
+    }
+
+    public void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
+    {
+      if (policy == null)
+      {
+        policy = CDOUtil.createCollectionLoadingPolicy(CDORevision.UNCHUNKED, CDORevision.UNCHUNKED);
+      }
+
+      CDOSession oldSession = policy.getSession();
+      if (oldSession != null)
+      {
+        throw new IllegalArgumentException("Policy is already associated with " + oldSession);
+      }
+
+      policy.setSession(CDOSessionImpl.this);
+
+      IListener[] listeners = getListeners();
+      IEvent event = null;
+
+      synchronized (this)
+      {
+        if (collectionLoadingPolicy != policy)
+        {
+          collectionLoadingPolicy = policy;
+          if (listeners != null)
+          {
+            event = new CollectionLoadingPolicyEventImpl();
+          }
+        }
+      }
+
+      if (event != null)
+      {
+        fireEvent(event, listeners);
+      }
+    }
+
+    public CDOLobStore getLobCache()
+    {
+      synchronized (this)
+      {
+        return lobCache;
+      }
+    }
+
+    public void setLobCache(CDOLobStore cache)
+    {
+      if (cache == null)
+      {
+        cache = CDOLobStoreImpl.INSTANCE;
+      }
+
+      IListener[] listeners = getListeners();
+      IEvent event = null;
+
+      synchronized (this)
+      {
+        if (lobCache != cache)
+        {
+          lobCache = cache;
+          if (listeners != null)
+          {
+            event = new LobCacheEventImpl();
+          }
+        }
+      }
+
+      if (event != null)
+      {
+        fireEvent(event, listeners);
+      }
+    }
+
+    /**
+     * @author Eike Stepper
+     */
+    private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements
+        GeneratedPackageEmulationEvent
+    {
+      private static final long serialVersionUID = 1L;
+
+      public GeneratedPackageEmulationEventImpl()
+      {
+        super(OptionsImpl.this);
+      }
+    }
+
+    /**
+     * @author Eike Stepper
+     */
+    private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
+    {
+      private static final long serialVersionUID = 1L;
+
+      private boolean oldEnabled;
+
+      private boolean newEnabled;
+
+      private PassiveUpdateMode oldMode;
+
+      private PassiveUpdateMode newMode;
+
+      public PassiveUpdateEventImpl(boolean oldEnabled, boolean newEnabled, PassiveUpdateMode oldMode,
+          PassiveUpdateMode newMode)
+      {
+        super(OptionsImpl.this);
+        this.oldEnabled = oldEnabled;
+        this.newEnabled = newEnabled;
+        this.oldMode = oldMode;
+        this.newMode = newMode;
+      }
+
+      public boolean getOldEnabled()
+      {
+        return oldEnabled;
+      }
+
+      public boolean getNewEnabled()
+      {
+        return newEnabled;
+      }
+
+      public PassiveUpdateMode getOldMode()
+      {
+        return oldMode;
+      }
+
+      public PassiveUpdateMode getNewMode()
+      {
+        return newMode;
+      }
+    }
+
+    /**
+     * @author Caspar De Groot
+     */
+    private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent
+    {
+      private static final long serialVersionUID = 1L;
+
+      private LockNotificationMode oldMode, newMode;
+
+      public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode)
+      {
+        super(OptionsImpl.this);
+        this.oldMode = oldMode;
+        this.newMode = newMode;
+      }
+
+      public LockNotificationMode getOldMode()
+      {
+        return oldMode;
+      }
+
+      public LockNotificationMode getNewMode()
+      {
+        return newMode;
+      }
+    }
+
+    /**
+     * @author Eike Stepper
+     */
+    private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
+    {
+      private static final long serialVersionUID = 1L;
+
+      public CollectionLoadingPolicyEventImpl()
+      {
+        super(OptionsImpl.this);
+      }
+    }
+
+    /**
+     * @author Eike Stepper
+     */
+    private final class LobCacheEventImpl extends OptionsEvent implements LobCacheEvent
+    {
+      private static final long serialVersionUID = 1L;
+
+      public LobCacheEventImpl()
+      {
+        super(OptionsImpl.this);
+      }
+    }
+  }
+
+  /**
+   * @author Eike Stepper
+   */
+  private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
+  {
+    private static final long serialVersionUID = 1L;
+
+    private InternalCDOTransaction sender;
+
+    private CDOCommitInfo commitInfo;
+
+    public InvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
+    {
+      super(CDOSessionImpl.this);
+      this.sender = sender;
+      this.commitInfo = commitInfo;
+    }
+
+    @Override
+    public CDOSession getSource()
+    {
+      return (CDOSession)super.getSource();
+    }
+
+    public CDOCommitInfoManager getCommitInfoManager()
+    {
+      return commitInfo.getCommitInfoManager();
+    }
+
+    public CDOTransaction getLocalTransaction()
+    {
+      return sender;
+    }
+
+    @Deprecated
+    public InternalCDOView getView()
+    {
+      return sender;
+    }
+
+    public boolean isRemote()
+    {
+      return sender == null;
+    }
+
+    public CDOBranch getBranch()
+    {
+      return commitInfo.getBranch();
+    }
+
+    public long getTimeStamp()
+    {
+      return commitInfo.getTimeStamp();
+    }
+
+    public long getPreviousTimeStamp()
+    {
+      return commitInfo.getPreviousTimeStamp();
+    }
+
+    public String getUserID()
+    {
+      return commitInfo.getUserID();
+    }
+
+    public String getComment()
+    {
+      return commitInfo.getComment();
+    }
+
+    public boolean isEmpty()
+    {
+      return false;
+    }
+
+    public CDOChangeSetData copy()
+    {
+      return commitInfo.copy();
+    }
+
+    public void merge(CDOChangeSetData changeSetData)
+    {
+      commitInfo.merge(changeSetData);
+    }
+
+    public List<CDOPackageUnit> getNewPackageUnits()
+    {
+      return commitInfo.getNewPackageUnits();
+    }
+
+    public List<CDOIDAndVersion> getNewObjects()
+    {
+      return commitInfo.getNewObjects();
+    }
+
+    public List<CDORevisionKey> getChangedObjects()
+    {
+      return commitInfo.getChangedObjects();
+    }
+
+    public List<CDOIDAndVersion> getDetachedObjects()
+    {
+      return commitInfo.getDetachedObjects();
+    }
+
+    public Map<CDOID, CDOChangeKind> getChangeKinds()
+    {
+      return commitInfo.getChangeKinds();
+    }
+
+    public CDOChangeKind getChangeKind(CDOID id)
+    {
+      return commitInfo.getChangeKind(id);
+    }
+
+    @Override
+    public String toString()
+    {
+      return "CDOSessionInvalidationEvent[" + commitInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+    }
+  }
+
+  /**
+   * @author Caspar De Groot
+   * @since 4.1
+   */
+  private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOSessionLocksChangedEvent
+  {
+    private static final long serialVersionUID = 1L;
+
+    public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+    {
+      super(CDOSessionImpl.this, sender, lockChangeInfo);
+    }
+
+    @Override
+    public CDOSession getSource()
+    {
+      return (CDOSession)super.getSource();
+    }
+  }
+}
