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

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.revision.CDORevisable;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
import org.eclipse.emf.cdo.common.security.NoPermissionException;
import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler1;
import org.eclipse.emf.cdo.transaction.CDOTransactionHandler1.WithUndo;
import org.eclipse.emf.cdo.transaction.CDOUndoDetector;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOInvalidationPolicy;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.object.CDOLegacyWrapper;
import org.eclipse.emf.internal.cdo.object.CDONotificationBuilder;

import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.collection.Pair;
import org.eclipse.net4j.util.fsm.FiniteStateMachine;
import org.eclipse.net4j.util.fsm.ITransition;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.spi.cdo.CDOSessionProtocol.CommitTransactionResult;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOSavepoint;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.emf.spi.cdo.InternalCDOView.ViewAndState;

import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;

/**
 * @author Eike Stepper
 */
public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent, InternalCDOObject>
{
  // @Singleton
  public static final CDOStateMachine INSTANCE = new CDOStateMachine();

  static final ThreadLocal<Boolean> SWITCHING_TARGET = new InheritableThreadLocal<Boolean>();

  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_STATEMACHINE, CDOStateMachine.class);

  private static final Field NATIVE_VIEW_AND_STATE_FIELD = ReflectUtil.getAccessibleField(CDOObjectImpl.class, "viewAndState");

  private static final Field LEGACY_VIEW_AND_STATE_FIELD = ReflectUtil.getAccessibleField(CDOLegacyWrapper.class, "viewAndState");

  private InternalCDOObject lastTracedObject;

  private CDOState lastTracedState;

  private CDOEvent lastTracedEvent;

  @SuppressWarnings("unchecked")
  private CDOStateMachine()
  {
    super(CDOState.class, CDOEvent.class);

    init(CDOState.TRANSIENT, CDOEvent.PREPARE, new PrepareTransition());
    init(CDOState.TRANSIENT, CDOEvent.ATTACH, FAIL);
    init(CDOState.TRANSIENT, CDOEvent.DETACH, IGNORE);
    init(CDOState.TRANSIENT, CDOEvent.REATTACH, new ReattachTransition());
    init(CDOState.TRANSIENT, CDOEvent.READ, IGNORE);
    init(CDOState.TRANSIENT, CDOEvent.WRITE, IGNORE);
    init(CDOState.TRANSIENT, CDOEvent.INVALIDATE, IGNORE);
    init(CDOState.TRANSIENT, CDOEvent.DETACH_REMOTE, IGNORE);
    init(CDOState.TRANSIENT, CDOEvent.COMMIT, FAIL);
    init(CDOState.TRANSIENT, CDOEvent.ROLLBACK, FAIL);

    init(CDOState.PREPARED, CDOEvent.PREPARE, FAIL);
    init(CDOState.PREPARED, CDOEvent.ATTACH, new AttachTransition());
    init(CDOState.PREPARED, CDOEvent.DETACH, FAIL);
    init(CDOState.PREPARED, CDOEvent.REATTACH, FAIL);
    init(CDOState.PREPARED, CDOEvent.READ, IGNORE);
    init(CDOState.PREPARED, CDOEvent.WRITE, FAIL);
    init(CDOState.PREPARED, CDOEvent.INVALIDATE, FAIL);
    init(CDOState.PREPARED, CDOEvent.DETACH_REMOTE, FAIL);
    init(CDOState.PREPARED, CDOEvent.COMMIT, FAIL);
    init(CDOState.PREPARED, CDOEvent.ROLLBACK, FAIL);

    init(CDOState.NEW, CDOEvent.PREPARE, FAIL);
    init(CDOState.NEW, CDOEvent.ATTACH, FAIL);
    init(CDOState.NEW, CDOEvent.DETACH, new DetachTransition());
    init(CDOState.NEW, CDOEvent.REATTACH, FAIL);
    init(CDOState.NEW, CDOEvent.READ, IGNORE);
    init(CDOState.NEW, CDOEvent.WRITE, new WriteNewTransition());
    init(CDOState.NEW, CDOEvent.INVALIDATE, DetachRemoteTransition.INSTANCE);
    init(CDOState.NEW, CDOEvent.DETACH_REMOTE, FAIL);
    init(CDOState.NEW, CDOEvent.COMMIT, new CommitTransition(false));
    init(CDOState.NEW, CDOEvent.ROLLBACK, new RollbackTransition());

    init(CDOState.CLEAN, CDOEvent.PREPARE, FAIL);
    init(CDOState.CLEAN, CDOEvent.ATTACH, FAIL);
    init(CDOState.CLEAN, CDOEvent.DETACH, new DetachTransition());
    init(CDOState.CLEAN, CDOEvent.REATTACH, FAIL);
    init(CDOState.CLEAN, CDOEvent.READ, IGNORE);
    init(CDOState.CLEAN, CDOEvent.WRITE, new WriteTransition(false));
    init(CDOState.CLEAN, CDOEvent.INVALIDATE, new InvalidateTransition());
    init(CDOState.CLEAN, CDOEvent.DETACH_REMOTE, DetachRemoteTransition.INSTANCE);
    init(CDOState.CLEAN, CDOEvent.COMMIT, FAIL);
    init(CDOState.CLEAN, CDOEvent.ROLLBACK, FAIL);

    init(CDOState.DIRTY, CDOEvent.PREPARE, FAIL);
    init(CDOState.DIRTY, CDOEvent.ATTACH, FAIL);
    init(CDOState.DIRTY, CDOEvent.DETACH, new DetachTransition());
    init(CDOState.DIRTY, CDOEvent.REATTACH, FAIL);
    init(CDOState.DIRTY, CDOEvent.READ, IGNORE);
    init(CDOState.DIRTY, CDOEvent.WRITE, new RewriteTransition());
    init(CDOState.DIRTY, CDOEvent.INVALIDATE, new ConflictTransition());
    init(CDOState.DIRTY, CDOEvent.DETACH_REMOTE, new InvalidConflictTransition());
    init(CDOState.DIRTY, CDOEvent.COMMIT, new CommitTransition(true));
    init(CDOState.DIRTY, CDOEvent.ROLLBACK, new RollbackTransition());

    init(CDOState.PROXY, CDOEvent.PREPARE, FAIL);
    init(CDOState.PROXY, CDOEvent.ATTACH, FAIL);
    init(CDOState.PROXY, CDOEvent.DETACH, new DetachTransition());
    init(CDOState.PROXY, CDOEvent.REATTACH, FAIL);
    init(CDOState.PROXY, CDOEvent.READ, new LoadTransition());
    init(CDOState.PROXY, CDOEvent.WRITE, new WriteTransition(true));
    init(CDOState.PROXY, CDOEvent.INVALIDATE, IGNORE);
    init(CDOState.PROXY, CDOEvent.DETACH_REMOTE, DetachRemoteTransition.INSTANCE);
    init(CDOState.PROXY, CDOEvent.COMMIT, FAIL);
    init(CDOState.PROXY, CDOEvent.ROLLBACK, FAIL);

    init(CDOState.CONFLICT, CDOEvent.PREPARE, FAIL);
    init(CDOState.CONFLICT, CDOEvent.ATTACH, IGNORE);
    init(CDOState.CONFLICT, CDOEvent.DETACH, new DetachTransition());
    init(CDOState.CONFLICT, CDOEvent.REATTACH, FAIL);
    init(CDOState.CONFLICT, CDOEvent.READ, IGNORE);
    init(CDOState.CONFLICT, CDOEvent.WRITE, new RewriteTransition());
    init(CDOState.CONFLICT, CDOEvent.INVALIDATE, IGNORE);
    init(CDOState.CONFLICT, CDOEvent.DETACH_REMOTE, IGNORE);
    init(CDOState.CONFLICT, CDOEvent.COMMIT, IGNORE);
    init(CDOState.CONFLICT, CDOEvent.ROLLBACK, new RollbackTransition());

    init(CDOState.INVALID, CDOEvent.PREPARE, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.ATTACH, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.DETACH, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.REATTACH, FAIL);
    init(CDOState.INVALID, CDOEvent.READ, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.WRITE, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.INVALIDATE, IGNORE); // TODO Handle changeViewTarget!!!
    init(CDOState.INVALID, CDOEvent.DETACH_REMOTE, IGNORE);
    init(CDOState.INVALID, CDOEvent.COMMIT, InvalidTransition.INSTANCE);
    init(CDOState.INVALID, CDOEvent.ROLLBACK, InvalidTransition.INSTANCE);

    init(CDOState.INVALID_CONFLICT, CDOEvent.PREPARE, InvalidTransition.INSTANCE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.ATTACH, InvalidTransition.INSTANCE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.DETACH, InvalidTransition.INSTANCE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.REATTACH, FAIL);
    init(CDOState.INVALID_CONFLICT, CDOEvent.READ, IGNORE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.WRITE, IGNORE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.INVALIDATE, IGNORE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.DETACH_REMOTE, IGNORE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.COMMIT, InvalidTransition.INSTANCE);
    init(CDOState.INVALID_CONFLICT, CDOEvent.ROLLBACK, DetachRemoteTransition.INSTANCE);
  }

  /**
   * The object is already attached in EMF world. It contains all the information needed to know where it will be connected.
   */
  public void attach(InternalCDOObject object, InternalCDOTransaction transaction)
  {
    synchronized (transaction.getViewMonitor())
    {
      transaction.lockView();

      try
      {
        object.cdoInternalPreAttach();

        List<InternalCDOObject> contents = new ArrayList<InternalCDOObject>();
        prepare(object, Pair.create(transaction, contents));

        attachOrReattach(object, transaction);
        for (InternalCDOObject content : contents)
        {
          attachOrReattach(content, transaction);
        }
      }
      finally
      {
        transaction.unlockView();
      }
    }
  }

  private void attachOrReattach(InternalCDOObject object, InternalCDOTransaction transaction)
  {
    // Bug 283985 (Re-attachment):
    // If the object going through a prepareTransition is present in cleanRevisions,
    // then it was detached earlier, and so we can infer that it is being re-attached
    if (transaction.getCleanRevisions().containsKey(object))
    {
      reattachObject(object, transaction);
    }
    else
    {
      attachObject(object);
    }
  }

  /**
   * Phase 1: TRANSIENT --> PREPARED
   */
  private void prepare(InternalCDOObject object, Pair<InternalCDOTransaction, List<InternalCDOObject>> transactionAndContents)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("PREPARE: {0} --> {1}", object, transactionAndContents.getElement1()); //$NON-NLS-1$
    }

    process(object, CDOEvent.PREPARE, transactionAndContents);
  }

  /**
   * Phase 2: PREPARED --> NEW
   */
  private void attachObject(InternalCDOObject object)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("ATTACH: {0}", object); //$NON-NLS-1$
    }

    process(object, CDOEvent.ATTACH, null);
  }

  private void reattachObject(InternalCDOObject object, InternalCDOTransaction transaction)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("REATTACH: {0}", object);
    }

    process(object, CDOEvent.REATTACH, transaction);
  }

  public void detach(InternalCDOObject object)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.DETACH);
        }

        List<InternalCDOObject> objectsToDetach = new ArrayList<InternalCDOObject>();
        InternalCDOTransaction transaction = (InternalCDOTransaction)object.cdoView();

        // Accumulate objects that needs to be detached
        // If we have an error, we will keep the graph exactly like it was before.
        process(object, CDOEvent.DETACH, objectsToDetach);

        // postDetach() requires the object to be TRANSIENT, but listeners must not be notified at this point!
        for (InternalCDOObject content : objectsToDetach)
        {
          CDOState oldState = setStateQuietely(content, CDOState.TRANSIENT);
          content.cdoInternalPostDetach(false);
          setStateQuietely(content, oldState);
        }

        // detachObject() needs to know the state before we change the object to TRANSIENT
        for (InternalCDOObject content : objectsToDetach)
        {
          transaction.detachObject(content);
          content.cdoInternalSetState(CDOState.TRANSIENT);

          content.cdoInternalSetView(null);
          content.cdoInternalSetID(null);
        }
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public InternalCDORevision read(InternalCDOObject object)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.READ);
        }

        process(object, CDOEvent.READ, null);
        return object.cdoRevision();
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public InternalCDORevision readNoLoad(InternalCDOObject object)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        switch (object.cdoState())
        {
        case TRANSIENT:
        case PREPARED:
        case NEW:
        case CONFLICT:
        case INVALID_CONFLICT:
        case INVALID:
        case PROXY:
          return null;
        }

        return object.cdoRevision();
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public Object write(InternalCDOObject object, CDOFeatureDelta featureDelta)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        return writeUnsynced(object, featureDelta);
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public Object writeUnsynced(InternalCDOObject object, CDOFeatureDelta featureDelta)
  {
    if (TRACER.isEnabled())
    {
      trace(object, CDOEvent.WRITE);
    }

    // TODO: Make FeatureDeltaAndResult constant
    FeatureDeltaAndResult featureDeltaAndResult = new FeatureDeltaAndResult(featureDelta);

    process(object, CDOEvent.WRITE, featureDeltaAndResult);
    return featureDeltaAndResult.getResult();
  }

  public void reload(InternalCDOObject... objects)
  {
    if (objects == null || objects.length == 0)
    {
      return;
    }

    synchronized (getMonitor(objects[0]))
    {
      Lock lock = getLock(objects[0]);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        for (InternalCDOObject object : objects)
        {
          CDOState state = object.cdoState();
          if (state == CDOState.CLEAN || state == CDOState.PROXY)
          {
            changeState(object, CDOState.PROXY);
            object.cdoInternalSetRevision(null);
            read(object);
          }
        }
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public void invalidate(InternalCDOObject object, CDORevisionKey key)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.INVALIDATE);
        }

        process(object, CDOEvent.INVALIDATE, key);
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public void detachRemote(InternalCDOObject object)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.DETACH_REMOTE);
        }

        process(object, CDOEvent.DETACH_REMOTE, null);
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public void commit(Map<CDOID, CDOObject> objects, CommitTransactionResult result)
  {
    for (CDOObject object : objects.values())
    {
      commitObject((InternalCDOObject)object, result);
    }

    for (CDOObject object : objects.values())
    {
      changeState((InternalCDOObject)object, CDOState.CLEAN);
    }
  }

  private void commitObject(InternalCDOObject object, CommitTransactionResult result)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.COMMIT);
        }

        process(object, CDOEvent.COMMIT, result);
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  public void rollback(InternalCDOObject object, InternalCDOTransaction transaction)
  {
    synchronized (getMonitor(object))
    {
      Lock lock = getLock(object);
      if (lock != null)
      {
        lock.lock();
      }

      try
      {
        if (TRACER.isEnabled())
        {
          trace(object, CDOEvent.ROLLBACK);
        }

        process(object, CDOEvent.ROLLBACK, transaction);
      }
      finally
      {
        if (lock != null)
        {
          lock.unlock();
        }
      }
    }
  }

  @Override
  protected CDOState getState(InternalCDOObject object)
  {
    return object.cdoState();
  }

  @Override
  protected void setState(InternalCDOObject object, CDOState state)
  {
    object.cdoInternalSetState(state);
  }

  private CDOState setStateQuietely(InternalCDOObject object, CDOState state)
  {
    Field viewAndStateField;
    if (object instanceof CDOObjectImpl)
    {
      viewAndStateField = NATIVE_VIEW_AND_STATE_FIELD;
    }
    else if (object instanceof CDOLegacyWrapper)
    {
      viewAndStateField = LEGACY_VIEW_AND_STATE_FIELD;
    }
    else
    {
      return object.cdoInternalSetState(state);
    }

    try
    {
      ViewAndState viewAndState = (ViewAndState)viewAndStateField.get(object);
      CDOState oldState = viewAndState.state;
      ReflectUtil.setValue(viewAndStateField, object, viewAndState.getViewAndState(state));
      return oldState;
    }
    catch (Exception ex)
    {
      return object.cdoInternalSetState(state);
    }
  }

  private Lock getLock(InternalCDOObject object)
  {
    InternalCDOView view = object.cdoView();
    if (view != null)
    {
      return view.getViewLock();
    }

    // In TRANSIENT and PREPARED the object is not yet attached to a view
    return null;
  }

  private Object getMonitor(InternalCDOObject object)
  {
    InternalCDOView view = object.cdoView();
    if (view != null)
    {
      return view.getViewMonitor();
    }

    // In TRANSIENT and PREPARED the object is not yet attached to a view
    return object;
  }

  /**
   * Removes clutter from the trace log
   */
  private void trace(InternalCDOObject object, CDOEvent event)
  {
    CDOState state = object.cdoState();
    if (lastTracedObject != object || lastTracedState != state || lastTracedEvent != event)
    {
      TRACER.format("{0}: {1}", event, object.getClass().getName()); //$NON-NLS-1$
      lastTracedObject = object;
      lastTracedState = state;
      lastTracedEvent = event;
    }
  }

  @SuppressWarnings("unused")
  private void testAttach(InternalCDOObject object)
  {
    process(object, CDOEvent.ATTACH, null);
  }

  public void internalReattach(InternalCDOObject object, InternalCDOTransaction transaction)
  {
    InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
    InternalCDORevision cleanRevision = transaction.getCleanRevisions().get(object).copy();
    CDOID id = cleanRevision.getID();

    // Bug 373096: Determine clean revision of the CURRENT/LAST savepoint
    InternalCDOSavepoint savepoint = transaction.getFirstSavepoint();
    while (savepoint.getNextSavepoint() != null)
    {
      CDORevisionDelta delta = savepoint.getRevisionDeltas2().get(id);
      if (delta != null)
      {
        delta.applyTo(cleanRevision);
      }

      savepoint = savepoint.getNextSavepoint();
    }

    object.cdoInternalSetView(transaction);

    // Construct a new revision
    CDORevisionFactory factory = revisionManager.getFactory();
    InternalCDORevision revision = (InternalCDORevision)factory.createRevision(object.eClass());
    revision.setID(id);
    revision.setBranchPoint(cleanRevision.getBranch().getHead());
    revision.setVersion(cleanRevision.getVersion());

    // Populate the revision based on the values in the CDOObject
    object.cdoInternalSetRevision(revision);
    object.cdoInternalPostAttach();

    // Compute a revision delta and register it with the tx
    InternalCDORevisionDelta revisionDelta = revision.compare(cleanRevision);
    if (revisionDelta.isEmpty())
    {
      changeState(object, CDOState.CLEAN);
    }
    else
    {
      revisionDelta.setTarget(null);
      transaction.registerRevisionDelta(revisionDelta);
      transaction.registerDirty(object, (CDOFeatureDelta)null);
      changeState(object, CDOState.DIRTY);
    }

    // Add the object to the set of reattached objects
    InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
    lastSavepoint.getReattachedObjects().put(id, object);
  }

  public void dispatchLoadNotification(InternalCDOObject object)
  {
    InternalCDOView view = object.cdoView();
    if (view.options().isLoadNotificationEnabled())
    {
      try
      {
        InternalCDORevision revision = object.cdoRevision();
        CDONotificationBuilder builder = new CDONotificationBuilder(view);

        NotificationChain notification = builder.buildNotification(object, revision);
        if (notification != null)
        {
          notification.dispatch();
        }
      }
      catch (PartialCollectionLoadingNotSupportedException ex)
      {
        if (TRACER.isEnabled())
        {
          TRACER.trace(ex);
        }
      }
    }
  }

  private void internalLoad(InternalCDOObject object, boolean forWrite)
  {
    object.cdoInternalPreLoad();

    InternalCDOView view = object.cdoView();
    InternalCDORevision revision = view.getRevision(object.cdoID(), true);
    if (revision == null)
    {
      INSTANCE.detachRemote(object);
      CDOInvalidationPolicy policy = view.options().getInvalidationPolicy();
      policy.handleInvalidObject(object);
    }

    if (forWrite && !revision.isWritable())
    {
      throw new NoPermissionException(revision);
    }

    object.cdoInternalSetRevision(revision);
    changeState(object, CDOState.CLEAN);
    object.cdoInternalPostLoad();
    dispatchLoadNotification(object);
  }

  /**
   * @author Eike Stepper
   */
  public static final class FeatureDeltaAndResult
  {
    private final CDOFeatureDelta featureDelta;

    private Object result;

    public FeatureDeltaAndResult(CDOFeatureDelta featureDelta)
    {
      this.featureDelta = featureDelta;
    }

    public CDOFeatureDelta getFeatureDelta()
    {
      return featureDelta;
    }

    public Object getResult()
    {
      return result;
    }

    public void setResult(Object result)
    {
      this.result = result;
    }
  }

  /**
   * Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
   * <p>
   * Execution is recursive and includes:
   * <ol>
   * <li>Assignment of a new {@link CDOIDTemp}
   * <li>Assignment of a new {@link CDORevision}
   * <li>Bidirectional association with the {@link CDOView}
   * <li>Registration with the {@link CDOTransaction}
   * <li>Changing state to {@link CDOState#PREPARED PREPARED}
   * </ol>
   *
   * @see AttachTransition
   * @author Eike Stepper
   */
  private final class PrepareTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Pair<InternalCDOTransaction, List<InternalCDOObject>>>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Pair<InternalCDOTransaction, List<InternalCDOObject>> transactionAndContents)
    {
      InternalCDOTransaction transaction = transactionAndContents.getElement1();
      List<InternalCDOObject> contents = transactionAndContents.getElement2();

      // If the object going through a prepareTransition is present in cleanRevisions,
      // then it was detached earlier, and so we can infer that it is being re-attached
      boolean reattaching = transaction.getCleanRevisions().containsKey(object);

      if (!reattaching)
      {
        // Prepare object
        CDOID id = transaction.createIDForNewObject(object.cdoInternalInstance());
        object.cdoInternalSetView(transaction);
        changeState(object, CDOState.PREPARED);

        // Create new revision
        EClass eClass = object.eClass();
        InternalCDOSession session = transaction.getSession();
        checkPackageRegistrationProblems(session, eClass);

        CDORevisionFactory factory = session.getRevisionManager().getFactory();
        InternalCDORevision revision = (InternalCDORevision)factory.createRevision(eClass);
        revision.setID(id);
        revision.setBranchPoint(transaction.getBranch().getHead());

        object.cdoInternalSetRevision(revision);

        // Register object
        transaction.registerObject(object);
      }

      transaction.registerAttached(object, !reattaching);

      // Prepare content tree
      for (Iterator<InternalEObject> it = getPersistentContents(object); it.hasNext();)
      {
        InternalEObject content = it.next();
        Resource.Internal directResource = content.eDirectResource();

        boolean objectIsResource = directResource == object;
        if (objectIsResource || directResource == null)
        {
          InternalCDOObject adapted = FSMUtil.adapt(content, transaction);
          contents.add(adapted);
          INSTANCE.process(adapted, CDOEvent.PREPARE, transactionAndContents);
        }
      }
    }

    private Iterator<InternalEObject> getPersistentContents(InternalCDOObject object)
    {
      EStructuralFeature[] features = object.cdoClassInfo().getAllPersistentContainments();
      return new EContentsEList.ResolvingFeatureIteratorImpl<InternalEObject>(object, features);
    }

    private void checkPackageRegistrationProblems(InternalCDOSession session, EClass eClass)
    {
      if (session.options().isGeneratedPackageEmulationEnabled())
      {
        // Check that there are no multiple EPackages with the same URI in system. Bug 335004
        String packageURI = eClass.getEPackage().getNsURI();
        Object packageObject = session.getPackageRegistry().get(packageURI);
        if (packageObject instanceof InternalCDOPackageInfo)
        {
          packageObject = ((InternalCDOPackageInfo)packageObject).getEPackage(false);
        }

        if (packageObject instanceof EPackage && packageObject != eClass.getEPackage())
        {
          throw new IllegalStateException(
              MessageFormat.format("Global EPackage {0} for EClass {1} is different from EPackage found in CDOPackageRegistry", packageURI, eClass));
        }
      }
    }
  }

  /**
   * Attaches a tree of {@link PrepareTransition prepared} objects to a CDOView.
   * <p>
   * Execution is recursive and includes:
   * <ol>
   * <li>Calling {@link InternalCDOObject#cdoInternalPostAttach()},<br>
   * which includes for {@link CDOObjectImpl}:
   * <ol>
   * <li>Population of the CDORevision with the current values in
   * {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
   * <li>Unsetting {@link EStoreEObjectImpl#eSetting(org.eclipse.emf.ecore.EStructuralFeature) eSettings}
   * </ol>
   * <li>Changing state to {@link CDOState#NEW NEW}
   * </ol>
   *
   * @see PrepareTransition
   * @author Eike Stepper
   */
  private final class AttachTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
    {
      // Transfer the EObject values into a CDORevision.
      object.cdoInternalPostAttach();

      // Remember a copy of the new revision that can be used in case of a later rollback to reset the object.
      Map<CDOID, CDORevision> attachedRevisions = ((InternalCDOTransaction)object.cdoView()).options().getAttachedRevisionsMap();
      if (attachedRevisions != null)
      {
        InternalCDORevision revision = object.cdoRevision().copy();

        // This revision copy contains the container reference AFTER the attachment.
        // At rollback time it may have to be unset if this object is the root of an attached tree!
        attachedRevisions.put(revision.getID(), revision);
      }

      changeState(object, CDOState.NEW);
    }
  }

  /**
   * Bug 283985 (Re-attachment)
   *
   * @author Caspar De Groot
   */
  private final class ReattachTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, InternalCDOTransaction>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, InternalCDOTransaction transaction)
    {
      internalReattach(object, transaction);

      // Bug 385268
      CDOID reattachedObject = object.cdoID();
      processRevisionDeltas(reattachedObject, transaction);
    }

    private void processRevisionDeltas(CDOID reattachedObject, InternalCDOTransaction transaction)
    {
      InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
      Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
      for (Iterator<Entry<CDOID, CDORevisionDelta>> it = revisionDeltas.entrySet().iterator(); it.hasNext();)
      {
        Entry<CDOID, CDORevisionDelta> entry = it.next();
        CDORevisionDelta revisionDelta = entry.getValue();

        Map<EStructuralFeature, CDOFeatureDelta> map = ((InternalCDORevisionDelta)revisionDelta).getFeatureDeltaMap();
        processFeatureDeltas(reattachedObject, map);

        if (revisionDelta.isEmpty())
        {
          it.remove();

          CDOID id = revisionDelta.getID();
          InternalCDOObject cleanObject = (InternalCDOObject)lastSavepoint.getDirtyObjects().remove(id);
          if (cleanObject != null)
          {
            cleanObject.cdoInternalSetState(CDOState.CLEAN);
          }
        }
      }

      if (revisionDeltas.isEmpty())
      {
        transaction.setDirty(false);
      }
    }

    private void processFeatureDeltas(CDOID reattachedObject, Map<EStructuralFeature, CDOFeatureDelta> map)
    {
      for (Iterator<Entry<EStructuralFeature, CDOFeatureDelta>> it = map.entrySet().iterator(); it.hasNext();)
      {
        Entry<EStructuralFeature, CDOFeatureDelta> entry = it.next();
        CDOFeatureDelta featureDelta = entry.getValue();
        processFeatureDelta(reattachedObject, it, featureDelta);
      }
    }

    private void processFeatureDelta(CDOID reattachedObject, Iterator<?> it, CDOFeatureDelta featureDelta)
    {
      switch (featureDelta.getType())
      {
      case SET:
        CDOSetFeatureDelta setFeatureDelta = (CDOSetFeatureDelta)featureDelta;
        Object oldValue = setFeatureDelta.getOldValue();
        if (oldValue instanceof EObject)
        {
          oldValue = CDOUtil.getCDOObject((EObject)oldValue).cdoID();
        }

        Object newValue = setFeatureDelta.getValue();
        if (newValue instanceof EObject)
        {
          newValue = CDOUtil.getCDOObject((EObject)newValue).cdoID();
        }

        if (reattachedObject == oldValue && reattachedObject == newValue)
        {
          it.remove();
        }

        break;

      case LIST:
        CDOListFeatureDelta listFeatureDelta = (CDOListFeatureDelta)featureDelta;
        List<CDOFeatureDelta> listChanges = listFeatureDelta.getListChanges();
        for (Iterator<CDOFeatureDelta> listIt = listChanges.iterator(); listIt.hasNext();)
        {
          CDOFeatureDelta singleFeatureDelta = listIt.next();
          processFeatureDelta(reattachedObject, listIt, singleFeatureDelta);
        }

        if (listChanges.isEmpty())
        {
          it.remove();
        }

        break;
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static final class DetachTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, List<InternalCDOObject>>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, List<InternalCDOObject> objectsToDetach)
    {
      InternalCDOTransaction transaction = (InternalCDOTransaction)object.cdoView();
      objectsToDetach.add(object);
      boolean isResource = object instanceof Resource;

      // Prepare content tree
      for (Iterator<EObject> it = object.eContents().iterator(); it.hasNext();)
      {
        InternalEObject eObject = (InternalEObject)it.next();
        boolean isDirectlyConnected = isResource && eObject.eDirectResource() == object;
        if (isDirectlyConnected || eObject.eDirectResource() == null)
        {
          InternalCDOObject content = FSMUtil.adapt(eObject, transaction);
          if (content != null)
          {
            INSTANCE.process(content, CDOEvent.DETACH, objectsToDetach);
          }
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class CommitTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, CommitTransactionResult>
  {
    public CommitTransition(boolean useDeltas)
    {
    }

    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CommitTransactionResult data)
    {
      InternalCDOTransaction transaction = object.cdoView().toTransaction();
      InternalCDORevision revision = object.cdoRevision();
      Map<CDOID, CDOID> idMappings = data.getIDMappings();

      // Adjust object
      CDOID oldID = object.cdoID();
      CDOID newID = idMappings.get(oldID);
      if (newID != null)
      {
        revision.setID(newID);
        transaction.remapObject(oldID);
      }

      // Adjust revision
      revision.adjustForCommit(transaction.getBranch(), data.getTimeStamp());
      revision.adjustReferences(data.getReferenceAdjuster());
      revision.freeze();

      InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
      revisionManager.addRevision(revision);
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class RollbackTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, InternalCDOTransaction>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, InternalCDOTransaction transaction)
    {
      CDOID id = object.cdoID();
      if (transaction.getLastSavepoint().isNewObject(id))
      {
        // Map<CDOID, CDORevision> attachedRevisions = transaction.options().getAttachedRevisionsMap();
        // if (attachedRevisions != null)
        // {
        // InternalCDORevision revision = (InternalCDORevision)attachedRevisions.get(id);
        // if (revision != null)
        // {
        // CDOID containerID = transaction.provideCDOID(revision.getContainerID());
        // if (!CDOIDUtil.isNull(containerID) && !attachedRevisions.containsKey(containerID))
        // {
        // revision.setContainerID(null);
        // revision.setContainingFeatureID(0);
        // }
        //
        // CDOID resourceID = revision.getResourceID();
        // if (!CDOIDUtil.isNull(resourceID) && !attachedRevisions.containsKey(resourceID))
        // {
        // revision.setResourceID(null);
        // }
        //
        // object.cdoInternalSetRevision(revision);
        //
        // if (object instanceof CDOLegacyWrapper)
        // {
        // CDOLegacyWrapper wrapper = (CDOLegacyWrapper)object;
        // wrapper.cdoInternalPostLoad();
        // }
        // }
        // }

        // postDetach() requires the object to be TRANSIENT, but listeners must not be notified at this point!
        CDOState oldState = setStateQuietely(object, CDOState.TRANSIENT);
        object.cdoInternalPostDetach(false);
        setStateQuietely(object, oldState);

        changeState(object, CDOState.TRANSIENT);
      }
      else
      {
        changeState(object, CDOState.PROXY);
        object.cdoInternalPostRollback();
      }

      object.cdoInternalSetRevision(null);
    }
  }

  /**
   * @author Eike Stepper
   */
  private static abstract class AbstractWriteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, FeatureDeltaAndResult>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, FeatureDeltaAndResult featureDeltaAndResult)
    {
      InternalCDORevision revision = object.cdoRevision();
      if (!revision.isWritable())
      {
        throw new NoPermissionException(revision);
      }

      InternalCDOTransaction transaction = object.cdoView().toTransaction();
      CDOFeatureDelta featureDelta = featureDeltaAndResult.getFeatureDelta();
      Object result = execute(object, transaction, featureDelta, revision);
      featureDeltaAndResult.setResult(result);
    }

    protected abstract Object execute(InternalCDOObject object, InternalCDOTransaction transaction, CDOFeatureDelta featureDelta, InternalCDORevision revision);
  }

  /**
   * @author Simon McDuff
   */
  private final class WriteNewTransition extends AbstractWriteTransition
  {
    @Override
    protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction, CDOFeatureDelta featureDelta, InternalCDORevision revision)
    {
      Object result = null;
      if (featureDelta != null)
      {
        result = featureDelta.applyTo(revision);
      }

      transaction.registerFeatureDelta(object, featureDelta);
      return result;
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class WriteTransition extends AbstractWriteTransition
  {
    private boolean load;

    public WriteTransition(boolean load)
    {
      this.load = load;
    }

    @Override
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, FeatureDeltaAndResult featureDeltaAndResult)
    {
      if (load)
      {
        internalLoad(object, true);
      }

      super.execute(object, state, event, featureDeltaAndResult);
    }

    @Override
    protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction, CDOFeatureDelta featureDelta, InternalCDORevision cleanRevision)
    {
      InternalCDORevision revision = cleanRevision.copy();

      Object result = null;
      if (featureDelta != null)
      {
        result = featureDelta.applyTo(revision);

        if (!transaction.hasMultipleSavepoints())
        {
          CDOUndoDetector undoDetector = transaction.options().getUndoDetector();
          if (undoDetector.detectUndo(transaction, cleanRevision, revision, featureDelta))
          {
            return null;
          }
        }
      }

      transaction.getCleanRevisions().put(object, cleanRevision);
      object.cdoInternalSetRevision(revision);

      transaction.registerDirty(object, featureDelta, cleanRevision);
      changeState(object, CDOState.DIRTY);
      return result;
    }
  }

  /**
   * @author Simon McDuff
   */
  private final class RewriteTransition extends AbstractWriteTransition
  {
    @Override
    protected Object execute(InternalCDOObject object, InternalCDOTransaction transaction, CDOFeatureDelta featureDelta, InternalCDORevision revision)
    {
      Map<InternalCDOObject, InternalCDORevision> cleanRevisions = transaction.getCleanRevisions();
      InternalCDORevision cleanRevision = cleanRevisions.get(object);

      Object result = null;
      if (featureDelta != null)
      {
        result = featureDelta.applyTo(revision);

        if (!transaction.hasMultipleSavepoints())
        {
          CDOUndoDetector undoDetector = transaction.options().getUndoDetector();
          if (undoDetector.detectUndo(transaction, cleanRevision, revision, featureDelta))
          {
            CDOID id = revision.getID();

            InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
            Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
            InternalCDORevisionDelta revisionDelta = (InternalCDORevisionDelta)revisionDeltas.get(id);
            if (revisionDelta != null)
            {
              Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = revisionDelta.getFeatureDeltaMap();
              featureDeltas.remove(featureDelta.getFeature());

              if (featureDeltas.isEmpty())
              {
                cleanRevisions.remove(object);
                revisionDeltas.remove(id);
                lastSavepoint.getDirtyObjects().remove(id);

                if (lastSavepoint.getReattachedObjects().remove(id) != null)
                {
                  lastSavepoint.getDetachedObjects().remove(id);
                }

                object.cdoInternalSetRevision(cleanRevision);
                changeState(object, CDOState.CLEAN);
              }
            }

            if (revisionDeltas.isEmpty())
            {
              transaction.setDirty(false);
            }

            CDOTransactionHandler1[] handlers = transaction.getTransactionHandlers1();
            for (int i = 0; i < handlers.length; i++)
            {
              CDOTransactionHandler1 handler = handlers[i];
              if (handler instanceof WithUndo)
              {
                WithUndo withUndo = (WithUndo)handler;
                withUndo.undoingObject(transaction, object, featureDelta);
              }
            }

            return result;
          }
        }
      }

      transaction.registerFeatureDelta(object, featureDelta, cleanRevision);
      return result;
    }
  }

  /**
   * @author Simon McDuff
   */
  private static class DetachRemoteTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
  {
    static final DetachRemoteTransition INSTANCE = new DetachRemoteTransition();

    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
    {
      CDOStateMachine.INSTANCE.changeState(object, CDOState.INVALID);

      InternalCDOView view = object.cdoView();
      view.deregisterObject(object);
      object.cdoInternalPostDetach(true);
    }
  }

  /**
   * @author Eike Stepper
   */
  private class InvalidateTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, CDORevisionKey>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CDORevisionKey key)
    {
      InternalCDORevision oldRevision = object.cdoRevision();
      InternalCDOView view = object.cdoView();
      InternalCDOSession session = view.getSession();
      InternalCDORevisionCache cache = session.getRevisionManager().getCache();

      if (SWITCHING_TARGET.get() == Boolean.TRUE)
      {
        CDORevisionDelta delta = (CDORevisionDelta)key;
        CDORevisable target = delta.getTarget();
        InternalCDORevision newRevision = (InternalCDORevision)cache.getRevisionByVersion(delta.getID(), target);
        if (newRevision == null)
        {
          newRevision = oldRevision.copy();
          session.resolveAllElementProxies(newRevision);
          delta.applyTo(newRevision);
          newRevision.setBranchPoint(target);
          newRevision.setVersion(target.getVersion());
          newRevision.setRevised(target.getRevised());
          cache.addRevision(newRevision);
        }

        object.cdoInternalSetRevision(newRevision);
        changeState(object, CDOState.CLEAN);
        object.cdoInternalPostLoad();
        return;
      }

      if (key == null || key.getVersion() >= oldRevision.getVersion())
      {
        InternalCDORevision newRevision = null;

        CDOBranch viewBranch = view.getBranch();
        CDOBranchVersion newBranchVersion = getNewBranchVersion(key, viewBranch);
        if (newBranchVersion != null)
        {
          newRevision = (InternalCDORevision)cache.getRevisionByVersion(key.getID(), newBranchVersion);
        }

        if (newRevision != null)
        {
          object.cdoInternalSetRevision(newRevision);
          changeState(object, CDOState.CLEAN);
          object.cdoInternalPostLoad();
        }
        else
        {
          changeState(object, CDOState.PROXY);

          CDOInvalidationPolicy policy = view.options().getInvalidationPolicy();
          policy.handleInvalidation(object, key);

          object.cdoInternalPostInvalidate();
        }
      }
    }

    private CDOBranchVersion getNewBranchVersion(CDORevisionKey key, CDOBranch viewBranch)
    {
      if (key != null)
      {
        CDOBranch keyBranch = key.getBranch();

        if (key instanceof CDORevisionDelta)
        {
          CDORevisionDelta delta = (CDORevisionDelta)key;
          CDORevisable target = delta.getTarget();
          if (target != null && keyBranch == target.getBranch())
          {
            return target;
          }
        }

        if (keyBranch == viewBranch)
        {
          return keyBranch.getVersion(key.getVersion() + 1);
        }

        return viewBranch.getVersion(CDOBranchVersion.FIRST_VERSION);
      }

      return null;
    }
  }

  /**
   * @author Eike Stepper
   */
  private class ConflictTransition extends InvalidateTransition
  {
    @Override
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CDORevisionKey key)
    {
      InternalCDORevision oldRevision = object.cdoRevision();
      if (key == null || key.getVersion() >= oldRevision.getVersion() - 1)
      {
        changeState(object, CDOState.CONFLICT);
        InternalCDOTransaction transaction = object.cdoView().toTransaction();
        transaction.setConflict(object);
      }
    }
  }

  /**
   * @author Simon McDuff
   */
  private final class InvalidConflictTransition extends ConflictTransition
  {
    @Override
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CDORevisionKey UNUSED)
    {
      changeState(object, CDOState.INVALID_CONFLICT);

      InternalCDOTransaction transaction = object.cdoView().toTransaction();
      transaction.setConflict(object);
    }
  }

  /**
   * @author Eike Stepper
   */
  private final class LoadTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
  {
    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object UNUSED)
    {
      internalLoad(object, false);
    }
  }

  /**
   * @author Simon McDuff
   */
  private static final class InvalidTransition implements ITransition<CDOState, CDOEvent, InternalCDOObject, Object>
  {
    public static final InvalidTransition INSTANCE = new InvalidTransition();

    public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object NULL)
    {
      InternalCDOView view = object.cdoView();
      CDOInvalidationPolicy policy = view.options().getInvalidationPolicy();
      policy.handleInvalidObject(object);
    }
  }
}

/**
 * @author Eike Stepper
 */
enum CDOEvent
{
  PREPARE, ATTACH, DETACH, REATTACH, READ, WRITE, INVALIDATE, DETACH_REMOTE, COMMIT, ROLLBACK
}
