/*
 * Copyright (c) 2009-2016, 2018-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
 */
package org.eclipse.emf.internal.cdo.view;

import org.eclipse.emf.cdo.CDOLocalAdapter;
import org.eclipse.emf.cdo.CDONotification;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
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.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
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.protocol.CDOProtocol.CommitNotificationInfo;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants.UnitOpcode;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.lock.InternalCDOLockState;
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.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.LockTimeoutException;
import org.eclipse.emf.cdo.util.ReadOnlyException;
import org.eclipse.emf.cdo.util.StaleRevisionLockException;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
import org.eclipse.emf.cdo.view.CDOFeatureAnalyzer;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
import org.eclipse.emf.cdo.view.CDOLockStatePrefetcher;
import org.eclipse.emf.cdo.view.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
import org.eclipse.emf.cdo.view.CDOUnit;
import org.eclipse.emf.cdo.view.CDOUnitManager;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewDurabilityChangedEvent;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;

import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDODeltaNotificationImpl;
import org.eclipse.emf.internal.cdo.object.CDOInvalidationNotificationImpl;
import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;
import org.eclipse.emf.internal.cdo.object.CDOObjectWrapperBase;
import org.eclipse.emf.internal.cdo.session.SessionUtil;
import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;

import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.ConcurrentArray;
import org.eclipse.net4j.util.collection.HashBag;
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.RunnableWithName;
import org.eclipse.net4j.util.concurrent.SerializingExecutor;
import org.eclipse.net4j.util.container.Container;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.event.ThrowableEvent;
import org.eclipse.net4j.util.lifecycle.IDeactivateable;
import org.eclipse.net4j.util.lifecycle.ILifecycle;
import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
import org.eclipse.net4j.util.lifecycle.LifecycleException;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.om.log.OMLogger;
import org.eclipse.net4j.util.om.monitor.EclipseMonitor;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.options.OptionsEvent;
import org.eclipse.net4j.util.ref.ReferenceType;
import org.eclipse.net4j.util.ref.ReferenceValueMap;

import org.eclipse.emf.common.notify.Adapter;
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.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.emf.spi.cdo.InternalCDOViewSet;

import org.eclipse.core.runtime.IProgressMonitor;

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.LinkedHashSet;
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.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;

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

  private int viewID;

  private InternalCDOSession session;

  private String durableLockingID;

  private final CDOUnitManagerImpl unitManager = new CDOUnitManagerImpl();

  private final CommitInfoDistributor commitInfoDistributor = new CommitInfoDistributor();

  private ChangeSubscriptionManager changeSubscriptionManager = new ChangeSubscriptionManager();

  private AdapterManager adapterManager = new AdapterManager();

  private OptionsImpl options;

  private long lastUpdateTime;

  private CDOLockOwner lockOwner;

  private Map<CDOObject, CDOLockState> lockStates = new WeakHashMap<>();

  private ViewInvalidator invalidator = new ViewInvalidator();

  private volatile boolean invalidating;

  /**
   * @since 2.0
   */
  public CDOViewImpl(CDOSession session, CDOBranch branch, long timeStamp)
  {
    super(session, branch.getPoint(timeStamp));
    options = createOptions();
  }

  public CDOViewImpl(CDOSession session, String durableLockingID)
  {
    super(session);
    this.durableLockingID = durableLockingID;
    options = createOptions();
  }

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

  @Override
  public int getViewID()
  {
    return viewID;
  }

  /**
   * @since 2.0
   */
  @Override
  public void setViewID(int viewId)
  {
    viewID = viewId;
  }

  @Override
  public ExecutorService getExecutorService()
  {
    return ConcurrencyUtil.getExecutorService(session);
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOSession getSession()
  {
    return session;
  }

  /**
   * @since 2.0
   */
  @Override
  public void setSession(InternalCDOSession session)
  {
    super.setSession(session);
    this.session = session;
  }

  @Override
  public int getSessionID()
  {
    return session.getSessionID();
  }

  @Override
  public boolean setBranchPoint(CDOBranchPoint branchPoint, IProgressMonitor progressMonitor)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        branchPoint = adjustBranchPoint(branchPoint);

        long timeStamp = branchPoint.getTimeStamp();
        long creationTimeStamp = session.getRepositoryInfo().getCreationTime();
        if (timeStamp != UNSPECIFIED_DATE && timeStamp < creationTimeStamp)
        {
          throw new IllegalArgumentException(MessageFormat.format("timeStamp ({0}) < repository creation time ({1})", //$NON-NLS-1$
              CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp)));
        }

        CDOBranchPoint oldBranchPoint = CDOBranchUtil.copyBranchPoint(getBranchPoint());
        if (branchPoint.equals(oldBranchPoint))
        {
          return false;
        }

        if (TRACER.isEnabled())
        {
          TRACER.format("Changing view target to {0}", branchPoint); //$NON-NLS-1$
        }

        Map<CDOID, InternalCDORevision> oldRevisions = CDOIDUtil.createMap();
        List<CDORevisionKey> allChangedObjects = new ArrayList<>();
        List<CDOIDAndVersion> allDetachedObjects = new ArrayList<>();

        List<InternalCDOObject> invalidObjects = getInvalidObjects(branchPoint);
        for (InternalCDOObject object : invalidObjects)
        {
          InternalCDORevision revision = object.cdoRevision();
          if (revision != null)
          {
            oldRevisions.put(object.cdoID(), revision);
          }
        }

        CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
        sessionProtocol.switchTarget(viewID, branchPoint, invalidObjects, allChangedObjects, allDetachedObjects, EclipseMonitor.convert(progressMonitor));

        basicSetBranchPoint(branchPoint);

        try
        {
          CDOStateMachine.SWITCHING_TARGET.set(Boolean.TRUE);

          ViewInvalidationData invalidationData = new ViewInvalidationData();
          invalidationData.setLastUpdateTime(UNSPECIFIED_DATE);
          invalidationData.setBranch(branchPoint.getBranch());
          invalidationData.setAllChangedObjects(allChangedObjects);
          invalidationData.setAllDetachedObjects(allDetachedObjects);
          invalidationData.setOldRevisions(oldRevisions);
          invalidationData.setClearResourcePathCache(true);

          doInvalidate(invalidationData);
        }
        finally
        {
          CDOStateMachine.SWITCHING_TARGET.remove();
        }

        IListener[] listeners = getListeners();
        if (listeners != null)
        {
          fireViewTargetChangedEvent(oldBranchPoint, listeners);
        }

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

  private List<InternalCDOObject> getInvalidObjects(CDOBranchPoint branchPoint)
  {
    List<InternalCDOObject> result = new ArrayList<>();
    for (InternalCDOObject object : getModifiableObjects().values())
    {
      CDORevision revision = object.cdoRevision(false);
      if (revision == null || !revision.isValid(branchPoint))
      {
        result.add(object);
      }
    }

    return result;
  }

  private Set<? extends CDOObject> getSet(Collection<? extends CDOObject> objects)
  {
    if (objects instanceof Set)
    {
      return (Set<? extends CDOObject>)objects;
    }

    return new HashSet<CDOObject>(objects);
  }

  /**
   * @since 2.0
   */
  @Override
  public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout) throws InterruptedException
  {
    lockObjects(objects, lockType, timeout, false);
  }

  @Override
  public void lockObjects(Collection<? extends CDOObject> objects, LockType lockType, long timeout, boolean recursive) throws InterruptedException
  {
    checkActive();
    checkState(getTimeStamp() == UNSPECIFIED_DATE, "Locking not supported for historial views");

    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        Set<? extends CDOObject> uniqueObjects = getSet(objects);
        int size = uniqueObjects.size();

        List<CDORevisionKey> revisionKeys = new ArrayList<>(size);
        List<CDOLockState> locksOnNewObjects = new ArrayList<>(size);

        for (CDOObject object : uniqueObjects)
        {
          if (FSMUtil.isNew(object))
          {
            CDOLockState lockState = createUpdatedLockStateForNewObject(object, lockType, true);
            locksOnNewObjects.add(lockState);

            if (recursive)
            {
              for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();)
              {
                CDOObject child = CDOUtil.getCDOObject(it.next());
                lockState = createUpdatedLockStateForNewObject(child, lockType, true);
                locksOnNewObjects.add(lockState);
              }
            }
          }
          else
          {
            InternalCDORevision revision = getRevision(object);
            if (revision != null)
            {
              revisionKeys.add(revision);
            }
          }
        }

        LockObjectsResult result = null;
        if (!revisionKeys.isEmpty())
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          result = sessionProtocol.lockObjects2(revisionKeys, viewID, getBranch(), lockType, recursive, timeout);

          if (!result.isSuccessful())
          {
            if (result.isTimedOut())
            {
              throw new LockTimeoutException();
            }

            CDORevisionKey[] staleRevisions = result.getStaleRevisions();
            if (staleRevisions != null)
            {
              throw new StaleRevisionLockException(staleRevisions);
            }

            throw new AssertionError("Unexpected lock result state");
          }

          if (result.isWaitForUpdate())
          {
            if (!session.options().isPassiveUpdateEnabled())
            {
              throw new AssertionError("Lock result requires client to wait, but client does not have passiveUpdates enabled");
            }

            long requiredTimestamp = result.getRequiredTimestamp();
            if (!waitForUpdate(requiredTimestamp, 10000L))
            {
              throw new AssertionError(
                  "Lock result requires client to wait for commit " + requiredTimestamp + ", but client did not receive invalidations after " + lastUpdateTime);
            }

            InternalCDOSession session = this.session;
            InternalCDORevisionManager revisionManager = session.getRevisionManager();

            for (CDORevisionKey requiredKey : result.getStaleRevisions())
            {
              CDOID id = requiredKey.getID();
              InternalCDOObject object = getObject(id);

              CDORevision revision = object.cdoRevision(true);
              if (!requiredKey.equals(revision))
              {
                InternalCDORevision requiredRevision = revisionManager.getRevisionByVersion(id, requiredKey, CDORevision.UNCHUNKED, true);
                InternalCDORevisionDelta revisionDelta = requiredRevision.compare(revision);
                CDOStateMachine.INSTANCE.invalidate(object, revisionDelta);
              }
            }
          }
        }

        int locksOnNewObjectsCount = locksOnNewObjects.size();
        if (locksOnNewObjectsCount != 0)
        {
          CDOLockState[] locksOnNewObjectsArray = locksOnNewObjects.toArray(new CDOLockState[locksOnNewObjectsCount]);
          // updateLockStates(locksOnNewObjectsArray);
          updateAndNotifyLockStates(Operation.LOCK, lockType, getTimeStamp(), locksOnNewObjectsArray);
        }

        if (result != null)
        {
          updateAndNotifyLockStates(Operation.LOCK, lockType, result.getTimestamp(), result.getNewLockStates());
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  protected void updateAndNotifyLockStates(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates)
  {
    updateLockStates(newLockStates);
    notifyOtherViewsAboutLockChanges(op, type, timestamp, newLockStates);
  }

  /**
   * Updates the lock states of objects held in this view.
   */
  protected void updateLockStates(CDOLockState[] newLockStates)
  {
    updateLockStates(newLockStates, false, null);
  }

  /**
   * Updates the lock states of objects held in this view
   *
   * @param newLockStates new {@link CDOLockState lockStates} to integrate in cache
   * @param loadObjectsOnDemand true to load corresponding {@link CDOObject} if not already loaded to be able to store lockState in cache, false otherwise
   * @since 4.5
   */
  @Override
  public void updateLockStates(CDOLockState[] newLockStates, boolean loadObjectsOnDemand, Consumer<CDOLockState> consumer)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        for (CDOLockState newLockState : newLockStates)
        {
          Object lockedObject = newLockState.getLockedObject();
          CDOID id = CDOLockUtil.getLockedObjectID(lockedObject);

          if (id == null && lockedObject instanceof EObject)
          {
            CDOObject newObj = CDOUtil.getCDOObject((EObject)lockedObject);
            id = newObj.cdoID();
          }

          if (id == null)
          {
            throw new IllegalStateException("Unexpected: " + lockedObject.getClass().getSimpleName());
          }

          InternalCDOObject object = getObject(id, loadObjectsOnDemand);
          if (object != null)
          {
            InternalCDOLockState oldLockState = (InternalCDOLockState)lockStates.get(object);
            if (oldLockState != null)
            {
              oldLockState.updateFrom(newLockState);
              newLockState = oldLockState;
            }
            else
            {
              newLockState = CDOLockUtil.copyLockState(newLockState);
              lockStates.put(object, newLockState);
            }

            if (consumer != null)
            {
              consumer.accept(newLockState);
            }
          }
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * Notifies other views of lock changes performed in this view.
   */
  protected void notifyOtherViewsAboutLockChanges(Operation op, LockType type, long timestamp, CDOLockState[] lockStates)
  {
    if (lockStates.length > 0)
    {
      CDOLockChangeInfo lockChangeInfo = makeLockChangeInfo(op, type, timestamp, lockStates);

      // Do not call out from the current thread to other views while this view is holding its view lock!
      session.handleLockNotification(lockChangeInfo, this, true);

      if (isActive())
      {
        fireLocksChangedEvent(this, lockChangeInfo);
      }
    }
  }

  protected final CDOLockChangeInfo makeLockChangeInfo(Operation op, LockType type, long timestamp, CDOLockState[] newLockStates)
  {
    return CDOLockUtil.createLockChangeInfo(timestamp, this, getBranch(), op, type, newLockStates);
  }

  @Override
  public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
  {
    CDOLockChangeInfo lockChangeInfoToFire = null;

    try
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (lockChangeInfo.isInvalidateAll())
          {
            lockStates.clear();
            lockChangeInfoToFire = lockChangeInfo;
            return;
          }

          // If lockChangeInfo pertains to a different view, do nothing.
          CDOBranch lockChangeBranch = lockChangeInfo.getBranch();
          CDOBranch viewBranch = getBranch();
          if (lockChangeBranch != viewBranch)
          {
            return;
          }

          if (lockChangeInfo.getLockOwner().equals(lockOwner))
          {
            return;
          }

          updateLockStates(lockChangeInfo.getLockStates());

          if (options().isLockNotificationEnabled())
          {
            lockChangeInfoToFire = lockChangeInfo;
          }
        }
        finally
        {
          unlockView();
        }
      }
    }
    finally
    {
      if (lockChangeInfoToFire != null)
      {
        fireLocksChangedEvent(sender, lockChangeInfoToFire);
      }
    }
  }

  protected final void fireLocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
  {
    IListener[] listeners = getListeners();
    if (listeners != null)
    {
      fireEvent(new ViewLocksChangedEvent(sender, lockChangeInfo), listeners);
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType)
  {
    unlockObjects(objects, lockType, false);
  }

  /**
   * Note: This may get called with objects == null, and lockType == null, which is a request to remove all locks on all
   * objects in this view.
   */
  @Override
  public void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType, boolean recursive)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        List<CDOID> objectIDs = null;
        List<CDOLockState> locksOnNewObjects = new LinkedList<>();

        if (objects != null)
        {
          objectIDs = new ArrayList<>();

          for (CDOObject object : getSet(objects))
          {
            if (FSMUtil.isNew(object))
            {
              CDOLockState lockState = createUpdatedLockStateForNewObject(object, lockType, false);
              locksOnNewObjects.add(lockState);

              if (recursive)
              {
                for (TreeIterator<EObject> it = object.eAllContents(); it.hasNext();)
                {
                  CDOObject child = CDOUtil.getCDOObject(it.next());
                  lockState = createUpdatedLockStateForNewObject(child, lockType, false);
                  locksOnNewObjects.add(lockState);
                }
              }
            }
            else if (FSMUtil.isTransient(object))
            {
              CDOID id = getID((InternalCDOObject)object, true);
              if (id != null)
              {
                objectIDs.add(id);
              }
            }
            else
            {
              objectIDs.add(object.cdoID());
            }
          }
        }
        else
        {
          locksOnNewObjects.addAll(createUnlockedLockStatesForAllNewObjects());
        }

        UnlockObjectsResult result = null;
        if (objectIDs == null || !objectIDs.isEmpty())
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          result = sessionProtocol.unlockObjects2(this, objectIDs, lockType, recursive);
        }

        CDOLockState[] locksOnNewObjectsArray = locksOnNewObjects.toArray(new CDOLockState[locksOnNewObjects.size()]);
        updateLockStates(locksOnNewObjectsArray);

        if (result != null)
        {
          updateAndNotifyLockStates(Operation.UNLOCK, lockType, result.getTimestamp(), result.getNewLockStates());
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  protected InternalCDOLockState createUpdatedLockStateForNewObject(CDOObject object, LockType lockType, boolean on)
  {
    throw new ReadOnlyException();
  }

  protected Collection<CDOLockState> createUnlockedLockStatesForAllNewObjects()
  {
    return Collections.emptyList();
  }

  /**
   * @since 2.0
   */
  @Override
  public void unlockObjects()
  {
    unlockObjects(null, null);
  }

  /**
   * @since 2.0
   */
  @Override
  public boolean isObjectLocked(CDOObject object, LockType lockType, boolean byOthers)
  {
    checkActive();
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
        return sessionProtocol.isObjectLocked(this, object, lockType, byOthers);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public boolean isDurableView()
  {
    return durableLockingID != null;
  }

  @Override
  public String getDurableLockingID()
  {
    synchronized (getViewMonitor())
    {
      lockView(); // TODO ???

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

  @Override
  @Deprecated
  public String enableDurableLocking(boolean enable)
  {
    if (enable)
    {
      return enableDurableLocking();
    }

    disableDurableLocking(false);
    return null;
  }

  @Override
  public String enableDurableLocking()
  {
    final String oldID = durableLockingID;

    try
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          if (durableLockingID == null)
          {
            durableLockingID = sessionProtocol.changeLockArea(this, true);
          }

          // Recreate lockOwner with new durableLockingID.
          lockOwner = CDOLockUtil.createLockOwner(this);

          return durableLockingID;
        }
        finally
        {
          unlockView();
        }
      }
    }
    finally
    {
      fireDurabilityChangedEvent(oldID);
    }
  }

  @Override
  public void disableDurableLocking(boolean releaseLocks)
  {
    final String oldID = durableLockingID;

    try
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          if (durableLockingID != null)
          {
            sessionProtocol.changeLockArea(this, false);
            durableLockingID = null;

            // Recreate lockOwner without durableLockingID.
            lockOwner = CDOLockUtil.createLockOwner(this);

            if (releaseLocks)
            {
              unlockObjects();
            }
          }
        }
        finally
        {
          unlockView();
        }
      }
    }
    finally
    {
      fireDurabilityChangedEvent(oldID);
    }
  }

  private void fireDurabilityChangedEvent(final String oldID)
  {
    if (!ObjectUtil.equals(oldID, durableLockingID))
    {
      fireEvent(new CDOViewDurabilityChangedEvent()
      {
        @Override
        public CDOView getSource()
        {
          return CDOViewImpl.this;
        }

        @Override
        public String getOldDurableLockingID()
        {
          return oldID;
        }

        @Override
        public String getNewDurableLockingID()
        {
          return durableLockingID;
        }
      });
    }
  }

  /**
   * @since 2.0
   */
  @Override
  @Deprecated
  public CDOFeatureAnalyzer getFeatureAnalyzer()
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return options().getFeatureAnalyzer();
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  @Deprecated
  public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        options.setFeatureAnalyzer(featureAnalyzer);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public InternalCDOTransaction toTransaction()
  {
    checkActive();
    if (this instanceof InternalCDOTransaction)
    {
      return (InternalCDOTransaction)this;
    }

    throw new ReadOnlyException(MessageFormat.format(Messages.getString("CDOViewImpl.0"), this)); //$NON-NLS-1$
  }

  @Override
  public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        InternalCDORevisionManager revisionManager = session.getRevisionManager();
        int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
        CDOBranchPoint branchPoint = getBranchPointForID(id);
        return revisionManager.getRevision(id, branchPoint, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public void remapObject(CDOID oldID)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        InternalCDOObject object = remapObjectSynced(oldID);

        InternalCDOLockState oldLockState = (InternalCDOLockState)lockStates.remove(object);
        if (oldLockState != null)
        {
          Object lockedObject = getLockTarget(object); // CDOID or CDOIDAndBranch
          InternalCDOLockState newLockState = (InternalCDOLockState)CDOLockUtil.createLockState(lockedObject);
          newLockState.updateFrom(oldLockState);
          lockStates.put(object, newLockState);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  protected void objectRegistered(InternalCDOObject object)
  {
    super.objectRegistered(object);
    unitManager.addObject(object);
  }

  /**
   * The caller must synchronize on this view!
   */
  @Override
  protected void objectDeregistered(InternalCDOObject object)
  {
    lockStates.remove(object);
    super.objectDeregistered(object);
  }

  @Override
  public CDOLockOwner getLockOwner()
  {
    return lockOwner;
  }

  @Override
  public void refreshLockStates(Consumer<CDOLockState> consumer)
  {
    checkActive();
    checkState(getTimeStamp() == UNSPECIFIED_DATE, "Locking not supported for historial views");

    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (options().isLockNotificationEnabled())
        {
          return;
        }

        List<CDOID> ids = new ArrayList<>();
        for (CDOObject object : lockStates.keySet())
        {
          ids.add(object.cdoID());
        }

        if (!ids.isEmpty())
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, ids, CDOLockState.DEPTH_NONE);

          if (loadedLockStates != null && loadedLockStates.length != 0)
          {
            updateLockStates(loadedLockStates);
          }
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public CDOLockState[] getLockStates(Collection<CDOID> ids)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        return getLockStates(ids, true);
      }
      finally
      {
        unlockView();
      }
    }
  }

  public CDOLockState[] getLockStates(Collection<CDOID> ids, boolean loadOnDemand)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        List<CDOLockState> result = new ArrayList<>();
        List<CDOLockState> lockStatesToUpdate = new ArrayList<>();
        Set<CDOID> missingIDs = new LinkedHashSet<>();

        for (CDOID id : ids)
        {
          InternalCDOObject object = getObject(id, false);
          if (object != null)
          {
            CDOLockState lockState = lockStates.get(object);
            if (lockState != null)
            {
              result.add(lockState);
              continue;
            }

            if (loadOnDemand && FSMUtil.isNew(object))
            {
              Object lockTarget = getLockTarget(this, id);
              CDOLockState newLockState = CDOLockUtil.createLockState(lockTarget);

              result.add(newLockState);
              lockStatesToUpdate.add(newLockState);
              continue;
            }
          }

          missingIDs.add(id);
        }

        if (loadOnDemand && (!missingIDs.isEmpty() || ids.isEmpty()))
        {
          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, missingIDs, CDOLockState.DEPTH_NONE);

          for (CDOLockState loadedLockState : loadedLockStates)
          {
            result.add(loadedLockState);
            lockStatesToUpdate.add(loadedLockState);

            CDOID id = CDOIDUtil.getCDOID(loadedLockState.getLockedObject());
            if (id != null)
            {
              missingIDs.remove(id);
            }
          }

          for (CDOID missingID : missingIDs)
          {
            Object lockTarget = getLockTarget(this, missingID);
            CDOLockState defaultLockState = CDOLockUtil.createLockState(lockTarget);

            result.add(defaultLockState);
            lockStatesToUpdate.add(defaultLockState);
          }
        }

        if (!lockStatesToUpdate.isEmpty())
        {
          updateLockStates(lockStatesToUpdate.toArray(new CDOLockState[lockStatesToUpdate.size()]));
        }

        return result.toArray(new CDOLockState[result.size()]);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * The caller must synchronize on this view!
   */
  public Map<CDOObject, CDOLockState> getLockStates()
  {
    return lockStates;
  }

  private CDOBranchPoint getBranchPointForID(CDOID id)
  {
    // If this view's timestamp is something other than UNSPECIFIED_DATE,
    // then this is an 'audit' view, and so this timestamp must always be
    // used without any concern for possible sticky-view behavior
    CDOBranchPoint branchPoint = getNormalizedBranchPoint();
    if (branchPoint.getTimeStamp() != UNSPECIFIED_DATE)
    {
      return branchPoint;
    }

    if (session.isSticky())
    {
      branchPoint = session.getCommittedSinceLastRefresh(id);
      if (branchPoint == null)
      {
        branchPoint = getBranch().getPoint(session.getLastUpdateTime());
      }

      return branchPoint;
    }

    return this;
  }

  @Override
  public void prefetchRevisions(CDOID id, int depth)
  {
    checkArg(depth != CDORevision.DEPTH_NONE, "Prefetch depth must not be zero"); //$NON-NLS-1$

    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
        prefetchRevisions(id, depth, initialChunkSize);
      }
      finally
      {
        unlockView();
      }
    }
  }

  protected void prefetchRevisions(CDOID id, int depth, int initialChunkSize)
  {
    CDORevisionManager revisionManager = session.getRevisionManager();
    revisionManager.getRevision(id, this, initialChunkSize, depth, true);
  }

  @Override
  @Deprecated
  public void invalidate(CDOBranch branch, long lastUpdateTime, List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects,
      Map<CDOID, InternalCDORevision> oldRevisions, boolean async)
  {
    throw new UnsupportedOperationException();
  }

  @Override
  @Deprecated
  public void invalidate(CDOBranch branch, long lastUpdateTime, List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects,
      Map<CDOID, InternalCDORevision> oldRevisions, boolean async, boolean clearResourcePathCache)
  {
    throw new UnsupportedOperationException();
  }

  /*
   * Must not by synchronized on the view!
   */
  @Override
  public void invalidate(ViewInvalidationData invalidationData)
  {
    if (invalidationData.isAsync())
    {
      ViewInvalidation work = new ViewInvalidation(invalidationData);
      invalidator.execute(work);
    }
    else
    {
      doInvalidate(invalidationData);
    }
  }

  protected void doInvalidate(ViewInvalidationData invalidationData)
  {
    long timeStamp = invalidationData.getLastUpdateTime();

    try
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          doInvalidateSynced(invalidationData);
        }
        finally
        {
          unlockView();
        }
      }

      commitInfoDistributor.distribute(timeStamp);
    }
    catch (RuntimeException | Error ex)
    {
      commitInfoDistributor.error(timeStamp, ex);
    }
  }

  private void doInvalidateSynced(ViewInvalidationData invalidationData)
  {
    if (invalidationData.getSecurityImpact() != CommitNotificationInfo.IMPACT_NONE)
    {
      CDOBranchPoint head = session.getBranchManager().getMainBranch().getHead();
      if (!head.equals(this))
      {
        throw new IllegalStateException("Security not supported with auditing or branching");
      }
    }

    if (getTimeStamp() != UNSPECIFIED_DATE && CDOStateMachine.SWITCHING_TARGET.get() != Boolean.TRUE)
    {
      // Don't invalidate historical views unless during a branch point switch.
      return;
    }

    long lastUpdateTime = invalidationData.getLastUpdateTime();

    try
    {
      // Also false for FailureCommitInfos (because of branch==null). Only setLastUpdateTime() is called below.
      if (invalidationData.getBranch() == getBranch())
      {
        if (invalidationData.isClearResourcePathCache())
        {
          clearResourcePathCacheIfNecessary(null);
        }

        List<CDORevisionDelta> deltas = new ArrayList<>();
        Map<CDOObject, CDORevisionDelta> revisionDeltas = new HashMap<>();
        Set<CDOObject> detachedObjects = new HashSet<>();
        Map<CDOID, InternalCDORevision> oldRevisions = invalidationData.getOldRevisions();
        if (oldRevisions == null)
        {
          oldRevisions = CDOIDUtil.createMap();
        }

        Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = invalidate( //
            invalidationData.getAllChangedObjects(), //
            invalidationData.getAllDetachedObjects(), //
            deltas, //
            revisionDeltas, //
            detachedObjects, //
            oldRevisions);

        handleConflicts(lastUpdateTime, conflicts, deltas);

        sendInvalidationNotifications(revisionDeltas.keySet(), detachedObjects);
        fireInvalidationEvent(lastUpdateTime, Collections.unmodifiableMap(revisionDeltas), Collections.unmodifiableSet(detachedObjects));

        // Then send the notifications. The deltas could have been modified by the conflict resolvers.
        if (!deltas.isEmpty() || !detachedObjects.isEmpty())
        {
          sendDeltaNotifications(deltas, detachedObjects, oldRevisions);
        }

        fireAdaptersNotifiedEvent(lastUpdateTime);

        CDOLockChangeInfo lockChangeInfo = invalidationData.getLockChangeInfo();
        if (lockChangeInfo != null)
        {
          updateLockStates(lockChangeInfo.getLockStates());
          fireLocksChangedEvent(null, lockChangeInfo);
        }
      }
    }
    catch (RuntimeException ex)
    {
      if (isActive())
      {
        fireEvent(new ThrowableEvent(this, ex));
        throw ex;
      }
    }
    finally
    {
      setLastUpdateTime(lastUpdateTime);
    }
  }

  public ViewInvalidator getInvalidator()
  {
    return invalidator;
  }

  @Override
  @Deprecated
  public boolean isInvalidationRunnerActive()
  {
    return isInvalidating();
  }

  @Override
  public boolean isInvalidating()
  {
    return invalidating;
  }

  private void sendInvalidationNotifications(Set<CDOObject> dirtyObjects, Set<CDOObject> detachedObjects)
  {
    if (options().isInvalidationNotificationEnabled())
    {
      for (CDOObject dirtyObject : dirtyObjects)
      {
        if (((InternalCDOObject)dirtyObject).eNotificationRequired())
        {
          CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(dirtyObject);
          dirtyObject.eNotify(notification);
        }
      }

      for (CDOObject detachedObject : detachedObjects)
      {
        if (((InternalCDOObject)detachedObject).eNotificationRequired())
        {
          CDOInvalidationNotificationImpl notification = new CDOInvalidationNotificationImpl(detachedObject);
          detachedObject.eNotify(notification);
        }
      }
    }
  }

  /**
   * @since 2.0
   */
  private void fireInvalidationEvent(long timeStamp, Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects)
  {
    if (!revisionDeltas.isEmpty() || !detachedObjects.isEmpty())
    {
      IListener[] listeners = getListeners();
      if (listeners != null)
      {
        fireEvent(new ViewInvalidationEvent(timeStamp, revisionDeltas, detachedObjects), listeners);
      }
    }
  }

  /**
   * @since 2.0
   */
  public void sendDeltaNotifications(Collection<CDORevisionDelta> deltas, Set<CDOObject> detachedObjects, Map<CDOID, InternalCDORevision> oldRevisions)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (deltas != null)
        {
          CDONotificationBuilder builder = new CDONotificationBuilder(this);
          Map<CDOID, InternalCDOObject> objects = getModifiableObjects();
          for (CDORevisionDelta delta : deltas)
          {
            CDOID id = delta.getID();
            InternalCDOObject object = objects.get(id);
            if (object != null && object.eNotificationRequired())
            {
              // if (!isLocked(object))
              {
                InternalCDORevision oldRevision = null;
                if (oldRevisions != null)
                {
                  oldRevision = oldRevisions.get(id);
                }

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

        if (detachedObjects != null && !detachedObjects.isEmpty())
        {
          if (options().isDetachmentNotificationEnabled())
          {
            for (CDOObject detachedObject : detachedObjects)
            {
              InternalCDOObject object = (InternalCDOObject)detachedObject;
              if (object.eNotificationRequired())
              {
                // if (!isLocked(object))
                {
                  new CDODeltaNotificationImpl(object, CDONotification.DETACH_OBJECT, null, null, null).dispatch();
                }
              }
            }
          }

          changeSubscriptionManager.handleDetachedObjects(detachedObjects);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * TODO For this method to be useable locks must be cached locally!
   */
  @SuppressWarnings("unused")
  private boolean isLocked(InternalCDOObject object)
  {
    if (object.cdoWriteLock().isLocked())
    {
      return true;
    }

    if (object.cdoReadLock().isLocked())
    {
      return true;
    }

    return false;
  }

  /**
   * @since 2.0
   */
  protected final AdapterManager getAdapterManager()
  {
    return adapterManager;
  }

  /**
   * @since 2.0
   */
  @Override
  public void handleAddAdapter(InternalCDOObject eObject, Adapter adapter)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (!FSMUtil.isNew(eObject))
        {
          subscribe(eObject, adapter);
        }

        adapterManager.attachAdapter(eObject, adapter);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (!FSMUtil.isNew(eObject))
        {
          unsubscribe(eObject, adapter);
        }

        adapterManager.detachAdapter(eObject, adapter);
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void subscribe(EObject eObject, Adapter adapter)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (changeSubscriptionManager != null)
        {
          changeSubscriptionManager.subscribe(eObject, adapter);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public void unsubscribe(EObject eObject, Adapter adapter)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (changeSubscriptionManager != null)
        {
          changeSubscriptionManager.unsubscribe(eObject, adapter);
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  public boolean hasSubscription(CDOID id)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (changeSubscriptionManager != null)
        {
          return changeSubscriptionManager.getSubcribeObject(id) != null;
        }

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

  /**
   * @since 2.0
   */
  protected final ChangeSubscriptionManager getChangeSubscriptionManager()
  {
    return changeSubscriptionManager;
  }

  @Override
  protected void listenerAdded(IListener listener)
  {
    if (listener instanceof CDOCommitInfoHandler)
    {
      CDOCommitInfoHandler handler = (CDOCommitInfoHandler)listener;
      commitInfoDistributor.register(handler);
    }
  }

  @Override
  protected void listenerRemoved(IListener listener)
  {
    if (listener instanceof CDOCommitInfoHandler)
    {
      CDOCommitInfoHandler handler = (CDOCommitInfoHandler)listener;
      commitInfoDistributor.deregister(handler);
    }
  }

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

  /**
   * @since 2.0
   */
  @Override
  protected void doBeforeActivate() throws Exception
  {
    super.doBeforeActivate();
    checkState(session, "session"); //$NON-NLS-1$
    checkState(viewID > 0, "viewID"); //$NON-NLS-1$
  }

  /**
   * @since 2.0
   */
  @Override
  protected void doActivate() throws Exception
  {
    super.doActivate();

    CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
    if (durableLockingID != null)
    {
      CDOBranchPoint branchPoint = sessionProtocol.openView(viewID, isReadOnly(), durableLockingID);
      basicSetBranchPoint(branchPoint);
    }
    else
    {
      sessionProtocol.openView(viewID, isReadOnly(), this);
    }

    CDOViewRegistryImpl.INSTANCE.register(this);

    Runnable runnable = SessionUtil.getTestDelayInViewActivation();
    if (runnable != null)
    {
      runnable.run();
    }

    lockOwner = CDOLockUtil.createLockOwner(this);

    if (viewLock != null && Boolean.getBoolean("org.eclipse.emf.cdo.sync.tester"))
    {
      new SyncTester().start();
    }

    unitManager.activate();
  }

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

    ExecutorService executorService = getExecutorService();
    invalidator.setDelegate(executorService);

    try
    {
      LifecycleUtil.activate(invalidator);
    }
    catch (LifecycleException ex)
    {
      // Don't pollute the log if the worker thread is interrupted due to asynchronous view.close()
      if (!(ex.getCause() instanceof InterruptedException))
      {
        throw ex;
      }
    }
  }

  @Override
  protected void doBeforeDeactivate() throws Exception
  {
    // Detach the view set from the view.
    InternalCDOViewSet viewSet = getViewSet();
    viewSet.remove(this);

    CDOAdapterPolicy clearAdapterPolicy = options.getClearAdapterPolicy();
    if (clearAdapterPolicy == null)
    {
      clearAdapterPolicy = viewSet.getDefaultClearAdapterPolicy();
    }

    if (clearAdapterPolicy != null && clearAdapterPolicy != CDOAdapterPolicy.NONE)
    {
      clearAdapters(clearAdapterPolicy);
    }

    super.doBeforeDeactivate();
  }

  /**
   * @since 2.0
   */
  @Override
  protected void doDeactivate() throws Exception
  {
    unitManager.deactivate();
    commitInfoDistributor.deactivate();

    CDOViewRegistryImpl.INSTANCE.deregister(this);
    LifecycleUtil.deactivate(invalidator, OMLogger.Level.WARN);

    try
    {
      CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
      if (LifecycleUtil.isActive(sessionProtocol))
      {
        sessionProtocol.closeView(viewID);
      }
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
    }
    finally
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (session.isActive() && !lockStates.isEmpty())
          {
            List<CDOLockState> result = new ArrayList<>();
            for (CDOLockState lockState : lockStates.values())
            {
              if (((InternalCDOLockState)lockState).removeOwner(lockOwner))
              {
                result.add(lockState);
              }
            }

            if (!result.isEmpty())
            {
              CDOLockState[] deactivateLockStates = result.toArray(new CDOLockState[result.size()]);
              long timeStamp = session.getLastUpdateTime();
              notifyOtherViewsAboutLockChanges(Operation.UNLOCK, null, timeStamp, deactivateLockStates);
            }

            lockStates.clear();
            lockOwner = null;
          }
        }
        finally
        {
          unlockView();
        }
      }
    }

    try
    {
      session.viewDetached(this);
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
    }

    changeSubscriptionManager = null;
    super.doDeactivate();
  }

  private void clearAdapters(CDOAdapterPolicy adapterPolicy)
  {
    try
    {
      for (CDOObject object : getModifiableObjects().values())
      {
        EList<Adapter> adapters = object.eAdapters();
        if (!adapters.isEmpty())
        {
          for (Iterator<Adapter> it = adapters.iterator(); it.hasNext();)
          {
            Adapter adapter = it.next();
            if (adapter instanceof CDOObjectWrapperBase)
            {
              // Don't remove a legacy adapter because otherwise references to this CDOObject will break.
              continue;
            }

            boolean validAdapter;

            try
            {
              validAdapter = adapterPolicy.isValid(object, adapter);
            }
            catch (Exception ex)
            {
              OM.LOG.error(ex);
              continue;
            }

            if (validAdapter)
            {
              try
              {
                it.remove();
              }
              catch (Exception ex)
              {
                OM.LOG.error(ex);
              }
            }
          }
        }
      }
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
    }
  }

  @Override
  public long getLastUpdateTime()
  {
    synchronized (getViewMonitor())
    {
      lockView(); // TODO ???

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

  @Override
  public void setLastUpdateTime(long lastUpdateTime)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        if (this.lastUpdateTime < lastUpdateTime)
        {
          this.lastUpdateTime = lastUpdateTime;
        }

        if (viewLockCondition != null)
        {
          viewLockCondition.signalAll();
        }
        else
        {
          notifyAll();
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public boolean waitForUpdate(long updateTime, long timeoutMillis)
  {
    long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        for (;;)
        {
          if (lastUpdateTime >= updateTime)
          {
            return true;
          }

          long now = System.currentTimeMillis();
          if (now >= end)
          {
            return false;
          }

          try
          {
            long waitMillis = end - now;

            if (viewLockCondition != null)
            {
              viewLockCondition.await(waitMillis, TimeUnit.MILLISECONDS);
            }
            else
            {
              wait(waitMillis);
            }
          }
          catch (InterruptedException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
      }
      finally
      {
        unlockView();
      }
    }
  }

  @Override
  public boolean runAfterUpdate(final long updateTime, final Runnable runnable)
  {
    synchronized (getViewMonitor())
    {
      lockView();

      try
      {
        long lastUpdateTime = getLastUpdateTime();
        if (lastUpdateTime < updateTime)
        {
          addListener(new IListener()
          {
            @Override
            public void notifyEvent(IEvent event)
            {
              if (event instanceof CDOViewInvalidationEvent)
              {
                CDOViewInvalidationEvent e = (CDOViewInvalidationEvent)event;
                if (e.getTimeStamp() >= updateTime)
                {
                  removeListener(this);
                  runnable.run();
                }
              }
            }
          });

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

    runnable.run();
    return true;
  }

  @Override
  public void resourceLoaded(CDOResourceImpl resource, boolean loaded)
  {
    if (session.getRepositoryInfo().isSupportingUnits())
    {
      unitManager.resourceLoaded(resource, loaded);
    }
  }

  @Override
  public final CDOUnitManagerImpl getUnitManager()
  {
    return unitManager;
  }

  public static Object getLockTarget(CDOObject object)
  {
    CDOView view = object.cdoView();
    if (view == null)
    {
      return null;
    }

    CDOID id = object.cdoID();
    return getLockTarget(view, id);
  }

  public static Object getLockTarget(CDOView view, CDOID id)
  {
    if (view.getSession().getRepositoryInfo().isSupportingBranches())
    {
      return CDOIDUtil.createIDAndBranch(id, view.getBranch());
    }

    return id;
  }

  /**
   * @author Eike Stepper
   */
  public final class CDOUnitManagerImpl extends Container<CDOUnit> implements CDOUnitManager
  {
    private final Map<EObject, CDOUnit> unitPerRoot = new HashMap<>();

    private final Map<EObject, CDOUnit> unitPerObject = new HashMap<>();

    private CDOUnitImpl openingUnit;

    private Set<CDOID> openingIDs;

    private Map<CDOResource, CDOUnit> resourceUnits;

    public CDOUnitManagerImpl()
    {
    }

    @Override
    public CDOView getView()
    {
      return CDOViewImpl.this;
    }

    @Override
    public boolean isUnit(EObject root)
    {
      CDOUnitImpl unit = requestUnit(root, UnitOpcode.CHECK, null);
      return unit != null;
    }

    @Override
    public CDOUnit createUnit(EObject root, boolean open, IProgressMonitor monitor) throws UnitExistsException
    {
      UnitOpcode opcode = open ? UnitOpcode.CREATE_AND_OPEN : UnitOpcode.CREATE;

      CDOUnitImpl unit = requestUnit(root, opcode, monitor);

      if (open)
      {
        if (unit == null)
        {
          throw new UnitExistsException();
        }

        fireElementAddedEvent(unit);
      }

      return unit;
    }

    @Override
    public CDOUnit openUnit(EObject root, boolean createOnDemand, IProgressMonitor monitor) throws UnitNotFoundException
    {
      UnitOpcode opcode = createOnDemand ? UnitOpcode.OPEN_DEMAND_CREATE : UnitOpcode.OPEN;

      CDOUnitImpl unit = requestUnit(root, opcode, monitor);
      if (unit == null)
      {
        throw new UnitNotFoundException();
      }

      fireElementAddedEvent(unit);
      return unit;
    }

    @Override
    public CDOUnit[] getElements()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return unitPerRoot.values().toArray(new CDOUnit[unitPerRoot.size()]);
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public CDOUnit[] getOpenUnits()
    {
      return getElements();
    }

    @Override
    public CDOUnit getOpenUnit(EObject object)
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return getOpenUnitUnsynced(object);
        }
        finally
        {
          unlockView();
        }
      }
    }

    public CDOUnit getOpenUnitUnsynced(EObject object)
    {
      CDOUnit unit = unitPerObject.get(object);
      if (unit == null && openingUnit != null)
      {
        CDOObject cdoObject = CDOUtil.getCDOObject(object);
        if (cdoObject != null)
        {
          CDOID id = cdoObject.cdoID();
          if (openingIDs.contains(id))
          {
            unit = openingUnit;
          }
        }
      }

      return unit;
    }

    public void addObject(InternalCDOObject object)
    {
      if (!unitPerRoot.isEmpty())
      {
        CDOUnit unit = getOpenUnitUnsynced(object);
        if (unit == null)
        {
          EObject parent = getParent(object);
          EObject rootResource = getRootResource();

          while (parent != null && parent != rootResource)
          {
            unit = getOpenUnitUnsynced(parent);
            if (unit != null)
            {
              unitPerObject.put(object, unit);
              ++((CDOUnitImpl)unit).elements;
              break;
            }

            parent = getParent(parent);
          }
        }
      }
    }

    public void removeObject(InternalCDOObject object)
    {
      if (!unitPerRoot.isEmpty())
      {
        CDOUnit unit = unitPerObject.remove(object);
        if (unit != null)
        {
          if (unit.getRoot() == object)
          {
            unitPerRoot.remove(object);
          }

          --((CDOUnitImpl)unit).elements;
        }
      }
    }

    @Override
    public synchronized boolean isAutoResourceUnitsEnabled()
    {
      return resourceUnits != null;
    }

    @Override
    public synchronized void setAutoResourceUnitsEnabled(boolean enabled)
    {
      if (enabled)
      {
        resourceUnits = new HashMap<>();
      }
      else
      {
        resourceUnits = null;
      }
    }

    public synchronized void resourceLoaded(CDOResourceImpl resource, boolean loaded)
    {
      if (resourceUnits != null)
      {
        if (loaded)
        {
          loadResource(resource);
        }
        else
        {
          unloadResource(resource);
        }
      }
    }

    @Override
    protected void doDeactivate() throws Exception
    {
      unitPerRoot.clear();
      unitPerObject.clear();
      super.doDeactivate();
    }

    private void loadResource(CDOResource resource)
    {
      CDOUnit unit = resourceUnits.get(resource);
      if (unit == null)
      {
        CDOUnitManager unitManager = resource.cdoView().getUnitManager();
        unit = unitManager.openUnit(resource, true, null);
        resourceUnits.put(resource, unit);
      }
    }

    private void unloadResource(CDOResource resource)
    {
      CDOUnit unit = resourceUnits.remove(resource);
      if (unit != null)
      {
        unit.close();
      }
    }

    private EObject getParent(EObject object)
    {
      EObject parent = object.eContainer();
      if (parent == null)
      {
        parent = (EObject)((InternalEObject)object).eDirectResource();
      }

      return parent;
    }

    private CDOObject getCDORoot(EObject root)
    {
      CDOObject cdoRoot = CDOUtil.getCDOObject(root);
      if (cdoRoot == null)
      {
        throw new IllegalArgumentException("Root " + root + " is not managed by CDO");
      }

      CDOView view = cdoRoot.cdoView();
      if (view != CDOViewImpl.this)
      {
        throw new IllegalArgumentException("Root " + root + " is managed by " + view);
      }

      return cdoRoot;
    }

    private CDOUnitImpl requestUnit(EObject root, UnitOpcode opcode, IProgressMonitor monitor)
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (opcode.isCreate())
          {
            CDOUnit containingUnit = getOpenUnit(root);
            if (containingUnit != null)
            {
              throw new CDOException("Attempt to nest the new unit " + root + " in the existing unit " + containingUnit);
            }

            for (CDOUnit existingUnit : unitPerRoot.values())
            {
              if (EcoreUtil.isAncestor(root, existingUnit.getRoot()))
              {
                throw new CDOException("Attempt to nest the existing unit " + existingUnit + " in the new unit " + root);
              }
            }
          }

          final InternalCDORevisionManager revisionManager = session.getRevisionManager();
          openingUnit = new CDOUnitImpl(root);

          int viewID = getViewID();
          CDOID rootID = getCDORoot(root).cdoID();

          CDORevisionHandler revisionHandler = null;
          final List<CDORevision> revisions = new ArrayList<>();

          if (opcode.isOpen())
          {
            openingIDs = new HashSet<>();

            revisionHandler = new CDORevisionHandler()
            {
              @Override
              public boolean handleRevision(CDORevision revision)
              {
                ++openingUnit.elements;
                revisionManager.addRevision(revision);
                revisions.add(revision);

                CDOID id = revision.getID();
                changeSubscriptionManager.removeEntry(id);
                openingIDs.add(id);

                return true;
              }
            };
          }

          CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
          boolean success = sessionProtocol.requestUnit(viewID, rootID, opcode, revisionHandler, EclipseMonitor.safe(monitor));

          if (success)
          {
            if (revisionHandler != null)
            {
              unitPerRoot.put(root, openingUnit);
              unitPerObject.put(root, openingUnit);

              for (CDORevision revision : revisions)
              {
                CDOID id = revision.getID();

                InternalCDOObject object = getObject(id);
                unitPerObject.put(object, openingUnit);
              }
            }

            return openingUnit;
          }

          return null;
        }
        finally
        {
          openingUnit = null;
          openingIDs = null;
          unlockView();
        }
      }
    }

    private void closeUnit(CDOUnit unit, boolean resubscribe)
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          requestUnit(unit.getRoot(), UnitOpcode.CLOSE, null);

          if (resubscribe && !options.hasChangeSubscriptionPolicies())
          {
            resubscribe = false;
          }

          for (Iterator<Entry<EObject, CDOUnit>> it = unitPerObject.entrySet().iterator(); it.hasNext();)
          {
            Entry<EObject, CDOUnit> entry = it.next();
            if (entry.getValue() == unit)
            {
              it.remove(); // Remove the object from its unit first, so that shouldSubscribe() can return true.

              if (resubscribe)
              {
                EObject object = entry.getKey();
                for (Adapter adapter : object.eAdapters())
                {
                  changeSubscriptionManager.subscribe(object, adapter);
                }
              }
            }
          }

          unitPerRoot.remove(unit.getRoot());
        }
        finally
        {
          unlockView();
        }
      }

      fireElementRemovedEvent(unit);
    }

    /**
     * @author Eike Stepper
     */
    public final class CDOUnitImpl implements CDOUnit
    {
      private final EObject root;

      private int elements;

      public CDOUnitImpl(EObject root)
      {
        this.root = root;
      }

      @Override
      public CDOUnitManagerImpl getManager()
      {
        return CDOUnitManagerImpl.this;
      }

      @Override
      public EObject getRoot()
      {
        return root;
      }

      @Override
      public int getElements()
      {
        return elements;
      }

      @Override
      public void close()
      {
        close(true);
      }

      @Override
      public void close(boolean resubscribe)
      {
        closeUnit(this, resubscribe);
      }

      @Override
      public String toString()
      {
        return "CDOUnit[" + root + "]";
      }
    }
  }

  /**
   * @author Simon McDuff
   * @since 2.0
   */
  protected final class AdapterManager
  {
    private Set<CDOObject> objects = new HashBag<>();

    public AdapterManager()
    {
    }

    public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
    {
      if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE)
      {
        for (CDOObject object : commitContext.getNewObjects().values())
        {
          attachObject(object);
        }

        for (CDOObject object : commitContext.getDetachedObjects().values())
        {
          detachObject(object);
        }
      }
    }

    private void attachObject(CDOObject object)
    {
      if (((InternalEObject)object).eNotificationRequired())
      {
        CDOAdapterPolicy strongReferencePolicy = options().getStrongReferencePolicy();
        int count = 0;
        for (Adapter adapter : object.eAdapters())
        {
          if (strongReferencePolicy.isValid(object, adapter))
          {
            count++;
          }
        }

        for (int i = 0; i < count; i++)
        {
          objects.add(object);
        }
      }
    }

    private void detachObject(CDOObject object)
    {
      while (objects.remove(object))
      {
        // Do nothing
      }
    }

    private void attachAdapter(CDOObject object, Adapter adapter)
    {
      if (options().getStrongReferencePolicy().isValid(object, adapter))
      {
        objects.add(object);
      }
    }

    private void detachAdapter(CDOObject object, Adapter adapter)
    {
      if (options().getStrongReferencePolicy().isValid(object, adapter))
      {
        objects.remove(object);
      }
    }

    private void reset()
    {
      // Keep the objects in memory
      Set<CDOObject> oldObjects = objects;
      objects = new HashBag<>();
      if (options().getStrongReferencePolicy() != CDOAdapterPolicy.NONE)
      {
        for (InternalCDOObject object : getObjectsList())
        {
          attachObject(object);
        }
      }

      oldObjects.clear();
    }
  }

  /**
   * @author Simon McDuff
   * @since 2.0
   */
  protected final class ChangeSubscriptionManager
  {
    private Map<CDOID, SubscribeEntry> subscriptions = CDOIDUtil.createMap();

    public ChangeSubscriptionManager()
    {
    }

    public void committedTransaction(CDOTransaction transaction, CDOCommitContext commitContext)
    {
      handleNewObjects(commitContext.getNewObjects().values());
      handleDetachedObjects(commitContext.getDetachedObjects().values());
    }

    private boolean hasSubscriptions()
    {
      return !subscriptions.isEmpty();
    }

    private void subscribe(EObject eObject, Adapter adapter)
    {
      subscribe(eObject, adapter, 1);
    }

    private void unsubscribe(EObject eObject, Adapter adapter)
    {
      subscribe(eObject, adapter, -1);
    }

    /**
     * Register to the server all objects from the active list
     */
    private void handleChangeSubcriptionPoliciesChanged()
    {
      boolean policiesPresent = options().hasChangeSubscriptionPolicies();
      subscriptions.clear();

      List<CDOID> ids = new ArrayList<>();
      if (policiesPresent)
      {
        for (InternalCDOObject object : getObjectsList())
        {
          int count = getNumberOfValidAdapters(object);
          if (count > 0)
          {
            ids.add(object.cdoID());
            addEntry(object.cdoID(), object, count);
          }
        }
      }

      request(ids, true, true);
    }

    private void handleDetachedObjects(Collection<CDOObject> detachedObjects)
    {
      for (CDOObject detachedObject : detachedObjects)
      {
        CDOID id = detachedObject.cdoID();
        SubscribeEntry entry = subscriptions.get(id);
        if (entry != null)
        {
          detachObject(id);
        }
      }
    }

    private void handleNewObjects(Collection<? extends CDOObject> newObjects)
    {
      for (CDOObject object : newObjects)
      {
        InternalCDOObject internalObject = (InternalCDOObject)object;
        if (internalObject != null)
        {
          int count = getNumberOfValidAdapters(internalObject);
          if (count > 0)
          {
            subscribe(internalObject.cdoID(), internalObject, count);
          }
        }
      }
    }

    private InternalCDOObject getSubcribeObject(CDOID id)
    {
      SubscribeEntry entry = subscriptions.get(id);
      if (entry != null)
      {
        return entry.getObject();
      }

      return null;
    }

    private void request(List<CDOID> ids, boolean clear, boolean subscribeMode)
    {
      CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
      sessionProtocol.changeSubscription(getViewID(), ids, subscribeMode, clear);
    }

    private int getNumberOfValidAdapters(InternalCDOObject object)
    {
      int count = 0;
      if (!FSMUtil.isTransient(object) && !FSMUtil.isNew(object))
      {
        if (object.eNotificationRequired())
        {
          EObject instance = CDOUtil.getEObject(object);
          for (Adapter adapter : instance.eAdapters())
          {
            if (shouldSubscribe(object, adapter))
            {
              ++count;
            }
          }
        }
      }

      return count;
    }

    private void subscribe(EObject eObject, Adapter adapter, int adjust)
    {
      if (shouldSubscribe(eObject, adapter))
      {
        CDOView view = CDOViewImpl.this;
        InternalCDOObject internalCDOObject = FSMUtil.adapt(eObject, view);
        if (internalCDOObject.cdoView() != view)
        {
          throw new CDOException(MessageFormat.format(Messages.getString("CDOViewImpl.27"), internalCDOObject)); //$NON-NLS-1$
        }

        subscribe(internalCDOObject.cdoID(), internalCDOObject, adjust);
      }
    }

    private boolean shouldSubscribe(EObject eObject, Adapter adapter)
    {
      if (adapter instanceof CDOLocalAdapter)
      {
        return false;
      }

      if (unitManager.getOpenUnitUnsynced(eObject) != null)
      {
        return false;
      }

      for (CDOAdapterPolicy policy : options().getChangeSubscriptionPolicies())
      {
        if (policy.isValid(eObject, adapter))
        {
          return true;
        }
      }

      return false;
    }

    private void subscribe(CDOID id, InternalCDOObject cdoObject, int adjust)
    {
      boolean policiesPresent = options().hasChangeSubscriptionPolicies();

      int count = 0;
      SubscribeEntry entry = subscriptions.get(id);
      if (entry == null)
      {
        // Cannot adjust negative value
        if (adjust < 0)
        {
          return;
        }

        // Notification need to be enable to send correct value to the server
        if (policiesPresent)
        {
          request(Collections.singletonList(id), false, true);
        }
      }
      else
      {
        count = entry.getCount();
      }

      count += adjust;

      // Look if objects need to be unsubscribe
      if (count <= 0)
      {
        removeEntry(id);

        // Notification need to be enable to send correct value to the server
        if (policiesPresent)
        {
          request(Collections.singletonList(id), false, false);
        }
      }
      else
      {
        if (entry == null)
        {
          addEntry(id, cdoObject, count);
        }
        else
        {
          entry.setCount(count);
        }
      }
    }

    private void detachObject(CDOID id)
    {
      subscribe(id, null, Integer.MIN_VALUE);
    }

    private void addEntry(CDOID id, InternalCDOObject object, int count)
    {
      subscriptions.put(id, new SubscribeEntry(object, count));
    }

    private void removeEntry(CDOID id)
    {
      subscriptions.remove(id);
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class SubscribeEntry
  {
    private final InternalCDOObject object;

    private int count;

    public SubscribeEntry(InternalCDOObject object, int count)
    {
      this.object = object;
      this.count = count;
    }

    public InternalCDOObject getObject()
    {
      return object;
    }

    public int getCount()
    {
      return count;
    }

    public void setCount(int count)
    {
      this.count = count;
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class ViewInvalidator extends SerializingExecutor
  {
  }

  /**
   * @author Eike Stepper
   */
  private final class ViewInvalidation extends RunnableWithName
  {
    private final ViewInvalidationData invalidationData;

    public ViewInvalidation(ViewInvalidationData invalidationData)
    {
      this.invalidationData = invalidationData;
    }

    @Override
    public String getName()
    {
      return "Invalidator-" + CDOViewImpl.this; //$NON-NLS-1$
    }

    @Override
    protected void doRun()
    {
      try
      {
        invalidating = true;
        doInvalidate(invalidationData);
      }
      catch (Exception ex)
      {
        if (isActive())
        {
          OM.LOG.error(ex);
        }
      }
      finally
      {
        invalidating = false;
      }
    }
  }

  /**
   * @author Simon McDuff
   */
  private final class ViewInvalidationEvent extends Event implements CDOViewInvalidationEvent
  {
    private static final long serialVersionUID = 1L;

    private long timeStamp;

    private Map<CDOObject, CDORevisionDelta> revisionDeltas;

    private Set<CDOObject> detachedObjects;

    public ViewInvalidationEvent(long timeStamp, Map<CDOObject, CDORevisionDelta> revisionDeltas, Set<CDOObject> detachedObjects)
    {
      this.timeStamp = timeStamp;
      this.revisionDeltas = revisionDeltas;
      this.detachedObjects = detachedObjects;
    }

    @Override
    public long getTimeStamp()
    {
      return timeStamp;
    }

    @Override
    public Set<CDOObject> getDirtyObjects()
    {
      return revisionDeltas.keySet();
    }

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

    @Override
    public Set<CDOObject> getDetachedObjects()
    {
      return detachedObjects;
    }

    @Override
    protected String formatEventName()
    {
      return "CDOViewInvalidationEvent";
    }

    @Override
    protected String formatAdditionalParameters()
    {
      return "timeStamp=" + timeStamp + ", revisionDeltas=" + revisionDeltas + ", detachedObjects=" + detachedObjects + "]";
    }
  }

  /**
   * @author Caspar De Groot
   * @since 4.1
   */
  private final class ViewLocksChangedEvent extends DefaultLocksChangedEvent implements CDOViewLocksChangedEvent
  {
    private static final long serialVersionUID = 1L;

    public ViewLocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
    {
      super(CDOViewImpl.this, sender, lockChangeInfo);
    }

    @Override
    public InternalCDOView getSource()
    {
      return (InternalCDOView)super.getSource();
    }

    @Override
    public EObject[] getAffectedObjects()
    {
      List<EObject> objects = new ArrayList<>();
      CDOView view = getSource();

      CDOLockState[] lockStates = getLockStates();
      for (int i = 0; i < lockStates.length; i++)
      {
        CDOLockState lockState = lockStates[i];
        Object lockedObject = lockState.getLockedObject();

        CDOID id = null;
        if (lockedObject instanceof CDOIDAndBranch)
        {
          CDOIDAndBranch idAndBranch = (CDOIDAndBranch)lockedObject;
          if (idAndBranch.getBranch().getID() == view.getBranch().getID())
          {
            id = idAndBranch.getID();
          }
        }
        else if (lockedObject instanceof CDOID)
        {
          id = (CDOID)lockedObject;
        }

        if (id != null)
        {
          CDOObject object = view.getObject(id, false);
          if (object != null)
          {
            objects.add(CDOUtil.getEObject(object));
          }
        }
      }

      return objects.toArray(new EObject[objects.size()]);
    }

    @Override
    protected String formatEventName()
    {
      return "CDOViewLocksChangedEvent";
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class CommitInfoDistributor implements IListener, IDeactivateable
  {
    private final ConcurrentArray<CDOCommitInfoHandler> handlers = new ConcurrentArray<CDOCommitInfoHandler>()
    {
      @Override
      protected CDOCommitInfoHandler[] newArray(int length)
      {
        return new CDOCommitInfoHandler[length];
      }

      @Override
      protected void firstElementAdded()
      {
        getSession().addListener(CommitInfoDistributor.this);
      }

      @Override
      protected void lastElementRemoved()
      {
        getSession().removeListener(CommitInfoDistributor.this);
        deactivate();
      }
    };

    private final Map<Long, CDOCommitInfo> commitInfos = new ConcurrentHashMap<>();

    public CommitInfoDistributor()
    {
    }

    @Override
    public Exception deactivate()
    {
      commitInfos.clear();
      return null;
    }

    public void register(CDOCommitInfoHandler handler)
    {
      CheckUtil.checkArg(handler, "handler"); //$NON-NLS-1$
      handlers.add(handler);
    }

    public void deregister(CDOCommitInfoHandler handler)
    {
      CheckUtil.checkArg(handler, "handler"); //$NON-NLS-1$
      handlers.remove(handler);
    }

    @Override
    public void notifyEvent(IEvent event)
    {
      if (event instanceof CDOSessionInvalidationEvent)
      {
        CDOSessionInvalidationEvent e = (CDOSessionInvalidationEvent)event;
        commitInfos.put(e.getTimeStamp(), e);
      }
    }

    public void error(long timeStamp, Throwable t)
    {
      commitInfos.remove(timeStamp);
    }

    public void distribute(long timeStamp)
    {
      CDOCommitInfo commitInfo = commitInfos.remove(timeStamp);
      if (commitInfo != null)
      {
        distributeSafe(commitInfo, handlers.get());
      }
    }

    private void distributeSafe(CDOCommitInfo commitInfo, CDOCommitInfoHandler[] handlers)
    {
      if (handlers != null)
      {
        ObjectUtil.forEachSafe(handlers, handler -> handler.handleCommitInfo(commitInfo));
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class SyncTester extends Thread
  {
    private final CountDownLatch latch = new CountDownLatch(1);

    public SyncTester()
    {
      super(CDOViewImpl.this + "-sync-tester");
      setDaemon(true);
    }

    @Override
    public void run()
    {
      addListener(new LifecycleEventAdapter()
      {
        @Override
        protected void onAboutToDeactivate(ILifecycle lifecycle)
        {
          latch.countDown();
        }
      });

      synchronized (CDOViewImpl.this)
      {
        try
        {
          latch.await();
        }
        catch (InterruptedException ex)
        {
          return;
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   * @since 2.0
   */
  public class OptionsImpl extends Notifier implements Options
  {
    private boolean loadNotificationEnabled;

    private boolean detachmentNotificationEnabled;

    private boolean invalidationNotificationEnabled;

    private CDOInvalidationPolicy invalidationPolicy = CDOInvalidationPolicy.DEFAULT;

    private boolean lockNotificationsEnabled;

    /**
     * See bug 568778.
     */
    @Deprecated
    private CDOLockStatePrefetcher lockStatePrefetcher;

    private CDORevisionPrefetchingPolicy revisionPrefetchingPolicy = CDOUtil.createRevisionPrefetchingPolicy(NO_REVISION_PREFETCHING);

    private CDOFeatureAnalyzer featureAnalyzer = CDOFeatureAnalyzer.NOOP;

    private CDOStaleReferencePolicy staleReferencePolicy = CDOStaleReferencePolicy.DEFAULT;

    private HashBag<CDOAdapterPolicy> changeSubscriptionPolicies = new HashBag<>();

    private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL;

    private CDOAdapterPolicy clearAdapterPolicy;

    public OptionsImpl()
    {
    }

    public void recoverView()
    {
      if (lockNotificationsEnabled)
      {
        CDOSessionProtocol protocol = session.getSessionProtocol();
        protocol.enableLockNotifications(viewID, true);
      }

      if (changeSubscriptionManager.hasSubscriptions())
      {
        changeSubscriptionManager.handleChangeSubcriptionPoliciesChanged();
      }

      // TODO unitManager.recoverView();
    }

    @Override
    public CDOViewImpl getContainer()
    {
      return CDOViewImpl.this;
    }

    @Override
    public boolean isLoadNotificationEnabled()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setLoadNotificationEnabled(boolean enabled)
    {
      checkActive();

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

        try
        {
          if (loadNotificationEnabled != enabled)
          {
            loadNotificationEnabled = enabled;
            event = new LoadNotificationEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public boolean isDetachmentNotificationEnabled()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setDetachmentNotificationEnabled(boolean enabled)
    {
      checkActive();

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

        try
        {
          if (detachmentNotificationEnabled != enabled)
          {
            detachmentNotificationEnabled = enabled;
            event = new DetachmentNotificationEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public boolean isInvalidationNotificationEnabled()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setInvalidationNotificationEnabled(boolean enabled)
    {
      checkActive();

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

        try
        {
          if (invalidationNotificationEnabled != enabled)
          {
            invalidationNotificationEnabled = enabled;
            event = new InvalidationNotificationEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDOInvalidationPolicy getInvalidationPolicy()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setInvalidationPolicy(CDOInvalidationPolicy policy)
    {
      checkActive();

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

        try
        {
          if (invalidationPolicy != policy)
          {
            invalidationPolicy = policy;
            event = new InvalidationPolicyEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public boolean isLockNotificationEnabled()
    {
      return lockNotificationsEnabled;
    }

    @Override
    public void setLockNotificationEnabled(boolean enabled)
    {
      checkActive();

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

        try
        {
          if (enabled != lockNotificationsEnabled)
          {
            CDOSessionProtocol protocol = session.getSessionProtocol();
            protocol.enableLockNotifications(viewID, enabled);
            lockNotificationsEnabled = enabled;
            event = new LockNotificationEventImpl(enabled);
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    /**
     * @deprecated As of 4.12 use {@link CDOLockStatePrefetcher}, see bug 568778.
     */
    @Deprecated
    public boolean isLockStatePrefetchEnabled()
    {
      return lockStatePrefetcher != null;
    }

    /**
     * @deprecated As of 4.12 use {@link CDOLockStatePrefetcher}, see bug 568778.
     */
    @Deprecated
    public void setLockStatePrefetchEnabled(boolean enabled)
    {
      checkActive();

      if (enabled)
      {
        if (lockStatePrefetcher == null)
        {
          lockStatePrefetcher = new CDOLockStatePrefetcher(CDOViewImpl.this, false);
        }
      }
      else
      {
        if (lockStatePrefetcher != null)
        {
          lockStatePrefetcher.dispose();
          lockStatePrefetcher = null;
        }
      }
    }

    /**
     * @deprecated As of 4.12 use {@link CDOLockStatePrefetcher#getObjectFilter()}, see bug 568778.
     */
    @Deprecated
    public CDOLockStateLoadingPolicy getLockStateLoadingPolicy()
    {
      return new CDOLockStateLoadingPolicy()
      {
        @Override
        public boolean loadLockState(CDOID id)
        {
          Predicate<CDOID> filter = lockStatePrefetcher == null ? CDOLockStatePrefetcher.DEFAULT_OBJECT_FILTER : lockStatePrefetcher.getObjectFilter();
          return filter.test(id);
        }
      };
    }

    /**
     * @deprecated As of 4.12 use {@link CDOLockStatePrefetcher#setObjectFilter(java.util.function.Predicate)}, see bug 568778.
     */
    @Deprecated
    @SuppressWarnings("deprecation")
    public void setLockStateLoadingPolicy(CDOLockStateLoadingPolicy lockStateLoadingPolicy)
    {
      checkActive();
      if (lockStatePrefetcher == null)
      {
        lockStatePrefetcher = new CDOLockStatePrefetcher(CDOViewImpl.this, false);
      }

      lockStatePrefetcher.setObjectFilter(id -> lockStateLoadingPolicy.loadLockState(id));
    }

    public boolean hasChangeSubscriptionPolicies()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return !changeSubscriptionPolicies.isEmpty();
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public CDOAdapterPolicy[] getChangeSubscriptionPolicies()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          return changeSubscriptionPolicies.toArray(new CDOAdapterPolicy[changeSubscriptionPolicies.size()]);
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public void addChangeSubscriptionPolicy(CDOAdapterPolicy policy)
    {
      checkActive();

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

        try
        {
          if (changeSubscriptionPolicies.add(policy))
          {
            changeSubscriptionManager.handleChangeSubcriptionPoliciesChanged();
            event = new ChangeSubscriptionPoliciesEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public void removeChangeSubscriptionPolicy(CDOAdapterPolicy policy)
    {
      checkActive();

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

        try
        {
          if (changeSubscriptionPolicies.remove(policy) && !changeSubscriptionPolicies.contains(policy))
          {
            changeSubscriptionManager.handleChangeSubcriptionPoliciesChanged();
            event = new ChangeSubscriptionPoliciesEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDOAdapterPolicy getStrongReferencePolicy()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setStrongReferencePolicy(CDOAdapterPolicy adapterPolicy)
    {
      checkActive();

      if (adapterPolicy == null)
      {
        adapterPolicy = CDOAdapterPolicy.ALL;
      }

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

        try
        {
          if (strongReferencePolicy != adapterPolicy)
          {
            strongReferencePolicy = adapterPolicy;
            adapterManager.reset();
            event = new ReferencePolicyEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setRevisionPrefetchingPolicy(CDORevisionPrefetchingPolicy prefetchingPolicy)
    {
      checkActive();

      if (prefetchingPolicy == null)
      {
        prefetchingPolicy = CDORevisionPrefetchingPolicy.NO_PREFETCHING;
      }

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

        try
        {
          if (revisionPrefetchingPolicy != prefetchingPolicy)
          {
            revisionPrefetchingPolicy = prefetchingPolicy;
            event = new RevisionPrefetchingPolicyEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public CDOFeatureAnalyzer getFeatureAnalyzer()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer)
    {
      checkActive();

      if (featureAnalyzer == null)
      {
        featureAnalyzer = CDOFeatureAnalyzer.NOOP;
      }

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

        try
        {
          if (this.featureAnalyzer != featureAnalyzer)
          {
            this.featureAnalyzer = featureAnalyzer;
            event = new FeatureAnalyzerEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    @Deprecated
    public CDOStaleReferencePolicy getStaleReferenceBehaviour()
    {
      return getStaleReferencePolicy();
    }

    @Override
    @Deprecated
    public void setStaleReferenceBehaviour(CDOStaleReferencePolicy policy)
    {
      setStaleReferencePolicy(policy);
    }

    @Override
    public CDOStaleReferencePolicy getStaleReferencePolicy()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setStaleReferencePolicy(CDOStaleReferencePolicy policy)
    {
      checkActive();

      if (policy == null)
      {
        policy = CDOStaleReferencePolicy.DEFAULT;
      }

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

        try
        {
          if (staleReferencePolicy != policy)
          {
            staleReferencePolicy = policy;
            event = new StaleReferencePolicyEventImpl();
          }
        }
        finally
        {
          unlockView();
        }
      }

      fireEvent(event);
    }

    @Override
    public ReferenceType getCacheReferenceType()
    {
      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          Map<CDOID, InternalCDOObject> objects = getModifiableObjects();
          if (objects instanceof ReferenceValueMap.Strong<?, ?>)
          {
            return ReferenceType.STRONG;
          }

          if (objects instanceof ReferenceValueMap.Soft<?, ?>)
          {
            return ReferenceType.SOFT;
          }

          if (objects instanceof ReferenceValueMap.Weak<?, ?>)
          {
            return ReferenceType.WEAK;
          }

          throw new IllegalStateException(Messages.getString("CDOViewImpl.29")); //$NON-NLS-1$
        }
        finally
        {
          unlockView();
        }
      }
    }

    @Override
    public boolean setCacheReferenceType(ReferenceType referenceType)
    {
      checkActive();

      if (referenceType == null)
      {
        referenceType = ReferenceType.SOFT;
      }

      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          if (!initObjectsMap(referenceType))
          {
            return false;
          }
        }
        finally
        {
          unlockView();
        }
      }

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

      return true;
    }

    @Override
    public CDOAdapterPolicy getClearAdapterPolicy()
    {
      synchronized (getViewMonitor())
      {
        lockView();

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

    @Override
    public void setClearAdapterPolicy(CDOAdapterPolicy policy)
    {
      checkActive();

      synchronized (getViewMonitor())
      {
        lockView();

        try
        {
          clearAdapterPolicy = policy;
        }
        finally
        {
          unlockView();
        }
      }

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @author Caspar De Groot
     */
    private final class LockNotificationEventImpl extends OptionsEvent implements LockNotificationEvent
    {
      private static final long serialVersionUID = 1L;

      private boolean enabled;

      public LockNotificationEventImpl(boolean enabled)
      {
        super(OptionsImpl.this);
        this.enabled = enabled;
      }

      @Override
      public boolean getEnabled()
      {
        return enabled;
      }
    }

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

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

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

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

    /**
     * @author Eike Stepper
     */
    @SuppressWarnings("deprecation")
    private final class ReferencePolicyEventImpl extends OptionsEvent implements ReferencePolicyEvent
    {
      private static final long serialVersionUID = 1L;

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

    /**
     * @author Simon McDuff
     */
    private final class StaleReferencePolicyEventImpl extends OptionsEvent implements StaleReferencePolicyEvent
    {
      private static final long serialVersionUID = 1L;

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

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

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