/*
 * Copyright (c) 2007-2021 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 - bug 201266
 *    Simon McDuff - bug 233273
 *    Simon McDuff - bug 233490
 *    Stefan Winkler - changed order of determining audit and revision delta support.
 *    Andre Dietisheim - bug 256649
 */
package org.eclipse.emf.cdo.internal.server;

import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager.CDOTagList;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.branch.CDOBranchPointRange;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
import org.eclipse.emf.cdo.common.commit.CDOCommitData;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
import org.eclipse.emf.cdo.common.util.CDOTimeProvider;
import org.eclipse.emf.cdo.common.util.CurrentTimeProvider;
import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.etypes.EtypesPackage;
import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
import org.eclipse.emf.cdo.internal.server.bundle.OM;
import org.eclipse.emf.cdo.server.IQueryHandler;
import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
import org.eclipse.emf.cdo.server.IStoreAccessor;
import org.eclipse.emf.cdo.server.IStoreChunkReader;
import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.server.StoreThreadLocal;
import org.eclipse.emf.cdo.server.StoreThreadLocal.NoSessionRegisteredException;
import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader3;
import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader4;
import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
import org.eclipse.emf.cdo.spi.common.revision.BaseCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
import org.eclipse.emf.cdo.spi.server.ICommitConflictResolver;
import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalSession;
import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
import org.eclipse.emf.cdo.spi.server.InternalStore;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
import org.eclipse.emf.cdo.spi.server.InternalUnitManager;
import org.eclipse.emf.cdo.spi.server.InternalView;

import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;

import org.eclipse.net4j.util.AdapterUtil;
import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.MoveableList;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.container.Container;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.container.IPluginContainer;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.net4j.util.om.monitor.Monitor;
import org.eclipse.net4j.util.om.monitor.OMMonitor;
import org.eclipse.net4j.util.om.monitor.ProgressDistributor;
import org.eclipse.net4j.util.transaction.TransactionException;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.MergeDataResult;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;

import org.eclipse.core.runtime.IProgressMonitor;

import java.io.IOException;
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.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * @author Eike Stepper
 * @since 2.0
 */
public class Repository extends Container<Object> implements InternalRepository
{
  private static final int UNCHUNKED = CDORevision.UNCHUNKED;

  private static final int NONE = CDORevision.DEPTH_NONE;

  private static final String PROP_UUID = "org.eclipse.emf.cdo.server.repositoryUUID"; //$NON-NLS-1$

  private static final boolean DISABLE_FEATURE_MAP_CHECKS = OMPlatform.INSTANCE
      .isProperty("org.eclipse.emf.cdo.internal.server.Repository.DISABLE_FEATURE_MAP_CHECKS");

  private String name;

  private String uuid;

  private InternalStore store;

  private Type type = Type.MASTER;

  private State state = State.INITIAL;

  private Map<String, String> properties;

  private boolean supportingAudits;

  private boolean supportingBranches;

  private boolean supportingUnits;

  private boolean serializingCommits;

  private boolean ensuringReferentialIntegrity;

  private IDGenerationLocation idGenerationLocation;

  private CommitInfoStorage commitInfoStorage;

  private long optimisticLockingTimeout = 10000L;

  private CDOTimeProvider timeProvider;

  /**
   * Must not be thread-bound to support XA commits.
   */
  private final Semaphore packageRegistryCommitLock = new Semaphore(1);

  private InternalCDOPackageRegistry packageRegistry;

  private InternalCDOBranchManager branchManager;

  private InternalCDORevisionManager revisionManager;

  private InternalCDOCommitInfoManager commitInfoManager;

  private ICommitConflictResolver commitConflictResolver;

  private InternalSessionManager sessionManager;

  private InternalQueryManager queryManager;

  private InternalCommitManager commitManager;

  private InternalLockManager lockingManager;

  private InternalUnitManager unitManager;

  private IQueryHandlerProvider queryHandlerProvider;

  private IManagedContainer container;

  private final List<ReadAccessHandler> readAccessHandlers = new ArrayList<>();

  private final List<WriteAccessHandler> writeAccessHandlers = new ArrayList<>();

  // Bug 297940
  private final TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);

  @ExcludeFromDump
  private final transient Object commitTransactionLock = new Object();

  @ExcludeFromDump
  private final transient Object createBranchLock = new Object();

  @ExcludeFromDump
  private final transient Object changeTagLock = new Object();

  private boolean skipInitialization;

  private EPackage[] initialPackages;

  private CDOID rootResourceID;

  private long lastTreeRestructuringCommit = -1;

  /**
   * This strong reference is only kept to avoid frequent tag loading.
   */
  @SuppressWarnings("unused")
  private CDOTagList tagList;

  public Repository()
  {
  }

  @Override
  public String getName()
  {
    return name;
  }

  @Override
  public void setName(String name)
  {
    this.name = name;
  }

  @Override
  public String getUUID()
  {
    return uuid;
  }

  @Override
  public InternalStore getStore()
  {
    return store;
  }

  @Override
  public void setStore(InternalStore store)
  {
    this.store = store;
  }

  @Override
  public Type getType()
  {
    return type;
  }

  @Override
  public void setType(Type type)
  {
    checkArg(type, "type"); //$NON-NLS-1$
    if (this.type != type)
    {
      changingType(this.type, type);
    }
  }

  protected void changingType(Type oldType, Type newType)
  {
    type = newType;
    fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));

    if (sessionManager != null)
    {
      sessionManager.sendRepositoryTypeNotification(oldType, newType);
    }
  }

  @Override
  public State getState()
  {
    return state;
  }

  @Override
  public void setState(State state)
  {
    checkArg(state, "state"); //$NON-NLS-1$
    if (this.state != state)
    {
      changingState(this.state, state);
    }
  }

  protected void changingState(State oldState, State newState)
  {
    state = newState;
    fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));

    if (sessionManager != null)
    {
      sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
    }
  }

  @Override
  public boolean waitWhileInitial(IProgressMonitor monitor)
  {
    return CDOCommonUtil.waitWhileInitial(this, this, monitor);
  }

  @Override
  public synchronized Map<String, String> getProperties()
  {
    if (properties == null)
    {
      properties = new HashMap<>();
    }

    return properties;
  }

  @Override
  public synchronized void setProperties(Map<String, String> properties)
  {
    this.properties = properties;
  }

  @Override
  public boolean isAuthenticating()
  {
    if (sessionManager != null)
    {
      return sessionManager.getAuthenticator() != null;
    }

    return false;
  }

  @Override
  public boolean isSupportingAudits()
  {
    return supportingAudits;
  }

  @Override
  public boolean isSupportingBranches()
  {
    return supportingBranches;
  }

  @Override
  public boolean isSupportingUnits()
  {
    return supportingUnits;
  }

  @Override
  @Deprecated
  public boolean isSupportingEcore()
  {
    return true;
  }

  @Override
  public boolean isSerializingCommits()
  {
    return serializingCommits;
  }

  @Override
  public boolean isEnsuringReferentialIntegrity()
  {
    return ensuringReferentialIntegrity;
  }

  @Override
  public IDGenerationLocation getIDGenerationLocation()
  {
    return idGenerationLocation;
  }

  @Override
  public CommitInfoStorage getCommitInfoStorage()
  {
    return commitInfoStorage;
  }

  @Override
  public long getOptimisticLockingTimeout()
  {
    return optimisticLockingTimeout;
  }

  @Override
  public void setOptimisticLockingTimeout(long optimisticLockingTimeout)
  {
    this.optimisticLockingTimeout = optimisticLockingTimeout;
  }

  @Override
  public String getStoreType()
  {
    return store.getType();
  }

  @Override
  public Set<CDOID.ObjectType> getObjectIDTypes()
  {
    return store.getObjectIDTypes();
  }

  @Override
  public CDOID getRootResourceID()
  {
    return rootResourceID;
  }

  @Override
  public void setRootResourceID(CDOID rootResourceID)
  {
    this.rootResourceID = rootResourceID;
  }

  @Override
  public Object processPackage(Object value)
  {
    CDOFactoryImpl.prepareDynamicEPackage(value);
    return value;
  }

  @Override
  public EPackage[] loadPackages(CDOPackageUnit packageUnit)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
  }

  @Override
  public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
  {
    if (!isSupportingBranches())
    {
      throw new IllegalStateException("Branching is not supported by " + this);
    }

    long baseTimeStamp = branchInfo.getBaseTimeStamp();
    long baseTimeStampMax = timeStampAuthority.getMaxBaseTimeForNewBranch();

    if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE || baseTimeStamp > baseTimeStampMax)
    {
      baseTimeStamp = baseTimeStampMax;
      branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
    }

    synchronized (createBranchLock)
    {
      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
      return accessor.createBranch(branchID, branchInfo);
    }
  }

  @Override
  public BranchInfo loadBranch(int branchID)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.loadBranch(branchID);
  }

  @Override
  public SubBranchInfo[] loadSubBranches(int branchID)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.loadSubBranches(branchID);
  }

  @Override
  public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.loadBranches(startID, endID, branchHandler);
  }

  @Override
  @Deprecated
  public void deleteBranch(int branchID)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  @Deprecated
  public void renameBranch(int branchID, String newName)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public void renameBranch(int branchID, String oldName, String newName)
  {
    if (!isSupportingBranches())
    {
      throw new IllegalStateException("Branching is not supported by " + this);
    }

    if (branchID == CDOBranch.MAIN_BRANCH_ID)
    {
      throw new IllegalArgumentException("Renaming of the MAIN branch is not supported");
    }

    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    if (!(accessor instanceof BranchLoader3))
    {
      throw new UnsupportedOperationException("Branch renaming is not supported by " + this);
    }

    synchronized (createBranchLock)
    {
      ((BranchLoader3)accessor).renameBranch(branchID, oldName, newName);
    }
  }

  @Override
  public CDOBranchPoint changeTag(AtomicInteger modCount, String oldName, String newName, CDOBranchPoint branchPoint)
  {
    if (isSupportingAudits())
    {
      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
      if (accessor instanceof BranchLoader4)
      {
        synchronized (changeTagLock)
        {
          if (oldName == null && branchPoint == null)
          {
            // Augment missing tag creation branch point.
            branchPoint = branchManager.getMainBranch().getHead();
          }

          if (branchPoint != null && branchPoint.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
          {
            // Augment missing time stamp.
            branchPoint = branchPoint.getBranch().getPoint(getTimeStamp());
          }

          ((BranchLoader4)accessor).changeTag(modCount, oldName, newName, branchPoint);

          InternalSession sender = null;

          try
          {
            sender = StoreThreadLocal.getSession();
          }
          catch (NoSessionRegisteredException ignore)
          {
            //$FALL-THROUGH$
          }

          // The branch manager's modCount will be bumped later by the caller of this method.
          int newModCount = modCount.get() + 1;

          sessionManager.sendTagNotification(sender, newModCount, oldName, newName, branchPoint);

          return branchPoint;
        }
      }
    }

    throw new UnsupportedOperationException("Branch tagging is not supported by " + this);
  }

  @Override
  public void loadTags(String name, Consumer<BranchInfo> handler)
  {
    if (isSupportingAudits())
    {
      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
      if (accessor instanceof BranchLoader4)
      {
        ((BranchLoader4)accessor).loadTags(name, handler);
      }
    }
  }

  @Override
  public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    accessor.loadCommitInfos(branch, startTime, endTime, handler);
  }

  @Override
  public CDOCommitData loadCommitData(long timeStamp)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.loadCommitData(timeStamp);
  }

  @Override
  public List<RevisionInfo> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint, int referenceChunk, int prefetchDepth)
  {
    for (RevisionInfo info : infos)
    {
      CDOID id = info.getID();
      RevisionInfo.Type type = info.getType();
      switch (type)
      {
      case AVAILABLE_NORMAL: // direct == false
      {
        RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
        checkArg(availableInfo.isDirect() == false, "Load is not needed");
        break;
      }

      case AVAILABLE_POINTER: // direct == false || target == null
      {
        RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
        boolean needsTarget = !pointerInfo.hasTarget();
        checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");

        if (needsTarget)
        {
          CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
          InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
          PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo.getAvailableBranchVersion().getBranch(),
              CDORevision.UNSPECIFIED_DATE, target);

          info.setResult(target);
          info.setSynthetic(pointer);
          continue;
        }

        break;
      }

      case AVAILABLE_DETACHED: // direct == false
      {
        RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
        checkArg(detachedInfo.isDirect() == false, "Load is not needed");
        break;
      }

      case MISSING:
      {
        break;
      }

      default:
        throw new IllegalStateException("Invalid revision info type: " + type);
      }

      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
      if (revision == null)
      {
        if (isSupportingAudits())
        {
          InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
          if (target != null)
          {
            target = normalizeRevision(target, info, referenceChunk);

            CDOBranch branch = branchPoint.getBranch();
            long revised = loadRevisionRevised(id, branch);
            PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
            info.setSynthetic(pointer);
          }

          info.setResult(target);
        }
        else
        {
          DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id, branchPoint.getBranch(), 0,
              CDORevision.UNSPECIFIED_DATE);
          info.setSynthetic(detachedRevision);
        }
      }
      else if (revision instanceof DetachedCDORevision)
      {
        DetachedCDORevision detached = (DetachedCDORevision)revision;
        info.setSynthetic(detached);
      }
      else
      {
        revision.freeze();

        revision = normalizeRevision(revision, info, referenceChunk);
        info.setResult(revision);
      }
    }

    return null;
  }

  private InternalCDORevision normalizeRevision(InternalCDORevision revision, RevisionInfo info, int referenceChunk)
  {
    if (info instanceof RevisionInfo.Available)
    {
      RevisionInfo.Available availableInfo = (RevisionInfo.Available)info;

      CDOBranchVersion availableBranchVersion = availableInfo.getAvailableBranchVersion();
      if (availableBranchVersion instanceof BaseCDORevision)
      {
        BaseCDORevision availableRevision = (BaseCDORevision)availableBranchVersion;
        if (availableRevision.equals(revision))
        {
          ensureChunks(availableRevision, referenceChunk);
          return availableRevision;
        }
      }
    }

    if (referenceChunk == UNCHUNKED)
    {
      revision.setUnchunked();
    }

    return revision;
  }

  private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk, IStoreAccessor accessor)
  {
    CDOBranch branch = branchPoint.getBranch();
    while (!branch.isMainBranch())
    {
      branchPoint = branch.getBase();
      branch = branchPoint.getBranch();

      InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
      if (revision != null)
      {
        revision.freeze();
        return revision;
      }
    }

    return null;
  }

  private long loadRevisionRevised(CDOID id, CDOBranch branch)
  {
    InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION), UNCHUNKED);
    if (revision != null)
    {
      return revision.getTimeStamp() - 1;
    }

    return CDORevision.UNSPECIFIED_DATE;
  }

  @Override
  public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
  }

  @Override
  public CDOBranchPointRange loadObjectLifetime(CDOID id, CDOBranchPoint branchPoint)
  {
    CDORevision revision = revisionManager.getRevision(id, branchPoint, UNCHUNKED, NONE, true);
    if (revision == null)
    {
      return null;
    }

    CDORevision firstRevision = getFirstRevision(id, revision);
    if (firstRevision == null)
    {
      return null;
    }

    CDOBranchPoint lastPoint = getLastBranchPoint(revision, branchPoint);
    return CDOBranchUtil.createRange(firstRevision, lastPoint);
  }

  private CDORevision getFirstRevision(CDOID id, CDORevision revision)
  {
    CDOBranch branch = revision.getBranch();

    for (int version = revision.getVersion() - 1; version >= CDOBranchVersion.FIRST_VERSION; --version)
    {
      CDORevision rev = revisionManager.getRevisionByVersion(id, branch.getVersion(version), UNCHUNKED, true);
      if (rev == null)
      {
        return revision;
      }

      revision = rev;
    }

    if (!branch.isMainBranch())
    {
      CDOBranchPoint base = branch.getBase();
      CDORevision baseRevision = revisionManager.getRevision(id, base, UNCHUNKED, NONE, true);
      if (baseRevision != null)
      {
        return getFirstRevision(id, baseRevision);
      }
    }

    return revision;
  }

  private CDOBranchPoint getLastBranchPoint(CDORevision revision, CDOBranchPoint branchPoint)
  {
    CDOBranch branch = branchPoint.getBranch();
    if (revision.getBranch() != branch)
    {
      return branch.getHead();
    }

    CDOID id = revision.getID();
    for (int version = revision.getVersion() + 1; version <= Integer.MAX_VALUE; ++version)
    {
      if (revision.getRevised() == CDOBranchPoint.UNSPECIFIED_DATE)
      {
        break;
      }

      CDORevision rev = revisionManager.getRevisionByVersion(id, branch.getVersion(version), UNCHUNKED, true);
      if (rev == null)
      {
        break;
      }

      revision = rev;
    }

    return branch.getPoint(revision.getRevised());
  }

  /**
   * @deprecated Not used.
   */
  @Deprecated
  protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public void ensureChunks(InternalCDORevision revision)
  {
    ensureChunks(revision, UNCHUNKED);
  }

  @Override
  public void ensureChunks(InternalCDORevision revision, int chunkSize)
  {
    if (revision.isUnchunked())
    {
      return;
    }

    IStoreAccessor accessor = null;
    boolean unchunked = true;
    for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures())
    {
      if (feature.isMany())
      {
        MoveableList<Object> list = revision.getListOrNull(feature);
        if (list != null)
        {
          int size = list.size();
          if (size != 0)
          {
            int chunkSizeToUse = chunkSize;
            if (chunkSizeToUse == UNCHUNKED)
            {
              chunkSizeToUse = size;
            }

            int chunkEnd = Math.min(chunkSizeToUse, size);
            accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);

            if (unchunked)
            {
              for (int i = chunkEnd; i < size; i++)
              {
                if (list.get(i) == InternalCDOList.UNINITIALIZED)
                {
                  unchunked = false;
                  break;
                }
              }
            }
          }
        }
      }
    }

    if (unchunked)
    {
      revision.setUnchunked();
    }
  }

  @Override
  public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart, int chunkEnd)
  {
    if (!revision.isUnchunked())
    {
      MoveableList<Object> list = revision.getListOrNull(feature);
      if (list == null)
      {
        return null;
      }

      chunkEnd = Math.min(chunkEnd, list.size());
      IStoreAccessor accessor = StoreThreadLocal.getAccessor();
      ensureChunk(revision, feature, accessor, list, chunkStart, chunkEnd);

      // TODO Expensive: if the revision is unchunked all lists/elements must be visited
      if (isUnchunked(revision))
      {
        revision.setUnchunked();
      }

      return accessor;
    }

    return null;
  }

  private boolean isUnchunked(InternalCDORevision revision)
  {
    for (EStructuralFeature feature : revision.getClassInfo().getAllPersistentFeatures())
    {
      if (feature.isMany())
      {
        MoveableList<Object> list = revision.getListOrNull(feature);
        if (list != null)
        {
          int size = list.size();
          for (int i = 0; i < size; i++)
          {
            if (list.get(i) == InternalCDOList.UNINITIALIZED)
            {
              return false;
            }
          }
        }
      }
    }

    return true;
  }

  protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, IStoreAccessor accessor, MoveableList<Object> list,
      int chunkStart, int chunkEnd)
  {
    IStoreChunkReader chunkReader = null;
    int fromIndex = -1;
    for (int j = chunkStart; j < chunkEnd; j++)
    {
      if (list.get(j) == InternalCDOList.UNINITIALIZED)
      {
        if (fromIndex == -1)
        {
          fromIndex = j;
        }
      }
      else
      {
        if (fromIndex != -1)
        {
          if (chunkReader == null)
          {
            if (accessor == null)
            {
              accessor = StoreThreadLocal.getAccessor();
            }

            chunkReader = accessor.createChunkReader(revision, feature);
          }

          int toIndex = j;
          if (fromIndex == toIndex - 1)
          {
            chunkReader.addSimpleChunk(fromIndex);
          }
          else
          {
            chunkReader.addRangedChunk(fromIndex, toIndex);
          }

          fromIndex = -1;
        }
      }
    }

    // Add last chunk
    if (fromIndex != -1)
    {
      if (chunkReader == null)
      {
        if (accessor == null)
        {
          accessor = StoreThreadLocal.getAccessor();
        }

        chunkReader = accessor.createChunkReader(revision, feature);
      }

      int toIndex = chunkEnd;
      if (fromIndex == toIndex - 1)
      {
        chunkReader.addSimpleChunk(fromIndex);
      }
      else
      {
        chunkReader.addRangedChunk(fromIndex, toIndex);
      }
    }

    if (chunkReader != null)
    {
      InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;

      List<Chunk> chunks = chunkReader.executeRead();
      for (Chunk chunk : chunks)
      {
        int startIndex = chunk.getStartIndex();
        for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
        {
          Object id = chunk.get(indexInChunk);
          if (cdoList != null)
          {
            cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
          }
          else
          {
            list.set(startIndex + indexInChunk, id);
          }
        }
      }
    }

    return accessor;
  }

  @Override
  public CDOTimeProvider getTimeProvider()
  {
    return timeProvider;
  }

  @Override
  public void setTimeProvider(CDOTimeProvider timeProvider)
  {
    checkInactive();
    this.timeProvider = timeProvider;
  }

  @Override
  public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
  {
    if (considerCommitContext)
    {
      IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
      if (commitContext != null)
      {
        InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
        if (contextualPackageRegistry != null)
        {
          return contextualPackageRegistry;
        }
      }
    }

    return packageRegistry;
  }

  @Override
  public Semaphore getPackageRegistryCommitLock()
  {
    return packageRegistryCommitLock;
  }

  @Override
  public InternalCDOPackageRegistry getPackageRegistry()
  {
    return getPackageRegistry(true);
  }

  public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
  {
    checkInactive();
    this.packageRegistry = packageRegistry;
  }

  @Override
  public InternalSessionManager getSessionManager()
  {
    return sessionManager;
  }

  /**
   * @since 2.0
   */
  @Override
  public void setSessionManager(InternalSessionManager sessionManager)
  {
    checkInactive();
    this.sessionManager = sessionManager;
  }

  @Override
  public InternalUnitManager getUnitManager()
  {
    return unitManager;
  }

  @Override
  public void setUnitManager(InternalUnitManager unitManager)
  {
    checkInactive();
    this.unitManager = unitManager;
  }

  @Override
  public InternalCDOBranchManager getBranchManager()
  {
    return branchManager;
  }

  @Override
  public void setBranchManager(InternalCDOBranchManager branchManager)
  {
    checkInactive();
    this.branchManager = branchManager;
  }

  @Override
  public InternalCDOCommitInfoManager getCommitInfoManager()
  {
    return commitInfoManager;
  }

  public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
  {
    checkInactive();
    this.commitInfoManager = commitInfoManager;
  }

  @Override
  public ICommitConflictResolver getCommitConflictResolver()
  {
    return commitConflictResolver;
  }

  @Override
  public void setCommitConflictResolver(ICommitConflictResolver commitConflictResolver)
  {
    checkInactive();
    this.commitConflictResolver = commitConflictResolver;
  }

  @Override
  public InternalCDORevisionManager getRevisionManager()
  {
    return revisionManager;
  }

  /**
   * @since 2.0
   */
  @Override
  public void setRevisionManager(InternalCDORevisionManager revisionManager)
  {
    checkInactive();
    this.revisionManager = revisionManager;
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalQueryManager getQueryManager()
  {
    return queryManager;
  }

  /**
   * @since 2.0
   */
  public void setQueryManager(InternalQueryManager queryManager)
  {
    checkInactive();
    this.queryManager = queryManager;
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCommitManager getCommitManager()
  {
    return commitManager;
  }

  /**
   * @since 2.0
   */
  public void setCommitManager(InternalCommitManager commitManager)
  {
    checkInactive();
    this.commitManager = commitManager;
  }

  /**
   * @since 2.0
   * @deprecated
   */
  @Override
  @Deprecated
  public InternalLockManager getLockManager()
  {
    return getLockingManager();
  }

  @Override
  public InternalLockManager getLockingManager()
  {
    return lockingManager;
  }

  /**
   * @since 2.0
   */
  public void setLockingManager(InternalLockManager lockingManager)
  {
    checkInactive();
    this.lockingManager = lockingManager;
  }

  @Override
  public InternalCommitContext createCommitContext(InternalTransaction transaction)
  {
    return new TransactionCommitContext(transaction);
  }

  @Override
  public long getLastCommitTimeStamp()
  {
    return timeStampAuthority.getLastFinishedTimeStamp();
  }

  @Override
  public void setLastCommitTimeStamp(long lastCommitTimeStamp)
  {
    timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
  }

  @Override
  public long waitForCommit(long timeout)
  {
    return timeStampAuthority.waitForCommit(timeout);
  }

  @Override
  public long[] createCommitTimeStamp(OMMonitor monitor)
  {
    return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
  }

  @Override
  public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
  {
    return timeStampAuthority.startCommit(override, monitor);
  }

  @Override
  public void endCommit(long timestamp)
  {
    timeStampAuthority.endCommit(timestamp);
  }

  @Override
  public void failCommit(long timestamp)
  {
    timeStampAuthority.failCommit(timestamp);
  }

  @Override
  public void executeOutsideStartCommit(Runnable runnable)
  {
    synchronized (timeStampAuthority)
    {
      runnable.run();
    }
  }

  @Override
  public void commit(InternalCommitContext commitContext, OMMonitor monitor)
  {
    if (!DISABLE_FEATURE_MAP_CHECKS)
    {
      InternalCDORevision[] newObjects = commitContext.getNewObjects();
      if (newObjects != null && newObjects.length != 0)
      {
        for (int i = 0; i < newObjects.length; i++)
        {
          InternalCDORevision revision = newObjects[i];
          if (revision.getClassInfo().hasPersistentFeatureMaps())
          {
            throw new CDOException(revision + " contains a feature map");
          }
        }
      }
    }

    if (commitContext.isTreeRestructuring())
    {
      synchronized (commitTransactionLock)
      {
        commitContext.setLastTreeRestructuringCommit(lastTreeRestructuringCommit);
        commitUnsynced(commitContext, monitor);
        lastTreeRestructuringCommit = commitContext.getTimeStamp();
      }
    }
    else if (serializingCommits)
    {
      synchronized (commitTransactionLock)
      {
        commitUnsynced(commitContext, monitor);
      }
    }
    else
    {
      commitUnsynced(commitContext, monitor);
    }
  }

  protected void commitUnsynced(InternalCommitContext commitContext, OMMonitor monitor)
  {
    ProgressDistributor distributor = store.getIndicatingCommitDistributor();
    distributor.run(InternalCommitContext.OPS, commitContext, monitor);
  }

  @Override
  @Deprecated
  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
  {
    sendCommitNotification(sender, commitInfo, true);
  }

  @Override
  @Deprecated
  public CDOCommitInfoHandler[] getCommitInfoHandlers()
  {
    return commitInfoManager.getCommitInfoHandlers();
  }

  @Override
  @Deprecated
  public void addCommitInfoHandler(CDOCommitInfoHandler handler)
  {
    commitInfoManager.addCommitInfoHandler(handler);
  }

  @Override
  @Deprecated
  public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
  {
    commitInfoManager.removeCommitInfoHandler(handler);
  }

  @Override
  @Deprecated
  public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo, boolean clearResourcePathCache)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  public void sendCommitNotification(CommitNotificationInfo info)
  {
    CDOCommitInfo commitInfo = info.getCommitInfo();
    boolean isFailureCommitInfo = commitInfo.getBranch() == null;
    if (isFailureCommitInfo || !commitInfo.isEmpty() || info.getLockChangeInfo() != null)
    {
      sessionManager.sendCommitNotification(info);
      commitInfoManager.notifyCommitInfoHandlers(commitInfo);
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public IQueryHandlerProvider getQueryHandlerProvider()
  {
    return queryHandlerProvider;
  }

  /**
   * @since 2.0
   */
  @Override
  public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
  {
    this.queryHandlerProvider = queryHandlerProvider;
  }

  /**
   * @since 2.0
   */
  @Override
  public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
  {
    String language = info.getQueryLanguage();
    if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
    {
      return new ResourcesQueryHandler();
    }

    if (CDOProtocolConstants.QUERY_LANGUAGE_INSTANCES.equals(language))
    {
      return new InstancesQueryHandler();
    }

    if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
    {
      return new XRefsQueryHandler();
    }

    IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
    if (storeAccessor != null)
    {
      IQueryHandler handler = storeAccessor.getQueryHandler(info);
      if (handler != null)
      {
        return handler;
      }
    }

    if (queryHandlerProvider == null)
    {
      IManagedContainer container = getContainer();
      queryHandlerProvider = new ContainerQueryHandlerProvider(container);
    }

    IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
    if (handler != null)
    {
      return handler;
    }

    return null;
  }

  @Override
  public IManagedContainer getContainer()
  {
    if (container == null)
    {
      return IPluginContainer.INSTANCE;
    }

    return container;
  }

  @Override
  public void setContainer(IManagedContainer container)
  {
    this.container = container;
  }

  @Override
  public ExecutorService getExecutorService()
  {
    IManagedContainer container = getContainer();
    return ConcurrencyUtil.getExecutorService(container);
  }

  @Override
  public Object[] getElements()
  {
    final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager, commitManager, commitInfoManager,
        getLockingManager(), store };
    return elements;
  }

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

  /**
   * @since 2.0
   */
  @Override
  public long getCreationTime()
  {
    return store.getCreationTime();
  }

  /**
   * @since 2.0
   */
  @Override
  public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
  {
    long creationTimeStamp = getCreationTime();
    if (timeStamp < creationTimeStamp)
    {
      throw new IllegalArgumentException(MessageFormat.format("timeStamp ({0}) < repository creation time ({1})", //$NON-NLS-1$
          CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp)));
    }

    long currentTimeStamp = getTimeStamp();
    if (timeStamp > currentTimeStamp)
    {
      throw new IllegalArgumentException(MessageFormat.format("timeStamp ({0}) > current time ({1})", //$NON-NLS-1$
          CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp)));
    }
  }

  @Override
  public long getTimeStamp()
  {
    return timeProvider.getTimeStamp();
  }

  @Override
  public Set<Handler> getHandlers()
  {
    Set<Handler> handlers = new HashSet<>();

    synchronized (readAccessHandlers)
    {
      handlers.addAll(readAccessHandlers);
    }

    synchronized (writeAccessHandlers)
    {
      handlers.addAll(writeAccessHandlers);
    }

    return handlers;
  }

  /**
   * @since 2.0
   */
  @Override
  public void addHandler(Handler handler)
  {
    if (handler instanceof ReadAccessHandler)
    {
      synchronized (readAccessHandlers)
      {
        if (!readAccessHandlers.contains(handler))
        {
          readAccessHandlers.add((ReadAccessHandler)handler);
        }
      }
    }

    if (handler instanceof WriteAccessHandler)
    {
      synchronized (writeAccessHandlers)
      {
        if (!writeAccessHandlers.contains(handler))
        {
          writeAccessHandlers.add((WriteAccessHandler)handler);
        }
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void removeHandler(Handler handler)
  {
    if (handler instanceof ReadAccessHandler)
    {
      synchronized (readAccessHandlers)
      {
        readAccessHandlers.remove(handler);
      }
    }

    if (handler instanceof WriteAccessHandler)
    {
      synchronized (writeAccessHandlers)
      {
        writeAccessHandlers.remove(handler);
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions, List<CDORevision> additionalRevisions)
  {
    ReadAccessHandler[] handlers;
    synchronized (readAccessHandlers)
    {
      int size = readAccessHandlers.size();
      if (size == 0)
      {
        return;
      }

      handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
    }

    for (ReadAccessHandler handler : handlers)
    {
      // Do *not* protect against unchecked exceptions from handlers!
      handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
    }
  }

  @Override
  public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext, boolean beforeCommit, OMMonitor monitor)
  {
    WriteAccessHandler[] handlers;
    synchronized (writeAccessHandlers)
    {
      int size = writeAccessHandlers.size();
      if (size == 0)
      {
        return;
      }

      handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
    }

    try
    {
      monitor.begin(handlers.length);
      for (WriteAccessHandler handler : handlers)
      {
        try
        {
          if (beforeCommit)
          {
            handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
          }
          else
          {
            handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
          }
        }
        catch (RuntimeException ex)
        {
          if (!beforeCommit)
          {
            OM.LOG.error(ex);
          }
          else
          {
            // Do *not* protect against unchecked exceptions from handlers on before case!
            throw ex;
          }
        }
      }
    }
    finally
    {
      monitor.done();
    }
  }

  @Override
  public void setInitialPackages(EPackage... initialPackages)
  {
    checkInactive();
    this.initialPackages = initialPackages;
  }

  @Override
  public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime) throws IOException
  {
    final int fromBranchID = lastReplicatedBranchID + 1;
    final int toBranchID = store.getLastBranchID();

    final long fromCommitTime = lastReplicatedCommitTime + 1L;
    final long toCommitTime = store.getLastCommitTime();

    out.writeXInt(toBranchID);
    out.writeXLong(toCommitTime);

    IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
    accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);

    return new CDOReplicationInfo()
    {
      @Override
      public int getLastReplicatedBranchID()
      {
        return toBranchID;
      }

      @Override
      public long getLastReplicatedCommitTime()
      {
        return toCommitTime;
      }

      @Override
      public String[] getLockAreaIDs()
      {
        return null; // TODO (CD) Raw replication of lockAreas
      }
    };
  }

  @Override
  public void replicate(CDOReplicationContext context)
  {
    int startID = context.getLastReplicatedBranchID() + 1;
    branchManager.getBranches(startID, 0, context);

    long startTime = context.getLastReplicatedCommitTime();
    commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);

    getLockingManager().getLockAreas(null, context);
  }

  @Override
  public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
  {
    CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);

    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);

    return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
  }

  @Override
  @Deprecated
  public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo, CDORevisionAvailabilityInfo targetBaseInfo,
      CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
  {
    MergeDataResult result = getMergeData2(targetInfo, sourceInfo, targetBaseInfo, sourceBaseInfo, monitor);
    Set<CDOID> ids = result.getTargetIDs();
    ids.addAll(result.getSourceIDs());
    return ids;
  }

  @Override
  public MergeDataResult getMergeData2(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
      CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
  {
    CDOBranchPoint target = targetInfo.getBranchPoint();
    CDOBranchPoint source = sourceInfo.getBranchPoint();

    monitor.begin(5);

    try
    {
      IStoreAccessor accessor = StoreThreadLocal.getAccessor();

      MergeDataResult result = new MergeDataResult();
      Set<CDOID> targetIDs = result.getTargetIDs();
      Set<CDOID> sourceIDs = result.getSourceIDs();

      if (targetBaseInfo == null && sourceBaseInfo == null)
      {
        if (CDOBranchUtil.isContainedBy(source, target))
        {
          // This is a "compare" case, see CDOSessionImpl.compareRevisions().
          targetIDs.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
        }
        else if (CDOBranchUtil.isContainedBy(target, source))
        {
          // This is a "compare" case, see CDOSessionImpl.compareRevisions().
          targetIDs.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
        }
        else
        {
          CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
          targetIDs.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
          sourceIDs.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
        }
      }
      else
      {
        CDOChangeSetSegment[] targetSegments;
        CDOChangeSetSegment[] sourceSegments;

        if (targetBaseInfo.getBranchPoint() == CDOBranchUtil.AUTO_BRANCH_POINT)
        {
          CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
          targetSegments = CDOChangeSetSegment.createFrom(ancestor, target);
          sourceSegments = CDOChangeSetSegment.createFrom(ancestor, source);

          CDOBranchPoint targetBase = ancestor;
          CDOBranchPoint sourceBase = ancestor;
          long ancestorTime = ancestor.getTimeStamp();

          CDOBranchPointRange latestTargetMerge = getLatestMerge(targetSegments, sourceSegments, ancestorTime);
          if (latestTargetMerge != null)
          {
            targetBase = latestTargetMerge.getEndPoint();
            sourceBase = latestTargetMerge.getStartPoint();

            if (!sourceBase.equals(ancestor))
            {
              sourceSegments = CDOChangeSetSegment.createFrom(sourceBase, source);
            }
          }

          CDOBranchPointRange latestSourceMerge = getLatestMerge(sourceSegments, targetSegments, ancestorTime);
          if (latestSourceMerge != null)
          {
            CDOBranchPoint mergeSource = latestSourceMerge.getStartPoint();
            if (targetBase.getTimeStamp() < mergeSource.getTimeStamp())
            {
              targetBase = mergeSource;
            }

            result.setResultBase(sourceBase);
          }

          if (!targetBase.equals(ancestor))
          {
            targetSegments = CDOChangeSetSegment.createFrom(targetBase, target);
          }

          targetBaseInfo.setBranchPoint(targetBase);
          sourceBaseInfo.setBranchPoint(sourceBase);
        }
        else
        {
          CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
          targetSegments = CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target);
          sourceSegments = CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source);
        }

        targetIDs.addAll(accessor.readChangeSet(monitor.fork(), targetSegments));
        sourceIDs.addAll(accessor.readChangeSet(monitor.fork(), sourceSegments));
      }

      loadMergeData(targetIDs, targetInfo, monitor.fork());
      loadMergeData(sourceIDs, sourceInfo, monitor.fork());

      if (targetBaseInfo != null)
      {
        loadMergeData(targetIDs, targetBaseInfo, monitor.fork());
      }

      if (sourceBaseInfo != null && !targetBaseInfo.getBranchPoint().equals(sourceBaseInfo.getBranchPoint()))
      {
        loadMergeData(sourceIDs, sourceBaseInfo, monitor.fork());
      }

      return result;
    }
    finally
    {
      monitor.done();
    }
  }

  private CDOBranchPointRange getLatestMerge(CDOChangeSetSegment[] targetSegments, CDOChangeSetSegment[] sourceSegments, long ancestorTime)
  {
    for (int i = targetSegments.length - 1; i >= 0; --i)
    {
      CDOChangeSetSegment targetSegment = targetSegments[i];
      CDOBranch targetBranch = targetSegment.getBranch();
      long startTime = targetSegment.getTimeStamp();
      long endTime = targetSegment.getEndTime();

      while (endTime > startTime || endTime == CDOBranchPoint.UNSPECIFIED_DATE)
      {
        CDOCommitInfo commitInfo = commitInfoManager.getCommitInfo(targetBranch, endTime, false);
        if (commitInfo == null)
        {
          break;
        }

        long timeStamp = commitInfo.getTimeStamp();
        if (timeStamp <= startTime)
        {
          break;
        }

        CDOBranchPoint mergeSource = getMergeSource(commitInfo, sourceSegments, ancestorTime);
        if (mergeSource != null)
        {
          CDOBranchPoint endPoint = CDOBranchUtil.copyBranchPoint(commitInfo);
          return CDOBranchUtil.createRange(mergeSource, endPoint);
        }

        endTime = timeStamp - 1;
      }
    }

    return null;
  }

  private CDOBranchPoint getMergeSource(CDOCommitInfo commitInfo, CDOChangeSetSegment[] sourceSegments, long ancestorTime)
  {
    CDOBranchPoint mergeSource = commitInfo.getMergeSource();
    if (mergeSource != null)
    {
      if (CDOChangeSetSegment.contains(sourceSegments, mergeSource))
      {
        return mergeSource;
      }

      CDOChangeSetSegment[] targetSegments = CDOChangeSetSegment.createFrom(ancestorTime, mergeSource);
      CDOBranchPointRange latestMerge = getLatestMerge(targetSegments, sourceSegments, ancestorTime);
      if (latestMerge != null)
      {
        return latestMerge.getStartPoint();
      }
    }

    return null;
  }

  private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
  {
    int size = ids.size();
    monitor.begin(size);

    try
    {
      CDOBranchPoint branchPoint = info.getBranchPoint();
      for (CDOID id : ids)
      {
        if (info.containsRevision(id))
        {
          info.removeRevision(id);
        }
        else
        {
          InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
          if (revision != null)
          {
            info.addRevision(revision);
          }
          else
          {
            info.removeRevision(id);
          }
        }

        monitor.worked();
      }
    }
    finally
    {
      monitor.done();
    }
  }

  private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
  {
    return revisionManager.getRevision(id, branchPoint, UNCHUNKED, NONE, true);
  }

  @Override
  public void queryLobs(List<byte[]> ids)
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    accessor.queryLobs(ids);
  }

  @Override
  public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    accessor.handleLobs(fromTime, toTime, handler);
  }

  @Override
  public void loadLob(byte[] id, OutputStream out) throws IOException
  {
    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    accessor.loadLob(id, out);
  }

  @Override
  public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime, final CDORevisionHandler handler)
  {
    CDORevisionHandler wrapper = handler;
    if (!exactBranch && !branch.isMainBranch())
    {
      if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
      {
        throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
      }

      wrapper = new CDORevisionHandler()
      {
        private Set<CDOID> handled = new HashSet<>();

        @Override
        public boolean handleRevision(CDORevision revision)
        {
          CDOID id = revision.getID();
          if (handled.add(id))
          {
            return handler.handleRevision(revision);
          }

          return true;
        }
      };
    }

    IStoreAccessor accessor = StoreThreadLocal.getAccessor();
    while (branch != null)
    {
      accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
      if (exactBranch)
      {
        break;
      }

      CDOBranchPoint base = branch.getBase();
      branch = base.getBranch();
      timeStamp = base.getTimeStamp();
    }
  }

  public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch, boolean isSupportingBranches)
  {
    List<Object> lockables = new ArrayList<>();
    for (CDORevisionKey revKey : revisionKeys)
    {
      CDOID id = revKey.getID();
      if (isSupportingBranches)
      {
        lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
      }
      else
      {
        lockables.add(id);
      }
    }

    return lockables;
  }

  @Override
  public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, boolean recursive, long timeout)
  {
    List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
    return lock(view, lockType, lockables, revKeys, recursive, timeout);
  }

  protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables, List<CDORevisionKey> loadedRevs, boolean recursive, long timeout)
  {
    List<LockState<Object, IView>> newLockStates = null;

    try
    {
      newLockStates = getLockingManager().lock2(true, type, view, lockables, recursive, timeout);
    }
    catch (TimeoutRuntimeException ex)
    {
      return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
    }
    catch (InterruptedException ex)
    {
      throw WrappedException.wrap(ex);
    }

    long[] requiredTimestamp = { 0L };
    CDORevisionKey[] staleRevisionsArray = null;

    try
    {
      staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
    }
    catch (IllegalArgumentException e)
    {
      getLockingManager().unlock2(true, type, view, lockables, recursive);
      throw e;
    }

    // If some of the clients' revisions are stale and it has passiveUpdates disabled,
    // then the locks are useless so we release them and report the stale revisions
    //
    InternalSession session = view.getSession();
    boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
    if (staleNoUpdate)
    {
      getLockingManager().unlock2(true, type, view, lockables, recursive);
      return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0], getTimeStamp());
    }

    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
    sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);

    boolean waitForUpdate = staleRevisionsArray.length > 0;
    return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates, getTimeStamp());
  }

  private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys, List<Object> objectsToLock, LockType lockType,
      long[] requiredTimestamp)
  {
    List<CDORevisionKey> staleRevisions = new LinkedList<>();
    if (revisionKeys != null)
    {
      InternalCDORevisionManager revManager = getRevisionManager();
      CDOBranch viewedBranch = view.getBranch();
      for (CDORevisionKey revKey : revisionKeys)
      {
        CDOID id = revKey.getID();
        InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), UNCHUNKED, NONE, true);

        if (rev == null)
        {
          throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id, viewedBranch));
        }

        if (!revKey.equals(rev))
        {
          // Send back the *expected* revision keys, so that the client can check that it really has loaded those.
          staleRevisions.add(CDORevisionUtil.copyRevisionKey(rev));
          requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
        }
      }
    }

    // Convert the list to an array, to satisfy the API later
    CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
    staleRevisions.toArray(staleRevisionsArray);

    return staleRevisionsArray;
  }

  private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
  {
    long timestamp = getTimeStamp();
    CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation, lockType, cdoLockStates);
    getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
  }

  // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
  public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
  {
    CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
    int i = 0;

    for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
    {
      CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
      cdoLockStates[i++] = cdoLockState;
    }

    return cdoLockStates;
  }

  @Override
  public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs, boolean recursive)
  {
    List<Object> unlockables = null;
    if (objectIDs != null)
    {
      unlockables = new ArrayList<>(objectIDs.size());
      CDOBranch branch = view.getBranch();
      for (CDOID id : objectIDs)
      {
        Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
        unlockables.add(key);
      }
    }

    return doUnlock(view, lockType, unlockables, recursive);
  }

  protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables, boolean recursive)
  {
    List<LockState<Object, IView>> newLockStates = null;
    if (lockType == null) // Signals an unlock-all operation
    {
      newLockStates = getLockingManager().unlock2(true, view);
    }
    else
    {
      newLockStates = getLockingManager().unlock2(true, lockType, view, unlockables, recursive);
    }

    long timestamp = getTimeStamp();
    CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
    sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);

    return new UnlockObjectsResult(cdoLockStates, timestamp);
  }

  @Override
  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Object getAdapter(Class adapter)
  {
    return AdapterUtil.adapt(this, adapter, false);
  }

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

  @Override
  public boolean isSkipInitialization()
  {
    return skipInitialization;
  }

  @Override
  public void setSkipInitialization(boolean skipInitialization)
  {
    this.skipInitialization = skipInitialization;
  }

  protected void initProperties()
  {
    // OVERRIDE_UUID
    uuid = properties.get(Props.OVERRIDE_UUID);
    if (uuid != null && uuid.length() == 0)
    {
      uuid = getName();
    }

    // SUPPORTING_AUDITS
    String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
    if (valueAudits != null)
    {
      supportingAudits = Boolean.valueOf(valueAudits);
    }
    else
    {
      supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
    }

    // SUPPORTING_BRANCHES
    String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
    if (valueBranches != null)
    {
      supportingBranches = Boolean.valueOf(valueBranches);
    }
    else
    {
      supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
    }

    // SUPPORTING_UNITS
    String valueUnits = properties.get(Props.SUPPORTING_UNITS);
    if (valueUnits != null)
    {
      supportingUnits = Boolean.valueOf(valueUnits);
    }

    // SERIALIZE_COMMITS
    String valueCommits = properties.get(Props.SERIALIZE_COMMITS);
    if (valueCommits != null)
    {
      serializingCommits = Boolean.valueOf(valueCommits);
    }

    // ENSURE_REFERENTIAL_INTEGRITY
    String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
    if (valueIntegrity != null)
    {
      ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
    }

    // ID_GENERATION_LOCATION
    String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
    if (valueIDLocation != null)
    {
      idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
    }

    if (idGenerationLocation == null)
    {
      idGenerationLocation = IDGenerationLocation.STORE;
    }

    // COMMIT_INFO_STORAGE
    String valueCommitInfoStorage = properties.get(Props.COMMIT_INFO_STORAGE);
    if (valueCommitInfoStorage != null)
    {
      commitInfoStorage = CommitInfoStorage.valueOf(valueCommitInfoStorage);
    }

    if (commitInfoStorage == null)
    {
      commitInfoStorage = CommitInfoStorage.WITH_MERGE_SOURCE;
    }

    if (commitInfoStorage != CommitInfoStorage.NO && !supportingBranches)
    {
      commitInfoStorage = CommitInfoStorage.YES;
    }

    // ENSURE_REFERENTIAL_INTEGRITY
    String valueTimeout = properties.get(Props.OPTIMISTIC_LOCKING_TIMEOUT);
    if (valueTimeout != null)
    {
      optimisticLockingTimeout = Long.valueOf(valueTimeout);
    }
  }

  @Override
  @Deprecated
  public void initSystemPackages()
  {
    initSystemPackages(true);
  }

  @Override
  public void initSystemPackages(final boolean firstStart)
  {
    List<InternalCDOPackageUnit> newPackageUnits = new ArrayList<>();
    long timeStamp;

    if (firstStart)
    {
      timeStamp = store.getCreationTime();
      newPackageUnits.add(initPackage(timeStamp, EcorePackage.eINSTANCE));
      newPackageUnits.add(initPackage(timeStamp, EresourcePackage.eINSTANCE));
      newPackageUnits.add(initPackage(timeStamp, EtypesPackage.eINSTANCE));
    }
    else
    {
      readPackageUnits(); // Makes sure that all mapped package units have proper originalType/timeStamp.

      timeStamp = getTimeStamp();
      initPackage(timeStamp, EcorePackage.eINSTANCE);
      initPackage(timeStamp, EresourcePackage.eINSTANCE);
      initPackage(timeStamp, EtypesPackage.eINSTANCE);
    }

    if (initialPackages != null)
    {
      for (EPackage initialPackage : initialPackages)
      {
        if (!packageRegistry.containsKey(initialPackage.getNsURI()))
        {
          newPackageUnits.add(initPackage(timeStamp, initialPackage));
        }
      }
    }

    if (!newPackageUnits.isEmpty())
    {
      IStoreAccessor writer = store.getWriter(null);
      StoreThreadLocal.setAccessor(writer);

      try
      {
        InternalCDOPackageUnit[] packageUnits = newPackageUnits.toArray(new InternalCDOPackageUnit[newPackageUnits.size()]);
        writer.writePackageUnits(packageUnits, new Monitor());
        writer.commit(new Monitor());
      }
      finally
      {
        StoreThreadLocal.release();
      }
    }

    fireEvent(new PackagesInitializedEvent()
    {
      @Override
      public InternalRepository getSource()
      {
        return Repository.this;
      }

      @Override
      public boolean isFirstStart()
      {
        return firstStart;
      }

      @Override
      public List<InternalCDOPackageUnit> getPackageUnits()
      {
        return Collections.unmodifiableList(newPackageUnits);
      }
    });
  }

  protected InternalCDOPackageUnit initPackage(long timeStamp, EPackage ePackage)
  {
    EMFUtil.registerPackage(ePackage, packageRegistry);
    InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);

    InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
    packageUnit.setState(CDOPackageUnit.State.LOADED);

    if (packageUnit.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
    {
      packageUnit.setTimeStamp(timeStamp);
    }

    return packageUnit;
  }

  @Override
  public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
  {
    branchManager.initMainBranch(false, timeStamp);
  }

  protected void initRootResource()
  {
    CDOBranchPoint head = branchManager.getMainBranch().getHead();

    CDORevisionFactory factory = getRevisionManager().getFactory();
    InternalCDORevision rootResource = (InternalCDORevision)factory.createRevision(EresourcePackage.Literals.CDO_RESOURCE);

    rootResource.setBranchPoint(head);
    rootResource.setContainerID(CDOID.NULL);
    rootResource.setContainingFeatureID(0);

    CDOID id = createRootResourceID();
    rootResource.setID(id);
    rootResource.setResourceID(id);

    InternalSession session = getSessionManager().openSession(null);
    InternalTransaction transaction = session.openTransaction(1, head);
    InternalCommitContext commitContext = new TransactionCommitContext(transaction)
    {
      @Override
      protected long[] createTimeStamp(OMMonitor monitor)
      {
        InternalRepository repository = getTransaction().getSession().getManager().getRepository();
        return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
      }

      @Override
      public String getUserID()
      {
        return SYSTEM_USER_ID;
      }

      @Override
      public String getCommitComment()
      {
        return "<initialize>"; //$NON-NLS-1$
      }
    };

    commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
    commitContext.preWrite();
    commitContext.write(new Monitor());
    commitContext.commit(new Monitor());

    String rollbackMessage = commitContext.getRollbackMessage();
    if (rollbackMessage != null)
    {
      throw new TransactionException(rollbackMessage);
    }

    rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;

    commitContext.postCommit(true);
    session.close();
  }

  protected CDOID createRootResourceID()
  {
    if (getIDGenerationLocation() == IDGenerationLocation.STORE)
    {
      return CDOIDUtil.createTempObject(1);
    }

    return CDOIDGenerator.UUID.generateCDOID(null);
  }

  protected void readRootResource()
  {
    IStoreAccessor reader = store.getReader(null);
    StoreThreadLocal.setAccessor(reader);

    try
    {
      CDOBranchPoint head = branchManager.getMainBranch().getHead();
      rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
    }
    finally
    {
      StoreThreadLocal.release();
    }
  }

  protected void readPackageUnits()
  {
    IStoreAccessor reader = store.getReader(null);
    StoreThreadLocal.setAccessor(reader);

    try
    {
      Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
      for (InternalCDOPackageUnit packageUnit : packageUnits)
      {
        packageRegistry.putPackageUnit(packageUnit);
      }

      // Bug 521029: Initialize EPackages early from the main thread to avoid multi-threading issues.
      // This could be made optional at some point.
      for (InternalCDOPackageUnit packageUnit : packageUnits)
      {
        for (InternalCDOPackageInfo packageInfo : packageUnit.getPackageInfos())
        {
          packageInfo.getEPackage(true); // Trigger initialization.
        }
      }
    }
    finally
    {
      StoreThreadLocal.release();
    }
  }

  protected void setPostActivateState()
  {
    setState(State.ONLINE);
  }

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

    checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
    checkState(store, "store"); //$NON-NLS-1$
    checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
    checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
    checkState(branchManager, "branchManager"); //$NON-NLS-1$
    checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
    checkState(queryManager, "queryManager"); //$NON-NLS-1$
    checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
    checkState(commitManager, "commitManager"); //$NON-NLS-1$
    checkState(lockingManager, "lockingManager"); //$NON-NLS-1$

    packageRegistry.setReplacingDescriptors(true);

    if (packageRegistry.getPackageProcessor() == null)
    {
      packageRegistry.setPackageProcessor(this);
    }

    if (packageRegistry.getPackageLoader() == null)
    {
      packageRegistry.setPackageLoader(this);
    }

    if (branchManager.getRepository() == null)
    {
      branchManager.setRepository(this);
    }

    if (branchManager.getBranchLoader() == null)
    {
      branchManager.setBranchLoader(this);
    }

    if (revisionManager.getRevisionLoader() == null)
    {
      revisionManager.setRevisionLoader(this);
    }

    if (sessionManager.getRepository() == null)
    {
      sessionManager.setRepository(this);
    }

    if (queryManager.getRepository() == null)
    {
      queryManager.setRepository(this);
    }

    if (commitInfoManager.getRepository() == null)
    {
      commitInfoManager.setRepository(this);
    }

    if (commitInfoManager.getCommitInfoLoader() == null)
    {
      commitInfoManager.setCommitInfoLoader(this);
    }

    if (commitManager.getRepository() == null)
    {
      commitManager.setRepository(this);
    }

    if (lockingManager.getRepository() == null)
    {
      lockingManager.setRepository(this);
    }

    if (store.getRepository() == null)
    {
      store.setRepository(this);
    }
  }

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

    initProperties();
    if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
    {
      throw new IllegalStateException("Store can not handle client-assigned IDs: " + store);
    }

    store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING : IStore.RevisionTemporality.NONE);
    store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING : IStore.RevisionParallelism.NONE);
    revisionManager.setSupportingAudits(supportingAudits);
    revisionManager.setSupportingBranches(supportingBranches);

    LifecycleUtil.activate(store);

    Map<String, String> persistentProperties = store.getPersistentProperties(Collections.singleton(PROP_UUID));
    String persistentUUID = persistentProperties.get(PROP_UUID);

    if (uuid == null)
    {
      if (persistentUUID == null)
      {
        uuid = UUID.randomUUID().toString();
      }
      else
      {
        uuid = persistentUUID;
      }
    }

    if (persistentUUID == null || !persistentUUID.equals(uuid))
    {
      persistentProperties.put(PROP_UUID, uuid);
      store.setPersistentProperties(persistentProperties);
    }

    LifecycleUtil.activate(packageRegistry);
    LifecycleUtil.activate(sessionManager);
    LifecycleUtil.activate(revisionManager);
    LifecycleUtil.activate(branchManager);
    LifecycleUtil.activate(queryManager);
    LifecycleUtil.activate(commitInfoManager);
    LifecycleUtil.activate(commitManager);
    LifecycleUtil.activate(queryHandlerProvider);

    if (supportingUnits)
    {
      LifecycleUtil.activate(unitManager);
    }

    if (!skipInitialization)
    {
      long creationTime = store.getCreationTime();
      initMainBranch(branchManager, creationTime);

      long lastCommitTime = Math.max(creationTime, store.getLastCommitTime());
      timeStampAuthority.setLastFinishedTimeStamp(lastCommitTime);
      commitInfoManager.setLastCommitOfBranch(null, lastCommitTime);

      if (store.isFirstStart())
      {
        initSystemPackages(true);
        initRootResource();
      }
      else
      {
        initSystemPackages(false);
        readRootResource();
      }

      branchManager.setTagModCount(0);

      if (supportingAudits)
      {
        // Load all tags and keep a strong reference to avoid frequent tag loading.
        IStoreAccessor reader = store.getReader(null);
        StoreThreadLocal.setAccessor(reader);

        try
        {
          tagList = branchManager.getTagList();
        }
        finally
        {
          StoreThreadLocal.release();
        }
      }
    }

    LifecycleUtil.activate(lockingManager); // Needs an initialized main branch / branch manager
    setPostActivateState();
  }

  @Override
  protected void doDeactivate() throws Exception
  {
    LifecycleUtil.deactivate(unitManager);
    LifecycleUtil.deactivate(lockingManager);
    LifecycleUtil.deactivate(queryHandlerProvider);
    LifecycleUtil.deactivate(commitManager);
    LifecycleUtil.deactivate(commitInfoManager);
    LifecycleUtil.deactivate(queryManager);
    LifecycleUtil.deactivate(revisionManager);
    LifecycleUtil.deactivate(sessionManager);
    LifecycleUtil.deactivate(store);
    LifecycleUtil.deactivate(branchManager);
    LifecycleUtil.deactivate(packageRegistry);
    super.doDeactivate();
  }

  /**
   * @author Eike Stepper
   * @since 2.0
   */
  public static class Default extends Repository
  {
    public Default()
    {
    }

    @Override
    protected void doBeforeActivate() throws Exception
    {
      if (getTimeProvider() == null)
      {
        setTimeProvider(createTimeProvider());
      }

      if (getPackageRegistry(false) == null)
      {
        setPackageRegistry(createPackageRegistry());
      }

      if (getSessionManager() == null)
      {
        setSessionManager(createSessionManager());
      }

      if (getBranchManager() == null)
      {
        setBranchManager(createBranchManager());
      }

      if (getRevisionManager() == null)
      {
        setRevisionManager(createRevisionManager());
      }

      if (getQueryManager() == null)
      {
        setQueryManager(createQueryManager());
      }

      if (getCommitInfoManager() == null)
      {
        setCommitInfoManager(createCommitInfoManager());
      }

      if (getCommitManager() == null)
      {
        setCommitManager(createCommitManager());
      }

      if (getLockManager() == null)
      {
        setLockingManager(createLockManager());
      }

      if (getUnitManager() == null)
      {
        setUnitManager(createUnitManager());
      }

      super.doBeforeActivate();
    }

    protected CDOTimeProvider createTimeProvider()
    {
      return CurrentTimeProvider.INSTANCE;
    }

    protected InternalCDOPackageRegistry createPackageRegistry()
    {
      return new CDOPackageRegistryImpl();
    }

    protected InternalSessionManager createSessionManager()
    {
      return new SessionManager();
    }

    protected InternalCDOBranchManager createBranchManager()
    {
      return CDOBranchUtil.createBranchManager();
    }

    protected InternalCDORevisionManager createRevisionManager()
    {
      return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
    }

    protected InternalQueryManager createQueryManager()
    {
      return new QueryManager();
    }

    protected InternalCDOCommitInfoManager createCommitInfoManager()
    {
      return CDOCommitInfoUtil.createCommitInfoManager();
    }

    protected InternalCommitManager createCommitManager()
    {
      return new CommitManager();
    }

    protected InternalUnitManager createUnitManager()
    {
      return new UnitManager(this);
    }

    @Deprecated
    protected InternalLockManager createLockManager()
    {
      return createLockingManager();
    }

    public LockingManager createLockingManager()
    {
      return new LockingManager();
    }
  }
}
