/*
 * Copyright (c) 2009-2014 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Simon McDuff - maintenance
 *    Victor Roldan Betancort - maintenance
 */
package org.eclipse.emf.internal.cdo.view;

import org.eclipse.emf.cdo.CDONotification;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.CDOCommonView;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.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.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.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.common.revision.CDORevisionsLoadedEvent;
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.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.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.CDORevisionPrefetchingPolicy;
import org.eclipse.emf.cdo.view.CDOStaleReferencePolicy;
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.session.SessionUtil;
import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.collection.HashBag;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.concurrent.QueueRunner;
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.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.monitor.OMMonitor;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.net4j.util.options.IOptionsEvent;
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.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
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.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * @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 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<CDOObject, CDOLockState>();

  private QueueRunner invalidationRunner = createInvalidationRunner();

  private volatile boolean invalidationRunnerActive;

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

  public CDOViewImpl(String durableLockingID)
  {
    this.durableLockingID = durableLockingID;
    options = createOptions();
  }

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

  public int getViewID()
  {
    return viewID;
  }

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

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

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

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

  public synchronized boolean setBranchPoint(CDOBranchPoint branchPoint, IProgressMonitor progressMonitor)
  {
    checkActive();
    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<CDORevisionKey>();
    List<CDOIDAndVersion> allDetachedObjects = new ArrayList<CDOIDAndVersion>();

    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();
    OMMonitor monitor = progressMonitor != null ? new EclipseMonitor(progressMonitor) : null;
    sessionProtocol.switchTarget(viewID, branchPoint, invalidObjects, allChangedObjects, allDetachedObjects, monitor);

    basicSetBranchPoint(branchPoint);
    CDOBranch branch = branchPoint.getBranch();

    try
    {
      CDOStateMachine.SWITCHING_TARGET.set(Boolean.TRUE);
      doInvalidate(branch, UNSPECIFIED_DATE, allChangedObjects, allDetachedObjects, oldRevisions, true);
    }
    finally
    {
      CDOStateMachine.SWITCHING_TARGET.remove();
    }

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

    return true;
  }

  private List<InternalCDOObject> getInvalidObjects(CDOBranchPoint branchPoint)
  {
    List<InternalCDOObject> result = new ArrayList<InternalCDOObject>();
    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);
  }

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

  public synchronized 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");

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

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

    for (CDOObject object : uniqueObjects)
    {
      if (FSMUtil.isNew(object))
      {
        CDOLockState lockState = createUpdatedLockStateForNewObject(object, 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();
        waitForUpdate(requiredTimestamp);
      }
    }

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

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

  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)
  {
    for (CDOLockState lockState : newLockStates)
    {
      Object lockedObject = lockState.getLockedObject();
      CDOID id;

      if (lockedObject instanceof CDOID)
      {
        id = (CDOID)lockedObject;
      }
      else if (lockedObject instanceof CDOIDAndBranch)
      {
        id = ((CDOIDAndBranch)lockedObject).getID();
      }
      else if (lockedObject instanceof EObject)
      {
        CDOObject newObj = CDOUtil.getCDOObject((EObject)lockedObject);
        id = newObj.cdoID();
      }
      else
      {
        throw new IllegalStateException("Unexpected: " + lockedObject.getClass().getSimpleName());
      }

      InternalCDOObject object = getObject(id, false);
      if (object != null)
      {
        InternalCDOLockState existingLockState = (InternalCDOLockState)lockStates.get(object);
        if (existingLockState != null)
        {
          Object lockTarget = getLockTarget(object);
          existingLockState.updateFrom(lockTarget, lockState);
        }
        else
        {
          lockStates.put(object, lockState);
        }
      }
    }
  }

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

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

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

  public void handleLockNotification(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
  {
    CDOLockChangeInfo event = null;

    try
    {
      synchronized (lockStates)
      {
        if (!options().isLockNotificationEnabled())
        {
          return;
        }

        if (lockChangeInfo.isInvalidateAll())
        {
          lockStates.clear();
          event = 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;
        }

        // TODO (CD) I know it is Eike's desideratum that this be done asynchronously.. but beware,
        // this will require the tests to be fixed to listen for the view events instead of the
        // session events.
        updateLockStates(lockChangeInfo.getLockStates());
        event = lockChangeInfo;
      }
    }
    finally
    {
      if (event != null)
      {
        fireLocksChangedEvent(sender, event);
      }
    }
  }

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

  protected InternalCDORevision getRevision(CDOObject object)
  {
    if (object.cdoState() == CDOState.NEW)
    {
      return null;
    }

    InternalCDORevision revision = (InternalCDORevision)object.cdoRevision();
    if (revision == null)
    {
      revision = CDOStateMachine.INSTANCE.read((InternalCDOObject)object);
    }

    return revision;
  }

  /**
   * @since 2.0
   */
  public synchronized 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.
   */
  public synchronized void unlockObjects(Collection<? extends CDOObject> objects, LockType lockType, boolean recursive)
  {
    checkActive();

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

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

      for (CDOObject object : getSet(objects))
      {
        if (FSMUtil.isNew(object))
        {
          CDOLockState lockState = createUpdatedLockStateForNewObject(object, lockType, false);
          locksOnNewObjects.add(lockState);
        }
        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());
    }
  }

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

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

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

  /**
   * @since 2.0
   */
  public synchronized boolean isObjectLocked(CDOObject object, LockType lockType, boolean byOthers)
  {
    checkActive();
    CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
    return sessionProtocol.isObjectLocked(this, object, lockType, byOthers);
  }

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

  public synchronized String getDurableLockingID()
  {
    return durableLockingID;
  }

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

    disableDurableLocking(false);
    return null;
  }

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

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

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

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

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

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

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

        public String getOldDurableLockingID()
        {
          return oldID;
        }

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

  /**
   * @since 2.0
   */
  @Deprecated
  public synchronized CDOFeatureAnalyzer getFeatureAnalyzer()
  {
    return options().getFeatureAnalyzer();
  }

  /**
   * @since 2.0
   */
  @Deprecated
  public synchronized void setFeatureAnalyzer(CDOFeatureAnalyzer featureAnalyzer)
  {
    options.setFeatureAnalyzer(featureAnalyzer);
  }

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

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

  public synchronized InternalCDORevision getRevision(CDOID id, boolean loadOnDemand)
  {
    InternalCDORevisionManager revisionManager = session.getRevisionManager();
    int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
    CDOBranchPoint branchPoint = getBranchPointForID(id);
    return revisionManager.getRevision(id, branchPoint, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
  }

  public synchronized CDOLockState[] getLockStates(Collection<CDOID> ids)
  {
    return getLockStates(ids, true);
  }

  protected synchronized CDOLockState[] getLockStates(Collection<CDOID> ids, boolean loadOnDemand)
  {
    List<CDOID> missing = new LinkedList<CDOID>();
    List<CDOLockState> lockStates = new LinkedList<CDOLockState>();
    List<CDOLockState> locksOnNewObjects = new ArrayList<CDOLockState>(ids.size());

    for (CDOID id : ids)
    {
      CDOLockState lockState = null;
      InternalCDOObject obj = getObject(id, false);
      if (obj != null)
      {
        lockState = this.lockStates.get(obj);
      }

      if (lockState != null)
      {
        lockStates.add(lockState);
      }
      else if (loadOnDemand && obj != null && FSMUtil.isNew(obj))
      {
        CDOLockState defaultLockState = CDOLockUtil.createLockState(getLockTarget(obj));
        locksOnNewObjects.add(defaultLockState);
        lockStates.add(defaultLockState);
      }
      else
      {
        missing.add(id);
      }
    }

    if (loadOnDemand && (missing.size() > 0 || ids.isEmpty()))
    {
      CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
      CDOLockState[] loadedLockStates = sessionProtocol.getLockStates(viewID, missing, CDOLockState.DEPTH_NONE);
      List<CDOLockState> newLockStateForCache = new ArrayList<CDOLockState>(loadedLockStates.length + missing.size());
      for (CDOLockState loadedLockState : loadedLockStates)
      {
        lockStates.add(loadedLockState);
        newLockStateForCache.add(loadedLockState);

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

      for (CDOID missingLockStateForCDOID : missing)
      {
        Object target;

        InternalCDOObject obj = getObject(missingLockStateForCDOID, false);
        if (obj != null)
        {
          target = getLockTarget(obj);
        }
        else
        {
          target = missingLockStateForCDOID;
        }

        CDOLockState defaultLockState = CDOLockUtil.createLockState(target);
        lockStates.add(defaultLockState);
        newLockStateForCache.add(defaultLockState);
      }

      if (options().isLockNotificationEnabled())
      {
        updateLockStates(newLockStateForCache.toArray(new CDOLockState[newLockStateForCache.size()]));
      }

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

    return lockStates.toArray(new CDOLockState[lockStates.size()]);
  }

  protected CDOLockState removeLockState(CDOObject object)
  {
    return lockStates.remove(object);
  }

  protected CDOLockState getLockState(CDOObject object)
  {
    return lockStates.get(object);
  }

  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;
  }

  public synchronized void prefetchRevisions(CDOID id, int depth)
  {
    checkArg(depth != CDORevision.DEPTH_NONE, "Prefetch depth must not be zero"); //$NON-NLS-1$
    int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
    prefetchRevisions(id, depth, initialChunkSize);
  }

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

  /*
   * Must not by synchronized on the view!
   */
  @Deprecated
  public/* synchronized */void invalidate(CDOBranch branch, long lastUpdateTime, List<CDORevisionKey> allChangedObjects,
      List<CDOIDAndVersion> allDetachedObjects, Map<CDOID, InternalCDORevision> oldRevisions, boolean async)
  {
    invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, async, true);
  }

  /*
   * Must not by synchronized on the view!
   */
  public/* synchronized */void invalidate(CDOBranch branch, long lastUpdateTime, List<CDORevisionKey> allChangedObjects,
      List<CDOIDAndVersion> allDetachedObjects, Map<CDOID, InternalCDORevision> oldRevisions, boolean async,
      boolean clearResourcePathCache)
  {
    if (async)
    {
      QueueRunner runner = getInvalidationRunner();
      runner.addWork(new InvalidationRunnable(branch, lastUpdateTime, allChangedObjects, allDetachedObjects,
          oldRevisions, clearResourcePathCache));
    }
    else
    {
      doInvalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, clearResourcePathCache);
    }
  }

  protected synchronized void doInvalidate(CDOBranch branch, long lastUpdateTime,
      List<CDORevisionKey> allChangedObjects, List<CDOIDAndVersion> allDetachedObjects,
      Map<CDOID, InternalCDORevision> oldRevisions, boolean clearResourcePathCache)
  {
    if (getTimeStamp() != UNSPECIFIED_DATE && CDOStateMachine.SWITCHING_TARGET.get() != Boolean.TRUE)
    {
      // Don't invalidate historical views unless during a branch point switch.
      return;
    }

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

        List<CDORevisionDelta> deltas = new ArrayList<CDORevisionDelta>();
        Map<CDOObject, CDORevisionDelta> revisionDeltas = new HashMap<CDOObject, CDORevisionDelta>();
        Set<CDOObject> detachedObjects = new HashSet<CDOObject>();

        Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = invalidate(allChangedObjects,
            allDetachedObjects, deltas, revisionDeltas, detachedObjects);
        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);
      }
    }
    catch (RuntimeException ex)
    {
      if (isActive())
      {
        fireEvent(new ThrowableEvent(this, ex));
        throw ex;
      }
    }
    finally
    {
      setLastUpdateTime(lastUpdateTime);
    }
  }

  public QueueRunner getInvalidationRunner()
  {
    try
    {
      invalidationRunner.activate();
    }
    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;
      }
    }

    return invalidationRunner;
  }

  private QueueRunner createInvalidationRunner()
  {
    return new QueueRunner()
    {
      @Override
      protected String getThreadName()
      {
        return "CDOViewInvalidationRunner-" + CDOViewImpl.this; //$NON-NLS-1$
      }

      @Override
      protected void noWork(WorkContext context)
      {
        if (isClosed())
        {
          context.terminate();
        }
      }

      @Override
      public String toString()
      {
        return getThreadName();
      }
    };
  }

  public boolean isInvalidationRunnerActive()
  {
    return invalidationRunnerActive;
  }

  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 InvalidationEvent(timeStamp, revisionDeltas, detachedObjects), listeners);
      }
    }
  }

  /**
   * @since 2.0
   */
  public synchronized void sendDeltaNotifications(Collection<CDORevisionDelta> deltas, Set<CDOObject> detachedObjects,
      Map<CDOID, InternalCDORevision> oldRevisions)
  {
    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();
            }
          }
        }
      }

      getChangeSubscriptionManager().handleDetachedObjects(detachedObjects);
    }
  }

  /**
   * 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
   */
  public synchronized void handleAddAdapter(InternalCDOObject eObject, Adapter adapter)
  {
    if (!FSMUtil.isNew(eObject))
    {
      subscribe(eObject, adapter);
    }

    adapterManager.attachAdapter(eObject, adapter);
  }

  /**
   * @since 2.0
   */
  public synchronized void handleRemoveAdapter(InternalCDOObject eObject, Adapter adapter)
  {
    if (!FSMUtil.isNew(eObject))
    {
      unsubscribe(eObject, adapter);
    }

    adapterManager.detachAdapter(eObject, adapter);
  }

  /**
   * @since 2.0
   */
  public synchronized void subscribe(EObject eObject, Adapter adapter)
  {
    if (changeSubscriptionManager != null)
    {
      changeSubscriptionManager.subscribe(eObject, adapter);
    }
  }

  /**
   * @since 2.0
   */
  public synchronized void unsubscribe(EObject eObject, Adapter adapter)
  {
    if (changeSubscriptionManager != null)
    {
      changeSubscriptionManager.unsubscribe(eObject, adapter);
    }
  }

  /**
   * @since 2.0
   */
  public synchronized boolean hasSubscription(CDOID id)
  {
    if (changeSubscriptionManager != null)
    {
      return changeSubscriptionManager.getSubcribeObject(id) != null;
    }

    return false;
  }

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

  /**
   * @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);
  }

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

    super.doBeforeDeactivate();
  }

  /**
   * @since 2.0
   */
  @Override
  protected void doDeactivate() throws Exception
  {
    CDOViewRegistryImpl.INSTANCE.deregister(this);
    LifecycleUtil.deactivate(invalidationRunner, OMLogger.Level.WARN);

    try
    {
      CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
      if (LifecycleUtil.isActive(sessionProtocol))
      {
        sessionProtocol.closeView(viewID);
      }
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
    }
    finally
    {
      synchronized (lockStates)
      {
        if (options.lockStatePrefetcher != null)
        {
          options.lockStatePrefetcher.dispose();
          options.lockStatePrefetcher = null;
        }

        if (session.isActive() && !lockStates.isEmpty())
        {
          List<CDOLockState> result = new ArrayList<CDOLockState>();
          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;
        }
      }
    }

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

    changeSubscriptionManager = null;
    super.doDeactivate();
  }

  public synchronized long getLastUpdateTime()
  {
    return lastUpdateTime;
  }

  public synchronized void setLastUpdateTime(long lastUpdateTime)
  {
    if (this.lastUpdateTime < lastUpdateTime)
    {
      this.lastUpdateTime = lastUpdateTime;
    }

    notifyAll();
  }

  public boolean waitForUpdate(long updateTime, long timeoutMillis)
  {
    long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
    synchronized (this)
    {
      for (;;)
      {
        if (lastUpdateTime >= updateTime)
        {
          return true;
        }

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

        try
        {
          long waitMillis = end - now;
          wait(waitMillis);
        }
        catch (InterruptedException ex)
        {
          throw WrappedException.wrap(ex);
        }
      }
    }
  }

  public boolean runAfterUpdate(final long updateTime, final Runnable runnable)
  {
    synchronized (this)
    {
      long lastUpdateTime = getLastUpdateTime();
      if (lastUpdateTime < updateTime)
      {
        addListener(new IListener()
        {
          public void notifyEvent(IEvent event)
          {
            if (event instanceof CDOViewInvalidationEvent)
            {
              CDOViewInvalidationEvent e = (CDOViewInvalidationEvent)event;
              if (e.getTimeStamp() >= updateTime)
              {
                removeListener(this);
                runnable.run();
              }
            }
          }
        });

        return false;
      }
    }

    runnable.run();
    return true;
  }

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

    CDOID id = object.cdoID();
    boolean branching = view.getSession().getRepositoryInfo().isSupportingBranches();
    if (branching)
    {
      return CDOIDUtil.createIDAndBranch(id, view.getBranch());
    }

    return id;
  }

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

    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<CDOObject>();
      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 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 notifyChangeSubcriptionPolicy()
    {
      boolean policiesPresent = options().hasChangeSubscriptionPolicies();
      subscriptions.clear();
      List<CDOID> ids = new ArrayList<CDOID>();
      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 cdoDetachedObject = (InternalCDOObject)object;
        if (cdoDetachedObject != null)
        {
          int count = getNumberOfValidAdapters(cdoDetachedObject);
          if (count > 0)
          {
            subscribe(cdoDetachedObject.cdoID(), cdoDetachedObject, 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)
    {
      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)
      {
        subscriptions.remove(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 key, InternalCDOObject object, int count)
    {
      subscriptions.put(key, new SubscribeEntry(object, count));
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class SubscribeEntry
  {
    private 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;
    }
  }

  /**
   * A {@link IListener} to prefetch {@link CDOLockState lockstates} when {@link CDORevision revisions} are loaded, according to {@link Options#setLockStatePrefetchEnabled(boolean)} option.
   *
   * @author Esteban Dugueperoux
   */
  private final class LockStatePrefetcher implements IListener
  {
    public LockStatePrefetcher()
    {
      session.getRevisionManager().addListener(this);
    }

    public void notifyEvent(IEvent event)
    {
      if (event instanceof CDORevisionsLoadedEvent)
      {
        CDORevisionsLoadedEvent revisionsLoadedEvent = (CDORevisionsLoadedEvent)event;
        updateCDOViewObjectsCache(revisionsLoadedEvent);
      }
    }

    private void updateCDOViewObjectsCache(CDORevisionsLoadedEvent revisionsLoadedEvent)
    {
      Set<CDOID> ids = new HashSet<CDOID>();
      CDOLockStateLoadingPolicy lockStateLoadingPolicy = options().getLockStateLoadingPolicy();
      for (CDORevision revision : revisionsLoadedEvent.getPrimaryLoadedRevisions())
      {
        // Bug 466721 : Check null if it is a about a DetachedRevision
        if (revision != null)
        {
          CDOID id = revision.getID();
          if (id != null && lockStateLoadingPolicy.loadLockState(id))
          {
            // - Don't ask to create an object for CDOResource as the caller of ResourceSet.getResource()
            // can have created it but not yet registered in CDOView.
            // - Don't ask others CDOResourceNode either as it will create some load revisions request
            // in addition to mode without lock state prefetch
            boolean isResourceNode = revision.isResourceNode();
            InternalCDOObject object = getObject(id, !isResourceNode);
            if (object != null)
            {
              ids.add(id);
            }
          }
        }
      }

      if (!ids.isEmpty())
      {
        // direct call the session protocol
        CDOSessionProtocol sessionProtocol = session.getSessionProtocol();
        CDOLockState[] lockStates = sessionProtocol.getLockStates(viewID, ids, revisionsLoadedEvent.getPrefetchDepth());

        updateLockStatesForAllViews(lockStates);

        // add missing lock states
        List<CDOLockState> missingLockStates = new ArrayList<CDOLockState>();
        for (CDOID id : ids)
        {
          InternalCDOObject obj = getObject(id, false);

          if (obj != null && CDOViewImpl.this.lockStates.get(obj) == null)
          {
            missingLockStates.add(CDOLockUtil.createLockState(getLockTarget(obj)));
          }
        }

        for (CDORevision revision : revisionsLoadedEvent.getAdditionalLoadedRevisions())
        {
          CDOID id = revision.getID();
          if (id != null && lockStateLoadingPolicy.loadLockState(id))
          {
            boolean isResourceNode = revision.isResourceNode();
            InternalCDOObject obj = getObject(id, !isResourceNode);
            if (obj != null && CDOViewImpl.this.lockStates.get(obj) == null)
            {
              missingLockStates.add(CDOLockUtil.createLockState(getLockTarget(obj)));
            }
          }
        }

        updateLockStatesForAllViews(missingLockStates.toArray(new CDOLockState[missingLockStates.size()]));
      }
    }

    private void updateLockStatesForAllViews(CDOLockState[] lockStates)
    {
      updateLockStates(lockStates);

      for (CDOCommonView view : getSession().getViews())
      {
        if (view != CDOViewImpl.this && view.getBranch() == getBranch())
        {
          updateLockStates(lockStates);
        }
      }
    }

    public void dispose()
    {
      session.getRevisionManager().removeListener(this);
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class InvalidationRunnable implements Runnable
  {
    private final CDOBranch branch;

    private final long lastUpdateTime;

    private final List<CDORevisionKey> allChangedObjects;

    private final List<CDOIDAndVersion> allDetachedObjects;

    private final Map<CDOID, InternalCDORevision> oldRevisions;

    private boolean clearResourcePathCache;

    private InvalidationRunnable(CDOBranch branch, long lastUpdateTime, List<CDORevisionKey> allChangedObjects,
        List<CDOIDAndVersion> allDetachedObjects, Map<CDOID, InternalCDORevision> oldRevisions,
        boolean clearResourcePathCache)
    {
      this.branch = branch;
      this.lastUpdateTime = lastUpdateTime;
      this.allChangedObjects = allChangedObjects;
      this.allDetachedObjects = allDetachedObjects;
      this.oldRevisions = oldRevisions;
      this.clearResourcePathCache = clearResourcePathCache;
    }

    public void run()
    {
      try
      {
        invalidationRunnerActive = true;
        doInvalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions,
            clearResourcePathCache);
      }
      catch (Exception ex)
      {
        if (isActive())
        {
          OM.LOG.error(ex);
        }
      }
      finally
      {
        invalidationRunnerActive = false;
      }
    }
  }

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

    private long timeStamp;

    private Map<CDOObject, CDORevisionDelta> revisionDeltas;

    private Set<CDOObject> detachedObjects;

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

    public long getTimeStamp()
    {
      return timeStamp;
    }

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

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

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

    @Override
    public String toString()
    {
      return "CDOViewInvalidationEvent: " + revisionDeltas; //$NON-NLS-1$
    }
  }

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

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

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

    public EObject[] getAffectedObjects()
    {
      List<EObject> objects = new ArrayList<EObject>();
      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()]);
    }
  }

  /**
   * @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;

    private boolean lockStatePrefetchEnabled;

    private CDOLockStateLoadingPolicy lockStateLoadingPolicy = new CDODefaultLockStateLoadingPolicy();

    private LockStatePrefetcher 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<CDOAdapterPolicy>();

    private CDOAdapterPolicy strongReferencePolicy = CDOAdapterPolicy.ALL;

    public OptionsImpl()
    {
    }

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

    public boolean isLoadNotificationEnabled()
    {
      synchronized (CDOViewImpl.this)
      {
        return loadNotificationEnabled;
      }
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (loadNotificationEnabled != enabled)
        {
          loadNotificationEnabled = enabled;
          event = new LoadNotificationEventImpl();
        }
      }

      fireEvent(event);
    }

    public boolean isDetachmentNotificationEnabled()
    {
      synchronized (CDOViewImpl.this)
      {
        return detachmentNotificationEnabled;
      }
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (detachmentNotificationEnabled != enabled)
        {
          detachmentNotificationEnabled = enabled;
          event = new DetachmentNotificationEventImpl();
        }
      }

      fireEvent(event);
    }

    public boolean isInvalidationNotificationEnabled()
    {
      synchronized (CDOViewImpl.this)
      {
        return invalidationNotificationEnabled;
      }
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (invalidationNotificationEnabled != enabled)
        {
          invalidationNotificationEnabled = enabled;
          event = new InvalidationNotificationEventImpl();
        }
      }

      fireEvent(event);
    }

    public CDOInvalidationPolicy getInvalidationPolicy()
    {
      synchronized (CDOViewImpl.this)
      {
        return invalidationPolicy;
      }
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (invalidationPolicy != policy)
        {
          invalidationPolicy = policy;
          event = new InvalidationPolicyEventImpl();
        }
      }

      fireEvent(event);
    }

    public boolean isLockNotificationEnabled()
    {
      return lockNotificationsEnabled;
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (enabled != lockNotificationsEnabled)
        {
          CDOSessionProtocol protocol = session.getSessionProtocol();
          protocol.enableLockNotifications(viewID, enabled);
          lockNotificationsEnabled = enabled;
          event = new LockNotificationEventImpl(enabled);
        }
      }

      fireEvent(event);
    }

    public boolean isLockStatePrefetchEnabled()
    {
      return lockStatePrefetchEnabled;
    }

    public void setLockStatePrefetchEnabled(boolean enabled)
    {
      checkActive();

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (enabled != lockStatePrefetchEnabled)
        {
          lockStatePrefetchEnabled = enabled;
          if (enabled)
          {
            lockStatePrefetcher = new LockStatePrefetcher();
          }
          else
          {
            lockStatePrefetcher.dispose();
            lockStatePrefetcher = null;
          }

          event = new LockStatePrefetchEventImpl();
        }
      }

      fireEvent(event);
    }

    public CDOLockStateLoadingPolicy getLockStateLoadingPolicy()
    {
      synchronized (CDOViewImpl.this)
      {
        return lockStateLoadingPolicy;
      }
    }

    public void setLockStateLoadingPolicy(CDOLockStateLoadingPolicy lockStateLoadingPolicy)
    {
      checkActive();

      synchronized (CDOViewImpl.this)
      {
        this.lockStateLoadingPolicy = lockStateLoadingPolicy;
      }
    }

    public boolean hasChangeSubscriptionPolicies()
    {
      synchronized (CDOViewImpl.this)
      {
        return !changeSubscriptionPolicies.isEmpty();
      }
    }

    public CDOAdapterPolicy[] getChangeSubscriptionPolicies()
    {
      synchronized (CDOViewImpl.this)
      {
        return changeSubscriptionPolicies.toArray(new CDOAdapterPolicy[changeSubscriptionPolicies.size()]);
      }
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (changeSubscriptionPolicies.add(policy))
        {
          changeSubscriptionManager.notifyChangeSubcriptionPolicy();
          event = new ChangeSubscriptionPoliciesEventImpl();
        }
      }

      fireEvent(event);
    }

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (changeSubscriptionPolicies.remove(policy) && !changeSubscriptionPolicies.contains(policy))
        {
          changeSubscriptionManager.notifyChangeSubcriptionPolicy();
          event = new ChangeSubscriptionPoliciesEventImpl();
        }
      }

      fireEvent(event);
    }

    public CDOAdapterPolicy getStrongReferencePolicy()
    {
      synchronized (CDOViewImpl.this)
      {
        return strongReferencePolicy;
      }
    }

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

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (strongReferencePolicy != adapterPolicy)
        {
          strongReferencePolicy = adapterPolicy;
          adapterManager.reset();
          event = new ReferencePolicyEventImpl();
        }
      }

      fireEvent(event);
    }

    public CDORevisionPrefetchingPolicy getRevisionPrefetchingPolicy()
    {
      synchronized (CDOViewImpl.this)
      {
        return revisionPrefetchingPolicy;
      }
    }

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

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (revisionPrefetchingPolicy != prefetchingPolicy)
        {
          revisionPrefetchingPolicy = prefetchingPolicy;
          event = new RevisionPrefetchingPolicyEventImpl();
        }
      }

      fireEvent(event);
    }

    public CDOFeatureAnalyzer getFeatureAnalyzer()
    {
      synchronized (CDOViewImpl.this)
      {
        return featureAnalyzer;
      }
    }

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

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (this.featureAnalyzer != featureAnalyzer)
        {
          this.featureAnalyzer = featureAnalyzer;
          event = new FeatureAnalyzerEventImpl();
        }
      }

      fireEvent(event);
    }

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

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

    public CDOStaleReferencePolicy getStaleReferencePolicy()
    {
      synchronized (CDOViewImpl.this)
      {
        return staleReferencePolicy;
      }
    }

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

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

      IEvent event = null;
      synchronized (CDOViewImpl.this)
      {
        if (staleReferencePolicy != policy)
        {
          staleReferencePolicy = policy;
          event = new StaleReferencePolicyEventImpl();
        }
      }

      fireEvent(event);
    }

    public ReferenceType getCacheReferenceType()
    {
      synchronized (CDOViewImpl.this)
      {
        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$
      }
    }

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

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

      synchronized (CDOViewImpl.this)
      {
        if (!initObjectsMap(referenceType))
        {
          return false;
        }
      }

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

      return true;
    }

    /**
     * @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;
      }

      public boolean getEnabled()
      {
        return enabled;
      }
    }

    /**
     * An {@link IOptionsEvent options event} fired from common view {@link CDOCommonView#options() options} when the
     * {@link OptionsImpl#setLockStatePrefetchEnabled(boolean) lock state prefetch enabled} option has changed.
     *
     * @author Esteban Dugueperoux
     * @noextend This interface is not intended to be extended by clients.
     * @noimplement This interface is not intended to be implemented by clients.
     * @since 4.4
     */
    private final class LockStatePrefetchEventImpl extends OptionsEvent
    {
      private static final long serialVersionUID = 1L;

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

    /**
     * @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);
      }
    }
  }
}
