[369646] [DB] ClassCastException after setBranch when server cache contains partially loaded collections 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=369646
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();
+    }
+  }
+}