/*
 * Copyright (c) 2009-2020 Eike Stepper (Loehne, 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
 *    Victor Roldan Betancort - maintenance
 *    Gonzague Reydet - bug 298334
 *    Andre Dietisheim - bug 256649
 *    Caspar De Groot - bug 290032 (Sticky views)
 */
package org.eclipse.emf.internal.cdo.transaction;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOObjectReference;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.CDOCommonRepository;
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.commit.CDOChangeSet;
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.CDOCommitInfoManager;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
import org.eclipse.emf.cdo.common.id.CDOIDProvider;
import org.eclipse.emf.cdo.common.id.CDOIDReference;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.id.CDOIdentifiable;
import org.eclipse.emf.cdo.common.lob.CDOLob;
import org.eclipse.emf.cdo.common.lob.CDOLobStore;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
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.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitData;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDOListFactory;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.CDORevisionProvider;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOOriginSizeProvider;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.common.util.CDOResourceNodeNotFoundException;
import org.eclipse.emf.cdo.eresource.CDOBinaryResource;
import org.eclipse.emf.cdo.eresource.CDOFileResource;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceFolder;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.eresource.CDOTextResource;
import org.eclipse.emf.cdo.eresource.EresourceFactory;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceNodeImpl;
import org.eclipse.emf.cdo.internal.common.commit.FailureCommitInfo;
import org.eclipse.emf.cdo.internal.common.revision.CDOListWithElementProxiesImpl;
import org.eclipse.emf.cdo.session.CDORepositoryInfo;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOClassInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.protocol.CDODataInputImpl;
import org.eclipse.emf.cdo.spi.common.protocol.CDODataOutputImpl;
import org.eclipse.emf.cdo.spi.common.revision.CDOIDMapper;
import org.eclipse.emf.cdo.spi.common.revision.CDORevisionUnchunker;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
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.ManagedRevisionProvider;
import org.eclipse.emf.cdo.spi.common.revision.SyntheticCDORevision;
import org.eclipse.emf.cdo.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDOConflictResolver;
import org.eclipse.emf.cdo.transaction.CDOConflictResolver2;
import org.eclipse.emf.cdo.transaction.CDOConflictResolver3;
import org.eclipse.emf.cdo.transaction.CDODefaultTransactionHandler1;
import org.eclipse.emf.cdo.transaction.CDOMerger;
import org.eclipse.emf.cdo.transaction.CDOSavepoint;
import org.eclipse.emf.cdo.transaction.CDOStaleReferenceCleaner;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOTransaction.Options.AutoReleaseLocksEvent.AutoReleaseLocksEnabledEvent;
import org.eclipse.emf.cdo.transaction.CDOTransaction.Options.AutoReleaseLocksEvent.AutoReleaseLocksExemptionsEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler1;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler2;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler3;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandlerBase;
import org.eclipse.emf.cdo.transaction.CDOTransactionStartedEvent;
import org.eclipse.emf.cdo.transaction.CDOUndoDetector;
import org.eclipse.emf.cdo.transaction.CDOUserSavepoint;
import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.ConcurrentAccessException;
import org.eclipse.emf.cdo.util.DanglingIntegrityException;
import org.eclipse.emf.cdo.util.DanglingReferenceException;
import org.eclipse.emf.cdo.util.LocalCommitConflictException;
import org.eclipse.emf.cdo.util.ObjectNotFoundException;
import org.eclipse.emf.cdo.view.CDOQuery;

import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;
import org.eclipse.emf.internal.cdo.object.CDOObjectMerger;
import org.eclipse.emf.internal.cdo.object.CDOObjectReferenceImpl;
import org.eclipse.emf.internal.cdo.object.CDOObjectWrapper;
import org.eclipse.emf.internal.cdo.query.CDOQueryImpl;
import org.eclipse.emf.internal.cdo.util.CommitIntegrityCheck;
import org.eclipse.emf.internal.cdo.util.CompletePackageClosure;
import org.eclipse.emf.internal.cdo.util.IPackageClosure;
import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
import org.eclipse.emf.internal.cdo.view.CDOViewImpl;

import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.AbstractCloseableIterator;
import org.eclipse.net4j.util.collection.ByteArrayWrapper;
import org.eclipse.net4j.util.collection.CloseableIterator;
import org.eclipse.net4j.util.collection.ComposedIterator;
import org.eclipse.net4j.util.collection.ConcurrentArray;
import org.eclipse.net4j.util.collection.DelegatingCloseableIterator;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.IRWLockManager;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.io.ExtendedDataInputStream;
import org.eclipse.net4j.util.io.ExtendedDataOutputStream;
import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.net4j.util.om.monitor.MonitorCanceledException;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.options.OptionsEvent;
import org.eclipse.net4j.util.transaction.TransactionException;

import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EClassImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.ECrossReferenceEList;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
import org.eclipse.emf.spi.cdo.CDOTransactionStrategy;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOSession.CommitToken;
import org.eclipse.emf.spi.cdo.InternalCDOSession.InvalidationData;
import org.eclipse.emf.spi.cdo.InternalCDOSession.MergeData;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOViewSet;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubMonitor;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

/**
 * @author Eike Stepper
 */
public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransaction
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_TRANSACTION, CDOTransactionImpl.class);

  private static final boolean X_COMPRESSION = OMPlatform.INSTANCE.isProperty("org.eclipse.emf.cdo.transaction.X_COMPRESSION");

  private Object transactionHandlersLock = new Object();

  private ConcurrentArray<CDOTransactionHandler1> transactionHandlers1 = new ConcurrentArray<CDOTransactionHandler1>()
  {
    @Override
    protected CDOTransactionHandler1[] newArray(int length)
    {
      return new CDOTransactionHandler1[length];
    }
  };

  private ConcurrentArray<CDOTransactionHandler2> transactionHandlers2 = new ConcurrentArray<CDOTransactionHandler2>()
  {
    @Override
    protected CDOTransactionHandler2[] newArray(int length)
    {
      return new CDOTransactionHandler2[length];
    }
  };

  private InternalCDOSavepoint lastSavepoint = createSavepoint(null);

  private InternalCDOSavepoint firstSavepoint = lastSavepoint;

  private boolean dirty;

  private int conflict;

  private CDOTransactionStrategy transactionStrategy;

  private CDOIDGenerator idGenerator;

  private volatile long lastCommitTime = UNSPECIFIED_DATE;

  private String commitComment;

  private CommitToken commitToken;

  private CDOBranchPoint commitMergeSource;

  // Bug 283985 (Re-attachment)
  private final ThreadLocal<Boolean> providingCDOID = new InheritableThreadLocal<Boolean>()
  {
    @Override
    protected Boolean initialValue()
    {
      return false;
    }
  };

  /**
   * An optional set to specify which objects in this TX are to be committed by {@link #commit()}
   */
  private Set<? extends EObject> committables;

  /**
   * A map to hold a clean (i.e. unmodified) revision for objects that have been modified or detached.
   */
  private Map<InternalCDOObject, InternalCDORevision> cleanRevisions = new CleanRevisionsMap();

  public CDOTransactionImpl(CDOSession session, CDOBranch branch)
  {
    super(session, branch, UNSPECIFIED_DATE);
  }

  public CDOTransactionImpl(CDOSession session, String durableLockingID)
  {
    super(session, durableLockingID);
  }

  /**
   * @since 2.0
   */
  @Override
  public OptionsImpl options()
  {
    return (OptionsImpl)super.options();
  }

  /**
   * @since 2.0
   */
  @Override
  protected OptionsImpl createOptions()
  {
    return new OptionsImpl();
  }

  @Override
  public boolean isReadOnly()
  {
    return false;
  }

  @Override
  public boolean setBranchPoint(CDOBranchPoint branchPoint)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (branchPoint.getTimeStamp() != UNSPECIFIED_DATE)
        {
          throw new IllegalArgumentException("Changing the target time is not supported by transactions");
        }

        if (isDirty() && !getBranch().equals(branchPoint.getBranch()))
        {
          throw new IllegalStateException("Changing the target branch is impossible while transaction is dirty");
        }

        return super.setBranchPoint(branchPoint);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void addTransactionHandler(CDOTransactionHandlerBase handler)
  {
    synchronized (transactionHandlersLock)
    {
      if (handler instanceof CDOTransactionHandler1)
      {
        transactionHandlers1.add((CDOTransactionHandler1)handler);
      }

      if (handler instanceof CDOTransactionHandler2)
      {
        transactionHandlers2.add((CDOTransactionHandler2)handler);
      }
    }
  }

  @Override
  public void removeTransactionHandler(CDOTransactionHandlerBase handler)
  {
    synchronized (transactionHandlersLock)
    {
      if (handler instanceof CDOTransactionHandler1)
      {
        transactionHandlers1.remove((CDOTransactionHandler1)handler);
      }

      if (handler instanceof CDOTransactionHandler2)
      {
        transactionHandlers2.remove((CDOTransactionHandler2)handler);
      }
    }
  }

  @Override
  public CDOTransactionHandler[] getTransactionHandlers()
  {
    Set<CDOTransactionHandler> result = new HashSet<>();
    synchronized (transactionHandlersLock)
    {
      CDOTransactionHandler1[] handlers1 = transactionHandlers1.get();
      if (handlers1 != null)
      {
        for (CDOTransactionHandler1 handler : handlers1)
        {
          if (handler instanceof CDOTransactionHandler)
          {
            result.add((CDOTransactionHandler)handler);
          }
        }
      }

      CDOTransactionHandler2[] handlers2 = transactionHandlers2.get();
      if (handlers2 != null)
      {
        for (CDOTransactionHandler2 handler : handlers2)
        {
          if (handler instanceof CDOTransactionHandler)
          {
            result.add((CDOTransactionHandler)handler);
          }
        }
      }
    }

    return result.toArray(new CDOTransactionHandler[result.size()]);
  }

  @Override
  public CDOTransactionHandler1[] getTransactionHandlers1()
  {
    synchronized (transactionHandlersLock)
    {
      return transactionHandlers1.get();
    }
  }

  @Override
  public CDOTransactionHandler2[] getTransactionHandlers2()
  {
    synchronized (transactionHandlersLock)
    {
      return transactionHandlers2.get();
    }
  }

  @Override
  public boolean isDirty()
  {
    if (isClosed())
    {
      return false;
    }

    return dirty;
  }

  @Override
  public void setDirty(boolean dirty)
  {
    if (this.dirty != dirty)
    {
      this.dirty = dirty;

      IListener[] listeners = getListeners();
      if (listeners != null)
      {
        IEvent event = dirty ? new StartedEvent() : new FinishedEvent(false);
        fireEvent(event, listeners);
      }
    }
  }

  @Override
  public boolean hasConflict()
  {
    checkActive();
    return conflict > 0;
  }

  @Override
  public void setConflict(InternalCDOObject object)
  {
    IEvent event = null;
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        event = new ConflictEvent(object, conflict == 0);
        ++conflict;
      }
      finally
      {
        unlockView();
      }
    }

    fireEvent(event);
  }

  @Override
  public void removeConflict(InternalCDOObject object)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (conflict > 0)
        {
          --conflict;
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public Set<CDOObject> getConflicts()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        Set<CDOObject> conflicts = new HashSet<>();
        for (CDOObject object : getDirtyObjects().values())
        {
          if (object.cdoConflict())
          {
            conflicts.add(object);
          }
        }

        for (CDOObject object : getDetachedObjects().values())
        {
          if (object.cdoConflict())
          {
            conflicts.add(object);
          }
        }

        return conflicts;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOChangeSetData getChangeSetData()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllChangeSetData();
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOChangeSetData merge(CDOBranch source, CDOMerger merger)
  {
    return merge(source.getHead(), merger);
  }

  @Override
  public CDOChangeSetData merge(CDOBranchPoint source, CDOMerger merger)
  {
    return merge(source, CDOBranchUtil.AUTO_BRANCH_POINT, merger);
  }

  @Override
  public CDOChangeSetData merge(CDOBranchPoint source, CDOBranchPoint sourceBase, CDOMerger merger)
  {
    return merge(source, sourceBase, null, merger);
  }

  @Override
  public CDOChangeSetData merge(CDOBranchPoint source, CDOBranchPoint sourceBase, CDOBranchPoint targetBase, CDOMerger merger)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (isDirty())
        {
          throw new IllegalStateException("Merging into dirty transactions not yet supported");
        }

        long now = getLastUpdateTime();
        CDOBranchPoint target = getBranch().getPoint(now);

        if (source.getTimeStamp() == UNSPECIFIED_DATE)
        {
          source = source.getBranch().getPoint(now);
        }

        if (CDOBranchUtil.isContainedBy(source, target))
        {
          throw new IllegalArgumentException("Source is already contained in " + target);
        }

        if (sourceBase != CDOBranchUtil.AUTO_BRANCH_POINT)
        {
          if (sourceBase != null && !CDOBranchUtil.isContainedBy(sourceBase, source))
          {
            throw new IllegalArgumentException("Source base is not contained in " + source);
          }

          if (targetBase != null && !CDOBranchUtil.isContainedBy(targetBase, target))
          {
            throw new IllegalArgumentException("Target base is not contained in " + target);
          }
        }

        InternalCDOSession session = getSession();
        MergeData mergeData = session.getMergeData(target, source, targetBase, sourceBase, true);

        CDOChangeSet targetChanges = mergeData.getTargetChanges();
        CDOChangeSet sourceChanges = mergeData.getSourceChanges();
        CDOChangeSetData result = merger.merge(targetChanges, sourceChanges);
        if (result == null)
        {
          return null;
        }

        CDORevisionProvider targetProvider = mergeData.getTargetInfo();
        CDORevisionProvider resultBaseProvider;

        CDORevisionManager revisionManager = session.getRevisionManager();
        CDOBranchPoint resultBase = mergeData.getResultBase();
        if (resultBase != null)
        {
          resultBaseProvider = new ManagedRevisionProvider(revisionManager, resultBase);
        }
        else
        {
          resultBaseProvider = mergeData.getTargetBaseInfo();
        }

        ApplyChangeSetResult changeSet = applyChangeSet(result, resultBaseProvider, targetProvider, source, false);
        commitMergeSource = source;
        return changeSet.getChangeSetData();
      }
      finally
      {
        unlockView();
      }
    }
  }

  public CDOChangeSetData remerge(CDOBranchPoint source, CDOMerger merger)
  {
    return merge(source, CDOBranchUtil.AUTO_BRANCH_POINT, merger);
  }

  @Override
  @Deprecated
  public Pair<CDOChangeSetData, Pair<Map<CDOID, CDOID>, List<CDOID>>> applyChangeSetData(CDOChangeSetData changeSetData, CDORevisionProvider targetBaseProvider,
      CDORevisionProvider targetProvider, CDOBranchPoint source)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public ApplyChangeSetResult applyChangeSet(CDOChangeSetData changeSetData, CDORevisionProvider resultBaseProvider, CDORevisionProvider targetProvider,
      CDOBranchPoint source, boolean keepVersions) throws ChangeSetOutdatedException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        ApplyChangeSetResult result = new ApplyChangeSetResult();

        // Merges from local offline branches may require additional ID mappings: localID -> tempID
        if (source != null && source.getBranch().isLocal()
            && getSession().getRepositoryInfo().getIDGenerationLocation() == CDOCommonRepository.IDGenerationLocation.STORE)
        {
          applyLocalIDMapping(changeSetData, result);
        }

        CDOChangeSetData resultData = result.getChangeSetData();

        // New objects
        applyNewObjects(changeSetData.getNewObjects(), resultData.getNewObjects());

        // Detached objects
        Set<CDOObject> detachedSet = applyDetachedObjects(changeSetData.getDetachedObjects(), resultData.getDetachedObjects());

        // Changed objects
        Map<CDOID, InternalCDORevision> oldRevisions = applyChangedObjects(changeSetData.getChangedObjects(), resultBaseProvider, targetProvider, keepVersions,
            resultData.getChangedObjects());

        // Delta notifications
        Collection<CDORevisionDelta> notificationDeltas = lastSavepoint.getRevisionDeltas2().values();
        if (!notificationDeltas.isEmpty() || !detachedSet.isEmpty())
        {
          sendDeltaNotifications(notificationDeltas, detachedSet, oldRevisions);
        }

        return result;
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void applyLocalIDMapping(CDOChangeSetData changeSetData, ApplyChangeSetResult result)
  {
    Map<CDOID, CDOID> idMappings = result.getIDMappings();

    // Collect needed ID mappings
    for (CDOIDAndVersion key : changeSetData.getNewObjects())
    {
      InternalCDORevision revision = (InternalCDORevision)key;
      if (revision.getBranch().isLocal())
      {
        CDOID oldID = revision.getID();
        CDOID newID = createIDForNewObject(null);
        idMappings.put(oldID, newID);

        revision.setID(newID);
        revision.setVersion(0);
      }
    }

    if (!idMappings.isEmpty())
    {
      // Apply collected ID mappings
      CDOIDMapper idMapper = new CDOIDMapper(idMappings);
      idMapper.setAllowUnmappedTempIDs(true);

      for (CDOIDAndVersion key : changeSetData.getNewObjects())
      {
        InternalCDORevision revision = (InternalCDORevision)key;
        revision.adjustReferences(idMapper);
      }

      for (CDORevisionKey key : changeSetData.getChangedObjects())
      {
        InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)key;
        if (revisionDelta.adjustReferences(idMapper))
        {
          result.getAdjustedObjects().add(revisionDelta.getID());
        }
      }
    }
  }

  private void applyNewObjects(List<CDOIDAndVersion> newObjects, List<CDOIDAndVersion> result)
  {
    List<InternalCDOObject> objects = new ArrayList<>();

    for (CDOIDAndVersion key : newObjects)
    {
      InternalCDORevision revision = (InternalCDORevision)key;
      CDOID id = revision.getID();
      if (getObjectIfExists(id) == null)
      {
        revision = revision.copy();
        revision.setBranchPoint(getBranchPoint());
        revision.setVersion(0);

        InternalCDOObject object = newInstance(revision.getEClass());
        object.cdoInternalSetView(this);
        object.cdoInternalSetRevision(revision);
        object.cdoInternalSetState(CDOState.NEW);
        objects.add(object);

        registerObject(object);
        result.add(revision);
      }
    }

    if (!objects.isEmpty())
    {
      for (InternalCDOObject object : objects)
      {
        object.cdoInternalPostLoad();
        registerAttached(object, true);
      }

      setDirty(true);
    }
  }

  private Set<CDOObject> applyDetachedObjects(List<CDOIDAndVersion> detachedObjects, List<CDOIDAndVersion> result)
  {
    Set<CDOObject> detachedSet = new HashSet<>();
    for (CDOIDAndVersion key : detachedObjects)
    {
      CDOID id = key.getID();
      InternalCDOObject object = getObjectIfExists(id);
      if (object != null)
      {
        result.add(CDOIDUtil.createIDAndVersion(id, CDOBranchVersion.UNSPECIFIED_VERSION));
        CDOStateMachine.INSTANCE.detach(object);
        detachedSet.add(object);
        setDirty(true);
      }
    }

    return detachedSet;
  }

  private Map<CDOID, InternalCDORevision> applyChangedObjects(List<CDORevisionKey> changedObjects, CDORevisionProvider resultBaseProvider,
      CDORevisionProvider targetProvider, boolean keepVersions, List<CDORevisionKey> result) throws ChangeSetOutdatedException
  {
    Map<CDOID, InternalCDORevision> oldRevisions = CDOIDUtil.createMap();

    Map<CDOID, CDOObject> detachedObjects = lastSavepoint.getDetachedObjects();
    Map<CDOID, CDOObject> dirtyObjects = lastSavepoint.getDirtyObjects();
    Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();

    for (CDORevisionKey key : changedObjects)
    {
      InternalCDORevisionDelta resultBaseGoalDelta = (InternalCDORevisionDelta)key;
      resultBaseGoalDelta.setTarget(null);
      CDOID id = resultBaseGoalDelta.getID();
      InternalCDORevision resultBaseRevision = (InternalCDORevision)resultBaseProvider.getRevision(id);

      InternalCDOObject object = getObject(id);
      boolean revisionChanged = false;

      InternalCDORevision targetRevision = object.cdoRevision();
      if (targetRevision == null)
      {
        targetRevision = (InternalCDORevision)targetProvider.getRevision(id);
        object.cdoInternalSetRevision(targetRevision);
        revisionChanged = true;
      }

      oldRevisions.put(id, targetRevision);

      InternalCDORevision goalRevision = resultBaseRevision.copy();
      goalRevision.setBranchPoint(this);
      if (!keepVersions)
      {
        goalRevision.setVersion(targetRevision.getVersion());
      }

      goalRevision.setRevised(UNSPECIFIED_DATE);
      resultBaseGoalDelta.applyTo(goalRevision);

      InternalCDORevisionDelta targetGoalDelta = goalRevision.compare(targetRevision);
      targetGoalDelta.setTarget(null);

      if (!targetGoalDelta.isEmpty())
      {
        if (keepVersions && targetGoalDelta.getVersion() != resultBaseRevision.getVersion())
        {
          throw new ChangeSetOutdatedException();
        }

        revisionDeltas.put(id, targetGoalDelta);
        result.add(targetGoalDelta);

        // handle reattached objects.
        if (detachedObjects.containsKey(id))
        {
          CDOStateMachine.INSTANCE.internalReattach(object, this);
        }

        object.cdoInternalSetRevision(goalRevision);
        object.cdoInternalSetState(CDOState.DIRTY);
        revisionChanged = true;

        dirtyObjects.put(id, object);
        setDirty(true);
      }

      if (revisionChanged)
      {
        object.cdoInternalPostLoad();
      }
    }

    return oldRevisions;
  }

  private InternalCDOObject getObjectIfExists(CDOID id)
  {
    try
    {
      return getObject(id);
    }
    catch (ObjectNotFoundException ex)
    {
      return null;
    }
  }

  /*
   * Synchronized through InvalidationRunnable.run()
   */
  @Override
  protected void handleConflicts(long lastUpdateTime, Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts, List<CDORevisionDelta> deltas)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOConflictResolver[] resolvers = options().getConflictResolvers();
        if (resolvers.length == 0)
        {
          return;
        }

        if (conflicts == null)
        {
          for (CDOConflictResolver resolver : resolvers)
          {
            if (resolver instanceof CDOConflictResolver.NonConflictAware)
            {
              ((CDOConflictResolver.NonConflictAware)resolver).handleNonConflict(lastUpdateTime);
            }
          }

          return;
        }

        // Remember original state to be able to restore it after an exception
        List<CDOState> states = new ArrayList<>(conflicts.size());
        List<CDORevision> revisions = new ArrayList<>(conflicts.size());
        for (CDOObject conflict : conflicts.keySet())
        {
          states.add(conflict.cdoState());
          revisions.add(conflict.cdoRevision());
        }

        int resolved = 0;

        try
        {
          Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> remaining = new HashMap<>(conflicts);
          for (CDOConflictResolver resolver : resolvers)
          {
            if (resolver instanceof CDOConflictResolver2)
            {
              ((CDOConflictResolver2)resolver).resolveConflicts(Collections.unmodifiableMap(remaining), deltas);
            }
            else
            {
              resolver.resolveConflicts(Collections.unmodifiableSet(remaining.keySet()));
            }

            for (Iterator<CDOObject> it = remaining.keySet().iterator(); it.hasNext();)
            {
              CDOObject object = it.next();
              if (!object.cdoConflict())
              {
                ++resolved;
                it.remove();
              }
            }
          }
        }
        catch (Exception ex)
        {
          // Restore original state
          Iterator<CDOState> state = states.iterator();
          Iterator<CDORevision> revision = revisions.iterator();
          for (CDOObject object : conflicts.keySet())
          {
            ((InternalCDOObject)object).cdoInternalSetRevision(revision.next());
            ((InternalCDOObject)object).cdoInternalSetState(state.next());
          }

          throw WrappedException.wrap(ex);
        }

        conflict -= resolved;

        Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
        setDirty(!dirtyObjects.isEmpty());
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @deprecated {@link #createIDForNewObject(EObject object)} is called since 4.1.
   */
  @Override
  @Deprecated
  public CDOIDTemp getNextTemporaryID()
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public CDOID createIDForNewObject(EObject object)
  {
    return idGenerator.generateCDOID(object);
  }

  @Override
  public CDOResourceFolder createResourceFolder(String path) throws CDOResourceNodeNotFoundException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (path.endsWith(CDOURIUtil.SEGMENT_SEPARATOR))
        {
          path = path.substring(0, path.length() - 1);
        }

        CDOResourceFolder folder = EresourceFactory.eINSTANCE.createCDOResourceFolder();
        int pos = path.lastIndexOf(CDOURIUtil.SEGMENT_SEPARATOR_CHAR);
        if (pos <= 0)
        {
          String name = path.substring(pos == 0 ? 1 : 0);
          folder.setName(name);

          getRootResource().getContents().add(folder);
        }
        else
        {
          String name = path.substring(pos + 1);
          folder.setName(name);

          path = path.substring(0, pos);
          CDOResourceNode parent = null;

          try
          {
            parent = getResourceNode(path);
          }
          catch (Exception ex)
          {
            parent = createResourceFolder(path);
          }

          if (parent instanceof CDOResourceFolder)
          {
            ((CDOResourceFolder)parent).getNodes().add(folder);
          }
          else
          {
            throw new CDOException("Parent is not a folder: " + parent);
          }
        }

        return folder;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOResource createResource(String path)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        URI uri = CDOURIUtil.createResourceURI(this, path);
        return (CDOResource)getResourceSet().createResource(uri);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOResource getOrCreateResource(String path)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        try
        {
          CDOID id = getResourceNodeID(path);
          if (!CDOIDUtil.isNull(id))
          {
            return (CDOResource)getObject(id);
          }
        }
        catch (CDOResourceNodeNotFoundException ignore)
        {
          // Just create the missing resource.
        }

        return createResource(path);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOTextResource createTextResource(String path)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOTextResource resource = EresourceFactory.eINSTANCE.createCDOTextResource();
        createFileResource(path, resource);
        return resource;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOTextResource getOrCreateTextResource(String path)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        try
        {
          CDOID id = getResourceNodeID(path);
          if (!CDOIDUtil.isNull(id))
          {
            return (CDOTextResource)getObject(id);
          }
        }
        catch (CDOResourceNodeNotFoundException ignore)
        {
          // Just create the missing resource.
        }

        return createTextResource(path);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOBinaryResource createBinaryResource(String path)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOBinaryResource resource = EresourceFactory.eINSTANCE.createCDOBinaryResource();
        createFileResource(path, resource);
        return resource;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOBinaryResource getOrCreateBinaryResource(String path)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        try
        {
          CDOID id = getResourceNodeID(path);
          if (!CDOIDUtil.isNull(id))
          {
            return (CDOBinaryResource)getObject(id);
          }
        }
        catch (CDOResourceNodeNotFoundException ignore)
        {
          // Just create the missing resource
        }

        return createBinaryResource(path);
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void createFileResource(String path, CDOFileResource<?> resource)
  {
    int lastSlash = path.lastIndexOf('/');
    if (lastSlash == -1)
    {
      resource.setName(path);
      getRootResource().getContents().add(resource);
    }
    else
    {
      resource.setName(path.substring(lastSlash + 1));

      CDOResourceFolder folder = getOrCreateResourceFolder(path.substring(0, lastSlash));
      folder.getNodes().add(resource);
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void attachResource(CDOResourceImpl resource)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (resource.isExisting())
        {
          super.attachResource(resource);
        }
        else
        {
          // ResourceSet.createResource(uri) was called!!
          attachNewResource(resource);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void attachNewResource(CDOResourceImpl resource)
  {
    URI uri = resource.getURI();
    List<String> names = CDOURIUtil.analyzePath(uri);
    String resourceName = names.isEmpty() ? null : names.remove(names.size() - 1);

    CDOResourceFolder folder = getOrCreateResourceFolder(names);
    attachNewResourceNode(folder, resourceName, resource);
  }

  @Override
  public CDOResourceFolder getOrCreateResourceFolder(String path)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        try
        {
          CDOID id = getResourceNodeID(path);
          if (!CDOIDUtil.isNull(id))
          {
            return (CDOResourceFolder)getObject(id);
          }
        }
        catch (CDOResourceNodeNotFoundException ignore)
        {
          // Just create the missing resource.
        }

        return createResourceFolder(path);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @return never <code>null</code>;
   * @since 2.0
   */
  @Override
  public CDOResourceFolder getOrCreateResourceFolder(List<String> names)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOResourceFolder folder = null;
        for (String name : names)
        {
          CDOResourceNode node;

          try
          {
            CDOID folderID = folder == null ? null : folder.cdoID();
            node = getResourceNode(folderID, name);
          }
          catch (CDOResourceNodeNotFoundException ex)
          {
            node = EresourceFactory.eINSTANCE.createCDOResourceFolder();
            attachNewResourceNode(folder, name, node);
          }

          if (node instanceof CDOResourceFolder)
          {
            folder = (CDOResourceFolder)node;
          }
          else
          {
            throw new CDOException(MessageFormat.format(Messages.getString("CDOTransactionImpl.0"), node)); //$NON-NLS-1$
          }
        }

        return folder;
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void attachNewResourceNode(CDOResourceFolder folder, String name, CDOResourceNode newNode)
  {
    CDOResourceNodeImpl node = (CDOResourceNodeImpl)newNode;
    node.basicSetName(name, false);
    if (folder == null)
    {
      if (node.isRoot())
      {
        CDOStateMachine.INSTANCE.attach(node, this);
      }
      else
      {
        getRootResource().getContents().add(node);
      }
    }
    else
    {
      node.basicSetFolder(folder, false);
    }
  }

  /**
   * @since 2.0
   */
  public void detach(CDOResourceImpl cdoResource)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOStateMachine.INSTANCE.detach(cdoResource);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 4.1
   */
  @Override
  public InternalCDOSavepoint getFirstSavepoint()
  {
    return firstSavepoint;
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOSavepoint getLastSavepoint()
  {
    checkActive();
    return lastSavepoint;
  }

  /**
   * @since 2.0
   */
  @Override
  public CDOTransactionStrategy getTransactionStrategy()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (transactionStrategy == null)
        {
          transactionStrategy = CDOTransactionStrategy.DEFAULT;
          transactionStrategy.setTarget(this);
        }

        return transactionStrategy;
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void setTransactionStrategy(CDOTransactionStrategy transactionStrategy)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (this.transactionStrategy != null)
        {
          this.transactionStrategy.unsetTarget(this);
        }

        this.transactionStrategy = transactionStrategy;

        if (this.transactionStrategy != null)
        {
          this.transactionStrategy.setTarget(this);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  protected CDOID getRootOrTopLevelResourceNodeID(String name) throws CDOResourceNodeNotFoundException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (dirty)
        {
          CDOResourceNode node = getRootResourceNode(name, getDirtyObjects().values());
          if (node != null)
          {
            return node.cdoID();
          }

          node = getRootResourceNode(name, getNewObjects().values());
          if (node != null)
          {
            return node.cdoID();
          }
        }

        CDOID id = super.getRootOrTopLevelResourceNodeID(name);
        if (isObjectDetached(id) || isObjectDirty(id))
        {
          throw new CDOException(MessageFormat.format(Messages.getString("CDOTransactionImpl.1"), name)); //$NON-NLS-1$
        }

        return id;
      }
      finally
      {
        unlockView();
      }
    }
  }

  private CDOResourceNode getRootResourceNode(String name, Collection<? extends CDOObject> objects)
  {
    for (CDOObject object : objects)
    {
      if (object instanceof CDOResourceNode)
      {
        CDOResourceNode node = (CDOResourceNode)object;
        if (node.getFolder() == null && ObjectUtil.equals(name, node.getName()))
        {
          return node;
        }
      }
    }

    return null;
  }

  @Override
  protected InternalCDOObject getObjectUnsynced(CDOID id, boolean loadOnDemand)
  {
    if (isObjectNew(id) && isObjectDetached(id))
    {
      throw new ObjectNotFoundException(id, this);
    }

    return super.getObjectUnsynced(id, loadOnDemand);
  }

  @Override
  public boolean isObjectNew(CDOID id)
  {
    return lastSavepoint.isNewObject(id);
  }

  private boolean isObjectDirty(CDOID id)
  {
    return lastSavepoint.getDirtyObject(id) != null;
  }

  private boolean isObjectDetached(CDOID id)
  {
    return lastSavepoint.getDetachedObject(id) != null;
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOCommitContext createCommitContext()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return new CDOCommitContextImpl(this);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOCommitInfo commit() throws CommitException
  {
    return commit(null);
  }

  /**
   * @since 2.0
   */
  @Override
  public CDOCommitInfo commit(IProgressMonitor monitor) throws CommitException
  {
    CDOConflictResolver[] conflictResolvers = options().getConflictResolvers();
    if (conflictResolvers.length != 0)
    {
      try
      {
        checkActive();

        // Reach out to conflict resolvers before synchronizing on this transaction to avoid deadlocks in UI thread.
        for (CDOConflictResolver resolver : conflictResolvers)
        {
          if (resolver instanceof CDOConflictResolver3)
          {
            if (!((CDOConflictResolver3)resolver).preCommit())
            {
              return null;
            }
          }
        }
      }
      catch (Exception ex)
      {
        throw new CommitException(ex);
      }
    }

    CDOCommitInfo info = commitSynced(monitor);
    if (info != null)
    {
      waitForCommitInfo(info.getTimeStamp());
    }

    return info;
  }

  private void waitForCommitInfo(long timeStamp)
  {
    long timeout = options().getCommitInfoTimeout();
    if (!waitForUpdate(timeStamp, timeout))
    {
      throw new TimeoutRuntimeException("Did not receive an update: " + this);
    }
  }

  /**
   * Overridden by Bugzilla_547640_Test to resume the repository's commit notification sending.
   */
  protected void waitForBaseline(long timeStamp)
  {
    waitForCommitInfo(timeStamp);
  }

  private CDOCommitInfo commitSynced(IProgressMonitor progressMonitor) throws DanglingIntegrityException, CommitException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        InternalCDOSession session = getSession();

        try
        {
          checkActive();
          if (hasConflict())
          {
            throw new LocalCommitConflictException(Messages.getString("CDOTransactionImpl.2")); //$NON-NLS-1$
          }

          commitToken = (CommitToken)session.startLocalCommit();

          CDOTransactionStrategy transactionStrategy = getTransactionStrategy();
          CDOCommitInfo info = transactionStrategy.commit(this, progressMonitor);
          if (info != null)
          {
            lastCommitTime = info.getTimeStamp();
          }

          return info;
        }
        catch (DanglingReferenceException ex)
        {
          throw new DanglingIntegrityException(ex);
        }
        catch (CommitException ex)
        {
          throw ex;
        }
        catch (Throwable t)
        {
          try
          {
            // The commit may have succeeded on the server, but after that network problems or timeouts have hit us.
            // Let's see if we can recover...
            CDOCommitInfo info = session.getSessionProtocol().resetTransaction(getViewID(), commitToken.getCommitNumber());
            if (info != null)
            {
              lastCommitTime = info.getTimeStamp();

              InvalidationData invalidationData = new InvalidationData();
              invalidationData.setCommitInfo(info);
              invalidationData.setSender(this);
              invalidationData.setClearResourcePathCache(true);
              invalidationData.setSecurityImpact(CDOProtocol.CommitNotificationInfo.IMPACT_NONE);
              invalidationData.setNewPermissions(null);
              invalidationData.setLockChangeInfo(null);

              session.invalidate(invalidationData);

              // At this point the session (invalidator) is recovered.
              // Continue to rethrow the exception and let the client call rollback()...
            }
          }
          catch (Throwable ex)
          {
            if (TRACER.isEnabled())
            {
              TRACER.trace(ex);
            }
          }

          Throwable cause = t.getCause();
          if (cause instanceof MonitorCanceledException)
          {
            if (!(cause.getCause() instanceof TimeoutRuntimeException))
            {
              throw new OperationCanceledException("CDOTransactionImpl.7");//$NON-NLS-1$
            }
          }

          throw new CommitException(t);
        }
        finally
        {
          session.endLocalCommit(commitToken);
          commitToken = null;

          clearResourcePathCacheIfNecessary(null);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  @Deprecated
  public <T> CommitResult<T> commit(final Callable<T> callable, org.eclipse.net4j.util.Predicate<Long> retry, IProgressMonitor monitor)
      throws ConcurrentAccessException, CommitException, Exception
  {
    return commit(callable, org.eclipse.net4j.util.Predicates.toJava8(retry), monitor);
  }

  @Override
  public <T> CommitResult<T> commit(Callable<T> callable, java.util.function.Predicate<Long> retry, IProgressMonitor monitor)
      throws ConcurrentAccessException, CommitException, Exception
  {
    final Object[] result = { null };
    final Exception[] exception = { null };

    Runnable runnable = new Runnable()
    {
      @Override
      public void run()
      {
        try
        {
          result[0] = callable.call();
        }
        catch (Exception ex)
        {
          exception[0] = ex;
        }
      }
    };

    CDOCommitInfo info = commit(runnable, retry, monitor);
    if (exception[0] != null)
    {
      throw exception[0];
    }

    if (info == null)
    {
      return null;
    }

    @SuppressWarnings("unchecked")
    T r = (T)result[0];
    return new CommitResult<>(r, info);
  }

  @Override
  public <T> CommitResult<T> commit(Callable<T> callable, int attempts, IProgressMonitor monitor) throws ConcurrentAccessException, CommitException, Exception
  {
    return commit(callable, new CountedRetryPredicate(attempts), monitor);
  }

  @Override
  @Deprecated
  public CDOCommitInfo commit(Runnable runnable, org.eclipse.net4j.util.Predicate<Long> retry, IProgressMonitor monitor)
      throws ConcurrentAccessException, CommitException
  {
    return commit(runnable, org.eclipse.net4j.util.Predicates.toJava8(retry), monitor);
  }

  @Override
  public CDOCommitInfo commit(Runnable runnable, java.util.function.Predicate<Long> retry, IProgressMonitor monitor)
      throws ConcurrentAccessException, CommitException
  {
    long start = System.currentTimeMillis();
    SubMonitor subMonitor = SubMonitor.convert(monitor);

    for (;;)
    {
      subMonitor.setWorkRemaining(100);

      synchronized (getViewMonitor())
      {
        lockView();

        runnable.run();

        try
        {
          return commit(subMonitor.split(1));
        }
        catch (ConcurrentAccessException ex)
        {
          if (retry.test(System.currentTimeMillis() - start))
          {
            rollback();
            continue;
          }

          throw ex;
        }
        finally
        {
          unlockView();
        }
      }
    }
  }

  @Override
  public CDOCommitInfo commit(Runnable runnable, int attempts, IProgressMonitor monitor) throws ConcurrentAccessException, CommitException
  {
    return commit(runnable, new CountedRetryPredicate(attempts), monitor);
  }

  @Override
  public CommitToken getCommitToken()
  {
    return commitToken;
  }

  /**
   * @since 2.0
   */
  @Override
  public void rollback()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOTransactionStrategy strategy = getTransactionStrategy();
        strategy.rollback(this, firstSavepoint);

        cleanUp(null);
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void removeObject(CDOID id, final CDOObject object)
  {
    removeObject(id);

    if (object instanceof CDOResource)
    {
      InternalCDOViewSet viewSet = getViewSet();
      viewSet.executeWithoutNotificationHandling(new Callable<Boolean>()
      {
        @Override
        public Boolean call() throws Exception
        {
          EList<Resource> resources = getResourceSet().getResources();
          resources.remove(object);
          return true;
        }
      });
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void detachObject(InternalCDOObject object)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOTransactionHandler1[] handlers = getTransactionHandlers1();
        for (int i = 0; i < handlers.length; i++)
        {
          CDOTransactionHandler1 handler = handlers[i];
          handler.detachingObject(this, object);
        }

        // deregister object
        CDOID id = object.cdoID();
        if (object.cdoState() == CDOState.NEW)
        {
          Map<CDOID, CDOObject> map = lastSavepoint.getNewObjects();

          // Determine if we added object
          if (map.containsKey(id))
          {
            map.remove(id);
          }
          else
          {
            lastSavepoint.getDetachedObjects().put(id, object);
          }

          // deregister object
          deregisterObject(object);
        }
        else
        {
          if (!cleanRevisions.containsKey(object))
          {
            cleanRevisions.put(object, object.cdoRevision());
          }

          lastSavepoint.getDetachedObjects().put(id, object);

          // Object may have been reattached previously, in which case it must
          // here be removed from the collection of reattached objects
          lastSavepoint.getReattachedObjects().remove(id);
        }

        getUnitManager().removeObject(object);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void handleRollback(InternalCDOSavepoint savepoint)
  {
    if (savepoint == null)
    {
      throw new IllegalArgumentException(Messages.getString("CDOTransactionImpl.3")); //$NON-NLS-1$
    }

    if (savepoint.getTransaction() != this)
    {
      throw new IllegalArgumentException(MessageFormat.format(Messages.getString("CDOTransactionImpl.4"), savepoint)); //$NON-NLS-1$
    }

    if (!savepoint.isValid())
    {
      throw new IllegalArgumentException(MessageFormat.format(Messages.getString("CDOTransactionImpl.6"), savepoint)); //$NON-NLS-1$
    }

    if (TRACER.isEnabled())
    {
      TRACER.trace("handleRollback()"); //$NON-NLS-1$
    }

    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        // Remember current revisions
        Map<CDOObject, CDORevision> oldRevisions = new HashMap<>();
        collectRevisions(oldRevisions, getDirtyObjects());
        collectRevisions(oldRevisions, getNewObjects());

        // Rollback objects
        Map<CDOObject, CDORevision> newRevisions = new HashMap<>();
        Set<CDOID> idsOfNewObjectWithDeltas = rollbackCompletely(savepoint, newRevisions);

        lastSavepoint = savepoint;
        lastSavepoint.setNextSavepoint(null);
        lastSavepoint.clear();

        // Load from first savepoint up to current savepoint
        loadSavepoint(lastSavepoint, idsOfNewObjectWithDeltas);

        if (lastSavepoint == firstSavepoint && options().isAutoReleaseLocksEnabled())
        {
          CDORepositoryInfo repositoryInfo = getSession().getRepositoryInfo();
          if (isDurableView() && repositoryInfo.getState() == CDOCommonRepository.State.ONLINE || repositoryInfo.getType() == CDOCommonRepository.Type.MASTER)
          {
            // Unlock all objects
            unlockObjects(null, null);
          }
        }

        // Send notifications.
        for (Entry<CDOObject, CDORevision> entry : oldRevisions.entrySet())
        {
          InternalCDOObject object = (InternalCDOObject)entry.getKey();
          InternalCDORevision oldRevision = (InternalCDORevision)entry.getValue();

          InternalCDORevision newRevision = object.cdoRevision();
          if (newRevision == null)
          {
            newRevision = (InternalCDORevision)newRevisions.get(object);
          }

          if (newRevision == null && !FSMUtil.isTransient(object))
          {
            // This can happen for example for conflicting objects which have been set to PROXY in rollbackCompletely().
            CDOID id = oldRevision.getID();
            newRevision = getRevision(id, true);
            object.cdoInternalSetRevision(newRevision);
            object.cdoInternalSetState(CDOState.CLEAN);
          }

          if (newRevision != null)
          {
            InternalCDORevisionDelta delta = newRevision.compare(oldRevision);
            if (!delta.isEmpty())
            {
              Set<CDOObject> detachedObjects = Collections.emptySet();

              CDONotificationBuilder builder = new CDONotificationBuilder(this);
              NotificationChain notification = builder.buildNotification(object, oldRevision, delta, detachedObjects);
              if (notification != null)
              {
                notification.dispatch();
              }
            }
          }
        }

        IListener[] listeners = getListeners();
        if (listeners != null)
        {
          fireEvent(new FinishedEvent(true), listeners);
        }

        CDOTransactionHandler2[] handlers = getTransactionHandlers2();
        for (int i = 0; i < handlers.length; i++)
        {
          CDOTransactionHandler2 handler = handlers[i];

          try
          {
            handler.rolledBackTransaction(this);
          }
          catch (RuntimeException ex)
          {
            OM.LOG.error(ex);
          }
        }
      }
      catch (RuntimeException ex)
      {
        throw ex;
      }
      catch (Exception ex)
      {
        throw new TransactionException(ex);
      }
      finally
      {
        unlockView();
      }
    }
  }

  private Set<CDOID> rollbackCompletely(CDOUserSavepoint savepoint, Map<CDOObject, CDORevision> newRevisions)
  {
    Set<CDOID> idsOfNewObjectsWithDeltas = new HashSet<>();
    Set<InternalCDOObject> newObjects = new HashSet<>();

    // Start from the last savepoint and come back up to the active
    for (InternalCDOSavepoint itrSavepoint = lastSavepoint; itrSavepoint != null; itrSavepoint = itrSavepoint.getPreviousSavepoint())
    {
      Set<Object> toBeDetached = new HashSet<>();

      // Rollback new objects attached after the save point
      Map<CDOID, CDOObject> newObjectsMap = itrSavepoint.getNewObjects();
      for (CDOID id : newObjectsMap.keySet())
      {
        InternalCDOObject object = (InternalCDOObject)newObjectsMap.get(id);

        toBeDetached.add(id);
        toBeDetached.add(object);
        toBeDetached.add(object.cdoInternalInstance());
        removeObject(id, object);
        newObjects.add(object);
      }

      // Rollback new objects re-attached after the save point
      Map<CDOID, CDOObject> reattachedObjectsMap = itrSavepoint.getReattachedObjects();
      Set<CDOID> detachedIDs = itrSavepoint.getDetachedObjects().keySet();
      for (CDOObject reattachedObject : reattachedObjectsMap.values())
      {
        CDOID id = reattachedObject.cdoID();
        if (!detachedIDs.contains(id))
        {
          InternalCDOObject internal = (InternalCDOObject)reattachedObject;

          toBeDetached.add(id);
          toBeDetached.add(internal);
          toBeDetached.add(internal.cdoInternalInstance());
          removeObject(id, internal);

          internal.cdoInternalSetView(null);
          internal.cdoInternalSetID(null);
          internal.cdoInternalSetState(CDOState.TRANSIENT);
        }
      }

      Map<CDOID, CDORevision> attachedRevisions = options().getAttachedRevisionsMap();
      for (Object idOrObject : toBeDetached)
      {
        InternalCDORevision revision = null;

        if (idOrObject instanceof InternalCDOObject)
        {
          InternalCDOObject object = (InternalCDOObject)idOrObject;
          CDOID id = object.cdoID();

          if (attachedRevisions != null)
          {
            revision = (InternalCDORevision)attachedRevisions.get(id);
          }

          if (revision == null)
          {
            revision = object.cdoRevision();
            if (revision != null)
            {
              // Copy the revision, so that the revision modifications below don't apply to the oldRevisions,
              // which have been remembered in handleRollback() for the computation of delta notifications.
              revision = revision.copy();
            }
          }

          if (revision != null)
          {
            newRevisions.put((CDOObject)idOrObject, revision);
          }

          Resource.Internal directResource = object.eDirectResource();
          EObject container = object.eContainer();
          boolean topLevel = !toBeDetached.contains(directResource) && !toBeDetached.contains(container);
          if (topLevel)
          {
            if (revision != null)
            {
              // Unset direct resource and container in the revision.
              // Later cdoInternalPostDetach() will migrate these values into the EObject.
              // See CDOStateMachine.RollbackTransition.execute().
              revision.setResourceID(null);
              revision.setContainerID(null);
              revision.setContainingFeatureID(0);
            }
          }

          if (idOrObject instanceof CDOObjectImpl)
          {
            CDOObjectImpl impl = (CDOObjectImpl)idOrObject;

            if (revision != null)
            {
              impl.cdoInternalSetRevision(revision);
            }
            else if (topLevel)
            {
              // Unset direct resource and eContainer in the EObject.
              impl.cdoInternalSetResource(null);
            }
          }
          else if (idOrObject instanceof CDOObjectWrapper)
          {
            CDOObjectWrapper wrapper = (CDOObjectWrapper)idOrObject;

            if (revision != null)
            {
              wrapper.cdoInternalRollback(revision);
            }

            if (topLevel)
            {
              wrapper.setInstanceResource(null);
              wrapper.setInstanceContainer(null, 0);
            }
          }
        }
      }

      Map<CDOID, CDORevisionDelta> revisionDeltas = itrSavepoint.getRevisionDeltas2();
      if (!revisionDeltas.isEmpty())
      {
        for (CDORevisionDelta dirtyObject : revisionDeltas.values())
        {
          CDOID id = dirtyObject.getID();
          if (isObjectNew(id))
          {
            idsOfNewObjectsWithDeltas.add(id);
          }
        }
      }

      // Rollback all detached objects.
      Map<CDOID, CDOObject> detachedObjectsMap = itrSavepoint.getDetachedObjects();
      if (!detachedObjectsMap.isEmpty())
      {
        for (Entry<CDOID, CDOObject> detachedObjectEntry : detachedObjectsMap.entrySet())
        {
          CDOID id = detachedObjectEntry.getKey();
          if (isObjectNew(id))
          {
            idsOfNewObjectsWithDeltas.add(id);
          }
          else
          {
            InternalCDOObject detachedObject = (InternalCDOObject)detachedObjectEntry.getValue();
            InternalCDORevision cleanRev = cleanRevisions.get(detachedObject);
            cleanObject(detachedObject, cleanRev);
          }
        }
      }

      // Rollback dirty objects.
      for (Entry<CDOID, CDOObject> entryDirtyObject : itrSavepoint.getDirtyObjects().entrySet())
      {
        CDOID id = entryDirtyObject.getKey();
        if (!isObjectNew(id))
        {
          InternalCDOObject internalDirtyObject = (InternalCDOObject)entryDirtyObject.getValue();

          // Bug 283985 (Re-attachment): Skip objects that were reattached, because
          // they were already reset to TRANSIENT earlier in this method
          if (!reattachedObjectsMap.values().contains(internalDirtyObject))
          {
            CDOStateMachine.INSTANCE.rollback(internalDirtyObject, this);
          }
        }
      }

      if (savepoint == itrSavepoint)
      {
        break;
      }
    }

    // Rollback new objects.
    for (InternalCDOObject internalCDOObject : newObjects)
    {
      if (FSMUtil.isNew(internalCDOObject))
      {
        CDOStateMachine.INSTANCE.rollback(internalCDOObject, this);
        internalCDOObject.cdoInternalSetID(null);
        internalCDOObject.cdoInternalSetView(null);
      }
    }

    return idsOfNewObjectsWithDeltas;
  }

  private void loadSavepoint(CDOSavepoint savepoint, Set<CDOID> idsOfNewObjectWithDeltas)
  {
    Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
    Map<CDOID, CDOObject> newObjMaps = getNewObjects();
    Map<CDOID, CDORevision> newBaseRevision = getBaseNewObjects();
    Map<CDOID, CDOObject> detachedObjects = getDetachedObjects();

    // Reload the objects (NEW) with their base.
    for (CDOID id : idsOfNewObjectWithDeltas)
    {
      if (detachedObjects.containsKey(id))
      {
        continue;
      }

      InternalCDOObject object = (InternalCDOObject)newObjMaps.get(id);
      CDORevision revision = newBaseRevision.get(id);
      if (revision != null)
      {
        object.cdoInternalSetRevision(revision.copy());
        object.cdoInternalSetView(this);
        object.cdoInternalSetState(CDOState.NEW);

        // Load the object from revision to EObject
        object.cdoInternalPostLoad();
        if (super.getObject(object.cdoID(), false) == null)
        {
          registerObject(object);
        }
      }
    }

    // We need to register back new objects that are not removed anymore there.
    for (Entry<CDOID, CDOObject> entryNewObject : newObjMaps.entrySet())
    {
      InternalCDOObject object = (InternalCDOObject)entryNewObject.getValue();

      // Go back to the previous state
      cleanObject(object, object.cdoRevision());
      object.cdoInternalSetState(CDOState.NEW);
    }

    for (Entry<CDOID, CDOObject> entryDirtyObject : dirtyObjects.entrySet())
    {
      if (detachedObjects.containsKey(entryDirtyObject.getKey()))
      {
        continue;
      }

      // Rollback every persisted objects
      InternalCDOObject internalDirtyObject = (InternalCDOObject)entryDirtyObject.getValue();
      cleanObject(internalDirtyObject, getRevision(entryDirtyObject.getKey(), true));
    }

    CDOObjectMerger merger = new CDOObjectMerger();
    for (InternalCDOSavepoint itrSavepoint = firstSavepoint; itrSavepoint != savepoint; itrSavepoint = itrSavepoint.getNextSavepoint())
    {
      for (CDORevisionDelta delta : itrSavepoint.getRevisionDeltas2().values())
      {
        CDOID id = delta.getID();
        boolean isNew = isObjectNew(id);
        if (isNew && !idsOfNewObjectWithDeltas.contains(id) || detachedObjects.containsKey(id))
        {
          continue;
        }

        Map<CDOID, CDOObject> map = isNew ? newObjMaps : dirtyObjects;
        InternalCDOObject object = (InternalCDOObject)map.get(id);

        // Change state of the objects
        merger.merge(object, delta);

        // Load the object from revision to EObject
        object.cdoInternalPostLoad();
      }
    }

    dirty = savepoint.wasDirty();
  }

  private void collectRevisions(Map<CDOObject, CDORevision> revisions, Map<CDOID, CDOObject> objects)
  {
    for (CDOObject object : objects.values())
    {
      CDORevision oldRevision = object.cdoRevision();
      if (oldRevision != null)
      {
        revisions.put(object, oldRevision);
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOSavepoint handleSetSavepoint()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        addToBase(lastSavepoint.getNewObjects());
        lastSavepoint = createSavepoint(lastSavepoint);
        return lastSavepoint;
      }
      finally
      {
        unlockView();
      }
    }
  }

  private CDOSavepointImpl createSavepoint(InternalCDOSavepoint lastSavepoint)
  {
    return new CDOSavepointImpl(this, lastSavepoint);
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOSavepoint setSavepoint()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return (InternalCDOSavepoint)getTransactionStrategy().setSavepoint(this);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public boolean hasMultipleSavepoints()
  {
    return lastSavepoint != firstSavepoint;
  }

  private void addToBase(Map<CDOID, CDOObject> objects)
  {
    for (CDOObject object : objects.values())
    {
      // Load instance to revision
      ((InternalCDOObject)object).cdoInternalPreCommit();
      lastSavepoint.getBaseNewObjects().put(object.cdoID(), object.cdoRevision().copy());
    }
  }

  @Override
  protected String getClassName()
  {
    return "CDOTransaction"; //$NON-NLS-1$
  }

  @Override
  public void registerAttached(InternalCDOObject object, boolean isNew)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Registering new object {0}", object); //$NON-NLS-1$
    }

    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (isNew)
        {
          registerNewPackage(object.eClass().getEPackage());
        }

        CDOTransactionHandler1[] handlers = getTransactionHandlers1();
        for (int i = 0; i < handlers.length; i++)
        {
          CDOTransactionHandler1 handler = handlers[i];
          handler.attachingObject(this, object);
        }

        if (isNew)
        {
          registerNew(lastSavepoint.getNewObjects(), object);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void registerNewPackage(EPackage ePackage)
  {
    CDOPackageRegistry packageRegistry = getSession().getPackageRegistry();
    if (!packageRegistry.containsKey(ePackage.getNsURI()))
    {
      packageRegistry.putEPackage(ePackage);
    }
  }

  private CDOOriginSizeProvider getOriginSizeProvider(InternalCDOObject object, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
  {
    EStructuralFeature feature = featureDelta.getFeature();
    if (feature.isMany())
    {
      if (cleanRevision == null)
      {
        cleanRevision = cleanRevisions.get(object);
        if (cleanRevision == null)
        {
          cleanRevision = object.cdoRevision();
        }
      }

      CDOList list = cleanRevision.getListOrNull(feature);
      final int originSize = list == null ? 0 : list.size();

      return new CDOOriginSizeProvider()
      {
        @Override
        public int getOriginSize()
        {
          return originSize;
        }
      };
    }

    return null;
  }

  /**
   * Receives notification for new and dirty objects
   */
  @Override
  public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        registerFeatureDelta(object, featureDelta, null);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void registerFeatureDelta(InternalCDOObject object, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOID id = object.cdoID();
        boolean needToSaveFeatureDelta = true;

        if (object.cdoState() == CDOState.NEW)
        {
          // Register Delta for new objects only if objectA doesn't belong to this savepoint
          if (lastSavepoint.getPreviousSavepoint() == null || featureDelta == null)
          {
            needToSaveFeatureDelta = false;
          }
          else
          {
            Map<CDOID, CDOObject> map = lastSavepoint.getNewObjects();
            needToSaveFeatureDelta = !map.containsKey(id);
          }
        }

        if (needToSaveFeatureDelta)
        {
          Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
          InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)revisionDeltas.get(id);
          if (revisionDelta == null)
          {
            InternalCDORevision revision = object.cdoRevision();

            revisionDelta = (InternalCDORevisionDelta)CDORevisionUtil.createDelta(revision);
            revisionDeltas.put(id, revisionDelta);
          }

          CDOOriginSizeProvider originSizeProvider = getOriginSizeProvider(object, featureDelta, cleanRevision);
          revisionDelta.addFeatureDelta(featureDelta, originSizeProvider);
        }

        CDOTransactionHandler1[] handlers = getTransactionHandlers1();
        for (int i = 0; i < handlers.length; i++)
        {
          CDOTransactionHandler1 handler = handlers[i];
          handler.modifyingObject(this, object, featureDelta);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void registerRevisionDelta(CDORevisionDelta revisionDelta)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
        CDOID id = revisionDelta.getID();
        if (!revisionDeltas.containsKey(id))
        {
          revisionDeltas.put(id, revisionDelta);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta)
  {
    registerDirty(object, featureDelta, null);
  }

  @Override
  public void registerDirty(InternalCDOObject object, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Registering dirty object {0}", object); //$NON-NLS-1$
    }

    if (featureDelta != null)
    {
      registerFeatureDelta(object, featureDelta, cleanRevision);
    }

    registerNew(lastSavepoint.getDirtyObjects(), object);
  }

  /**
   * TODO Simon: Should this method go to CDOSavePointImpl?
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  private void registerNew(Map map, InternalCDOObject object)
  {
    Object old = map.put(object.cdoID(), object);
    if (old != null)
    {
      throw new IllegalStateException(MessageFormat.format(Messages.getString("CDOTransactionImpl.10"), object)); //$NON-NLS-1$
    }

    setDirty(true);
  }

  public List<CDOPackageUnit> analyzeNewPackages()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOPackageRegistry packageRegistry = getSession().getPackageRegistry();
        Set<EPackage> usedPackages = new HashSet<>();
        Set<EPackage> usedNewPackages = new HashSet<>();
        for (CDOObject object : getNewObjects().values())
        {
          EPackage ePackage = object.eClass().getEPackage();
          if (usedPackages.add(ePackage))
          {
            EPackage topLevelPackage = EMFUtil.getTopLevelPackage(ePackage);
            if (ePackage == topLevelPackage || usedPackages.add(topLevelPackage))
            {
              // if (!CDOModelUtil.isSystemPackage(topLevelPackage))
              {
                CDOPackageUnit packageUnit = packageRegistry.getPackageUnit(topLevelPackage);
                if (packageUnit.getState() == CDOPackageUnit.State.NEW)
                {
                  usedNewPackages.add(topLevelPackage);
                }
              }
            }
          }
        }

        if (usedNewPackages.size() > 0)
        {
          Set<CDOPackageUnit> result = new HashSet<>();
          for (EPackage usedNewPackage : analyzeNewPackages(usedNewPackages, packageRegistry))
          {
            CDOPackageUnit packageUnit = packageRegistry.getPackageUnit(usedNewPackage);
            result.add(packageUnit);
          }

          return new ArrayList<>(result);
        }

        return Collections.emptyList();
      }
      finally
      {
        unlockView();
      }
    }
  }

  private static List<EPackage> analyzeNewPackages(Collection<EPackage> usedTopLevelPackages, CDOPackageRegistry packageRegistry)
  {
    // Determine which of the corresponding EPackages are new
    List<EPackage> newPackages = new ArrayList<>();

    IPackageClosure closure = new CompletePackageClosure();
    usedTopLevelPackages = closure.calculate(usedTopLevelPackages);

    for (EPackage usedPackage : usedTopLevelPackages)
    {
      // if (!CDOModelUtil.isSystemPackage(usedPackage))
      {
        CDOPackageUnit packageUnit = packageRegistry.getPackageUnit(usedPackage);
        if (packageUnit == null)
        {
          throw new CDOException(MessageFormat.format(Messages.getString("CDOTransactionImpl.11"), usedPackage)); //$NON-NLS-1$
        }

        if (packageUnit.getState() == CDOPackageUnit.State.NEW)
        {
          newPackages.add(usedPackage);
        }
      }
    }

    return newPackages;
  }

  private void cleanUp(CDOCommitContext commitContext)
  {
    if (commitContext == null || !commitContext.isPartialCommit())
    {
      if (commitContext != null)
      {
        for (CDOObject object : commitContext.getDetachedObjects().values())
        {
          cleanUpLockState(object);
        }
      }

      lastSavepoint = firstSavepoint;
      firstSavepoint.clear();
      firstSavepoint.setNextSavepoint(null);

      cleanRevisions.clear();

      Map<CDOID, CDORevision> attachedRevisions = options().getAttachedRevisionsMap();
      if (attachedRevisions != null)
      {
        attachedRevisions.clear();
      }

      dirty = false;
      conflict = 0;
      idGenerator.reset();
    }
    else
    {
      collapseSavepoints(commitContext);

      for (CDOObject object : commitContext.getDetachedObjects().values())
      {
        cleanRevisions.remove(object);
        cleanUpLockState(object);
      }

      for (CDOObject object : commitContext.getDirtyObjects().values())
      {
        cleanRevisions.remove(object);
      }
    }

    // Reset partial-commit filter
    committables = null;
  }

  private void cleanUpLockState(CDOObject object)
  {
    InternalCDOLockState lockState = (InternalCDOLockState)removeLockState(object);
    if (lockState != null)
    {
      lockState.dispose();
    }
  }

  private void collapseSavepoints(CDOCommitContext commitContext)
  {
    InternalCDOSavepoint newSavepoint = createSavepoint(null);
    copyUncommitted(lastSavepoint.getAllNewObjects(), commitContext.getNewObjects(), newSavepoint.getNewObjects());
    copyUncommitted(lastSavepoint.getAllDirtyObjects(), commitContext.getDirtyObjects(), newSavepoint.getDirtyObjects());
    copyUncommitted(lastSavepoint.getAllRevisionDeltas(), commitContext.getRevisionDeltas(), newSavepoint.getRevisionDeltas2());
    copyUncommitted(lastSavepoint.getAllDetachedObjects(), commitContext.getDetachedObjects(), newSavepoint.getDetachedObjects());
    lastSavepoint = newSavepoint;
    firstSavepoint = lastSavepoint;
  }

  private <T> void copyUncommitted(Map<CDOID, T> oldSavepointMap, Map<CDOID, T> commitContextMap, Map<CDOID, T> newSavepointMap)
  {
    for (Entry<CDOID, T> entry : oldSavepointMap.entrySet())
    {
      if (!commitContextMap.containsKey(entry.getKey()))
      {
        newSavepointMap.put(entry.getKey(), entry.getValue());
      }
    }
  }

  @Override
  public CDOSavepoint[] exportChanges(OutputStream stream) throws IOException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDODataOutput out = new CDODataOutputImpl(new ExtendedDataOutputStream(stream))
        {
          @Override
          public CDOIDProvider getIDProvider()
          {
            return CDOTransactionImpl.this;
          }

          @Override
          public CDOPackageRegistry getPackageRegistry()
          {
            return getSession().getPackageRegistry();
          }

          @Override
          public CDORevisionUnchunker getRevisionUnchunker()
          {
            return getSession();
          }

          @Override
          protected boolean isXCompression()
          {
            return X_COMPRESSION;
          }
        };

        List<CDOSavepoint> savepoints = new ArrayList<>();
        int totalNewObjects = 0;

        InternalCDOSavepoint savepoint = firstSavepoint;
        while (savepoint != null)
        {
          Collection<CDOObject> newObjects = savepoint.getNewObjects().values();
          totalNewObjects += newObjects.size();

          savepoint = savepoint.getNextSavepoint();
        }

        out.writeXInt(totalNewObjects);

        savepoint = firstSavepoint;
        while (savepoint != null)
        {
          Collection<CDOObject> newObjects = savepoint.getNewObjects().values();
          Collection<CDORevisionDelta> revisionDeltas = savepoint.getRevisionDeltas2().values();
          if (newObjects.isEmpty() && revisionDeltas.isEmpty())
          {
            savepoint = savepoint.getNextSavepoint();
            continue;
          }

          savepoints.add(savepoint);
          out.writeBoolean(true);

          out.writeXInt(newObjects.size());
          for (CDOObject newObject : newObjects)
          {
            out.writeCDORevision(newObject.cdoRevision(), CDORevision.UNCHUNKED);
          }

          out.writeXInt(revisionDeltas.size());
          for (CDORevisionDelta revisionDelta : revisionDeltas)
          {
            out.writeCDORevisionDelta(revisionDelta);
          }

          savepoint = savepoint.getNextSavepoint();
        }

        out.writeBoolean(false);
        return savepoints.toArray(new CDOSavepoint[savepoints.size()]);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOSavepoint[] importChanges(InputStream stream, boolean reconstructSavepoints) throws IOException
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        List<CDOSavepoint> savepoints = new ArrayList<>();
        if (stream.available() > 0)
        {
          CDODataInput in = new CDODataInputImpl(new ExtendedDataInputStream(stream))
          {
            @Override
            public CDOPackageRegistry getPackageRegistry()
            {
              return getSession().getPackageRegistry();
            }

            @Override
            protected CDOBranchManager getBranchManager()
            {
              return getSession().getBranchManager();
            }

            @Override
            protected CDOCommitInfoManager getCommitInfoManager()
            {
              return getSession().getCommitInfoManager();
            }

            @Override
            protected CDORevisionFactory getRevisionFactory()
            {
              return getSession().getRevisionManager().getFactory();
            }

            @Override
            protected CDOLobStore getLobStore()
            {
              return getSession().getLobStore();
            }

            @Override
            protected CDOListFactory getListFactory()
            {
              return CDOListWithElementProxiesImpl.FACTORY;
            }

            @Override
            protected boolean isXCompression()
            {
              return X_COMPRESSION;
            }
          };

          // Increase the internal tempID counter to prevent ID collisions during mapping
          int totalNewObjects = in.readXInt();
          for (int i = 0; i < totalNewObjects; i++)
          {
            createIDForNewObject(null);
          }

          Map<CDOID, CDOID> idMappings = CDOIDUtil.createMap();
          while (in.readBoolean())
          {
            if (reconstructSavepoints)
            {
              InternalCDOSavepoint savepoint = setSavepoint();
              savepoints.add(savepoint);
            }

            // Import revisions and deltas
            List<InternalCDORevision> revisions = new ArrayList<>();
            importNewRevisions(in, revisions, idMappings);
            List<InternalCDORevisionDelta> revisionDeltas = importRevisionDeltas(in);

            if (!idMappings.isEmpty())
            {
              // Re-map temp IDs
              CDOIDMapper idMapper = new CDOIDMapper(idMappings);
              for (InternalCDORevision revision : revisions)
              {
                revision.adjustReferences(idMapper);
              }

              for (InternalCDORevisionDelta delta : revisionDeltas)
              {
                delta.adjustReferences(idMapper);
              }
            }

            if (!revisions.isEmpty())
            {
              // Create new objects
              List<InternalCDOObject> newObjects = new ArrayList<>();
              for (InternalCDORevision revision : revisions)
              {
                InternalCDOObject object = newInstance(revision);
                registerObject(object);
                registerAttached(object, true);

                newObjects.add(object);
              }

              // Post-load new objects (important for legacy objects!)
              for (InternalCDOObject object : newObjects)
              {
                object.cdoInternalPostLoad();
              }
            }

            // Apply deltas
            CDOObjectMerger merger = new CDOObjectMerger();
            for (InternalCDORevisionDelta delta : revisionDeltas)
            {
              InternalCDOObject object = getObject(delta.getID());
              int oldVersion = object.cdoRevision().getVersion();

              merger.merge(object, delta);
              registerRevisionDelta(delta);
              registerDirty(object, null);

              if (delta.getVersion() < oldVersion)
              {
                setConflict(object);
              }
            }
          }
        }

        return savepoints.toArray(new CDOSavepoint[savepoints.size()]);
      }
      finally
      {
        unlockView();
      }
    }
  }

  private void importNewRevisions(CDODataInput in, List<InternalCDORevision> revisions, Map<CDOID, CDOID> idMappings) throws IOException
  {
    int size = in.readXInt();
    for (int i = 0; i < size; i++)
    {
      InternalCDORevision revision = (InternalCDORevision)in.readCDORevision(false);

      CDOID oldID = revision.getID();
      if (oldID.isTemporary())
      {
        CDOID newID = createIDForNewObject(null);
        idMappings.put(oldID, newID);
        revision.setID(newID);
      }

      revisions.add(revision);
    }
  }

  private List<InternalCDORevisionDelta> importRevisionDeltas(CDODataInput in) throws IOException
  {
    int size = in.readXInt();
    List<InternalCDORevisionDelta> deltas = new ArrayList<>(size);
    for (int i = 0; i < size; i++)
    {
      InternalCDORevisionDelta delta = (InternalCDORevisionDelta)in.readCDORevisionDelta();
      deltas.add(delta);
    }

    return deltas;
  }

  private InternalCDOObject newInstance(InternalCDORevision revision)
  {
    InternalCDOObject object = newInstance(revision.getEClass());
    object.cdoInternalSetRevision(revision);
    object.cdoInternalSetView(this);
    object.cdoInternalSetState(CDOState.NEW);
    return object;
  }

  @Override
  public Map<CDOID, CDOObject> getDirtyObjects()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllDirtyObjects();
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public Map<CDOID, CDOObject> getNewObjects()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllNewObjects();
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  public Map<CDOID, CDORevision> getBaseNewObjects()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllBaseNewObjects();
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllRevisionDeltas();
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public Map<CDOID, CDOObject> getDetachedObjects()
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastSavepoint.getAllDetachedObjects();
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  protected CloseableIterator<CDOResourceNode> queryResourcesUnsynced(CDOResourceFolder folder, final String name, final boolean exactMatch)
  {
    if (!isDirty())
    {
      return super.queryResourcesUnsynced(folder, name, exactMatch);
    }

    CDOState state;
    CDOList list = null;

    if (folder == null)
    {
      CDOResource rootResource = getRootResource();
      state = rootResource.cdoState();
      if (state.isLocal())
      {
        InternalCDORevision revision = (InternalCDORevision)rootResource.cdoRevision();
        if (revision != null)
        {
          list = revision.getListOrNull(EresourcePackage.Literals.CDO_RESOURCE__CONTENTS);
        }
      }
    }
    else
    {
      state = folder.cdoState();
      if (state == CDOState.TRANSIENT)
      {
        throw new CDOException("Folder " + folder + " is transient");
      }

      if (state.isLocal())
      {
        InternalCDORevision revision = (InternalCDORevision)folder.cdoRevision();
        if (revision != null)
        {
          list = revision.getListOrNull(EresourcePackage.Literals.CDO_RESOURCE_FOLDER__NODES);
        }
      }
    }

    if (state.isRemote())
    {
      Set<CDOID> validIDs = null;
      List<CDOResourceNode> addedNodes = null;

      if (list != null)
      {
        for (Object element : list)
        {
          if (element instanceof CDOResourceNode)
          {
            CDOResourceNode node = (CDOResourceNode)element;

            if (addedNodes == null)
            {
              addedNodes = new ArrayList<>();
            }

            addedNodes.add(node);
          }
          else
          {
            CDOID id = (CDOID)element;
            if (isObjectNew(id))
            {
              CDOResourceNode node = (CDOResourceNode)getObject(id);
              addedNodes.add(node);
            }
            else
            {
              if (validIDs == null)
              {
                validIDs = new HashSet<>();
              }

              validIDs.add(id);
            }
          }
        }
      }

      final Set<CDOID> finalValidIDs = validIDs;
      final List<CDOResourceNode> finalAddedNodes = addedNodes;
      final CloseableIterator<CDOResourceNode> delegate = super.queryResourcesUnsynced(folder, name, exactMatch);

      return new AbstractCloseableIterator<CDOResourceNode>()
      {
        private Iterator<CDOResourceNode> addedNodesIterator = finalAddedNodes == null ? null : finalAddedNodes.iterator();

        @Override
        protected Object computeNextElement()
        {
          if (addedNodesIterator != null)
          {
            if (isClosed())
            {
              return END_OF_DATA;
            }

            while (addedNodesIterator.hasNext())
            {
              CDOResourceNode node = addedNodesIterator.next();

              // Locally added node is not matched by the server; match it now.
              if (isResourceMatch(node.getName(), name, exactMatch))
              {
                return node;
              }
            }

            addedNodesIterator = null;
          }

          if (finalValidIDs != null)
          {
            while (delegate.hasNext())
            {
              CDOResourceNode node = delegate.next();
              if (finalValidIDs.contains(node.cdoID()))
              {
                if (node.cdoState().isLocal())
                {
                  // Locally changed node is not matched by the server; match it now.
                  if (isResourceMatch(node.getName(), name, exactMatch))
                  {
                    return node;
                  }
                }
                else
                {
                  // Locally unchanged node is matched by the server already; just return it.
                  return node;
                }
              }
            }
          }

          return END_OF_DATA;
        }

        @Override
        public void close()
        {
          delegate.close();
        }

        @Override
        public boolean isClosed()
        {
          return delegate.isClosed();
        }
      };
    }

    final CDOList finalList = list;

    return new AbstractCloseableIterator<CDOResourceNode>()
    {

      private Iterator<Object> listIterator = finalList == null ? null : finalList.iterator();

      @Override
      protected Object computeNextElement()
      {
        if (listIterator != null)
        {
          while (listIterator.hasNext())
          {
            Object element = listIterator.next();
            CDOResourceNode node = getResourceNode(element);

            // Locally added node is not matched by the server; match it now.
            if (isResourceMatch(node.getName(), name, exactMatch))
            {
              return node;
            }
          }

          listIterator = null;
        }

        return END_OF_DATA;
      }

      private CDOResourceNode getResourceNode(Object element)
      {
        if (element instanceof CDOResourceNode)
        {
          return (CDOResourceNode)element;
        }

        return (CDOResourceNode)getObject((CDOID)element);
      }

      @Override
      public void close()
      {
        listIterator = null;
      }

      @Override
      public boolean isClosed()
      {
        return listIterator == null;
      }

    };
  }

  @Override
  protected <T extends EObject> CloseableIterator<T> queryInstancesUnsynced(final EClass type, final boolean exact)
  {
    if (!isDirty())
    {
      return super.queryInstancesUnsynced(type, exact);
    }

    final Map<CDOID, CDOObject> newObjects = lastSavepoint.getAllNewObjects();
    final CloseableIterator<T> delegate = super.queryInstancesUnsynced(type, exact);

    return new AbstractCloseableIterator<T>()
    {
      private Iterator<CDOObject> newObjectsIterator = newObjects.isEmpty() ? null : newObjects.values().iterator();

      @Override
      protected Object computeNextElement()
      {
        if (newObjectsIterator != null)
        {
          if (isClosed())
          {
            return END_OF_DATA;
          }

          while (newObjectsIterator.hasNext())
          {
            EObject newObject = CDOUtil.getEObject(newObjectsIterator.next());

            // Locally added node is not matched by the server; match it now.
            if (exact ? type == newObject.eClass() : type.isInstance(newObject))
            {
              return newObject;
            }
          }

          newObjectsIterator = null;
        }

        while (delegate.hasNext())
        {
          T object = delegate.next();
          CDOObject cdoObject = CDOUtil.getCDOObject(object);
          System.out.println(cdoObject);

          if (!FSMUtil.isTransient(cdoObject))
          {
            return object;
          }
        }

        return END_OF_DATA;
      }

      @Override
      public void close()
      {
        delegate.close();
      }

      @Override
      public boolean isClosed()
      {
        return delegate.isClosed();
      }
    };
  }

  @Override
  protected CloseableIterator<CDOObjectReference> queryXRefsUnsynced(Set<CDOObject> targetObjects, EReference... sourceReferences)
  {
    if (!isDirty())
    {
      return super.queryXRefsUnsynced(targetObjects, sourceReferences);
    }

    final Set<CDOID> targetIDs = new HashSet<>();
    final Set<EReference> relevantReferences = toSet(sourceReferences);
    final CDOQuery query = createXRefsQuery(false, targetIDs, targetObjects, sourceReferences);

    if (query.getQueryString() != null)
    {
      final Set<CDOID> localIDs = new HashSet<>();
      final List<CDOObjectReference> localXRefs = queryXRefsLocal(localIDs, targetIDs, relevantReferences);
      final CloseableIterator<CDOObjectReference> delegate = query.getResultAsync(CDOObjectReference.class);

      return new AbstractCloseableIterator<CDOObjectReference>()
      {
        private Iterator<CDOObjectReference> localXRefsIterator = localXRefs == null ? null : localXRefs.iterator();

        @Override
        protected Object computeNextElement()
        {
          if (localXRefsIterator != null)
          {
            if (isClosed())
            {
              return END_OF_DATA;
            }

            if (localXRefsIterator.hasNext())
            {
              return localXRefsIterator.next();
            }

            localXRefsIterator = null;
          }

          while (delegate.hasNext())
          {
            CDOObjectReference ref = delegate.next();
            if (!localIDs.contains(ref.getSourceID()))
            {
              return ref;
            }
          }

          return END_OF_DATA;
        }

        @Override
        public void close()
        {
          delegate.close();
        }

        @Override
        public boolean isClosed()
        {
          return delegate.isClosed();
        }
      };
    }

    List<CDOObjectReference> localXRefs = queryXRefsLocal(null, targetIDs, relevantReferences);
    if (localXRefs != null)
    {
      return new DelegatingCloseableIterator<>(localXRefs.iterator());
    }

    return AbstractCloseableIterator.emptyCloseable();
  }

  private List<CDOObjectReference> queryXRefsLocal(Set<CDOID> localIDs, Set<CDOID> targetIDs, Set<EReference> relevantReferences)
  {
    List<CDOObjectReference> refs = null;

    Map<CDOID, CDOObject> newObjects = lastSavepoint.getAllNewObjects();
    Map<CDOID, CDOObject> dirtyObjects = lastSavepoint.getAllDirtyObjects();

    if (localIDs != null)
    {
      localIDs.addAll(newObjects.keySet());
      localIDs.addAll(dirtyObjects.keySet());
      localIDs.addAll(lastSavepoint.getAllDetachedObjects().keySet());
    }

    Iterator<CDOObject> it = new ComposedIterator<>( //
        newObjects.values().iterator(), //
        dirtyObjects.values().iterator());

    while (it.hasNext())
    {
      CDOObject object = it.next();
      InternalCDORevision revision = (InternalCDORevision)object.cdoRevision();

      for (EReference reference : revision.getClassInfo().getAllPersistentReferences())
      {
        if (!reference.isContainer() && !reference.isContainment() && (relevantReferences == null || relevantReferences.contains(reference)))
        {
          if (reference.isMany())
          {
            CDOList list = revision.getListOrNull(reference);
            if (list != null)
            {
              int index = 0;
              for (Object value : list)
              {
                refs = addXRefLocal(refs, targetIDs, object, reference, index, value);
                ++index;
              }
            }
          }
          else
          {
            Object value = revision.getValue(reference);
            refs = addXRefLocal(refs, targetIDs, object, reference, 0, value);
          }
        }
      }
    }

    return refs;
  }

  private List<CDOObjectReference> addXRefLocal(List<CDOObjectReference> refs, Set<CDOID> targetIDs, CDOObject object, EReference reference, int index,
      Object value)
  {
    if (value != null)
    {
      CDOID targetID = value instanceof CDOID ? (CDOID)value : getXRefID(CDOUtil.getCDOObject((EObject)value));
      if (!CDOIDUtil.isNull(targetID) && targetIDs.contains(targetID))
      {
        CDOIDReference delegateRef = new CDOIDReference(targetID, object.cdoID(), reference, index);
        CDOObjectReference ref = new CDOObjectReferenceImpl(this, delegateRef);

        if (refs == null)
        {
          refs = new ArrayList<>();
        }

        refs.add(ref);
      }
    }

    return refs;
  }

  private CDOID getXRefID(CDOObject object)
  {
    CDOID id = object.cdoID();
    if (id == null)
    {
      CDORevisionKey key = cleanRevisions.get(object);
      if (key != null)
      {
        id = key.getID();
      }
    }

    return id;
  }

  @Override
  protected CDOID getXRefTargetID(CDOObject target)
  {
    CDORevisionKey key = cleanRevisions.get(target);
    if (key != null)
    {
      return key.getID();
    }

    return super.getXRefTargetID(target);
  }

  @Override
  protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOID id = super.getID(object, onlyPersistedID);
        if (id != null)
        {
          return id;
        }

        // Don't perform the trickery that follows later in this method, if we are being called
        // indirectly through provideCDOID. This occurs when deltas or revisions are
        // being written out to a stream; in which case null must be returned (for transients) so that
        // the caller will detect a dangling reference
        if (providingCDOID.get() == Boolean.TRUE)
        {
          return null;
        }

        // The super implementation returns null for a transient (unattached) object;
        // but in a transaction, a transient object may have been attached previously.
        // So we consult the cleanRevisions if that's the case.
        CDORevisionKey revisionKey = cleanRevisions.get(object);
        if (revisionKey != null)
        {
          CDOID revisionID = revisionKey.getID();
          if (isObjectDetached(revisionID))
          {
            return revisionID;
          }
        }

        return null;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOID provideCDOID(Object idOrObject)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        try
        {
          providingCDOID.set(Boolean.TRUE);
          return super.provideCDOID(idOrObject);
        }
        finally
        {
          providingCDOID.remove();
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOQueryImpl createQuery(String language, String queryString, Object context)
  {
    return createQuery(language, queryString, context, false);
  }

  @Override
  public CDOQueryImpl createQuery(String language, String queryString, boolean considerDirtyState)
  {
    return createQuery(language, queryString, null, considerDirtyState);
  }

  @Override
  public CDOQueryImpl createQuery(String language, String queryString, Object context, boolean considerDirtyState)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOQueryImpl query = super.createQuery(language, queryString, context);
        if (considerDirtyState && isDirty())
        {
          query.setChangeSetData(getChangeSetData());
        }

        return query;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();

    InternalCDOSession session = getSession();
    if (session.getRepositoryInfo().getIDGenerationLocation() == CDOCommonRepository.IDGenerationLocation.STORE)
    {
      idGenerator = new TempIDGenerator();
    }
    else
    {
      idGenerator = session.getIDGenerator();
      if (idGenerator == null)
      {
        idGenerator = CDOIDGenerator.UUID;
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  protected void doDeactivate() throws Exception
  {
    providingCDOID.remove();
    options().disposeConflictResolvers();
    lastSavepoint = null;
    firstSavepoint = null;
    transactionStrategy = null;
    idGenerator = null;
    super.doDeactivate();
  }

  /**
   * Bug 298561: This override removes references to remotely detached objects that are present in any DIRTY or NEW
   * objects.
   *
   * @since 3.0
   */
  @Override
  protected Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> invalidate( //
      List<CDORevisionKey> allChangedObjects, //
      List<CDOIDAndVersion> allDetachedObjects, //
      List<CDORevisionDelta> deltas, //
      Map<CDOObject, CDORevisionDelta> revisionDeltas, //
      Set<CDOObject> detachedObjects, //
      Map<CDOID, InternalCDORevision> oldRevisions)
  {
    if (!allDetachedObjects.isEmpty())
    {
      // Remove stale references from locally changed or new objects to remotely detached objects
      Set<CDOObject> remotelyDetachedObjects = getObjects(allDetachedObjects);
      removeCrossReferences(remotelyDetachedObjects, getDirtyObjects().values());
      removeCrossReferences(remotelyDetachedObjects, getNewObjects().values());
      invalidateNewChildrenOfRemotelyDetached(remotelyDetachedObjects);
    }

    // Bug 290032 - Sticky views
    InternalCDOSession session = getSession();
    if (session.isSticky())
    {
      session.clearCommittedSinceLastRefresh();
    }

    Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = super.invalidate( //
        allChangedObjects, //
        allDetachedObjects, //
        deltas, //
        revisionDeltas, //
        detachedObjects, //
        oldRevisions);

    if (!allChangedObjects.isEmpty())
    {
      // Remove stale references from remotely changed objects to locally detached objects
      Set<CDOObject> remotelyChangedObjects = getObjects(allChangedObjects);
      removeCrossReferences(getDetachedObjects().values(), remotelyChangedObjects);
    }

    return conflicts;
  }

  private void invalidateNewChildrenOfRemotelyDetached(Set<CDOObject> remotelyDetachedObjects)
  {
    // Test EObject.eInternalContainer()/eDirectResource() implicit references to have them return null in legacy for
    // objects in NEW state whose a direct/indirect parent has been remotelly detached
    for (CDOObject referencer : getNewObjects().values())
    {

      if (CDOUtil.isLegacyObject(referencer))
      {
        InternalEObject referencerInternalEObject = (InternalEObject)referencer;
        InternalEObject eContainer = referencerInternalEObject.eInternalContainer();
        if (eContainer != null)
        {
          CDOObject containerCDOObject = CDOUtil.getCDOObject(eContainer);
          if (remotelyDetachedObjects.contains(containerCDOObject))
          {
            CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)referencer, referencer.cdoRevision());
          }
        }

        Resource.Internal eDirectResource = referencerInternalEObject.eDirectResource();
        if (eDirectResource instanceof CDOResource)
        {
          CDOObject cdoResource = (CDOObject)eDirectResource;
          if (remotelyDetachedObjects.contains(cdoResource))
          {
            CDOStateMachine.INSTANCE.invalidate((InternalCDOObject)referencer, referencer.cdoRevision());
          }
        }
      }
    }
  }

  @Override
  protected Map<String, CDOResourceNode> collectNewResourceNodes()
  {
    Map<String, CDOResourceNode> result = new HashMap<>();

    for (CDOObject object : getNewObjects().values())
    {
      if (object instanceof CDOResourceNode)
      {
        CDOResourceNode node = (CDOResourceNode)object;
        String path = node.getPath();
        result.put(path, node);
      }
    }

    return result;
  }

  private Set<CDOObject> getObjects(Collection<? extends CDOIdentifiable> identifiables)
  {
    Set<CDOObject> result = new HashSet<>();
    for (CDOIdentifiable identifiable : identifiables)
    {
      CDOID id = identifiable.getID();
      InternalCDOObject object = getObject(id, false);
      if (object != null)
      {
        result.add(object);
      }
    }

    return result;
  }

  private void removeCrossReferences(Collection<CDOObject> possibleTargets, Collection<CDOObject> referencers)
  {
    CDOStaleReferenceCleaner staleReferenceCleaner = options().getStaleReferenceCleaner();
    Collection<Pair<EStructuralFeature.Setting, EObject>> staleReferencesToClean = new LinkedList<>();

    for (CDOObject referencer : referencers)
    {
      InternalCDOObject internalReferencer = (InternalCDOObject)referencer;
      InternalCDOClassInfo referencerClassInfo = internalReferencer.cdoClassInfo();

      EContentsEList.FeatureIterator<EObject> it = getChangeableCrossReferences(referencer);
      while (it.hasNext())
      {
        EObject referencedObject = it.next();
        CDOObject referencedCDOObject = CDOUtil.getCDOObject(referencedObject);

        if (possibleTargets.contains(referencedCDOObject))
        {
          EReference reference = (EReference)it.feature();

          // In the case of DIRTY, we must investigate further: Is the referencer dirty
          // because a reference to the referencedObject was added? Only in this case
          // should we remove it. If this is not the case (i.e. it is dirty in a different
          // way), we skip it. (If the reference is not persistent, then this exception
          // doesn't apply: it must be removed for sure.)
          if (referencer.cdoState() == CDOState.DIRTY && referencerClassInfo.isPersistent(reference))
          {
            InternalCDORevision cleanRevision = cleanRevisions.get(referencer);

            if (reference.isMany())
            {
              CDOList list = cleanRevision.getListOrNull(reference);
              if (list != null)
              {
                for (Object value : list)
                {
                  if (value == referencedCDOObject.cdoID() || value == referencedObject)
                  {
                    continue;
                  }
                }
              }
            }
            else
            {
              Object value = cleanRevision.getValue(reference);
              if (value == referencedCDOObject.cdoID() || value == referencedObject)
              {
                continue;
              }
            }
          }

          EStructuralFeature.Setting setting = internalReferencer.eSetting(reference);
          staleReferencesToClean.add(Pair.create(setting, referencedObject));
        }
      }
    }

    if (!staleReferencesToClean.isEmpty())
    {
      staleReferenceCleaner.cleanStaleReferences(staleReferencesToClean);
    }
  }

  private EContentsEList.FeatureIterator<EObject> getChangeableCrossReferences(EObject object)
  {
    EClassImpl.FeatureSubsetSupplier features = (EClassImpl.FeatureSubsetSupplier)object.eClass().getEAllStructuralFeatures();

    EStructuralFeature[] crossReferences = features.crossReferences();
    if (crossReferences != null)
    {
      List<EStructuralFeature> changeableReferences = new ArrayList<>();
      for (int i = 0; i < crossReferences.length; i++)
      {
        EStructuralFeature reference = crossReferences[i];

        // Filter out derived references
        if (reference.isDerived())
        {
          continue;
        }

        // Filter out unchangeable references
        if (!reference.isChangeable())
        {
          continue;
        }

        changeableReferences.add(reference);
      }

      if (!changeableReferences.isEmpty())
      {
        EStructuralFeature[] collectedStructuralFeatures = changeableReferences.toArray(new EStructuralFeature[changeableReferences.size()]);
        return new EContentsEList.ResolvingFeatureIteratorImpl<>(object, collectedStructuralFeatures);
      }
    }

    return (EContentsEList.FeatureIterator<EObject>)ECrossReferenceEList.<EObject> emptyContentsEList().iterator();
  }

  @Override
  public long getLastCommitTime()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return lastCommitTime;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public String getCommitComment()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return commitComment;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void setCommitComment(String comment)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        commitComment = comment;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOBranchPoint getCommitMergeSource()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return commitMergeSource;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void setCommitMergeSource(CDOBranchPoint mergeSource)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        commitMergeSource = mergeSource;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void setCommittables(Set<? extends EObject> committables)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        this.committables = committables;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public Set<? extends EObject> getCommittables()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return committables;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public Map<InternalCDOObject, InternalCDORevision> getCleanRevisions()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return cleanRevisions;
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  protected InternalCDORevision getViewedRevision(InternalCDOObject object)
  {
    InternalCDORevision rev = super.getViewedRevision(object);

    // Bug 336590: If we have a clean revision for this object, return that instead
    if (rev != null)
    {
      InternalCDORevision cleanRev = cleanRevisions.get(object);
      if (cleanRev != null)
      {
        return cleanRev;
      }
    }

    return rev;
  }

  @Override
  protected InternalCDORevision getRevision(CDOObject object)
  {
    if (object.cdoState() == CDOState.TRANSIENT)
    {
      InternalCDORevision revision = cleanRevisions.get(object);
      if (revision == null)
      {
        throw new IllegalStateException("No revision for transient object " + object);
      }

      return revision;
    }

    return super.getRevision(object);
  }

  @Override
  protected InternalCDOLockState createUpdatedLockStateForNewObject(CDOObject object, IRWLockManager.LockType lockType, boolean on)
  {
    CheckUtil.checkState(FSMUtil.isNew(object), "Object is not in NEW state");
    CheckUtil.checkArg(lockType, "lockType");

    InternalCDOLockState lockState = (InternalCDOLockState)getLockState(object);
    if (lockState == null)
    {
      CheckUtil.checkArg(on == true, "on != true");
      Object lockTarget = getLockTarget(object);
      lockState = (InternalCDOLockState)CDOLockUtil.createLockState(lockTarget);
    }
    else
    {
      lockState = (InternalCDOLockState)CDOLockUtil.copyLockState(lockState);
    }

    CDOLockOwner lockOwner = CDOLockUtil.createLockOwner(this);

    if (on)
    {
      switch (lockType)
      {
      case READ:
        lockState.addReadLockOwner(lockOwner);
        break;
      case WRITE:
        lockState.setWriteLockOwner(lockOwner);
        break;
      case OPTION:
        lockState.setWriteOptionOwner(lockOwner);
        break;
      default:
        throw new IllegalArgumentException("Unknown lock type " + lockType);
      }
    }
    else
    {
      switch (lockType)
      {
      case READ:
        lockState.removeReadLockOwner(lockOwner);
        break;
      case WRITE:
        lockState.setWriteLockOwner(null);
        break;
      case OPTION:
        lockState.setWriteOptionOwner(null);
        break;
      default:
        throw new IllegalArgumentException("Unknown lock type " + lockType);
      }
    }

    return lockState;
  }

  @Override
  protected List<CDOLockState> createUnlockedLockStatesForAllNewObjects()
  {
    List<CDOLockState> locksOnNewObjects = new LinkedList<>();
    for (CDOObject object : getNewObjects().values())
    {
      Object lockTarget = getLockTarget(object);
      CDOLockState lockState = CDOLockUtil.createLockState(lockTarget);
      locksOnNewObjects.add(lockState);
    }

    return locksOnNewObjects;
  }

  public static boolean isResourceMatch(String nodeName, String name, boolean exactMatch)
  {
    boolean useEquals = exactMatch || nodeName == null || name == null;
    return useEquals ? ObjectUtil.equals(nodeName, name) : nodeName.startsWith(name);
  }

  public static void resurrectObject(CDOObject object, CDOID id)
  {
    if (object.cdoState() != CDOState.NEW)
    {
      throw new IllegalStateException("Object is not new: " + object);
    }

    CDOID oldID = object.cdoID();
    if (oldID == id)
    {
      return;
    }

    InternalCDORevision revision = (InternalCDORevision)object.cdoRevision(false);
    revision.setID(id);

    InternalCDOTransaction transaction = (InternalCDOTransaction)object.cdoView();
    transaction.remapObject(oldID);

    Map<CDOID, CDOObject> newObjects = transaction.getLastSavepoint().getNewObjects();
    newObjects.remove(oldID);
    newObjects.put(id, object);

    CDORevision detachedRevision = getDetachedRevision(transaction, id);
    if (detachedRevision != null)
    {
      revision.setVersion(detachedRevision.getVersion());
    }
  }

  private static CDORevision getDetachedRevision(InternalCDOTransaction transaction, CDOID id)
  {
    SyntheticCDORevision[] synthetics = new SyntheticCDORevision[1];
    InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();

    InternalCDORevision result = revisionManager.getRevision(id, transaction, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE, true, synthetics);

    if (result != null)
    {
      throw new IllegalStateException("An object with the same id already exists on this branch");
    }

    return synthetics[0];
  }

  @SafeVarargs
  private static <T> Set<T> toSet(T... objects)
  {
    Set<T> result = null;
    if (objects.length != 0)
    {
      result = new HashSet<>();
      for (T object : objects)
      {
        result.add(object);
      }
    }

    return result;
  }

  /**
   * @author Eike Stepper
   */
  private final class CleanRevisionsMap extends HashMap<InternalCDOObject, InternalCDORevision>
  {
    private static final long serialVersionUID = 1L;

    public CleanRevisionsMap()
    {
    }

    @Override
    public InternalCDORevision get(Object key)
    {
      if (key instanceof EObject)
      {
        CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
        InternalCDORevision revision = super.get(cdoObject);
        if (revision != null)
        {
          getSession().resolveAllElementProxies(revision);
        }

        return revision;
      }

      return null;
    }

    @Override
    public InternalCDORevision remove(Object key)
    {
      if (key instanceof EObject)
      {
        CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
        return super.remove(cdoObject);
      }

      return null;
    }

    @Override
    public boolean containsKey(Object key)
    {
      if (key instanceof EObject)
      {
        CDOObject cdoObject = CDOUtil.getCDOObject((EObject)key);
        return super.containsKey(cdoObject);
      }

      return false;
    }

    @Override
    public Set<InternalCDOObject> keySet()
    {
      throw new UnsupportedOperationException();
    }
  }

  /**
   * Generates {@link CDOIDTemp temporary} ID values.
   *
   * @author Eike Stepper
   */
  private static final class TempIDGenerator implements CDOIDGenerator
  {
    private AtomicInteger lastTemporaryID = new AtomicInteger();

    public TempIDGenerator()
    {
    }

    @Override
    public CDOID generateCDOID(EObject object)
    {
      return CDOIDUtil.createTempObject(lastTemporaryID.incrementAndGet());
    }

    @Override
    public void reset()
    {
      lastTemporaryID.set(0);
    }
  }

  /**
   * @author Simon McDuff
   */
  private final class CDOCommitContextImpl implements InternalCDOCommitContext
  {
    private InternalCDOTransaction transaction;

    /**
     * Tracks whether this commit is *actually* partial or not. (Having tx.committables != null does not in itself mean
     * that the commit will be partial, because the committables could cover all dirty/new/detached objects. But this
     * boolean gets set to reflect whether the commit will really commit less than all dirty/new/detached objects.)
     */
    private boolean isPartialCommit;

    private CDOCommitData commitData;

    private Map<CDOID, CDOObject> newObjects;

    private Map<CDOID, CDOObject> detachedObjects;

    private Map<CDOID, CDORevisionDelta> revisionDeltas;

    private Map<CDOID, CDOObject> dirtyObjects;

    private Map<ByteArrayWrapper, CDOLob<?>> lobs = new HashMap<>();

    private List<CDOLockState> locksOnNewObjects = new ArrayList<>();

    private List<CDOID> idsToUnlock = new ArrayList<>();

    public CDOCommitContextImpl(InternalCDOTransaction transaction)
    {
      this.transaction = transaction;
      calculateCommitData();
    }

    private void calculateCommitData()
    {
      OptionsImpl options = (OptionsImpl)transaction.options();

      List<CDOPackageUnit> newPackageUnits = analyzeNewPackages();

      newObjects = filterCommittables(transaction.getNewObjects());
      List<CDOIDAndVersion> revisions = new ArrayList<>(newObjects.size());
      for (CDOObject newObject : newObjects.values())
      {
        revisions.add(newObject.cdoRevision());

        CDOLockState lockState = getLockState(newObject);
        if (lockState != null)
        {
          if (!options.isEffectiveAutoReleaseLock(newObject))
          {
            locksOnNewObjects.add(lockState);
          }
        }
      }

      revisionDeltas = filterCommittables(transaction.getRevisionDeltas());
      List<CDORevisionKey> deltas = new ArrayList<>(revisionDeltas.size());
      for (CDORevisionDelta delta : revisionDeltas.values())
      {
        deltas.add(delta);
      }

      detachedObjects = filterCommittables(transaction.getDetachedObjects());
      List<CDOIDAndVersion> detached = new ArrayList<>(detachedObjects.size());
      for (Entry<CDOID, CDOObject> entry : detachedObjects.entrySet())
      {
        CDOObject object = entry.getValue();
        InternalCDORevision cleanRevision = cleanRevisions.get(object);
        if (cleanRevision == null)
        {
          // Can happen after merged detachments
          CDORevision revision = object.cdoRevision();
          detached.add(CDOIDUtil.createIDAndVersion(revision));
        }
        else if (cleanRevision.getBranch() == getBranch())
        {
          detached.add(CDOIDUtil.createIDAndVersion(cleanRevision));
        }
        else
        {
          detached.add(cleanRevision);
        }
      }

      dirtyObjects = filterCommittables(transaction.getDirtyObjects());

      for (CDOObject lockedObject : getLockStates().keySet())
      {
        if (!FSMUtil.isTransient(lockedObject))
        {
          if (options.isEffectiveAutoReleaseLock(lockedObject))
          {
            idsToUnlock.add(lockedObject.cdoID());
          }
        }
      }

      commitData = CDOCommitInfoUtil.createCommitData(newPackageUnits, revisions, deltas, detached);
    }

    private <T> Map<CDOID, T> filterCommittables(Map<CDOID, T> map)
    {
      if (committables == null)
      {
        // No partial commit filter -- nothing to do
        return map;
      }

      Map<CDOID, T> newMap = CDOIDUtil.createMap();
      for (Entry<CDOID, T> entry : map.entrySet())
      {
        CDOID id = entry.getKey();
        CDOObject o = getObject(id);
        if (committables.contains(o))
        {
          newMap.put(id, entry.getValue());
        }
        else
        {
          isPartialCommit = true;
        }
      }

      return newMap;
    }

    @Override
    public String getUserID()
    {
      return transaction.getSession().getUserID();
    }

    @Override
    public int getViewID()
    {
      return transaction.getViewID();
    }

    @Override
    public CDOBranch getBranch()
    {
      return transaction.getBranch();
    }

    @Override
    public InternalCDOTransaction getTransaction()
    {
      return transaction;
    }

    @Override
    public boolean isPartialCommit()
    {
      return isPartialCommit;
    }

    @Override
    public String getCommitComment()
    {
      return transaction.getCommitComment();
    }

    @Override
    public CDOBranchPoint getCommitMergeSource()
    {
      return transaction.getCommitMergeSource();
    }

    @Override
    public CDOCommitData getCommitData()
    {
      return commitData;
    }

    @Override
    public Map<CDOID, CDOObject> getDirtyObjects()
    {
      return dirtyObjects;
    }

    @Override
    public Map<CDOID, CDOObject> getNewObjects()
    {
      return newObjects;
    }

    @Override
    public List<CDOPackageUnit> getNewPackageUnits()
    {
      return commitData.getNewPackageUnits();
    }

    @Override
    public Map<CDOID, CDOObject> getDetachedObjects()
    {
      return detachedObjects;
    }

    @Override
    public Map<CDOID, CDORevisionDelta> getRevisionDeltas()
    {
      return revisionDeltas;
    }

    @Override
    public Collection<CDOLob<?>> getLobs()
    {
      return lobs.values();
    }

    @Override
    @Deprecated
    public boolean isAutoReleaseLocks()
    {
      return transaction.options().isAutoReleaseLocksEnabled();
    }

    @Override
    public Collection<CDOLockState> getLocksOnNewObjects()
    {
      return locksOnNewObjects;
    }

    @Override
    public List<CDOID> getIDsToUnlock()
    {
      return idsToUnlock;
    }

    @Override
    public void preCommit()
    {
      if (isDirty())
      {
        if (TRACER.isEnabled())
        {
          TRACER.trace("commit()"); //$NON-NLS-1$
        }

        CDOTransactionHandler2[] handlers = getTransactionHandlers2();
        if (handlers.length != 0)
        {
          final boolean[] modifiedAgain = { false };
          CDOTransactionHandler1 modifiedAgainHandler = new CDODefaultTransactionHandler1()
          {
            @Override
            public void modifyingObject(CDOTransaction transaction, CDOObject object, CDOFeatureDelta featureChange)
            {
              modifiedAgain[0] = true;
            }
          };

          addTransactionHandler(modifiedAgainHandler);

          try
          {
            for (int i = 0; i < handlers.length; i++)
            {
              modifiedAgain[0] = false;
              CDOTransactionHandler2 handler = handlers[i];
              handler.committingTransaction(getTransaction(), this);
              if (modifiedAgain[0])
              {
                calculateCommitData();
              }
            }
          }
          finally
          {
            removeTransactionHandler(modifiedAgainHandler);
          }
        }

        try
        {
          // TODO (CD) It might be wise to always do the checks,
          // instead of only for partial commits
          if (isPartialCommit)
          {
            new CommitIntegrityCheck(this, CommitIntegrityCheck.Style.EXCEPTION_FAST).check();
          }

          preCommit(getNewObjects(), lobs);
          preCommit(getDirtyObjects(), lobs);

          if (!lobs.isEmpty())
          {
            CDOSessionProtocol sessionProtocol = getSession().getSessionProtocol();
            List<byte[]> alreadyKnown = sessionProtocol.queryLobs(ByteArrayWrapper.toByteArray(lobs.keySet()));

            for (byte[] id : alreadyKnown)
            {
              lobs.remove(new ByteArrayWrapper(id));
            }
          }
        }
        catch (RuntimeException ex)
        {
          throw ex;
        }
        catch (Exception ex)
        {
          throw new TransactionException(ex);
        }
      }
    }

    @Override
    public void postCommit(CommitTransactionResult result)
    {
      try
      {
        InternalCDOSession session = getSession();
        long timeStamp = result.getTimeStamp();
        long previousTimeStamp = result.getPreviousTimeStamp();
        boolean clearResourcePathCache = result.isClearResourcePathCache();

        if (result.getRollbackMessage() != null)
        {
          InternalCDOCommitInfoManager commitInfoManager = session.getCommitInfoManager();
          CDOCommitInfo commitInfo = new FailureCommitInfo(commitInfoManager, timeStamp, previousTimeStamp);

          InvalidationData invalidationData = new InvalidationData();
          invalidationData.setCommitInfo(commitInfo);
          invalidationData.setSender(transaction);
          invalidationData.setClearResourcePathCache(clearResourcePathCache);
          invalidationData.setSecurityImpact(CDOProtocol.CommitNotificationInfo.IMPACT_NONE);
          invalidationData.setNewPermissions(null);
          invalidationData.setLockChangeInfo(null);

          session.invalidate(invalidationData);
          return;
        }

        CDOBranch oldBranch = getBranch();
        CDOBranch branch = result.getBranch();
        boolean branchChanged = branch != getBranch();
        if (branchChanged)
        {
          basicSetBranchPoint(branch.getHead());
        }

        for (CDOPackageUnit newPackageUnit : getNewPackageUnits())
        {
          ((InternalCDOPackageUnit)newPackageUnit).setState(CDOPackageUnit.State.LOADED);
        }

        CDOLockChangeInfo lockChangeInfo = makeUnlockChangeInfo(result);
        CDOCommitInfo commitInfo = null;

        CommitData newCommitData = result.getNewCommitData();
        if (newCommitData == null)
        {
          Map<CDOID, CDOObject> newObjects = getNewObjects();
          postCommit(newObjects, result);

          Map<CDOID, CDOObject> dirtyObjects = getDirtyObjects();
          postCommit(dirtyObjects, result);

          for (CDORevisionDelta delta : getRevisionDeltas().values())
          {
            ((InternalCDORevisionDelta)delta).adjustReferences(result.getReferenceAdjuster());
          }

          for (CDOID id : getDetachedObjects().keySet())
          {
            removeObject(id);
          }

          commitInfo = makeCommitInfo(timeStamp, previousTimeStamp);
          if (!commitInfo.isEmpty())
          {
            InvalidationData invalidationData = new InvalidationData();
            invalidationData.setCommitInfo(commitInfo);
            invalidationData.setSender(transaction);
            invalidationData.setClearResourcePathCache(clearResourcePathCache);
            invalidationData.setSecurityImpact(result.getSecurityImpact());
            invalidationData.setNewPermissions(result.getNewPermissions());
            invalidationData.setLockChangeInfo(lockChangeInfo);

            session.invalidate(invalidationData);
          }

          // Bug 290032 - Sticky views
          if (session.isSticky())
          {
            CDOBranchPoint commitBranchPoint = CDOBranchUtil.copyBranchPoint(result);

            // Note: keySet() does not work because ID mappings are not applied there!
            for (CDOObject object : newObjects.values())
            {
              session.setCommittedSinceLastRefresh(object.cdoID(), commitBranchPoint);
            }

            for (CDOID id : dirtyObjects.keySet())
            {
              session.setCommittedSinceLastRefresh(id, commitBranchPoint);
            }

            for (CDOID id : getDetachedObjects().keySet())
            {
              session.setCommittedSinceLastRefresh(id, commitBranchPoint);
            }
          }
        }
        else
        {
          applyNewCommitData(newCommitData, timeStamp);
        }

        CDOTransactionHandler2[] handlers = getTransactionHandlers2();
        for (int i = 0; i < handlers.length; i++)
        {
          CDOTransactionHandler2 handler = handlers[i];
          if (handler instanceof CDOTransactionHandler3)
          {
            CDOTransactionHandler3 handler3 = (CDOTransactionHandler3)handler;
            handler3.committedTransaction(transaction, this, commitInfo);
          }
          else
          {
            handler.committedTransaction(transaction, this);
          }
        }

        getChangeSubscriptionManager().committedTransaction(transaction, this);
        getAdapterManager().committedTransaction(transaction, this);

        if (newCommitData == null)
        {
          cleanUp(this);
        }

        IListener[] listeners = getListeners();
        if (listeners != null)
        {
          if (branchChanged)
          {
            fireViewTargetChangedEvent(oldBranch.getHead(), listeners);
          }

          Map<CDOID, CDOID> idMappings = result.getIDMappings();
          fireEvent(new FinishedEvent(idMappings), listeners);
        }

        if (lockChangeInfo != null && isActive())
        {
          fireLocksChangedEvent(CDOTransactionImpl.this, lockChangeInfo);
        }
      }
      catch (RuntimeException ex)
      {
        throw ex;
      }
      catch (Exception ex)
      {
        throw new TransactionException(ex);
      }
    }

    private CDOCommitInfo makeCommitInfo(long timeStamp, long previousTimeStamp)
    {
      InternalCDOSession session = getSession();
      CDOBranch branch = getBranch();
      String userID = session.getUserID();
      String comment = getCommitComment();
      CDOBranchPoint mergeSource = getCommitMergeSource();

      InternalCDOCommitInfoManager commitInfoManager = session.getCommitInfoManager();
      return commitInfoManager.createCommitInfo(branch, timeStamp, previousTimeStamp, userID, comment, mergeSource, commitData);
    }

    private CDOLockChangeInfo makeUnlockChangeInfo(CommitTransactionResult result)
    {
      Map<CDOObject, CDOLockState> lockStates = getLockStates();
      if (lockStates.isEmpty())
      {
        return null;
      }

      List<CDOLockState> objectsToUnlock = new ArrayList<>();

      for (Map.Entry<CDOObject, CDOLockState> entry : lockStates.entrySet())
      {
        CDOObject object = entry.getKey();
        if (options().isEffectiveAutoReleaseLock(object))
        {
          InternalCDOLockState lockState = (InternalCDOLockState)entry.getValue();
          lockState.updateFrom(InternalCDOLockState.UNLOCKED);

          objectsToUnlock.add(lockState);
        }
      }

      CDOLockState[] newLockStates = objectsToUnlock.toArray(new CDOLockState[objectsToUnlock.size()]);
      return makeLockChangeInfo(CDOLockChangeInfo.Operation.UNLOCK, null, result.getTimeStamp(), newLockStates);
    }

    private void preCommit(Map<CDOID, CDOObject> objects, Map<ByteArrayWrapper, CDOLob<?>> lobs)
    {
      if (!objects.isEmpty())
      {
        for (CDOObject object : objects.values())
        {
          collectLobs((InternalCDORevision)object.cdoRevision(), lobs);
          ((InternalCDOObject)object).cdoInternalPreCommit();
        }
      }
    }

    private void collectLobs(InternalCDORevision revision, Map<ByteArrayWrapper, CDOLob<?>> lobs)
    {
      EStructuralFeature[] features = revision.getClassInfo().getAllPersistentFeatures();
      for (int i = 0; i < features.length; i++)
      {
        EStructuralFeature feature = features[i];
        if (CDOModelUtil.isLob(feature.getEType()))
        {
          CDOLob<?> lob = (CDOLob<?>)revision.getValue(feature);
          if (lob != null)
          {
            lobs.put(new ByteArrayWrapper(lob.getID()), lob);
          }
        }
      }
    }

    private void postCommit(Map<CDOID, CDOObject> objects, CommitTransactionResult result)
    {
      if (!objects.isEmpty())
      {
        CDOStateMachine.INSTANCE.commit(objects, result);
      }
    }

    private void applyNewCommitData(CommitData newCommitData, long timeStamp)
    {
      getTransactionStrategy().rollback(CDOTransactionImpl.this, firstSavepoint); // Transitions objects to CLEAN.
      waitForBaseline(timeStamp); // Transitions objects to PROXY.
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class StartedEvent extends Event implements CDOTransactionStartedEvent
  {
    private static final long serialVersionUID = 1L;

    private StartedEvent()
    {
    }

    @Override
    public String toString()
    {
      return MessageFormat.format("CDOTransactionStartedEvent[source={0}]", getSource()); //$NON-NLS-1$
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class FinishedEvent extends Event implements CDOTransactionFinishedEvent
  {
    private static final long serialVersionUID = 1L;

    private final Cause cause;

    private final Map<CDOID, CDOID> idMappings;

    private FinishedEvent(Map<CDOID, CDOID> idMappings)
    {
      cause = Cause.COMMITTED;
      this.idMappings = idMappings;
    }

    private FinishedEvent(boolean rolledBack)
    {
      cause = rolledBack ? Cause.ROLLED_BACK : Cause.UNDONE;
      idMappings = Collections.emptyMap();
    }

    @Override
    @Deprecated
    public Type getType()
    {
      switch (cause)
      {
      case COMMITTED:
        return Type.COMMITTED;

      case ROLLED_BACK:
      case UNDONE:
        return Type.ROLLED_BACK;

      default:
        throw new IllegalStateException("Illegal cause: " + cause);
      }
    }

    @Override
    public Cause getCause()
    {
      return cause;
    }

    @Override
    public Map<CDOID, CDOID> getIDMappings()
    {
      return idMappings;
    }

    @Override
    public String toString()
    {
      return MessageFormat.format("CDOTransactionFinishedEvent[source={0}, cause={1}, idMappings={2}]", getSource(), //$NON-NLS-1$
          getCause(), idMappings == null ? 0 : idMappings.size());
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class ConflictEvent extends Event implements CDOTransactionConflictEvent
  {
    private static final long serialVersionUID = 1L;

    private InternalCDOObject conflictingObject;

    private boolean firstConflict;

    public ConflictEvent(InternalCDOObject conflictingObject, boolean firstConflict)
    {
      this.conflictingObject = conflictingObject;
      this.firstConflict = firstConflict;
    }

    @Override
    public InternalCDOObject getConflictingObject()
    {
      return conflictingObject;
    }

    @Override
    public boolean isFirstConflict()
    {
      return firstConflict;
    }

    @Override
    public String toString()
    {
      return MessageFormat.format("CDOTransactionConflictEvent[source={0}, conflictingObject={1}, firstConflict={2}]", //$NON-NLS-1$
          getSource(), getConflictingObject(), isFirstConflict());
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class CountedRetryPredicate implements Predicate<Long>
  {
    private final int attempts;

    private int attempt;

    private CountedRetryPredicate(int attempts)
    {
      this.attempts = attempts;
    }

    @Override
    public boolean test(Long startMillis)
    {
      return ++attempt < attempts;
    }
  }

  /**
   * @author Eike Stepper
   * @since 2.0
   */
  protected final class OptionsImpl extends CDOViewImpl.OptionsImpl implements CDOTransaction.Options
  {
    private CDOUndoDetector undoDetector = DEFAULT_UNDO_DETECTOR;

    private final List<CDOConflictResolver> conflictResolvers = new ArrayList<>();

    private CDOStaleReferenceCleaner staleReferenceCleaner = CDOStaleReferenceCleaner.DEFAULT;

    private boolean autoReleaseLocksEnabled = true;

    private final Map<EObject, Boolean> autoReleaseLocksExemptions = new WeakHashMap<>();

    private long commitInfoTimeout = DEFAULT_COMMIT_INFO_TIMEOUT;

    private Map<CDOID, CDORevision> attachedRevisionsMap;

    public OptionsImpl()
    {
    }

    @Override
    public CDOUndoDetector getUndoDetector()
    {
      return undoDetector;
    }

    @Override
    public void setUndoDetector(CDOUndoDetector undoDetector)
    {
      checkActive();

      if (undoDetector == null)
      {
        undoDetector = DEFAULT_UNDO_DETECTOR;
      }

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (this.undoDetector != undoDetector)
          {
            this.undoDetector = undoDetector;
            event = new UndoDetectorEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDOTransactionImpl getContainer()
    {
      return (CDOTransactionImpl)super.getContainer();
    }

    @Override
    public CDOConflictResolver[] getConflictResolvers()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return conflictResolvers.toArray(new CDOConflictResolver[conflictResolvers.size()]);
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public void setConflictResolvers(CDOConflictResolver[] resolvers)
    {
      checkActive();
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          for (CDOConflictResolver resolver : conflictResolvers)
          {
            resolver.setTransaction(null);
          }

          conflictResolvers.clear();

          for (CDOConflictResolver resolver : resolvers)
          {
            validateResolver(resolver);
            conflictResolvers.add(resolver);
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(new ConflictResolversEventImpl());
    }

    @Override
    public void addConflictResolver(CDOConflictResolver resolver)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          validateResolver(resolver);
          conflictResolvers.add(resolver);
          event = new ConflictResolversEventImpl();
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public void removeConflictResolver(CDOConflictResolver resolver)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (conflictResolvers.remove(resolver))
          {
            resolver.setTransaction(null);
            event = new ConflictResolversEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDOStaleReferenceCleaner getStaleReferenceCleaner()
    {
      return staleReferenceCleaner;
    }

    @Override
    public void setStaleReferenceCleaner(CDOStaleReferenceCleaner staleReferenceCleaner)
    {
      checkActive();

      if (staleReferenceCleaner == null)
      {
        staleReferenceCleaner = CDOStaleReferenceCleaner.DEFAULT;
      }

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (this.staleReferenceCleaner != staleReferenceCleaner)
          {
            this.staleReferenceCleaner = staleReferenceCleaner;
            event = new StaleReferenceCleanerEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    public void disposeConflictResolvers()
    {
      try
      {
        // Do not call getConflictResolvers() because that method may block!
        CDOConflictResolver[] array = conflictResolvers.toArray(new CDOConflictResolver[conflictResolvers.size()]);
        for (CDOConflictResolver resolver : array)
        {
          try
          {
            resolver.setTransaction(null);
          }
          catch (Exception ignore)
          {
          }
        }
      }
      catch (Exception ignore)
      {
      }
    }

    private void validateResolver(CDOConflictResolver resolver)
    {
      if (resolver.getTransaction() != null)
      {
        throw new IllegalArgumentException(Messages.getString("CDOTransactionImpl.17")); //$NON-NLS-1$
      }

      resolver.setTransaction(CDOTransactionImpl.this);
    }

    @Override
    public boolean isAutoReleaseLocksEnabled()
    {
      return autoReleaseLocksEnabled;
    }

    @Override
    public void setAutoReleaseLocksEnabled(boolean on)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (autoReleaseLocksEnabled != on)
          {
            autoReleaseLocksEnabled = on;
            event = new AutoReleaseLocksEnabledEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public Set<? extends EObject> getAutoReleaseLocksExemptions()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return new HashSet<>(autoReleaseLocksExemptions.keySet());
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public boolean isAutoReleaseLocksExemption(EObject object)
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return autoReleaseLocksExemptions.get(CDOUtil.getCDOObject(object)) == Boolean.TRUE;
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public void clearAutoReleaseLocksExemptions()
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (!autoReleaseLocksExemptions.isEmpty())
          {
            autoReleaseLocksExemptions.clear();
            event = new AutoReleaseLocksExemptionsEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public void addAutoReleaseLocksExemptions(boolean recursive, EObject... objects)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          for (EObject object : objects)
          {
            if (autoReleaseLocksExemptions.put(CDOUtil.getCDOObject(object), Boolean.TRUE) == null)
            {
              event = new AutoReleaseLocksExemptionsEventImpl();
            }

            if (recursive)
            {
              for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();)
              {
                EObject child = it.next();
                if (autoReleaseLocksExemptions.put(CDOUtil.getCDOObject(child), Boolean.TRUE) == null && event == null)
                {
                  event = new AutoReleaseLocksExemptionsEventImpl();
                }
              }
            }
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public void removeAutoReleaseLocksExemptions(boolean recursive, EObject... objects)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          for (EObject object : objects)
          {
            if (autoReleaseLocksExemptions.remove(CDOUtil.getCDOObject(object)) != null)
            {
              event = new AutoReleaseLocksExemptionsEventImpl();
            }

            if (recursive)
            {
              for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();)
              {
                EObject child = it.next();
                if (autoReleaseLocksExemptions.remove(CDOUtil.getCDOObject(child)) != null && event == null)
                {
                  event = new AutoReleaseLocksExemptionsEventImpl();
                }
              }
            }
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    public boolean isEffectiveAutoReleaseLock(CDOObject newObject)
    {
      boolean effectiveAutoReleaseLock = autoReleaseLocksEnabled;
      if (autoReleaseLocksExemptions.containsKey(newObject))
      {
        effectiveAutoReleaseLock = !effectiveAutoReleaseLock;
      }

      return effectiveAutoReleaseLock;
    }

    @Override
    public Map<CDOID, CDORevision> getAttachedRevisionsMap()
    {
      return attachedRevisionsMap;
    }

    @Override
    public void setAttachedRevisionsMap(Map<CDOID, CDORevision> attachedRevisionsMap)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (this.attachedRevisionsMap != attachedRevisionsMap)
          {
            this.attachedRevisionsMap = attachedRevisionsMap;
            event = new AttachedRevisionsMapImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public long getCommitInfoTimeout()
    {
      return commitInfoTimeout;
    }

    @Override
    public void setCommitInfoTimeout(long commitInfoTimeout)
    {
      checkActive();

      IEvent event = null;
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (this.commitInfoTimeout != commitInfoTimeout)
          {
            this.commitInfoTimeout = commitInfoTimeout;
            event = new CommitInfoTimeoutImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    /**
     * @author Eike Stepper
     */
    private final class UndoDetectorEventImpl extends OptionsEvent implements UndoDetectorEvent
    {
      private static final long serialVersionUID = 1L;

      public UndoDetectorEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class ConflictResolversEventImpl extends OptionsEvent implements ConflictResolversEvent
    {
      private static final long serialVersionUID = 1L;

      public ConflictResolversEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class StaleReferenceCleanerEventImpl extends OptionsEvent implements StaleReferenceCleanerEvent
    {
      private static final long serialVersionUID = 1L;

      public StaleReferenceCleanerEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class AutoReleaseLocksEnabledEventImpl extends OptionsEvent implements AutoReleaseLocksEnabledEvent
    {
      private static final long serialVersionUID = 1L;

      public AutoReleaseLocksEnabledEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class AutoReleaseLocksExemptionsEventImpl extends OptionsEvent implements AutoReleaseLocksExemptionsEvent
    {
      private static final long serialVersionUID = 1L;

      public AutoReleaseLocksExemptionsEventImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class AttachedRevisionsMapImpl extends OptionsEvent implements AttachedRevisionsMap
    {
      private static final long serialVersionUID = 1L;

      public AttachedRevisionsMapImpl()
      {
        super(OptionsImpl.this);
      }
    }

    /**
     * @author Eike Stepper
     */
    private final class CommitInfoTimeoutImpl extends OptionsEvent implements CommitInfoTimeout
    {
      private static final long serialVersionUID = 1L;

      public CommitInfoTimeoutImpl()
      {
        super(OptionsImpl.this);
      }
    }
  }
}
