/*
 * Copyright (c) 2007-2015 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
 *    Christian W. Damus - partial/conditional persistence of features
 */
package org.eclipse.emf.internal.cdo;

import org.eclipse.emf.cdo.CDOLock;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOObjectHistory;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.security.CDOPermission;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOClassInfo;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOClassInfo.PersistenceFilter;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.messages.Messages;
import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
import org.eclipse.emf.internal.cdo.view.CDOStateMachine;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList.Listener;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.BasicEMap;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Internal.DynamicValueHolder;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
import org.eclipse.emf.ecore.impl.EStoreEObjectImpl.BasicEStoreFeatureMap;
import org.eclipse.emf.ecore.impl.MinimalEStoreEObjectImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Internal;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.spi.cdo.CDOStore;
import org.eclipse.emf.spi.cdo.FSMUtil;
import org.eclipse.emf.spi.cdo.InternalCDOLoadable;
import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.emf.spi.cdo.InternalCDOView.ViewAndState;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * The base class of all <em>native</em> {@link CDOObject objects}.
 *
 * @author Eike Stepper
 */
public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalCDOObject
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.class);

  private static final EObservableAdapterList.Listener ADAPTERS_LISTENER = new EObservableAdapterList.Listener()
  {
    public void added(Notifier notifier, Adapter adapter)
    {
      CDOObjectImpl object = (CDOObjectImpl)notifier;
      object.eAdapterAdded(adapter);
    }

    public void removed(Notifier notifier, Adapter adapter)
    {
      CDOObjectImpl object = (CDOObjectImpl)notifier;
      object.eAdapterRemoved(adapter);
    }
  };

  private static final EObservableAdapterList.Listener[] ADAPTERS_LISTENERS = { ADAPTERS_LISTENER };

  /**
   * Optimized storage of {@link CDOObject#cdoView()} and {@link CDOObject#cdoState()}.
   *
   * @see ViewAndState
   */
  private ViewAndState viewAndState = ViewAndState.TRANSIENT;

  /**
   * Optimized storage of {@link CDOObject#cdoID()} and {@link CDOObject#cdoRevision()}.
   * The idea is that, if a revision is set, the object's ID is equal to the {@link CDORevision revision's} ID.
   * The same is true for the classInfo field.
   */
  private InternalCDORevision revision;

  /**
   * Don't use the optional slot in MinimalEObject because a CDOObject always needs eSettings to store:
   * <ul>
   *  <li>the values of all features of transient objects,
   *  <li>the values of transient features of persistent objects and
   *  <li>the list wrappers of all many-valued features of all objects.
   * </ul>
   */
  private Object[] eSettings;

  public CDOObjectImpl()
  {
    initClassInfo(eStaticClass());
  }

  /**
   * @since 4.2
   */
  public final InternalCDOClassInfo cdoClassInfo()
  {
    return revision.getClassInfo();
  }

  public final CDOState cdoState()
  {
    return viewAndState.state;
  }

  /**
   * @since 2.0
   */
  public final InternalCDOView cdoView()
  {
    return viewAndState.view;
  }

  public final CDOID cdoID()
  {
    return revision.getID();
  }

  /**
   * @since 2.0
   */
  public final InternalCDORevision cdoRevision()
  {
    return revision.getProperRevision();
  }

  /**
   * @since 4.3
   */
  public final InternalCDORevision cdoRevision(boolean loadOnDemand)
  {
    InternalCDORevision revision = cdoRevision();
    if (revision == null && loadOnDemand)
    {
      revision = CDOStateMachine.INSTANCE.read(this);
    }

    return revision;
  }

  /**
   * @since 4.3
   */
  public final CDOPermission cdoPermission()
  {
    if (FSMUtil.isTransient(this))
    {
      return CDOPermission.WRITE;
    }

    return cdoRevision(true).getPermission();
  }

  public final CDOResource cdoResource()
  {
    Resource resource = eResource();
    if (resource instanceof CDOResource)
    {
      return (CDOResource)resource;
    }

    return null;
  }

  /**
   * @since 2.0
   */
  public final CDOResource cdoDirectResource()
  {
    Resource.Internal resource = eDirectResource();
    if (resource instanceof CDOResource)
    {
      return (CDOResource)resource;
    }

    return null;
  }

  /**
   * @since 3.0
   */
  public final void cdoPrefetch(int depth)
  {
    CDOID id = cdoID();
    viewAndState.view.prefetchRevisions(id, depth);
  }

  @Deprecated
  public final void cdoReload()
  {
    CDOStateMachine.INSTANCE.reload(this);
  }

  /**
   * @since 4.2
   */
  public final CDOObjectHistory cdoHistory()
  {
    return viewAndState.view.getHistory(this);
  }

  /**
   * @since 2.0
   */
  public final boolean cdoConflict()
  {
    return FSMUtil.isConflict(this);
  }

  /**
   * @since 2.0
   */
  public final boolean cdoInvalid()
  {
    return FSMUtil.isInvalid(this);
  }

  /**
   * @since 2.0
   */
  public final CDOLock cdoReadLock()
  {
    return createLock(this, LockType.READ);
  }

  /**
   * @since 2.0
   */
  public final CDOLock cdoWriteLock()
  {
    return createLock(this, LockType.WRITE);
  }

  /**
   * @since 4.1
   */
  public final CDOLock cdoWriteOption()
  {
    return createLock(this, LockType.OPTION);
  }

  /**
   * @since 4.1
   */
  public final CDOLockState cdoLockState()
  {
    return getLockState(this);
  }

  public final CDOState cdoInternalSetState(CDOState state)
  {
    CDOState oldState = viewAndState.state;
    if (oldState != state)
    {
      if (TRACER.isEnabled())
      {
        TRACER.format("Setting state {0} for {1}", state, this); //$NON-NLS-1$
      }

      viewAndState = viewAndState.getViewAndState(state);
      if (viewAndState.view != null)
      {
        viewAndState.view.handleObjectStateChanged(this, oldState, state);
      }

      return oldState;
    }

    return null;
  }

  /**
   * @since 2.0
   */
  public final void cdoInternalSetView(CDOView view)
  {
    InternalCDOView newView = (InternalCDOView)view;
    if (newView != null)
    {
      viewAndState = newView.getViewAndState(viewAndState.state);
    }
    else
    {
      viewAndState = ViewAndState.TRANSIENT.getViewAndState(viewAndState.state);
    }
  }

  public final void cdoInternalSetID(CDOID id)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Setting ID: {0}", id); //$NON-NLS-1$
    }

    if (id == null)
    {
      revision = cdoClassInfo().getRevisionForID(null);
    }
    else
    {
      revision = revision.getRevisionForID(id);
    }
  }

  /**
   * @since 2.0
   */
  public final void cdoInternalSetRevision(CDORevision revision)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$
    }

    if (revision == null)
    {
      InternalCDOClassInfo classInfo = cdoClassInfo();
      CDOID id = this.revision.getID();
      this.revision = classInfo.getRevisionForID(id);
    }
    else
    {
      if (this.revision != null)
      {
        CDOID objectID = this.revision.getID();
        if (objectID != null && objectID != revision.getID())
        {
          throw new IllegalArgumentException("The revision " + revision + " does not match the object " + objectID);
        }
      }

      this.revision = (InternalCDORevision)revision;
    }
  }

  public final void cdoInternalSetResource(CDOResource resource)
  {
    // Unsets direct resource and/or eContainer.
    // Only intended to be called by CDOTransactionImpl.removeObject(CDOID, CDOObject).
    // See bug 383370.

    if (resource != null)
    {
      throw new IllegalArgumentException(
          "Only intended to be called by CDOTransactionImpl.removeObject(CDOID, CDOObject");
    }

    super.eSetDirectResource(null);
    eBasicSetContainer(null);
    eBasicSetContainerFeatureID(0);
  }

  /**
   * @since 2.0
   */
  public void cdoInternalPreLoad()
  {
    // Do nothing
  }

  public final void cdoInternalPostLoad()
  {
    // Reset EMAP objects
    Object[] eSettings = eBasicSettings();
    if (eSettings != null)
    {
      // Make sure transient features are kept but persisted values are not cached.
      InternalCDOClassInfo classInfo = cdoClassInfo();
      int featureCount = classInfo.getEClass().getFeatureCount();
      for (int i = 0; i < featureCount; i++)
      {
        // We need to keep the existing list if possible.
        int index = classInfo.getSettingsFeatureIndex(i);
        if (index != InternalCDOClassInfo.NO_SLOT)
        {
          Object value = eSettings[index];
          if (value instanceof InternalCDOLoadable)
          {
            ((InternalCDOLoadable)value).cdoInternalPostLoad();
          }
        }
      }
    }
  }

  /**
   * @since 2.0
   */
  public final void cdoInternalPostInvalidate()
  {
    cdoInternalSetRevision(null);
  }

  public final void cdoInternalPostAttach()
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Populating revision for {0}", this); //$NON-NLS-1$
    }

    InternalEObject eContainer = eBasicInternalContainer();
    int eContainerFeatureID = eBasicContainerFeatureID();

    InternalCDORevision revision = cdoRevision();
    revision.setContainerID(eContainer == null ? CDOID.NULL : viewAndState.view.convertObjectToID(eContainer, true));
    revision.setContainingFeatureID(eContainerFeatureID);

    Resource directResource = eDirectResource();
    if (directResource instanceof CDOResource)
    {
      CDOResource cdoResource = (CDOResource)directResource;
      revision.setResourceID(cdoResource.cdoID());
    }

    if (eSettings != null)
    {
      InternalCDOClassInfo classInfo = cdoClassInfo();
      EStructuralFeature[] allPersistentFeatures = classInfo.getAllPersistentFeatures();
      int length = allPersistentFeatures.length;
      for (int i = 0; i < length; i++)
      {
        EStructuralFeature eFeature = allPersistentFeatures[i];
        int transientIndex = classInfo.getTransientFeatureIndex(eFeature);
        Object setting = eSettings[transientIndex]; // Can be safely accessed directly because we come from TRANSIENT

        instanceToRevisionFeature(viewAndState.view, this, eFeature, setting);
      }

      cdoRevision().setUnchunked();

      int newSize = classInfo.getSettingsFeatureCount();
      if (newSize != eSettings.length)
      {
        Object[] newSettings = new Object[newSize];
        System.arraycopy(eSettings, 0, newSettings, 0, newSize);
        eSettings = newSettings;
      }
    }
  }

  /**
   * It is really important for accessing the data to go through {@link #cdoStore()}. {@link #eStore()} will redirect
   * you to the transient data.
   *
   * @since 2.0
   */
  public void cdoInternalPostDetach(boolean remote)
  {
    if (remote)
    {
      eSetDeliver(false);
      eBasicSetContainer(null, eContainerFeatureID());
      eSetDeliver(true);
      return;
    }

    if (TRACER.isEnabled())
    {
      TRACER.format("Depopulating revision for {0}", this); //$NON-NLS-1$
    }

    InternalCDOClassInfo classInfo = cdoClassInfo();

    CDOStore store = cdoStore();
    super.eSetDirectResource((Resource.Internal)store.getResource(this));
    eBasicSetContainer(store.getContainer(this));
    eBasicSetContainerFeatureID(store.getContainingFeatureID(this));

    if (eSettings != null)
    {
      int newSize = classInfo.getSettingsFeatureCount() + classInfo.getTransientFeatureCount();
      if (newSize != eSettings.length)
      {
        Object[] newSettings = new Object[newSize];
        System.arraycopy(eSettings, 0, newSettings, 0, eSettings.length);
        eSettings = newSettings;
      }
    }

    InternalCDORevision revision = cdoRevision();
    EStructuralFeature[] allPersistentFeatures = classInfo.getAllPersistentFeatures();
    for (EStructuralFeature eFeature : allPersistentFeatures)
    {
      revisionToInstanceFeature(this, revision, eFeature);
    }
  }

  /**
   * @since 3.0
   */
  public final void cdoInternalPostRollback()
  {
    // Do nothing
  }

  public final void cdoInternalPreCommit()
  {
    // Do nothing
  }

  public final InternalEObject cdoInternalInstance()
  {
    return this;
  }

  @Deprecated
  public final EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID)
  {
    throw new UnsupportedOperationException();
  }

  private CDOStore cdoStore()
  {
    return viewAndState.view.getStore();
  }

  /**
   * @since 2.0
   */
  @Override
  public final EStore eStore()
  {
    if (FSMUtil.isTransient(this))
    {
      return TransientStore.INSTANCE;
    }

    return cdoStore();
  }

  @Override
  protected final EClass eDynamicClass()
  {
    EClass eClass = eClass();
    if (eClass == eStaticClass())
    {
      return null;
    }

    return eClass;
  }

  @Override
  public final EClass eClass()
  {
    return revision.getEClass();
  }

  @Override
  public void eSetClass(EClass eClass)
  {
    initClassInfo(eClass);
  }

  /**
   * @since 2.0
   */
  @Override
  public Resource.Internal eDirectResource()
  {
    if (FSMUtil.isTransient(this))
    {
      return super.eDirectResource();
    }

    return (Resource.Internal)cdoStore().getResource(this);
  }

  @Override
  public final Resource.Internal eInternalResource()
  {
    CDOView view = cdoView();
    if (view != null && view.isClosed())
    {
      return null;
    }

    if (FSMUtil.isInvalid(this))
    {
      return null;
    }

    return super.eInternalResource();
  }

  @Override
  public final Object dynamicGet(int dynamicFeatureID)
  {
    InternalCDOClassInfo classInfo = cdoClassInfo();
    int index = classInfo.getSettingsFeatureIndex(dynamicFeatureID);
    if (index == InternalCDOClassInfo.NO_SLOT)
    {
      // The feature has no slot in eSettings, i.e., it's persistent or single-valued.
      // Delegate to the store. TransientStore delegates back to eSettings.
      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
      EStore eStore = eStore();
      return eStore.get(this, eStructuralFeature, EStore.NO_INDEX);
    }

    // Here we know that the feature is transient or many-valued, hence it has a slot in eSettings.
    Object[] eSettings = eBasicSettings();
    Object result = eSettings[index];
    if (result == null)
    {
      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
      if (classInfo.isPersistent(dynamicFeatureID))
      {
        if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
        {
          eSettings[index] = result = createFeatureMap(eStructuralFeature);
        }
        else if (eStructuralFeature.isMany())
        {
          eSettings[index] = result = createList(eStructuralFeature);
        }
      }
    }

    return result;
  }

  @Override
  public final void dynamicSet(int dynamicFeatureID, Object value)
  {
    InternalCDOClassInfo classInfo = cdoClassInfo();
    int index = classInfo.getSettingsFeatureIndex(dynamicFeatureID);
    if (index == InternalCDOClassInfo.NO_SLOT)
    {
      // The feature has no slot in eSettings, i.e., it's persistent or single-valued.
      // Delegate to the store. TransientStore delegates back to eSettings.
      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
      EStore eStore = eStore();
      eStore.set(this, eStructuralFeature, EStore.NO_INDEX, value);
    }
    else
    {
      Object[] eSettings = eBasicSettings();
      eSettings[index] = value;
    }
  }

  @Override
  public final void dynamicUnset(int dynamicFeatureID)
  {
    InternalCDOClassInfo classInfo = cdoClassInfo();
    int index = classInfo.getSettingsFeatureIndex(dynamicFeatureID);
    if (index == InternalCDOClassInfo.NO_SLOT)
    {
      // The feature has no slot in eSettings, i.e., it's persistent or single-valued.
      // Delegate to the store. TransientStore delegates back to eSettings.
      EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
      EStore eStore = eStore();
      eStore.unset(this, eStructuralFeature);
    }
    else
    {
      Object[] eSettings = eBasicSettings();
      Object oldValue = eSettings[index];
      if (oldValue != null)
      {
        if (oldValue instanceof InternalEList)
        {
          InternalEList<?> list = (InternalEList<?>)oldValue;
          if (list instanceof InternalEList.Unsettable)
          {
            ((InternalEList.Unsettable<?>)list).unset();
          }
          else
          {
            list.clear();
          }
        }
        else
        {
          eSettings[index] = null;
        }
      }
    }
  }

  /**
   * @since 2.0
   */
  @Override
  protected final boolean eDynamicIsSet(int dynamicFeatureID, EStructuralFeature eFeature)
  {
    if (dynamicFeatureID < 0)
    {
      return eOpenIsSet(eFeature);
    }

    InternalCDOClassInfo classInfo = cdoClassInfo();
    if (classInfo.isPersistent(dynamicFeatureID))
    {
      return eStore().isSet(this, eFeature);
    }

    return eSettingDelegate(eFeature).dynamicIsSet(this, eSettings(), dynamicFeatureID);
  }

  @Override
  public final InternalEObject eInternalContainer()
  {
    if (FSMUtil.isTransient(this) || FSMUtil.isInvalid(this))
    {
      return eBasicInternalContainer();
    }

    return cdoStore().getContainer(this);
  }

  @Override
  public final int eContainerFeatureID()
  {
    if (FSMUtil.isTransient(this) || FSMUtil.isInvalid(this))
    {
      return eBasicContainerFeatureID();
    }

    return cdoStore().getContainingFeatureID(this);
  }

  /**
   * Code taken from {@link BasicEObjectImpl#eBasicSetContainer} and modified to detect whether the object is moved in the
   * same context. (E.g.: An object is moved from resA to resB. resA and resB belongs to the same CDORepositoryInfo.
   * Without this special handling, a detach and newObject will be generated for the object moved)
   *
   * @since 2.0
   */
  @Override
  public final NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
      NotificationChain msgs)
  {
    boolean isResource = this instanceof CDOResource;
    boolean isRootResource = isResource && ((CDOResource)this).isRoot();

    InternalEObject oldContainer = eInternalContainer();
    Resource.Internal oldResource = eDirectResource();
    Resource.Internal newResource = null;
    if (oldResource != null)
    {
      if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
      {
        msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
        eSetDirectResource(null);
        newResource = newContainer.eInternalResource();
      }
      else
      {
        oldResource = null;
      }
    }
    else
    {
      if (oldContainer != null)
      {
        oldResource = oldContainer.eInternalResource();
      }

      if (newContainer != null)
      {
        newResource = newContainer.eInternalResource();
      }
    }

    CDOView oldView = viewAndState.view;
    CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
        : null;

    boolean moved = oldView != null && oldView == newView;
    if (!moved && oldResource != null && oldResource != newResource && !isRootResource)
    {
      oldResource.detached(this);
    }

    int oldContainerFeatureID = eContainerFeatureID();
    eBasicSetContainer(newContainer, newContainerFeatureID);

    if (!moved && newResource != null && newResource != oldResource)
    {
      newResource.attached(this);
    }

    if (eNotificationRequired())
    {
      if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
      {
        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
            oldContainer, null);
        if (msgs == null)
        {
          msgs = notification;
        }
        else
        {
          msgs.add(notification);
        }
      }

      if (newContainerFeatureID >= 0)
      {
        ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
            oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
        if (msgs == null)
        {
          msgs = notification;
        }
        else
        {
          msgs.add(notification);
        }
      }
    }

    return msgs;
  }

  /**
   * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
   * context.
   *
   * @since 2.0
   */
  @Override
  public final NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
  {
    Resource.Internal oldResource = eDirectResource();

    CDOView oldView = viewAndState.view;
    CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;

    boolean isSameView;
    if (viewAndState.state == CDOState.NEW)
    {
      isSameView = false;
    }
    else
    {
      isSameView = oldView != null && oldView == newView;
    }

    if (oldResource != null && resource != null)
    {
      notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);

      // When setting the resource to null we assume that detach has already been called in the resource implementation
      if (!isSameView)
      {
        oldResource.detached(this);
      }
    }

    InternalEObject oldContainer = eInternalContainer();
    if (oldContainer != null && !isSameView)
    {
      if (eContainmentFeature().isResolveProxies())
      {
        Resource.Internal oldContainerResource = oldContainer.eInternalResource();
        if (oldContainerResource != null)
        {
          // If we're not setting a new resource, attach it to the old container's resource.
          if (resource == null)
          {
            oldContainerResource.attached(this);
          }

          // If we didn't detach it from an old resource already, detach it from the old container's resource.
          //
          else if (oldResource == null)
          {
            oldContainerResource.detached(this);
          }
        }
      }
      else
      {
        notifications = eBasicRemoveFromContainer(notifications);
        notifications = eBasicSetContainer(null, -1, notifications);
      }
    }

    eSetDirectResource(resource);

    return notifications;
  }

  @Override
  protected final void eSetDirectResource(Internal resource)
  {
    if (FSMUtil.isTransient(this))
    {
      super.eSetDirectResource(resource);
    }
    else if (resource == null || resource instanceof CDOResource)
    {
      cdoStore().setContainer(this, (CDOResource)resource, eInternalContainer(), eContainerFeatureID());
    }
    else
    {
      throw new IllegalArgumentException(Messages.getString("CDOObjectImpl.8")); //$NON-NLS-1$
    }
  }

  @Override
  protected final void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID); //$NON-NLS-1$
    }

    if (FSMUtil.isTransient(this) || FSMUtil.isInvalid(this))
    {
      super.eBasicSetContainer(newEContainer, newContainerFeatureID);
    }
    else
    {
      CDOStore cdoStore = cdoStore();
      cdoStore.setContainer(this, cdoDirectResource(), newEContainer, newContainerFeatureID);
    }
  }

  @Override
  protected final int eDynamicFeatureID(EStructuralFeature eStructuralFeature)
  {
    // CDOObjectImpl has no static features, so don't subract their count here:
    EClass eClass = eClass();
    return eClass.getFeatureID(eStructuralFeature);
  }

  @Override
  protected final EStructuralFeature eDynamicFeature(int dynamicFeatureID)
  {
    // CDOObjectImpl has no static features, so don't add their count here:
    EClass eClass = eClass();
    return eClass.getEStructuralFeature(dynamicFeatureID);
  }

  @Override
  protected final DynamicValueHolder eSettings()
  {
    if (!eHasSettings())
    {
      InternalCDOClassInfo classInfo = cdoClassInfo();
      int size = classInfo.getSettingsFeatureCount();
      if (FSMUtil.isTransient(this))
      {
        size += classInfo.getTransientFeatureCount();
      }

      if (size != 0)
      {
        eBasicSetSettings(new Object[size]);
      }
    }

    return this;
  }

  @Override
  protected final boolean eHasSettings()
  {
    return eSettings != null;
  }

  @Override
  protected final Object[] eBasicSettings()
  {
    return eSettings;
  }

  @Override
  protected final void eBasicSetSettings(Object[] settings)
  {
    eSettings = settings;
  }

  /**
   * Don't cache non-transient features in this CDOObject's {@link #eSettings()}.
   */
  @Override
  protected final boolean eIsCaching()
  {
    return false;
  }

  @Override
  protected final Adapter[] eContainerAdapterArray()
  {
    if (FSMUtil.isTransient(this))
    {
      return super.eContainerAdapterArray();
    }

    InternalCDOView view = cdoView();
    if (view.isClosed())
    {
      return null;
    }

    CDOObject container;

    InternalCDORevision revision = cdoRevision();
    if (revision != null)
    {
      Object containerID = revision.getContainerID();

      if (containerID instanceof CDOID)
      {
        container = view.getObject((CDOID)containerID, false);
      }
      else
      {
        container = (CDOObject)containerID;
      }

      if (container != null)
      {
        if (container instanceof CDOObjectImpl)
        {
          return ((CDOObjectImpl)container).eBasicAdapterArray();
        }

        if (container instanceof BasicEObjectImpl)
        {
          return super.eContainerAdapterArray();
        }
      }
    }

    return null;
  }

  /**
   * This method is not called by the MinimalEStoreEObjectImpl in CDO's ecore.minimal (retrofitting) fragment
   * but it is called by the normal MinimalEObjectImpl as of EMF 2.9.
   *
   * @since 4.2
   */
  @Override
  protected final Listener[] eBasicAdapterListeners()
  {
    Listener[] listeners = super.eBasicAdapterListeners();
    if (listeners == null)
    {
      return ADAPTERS_LISTENERS;
    }

    return listeners;
  }

  /**
   * This method is not called by the MinimalEStoreEObjectImpl in CDO's ecore.minimal (retrofitting) fragment
   * but it is called by the normal MinimalEObjectImpl as of EMF 2.9.
   *
   * @since 4.2
   */
  @Override
  protected final void eBasicSetAdapterListeners(Listener[] eAdapterListeners)
  {
    if (eAdapterListeners != null)
    {
      if (eAdapterListeners.length == 1)
      {
        // Because noone else can remove ADAPTERS_LISTENER this must be it
        eAdapterListeners = null;
      }
    }

    super.eBasicSetAdapterListeners(eAdapterListeners);
  }

  /**
   * This method must not be private because the MinimalEStoreEObjectImpl in CDO's ecore.minimal (retrofitting) fragment
   * introduces it as a protected method and calls it.
   *
   * @since 4.2
   */
  protected final void eAdapterAdded(Adapter adapter)
  {
    if (!FSMUtil.isTransient(this))
    {
      viewAndState.view.handleAddAdapter(this, adapter);
    }
  }

  /**
   * This method must not be private because the MinimalEStoreEObjectImpl in CDO's ecore.minimal (retrofitting) fragment
   * introduces it as a protected method and calls it.
   *
   * @since 4.2
   */
  protected final void eAdapterRemoved(Adapter adapter)
  {
    if (!FSMUtil.isTransient(this))
    {
      viewAndState.view.handleRemoveAdapter(this, adapter);
    }
  }

  /**
   * Specializing the behaviour of {@link #hashCode()} is not permitted as per {@link EObject} specification.
   */
  @Override
  public final int hashCode()
  {
    return super.hashCode();
  }

  /**
   * Specializing the behaviour of {@link #equals(Object)} is not permitted as per {@link EObject} specification.
   */
  @Override
  public final boolean equals(Object obj)
  {
    return super.equals(obj);
  }

  @Override
  public String toString()
  {
    String str = eClass().getName();

    CDOID id = cdoID();
    if (id != null)
    {
      str += "@" + id;
    }

    CDOState cdoState = cdoState();
    if (cdoState != CDOState.CLEAN)
    {
      str += "[" + cdoState + "]";
    }

    return str;
  }

  @Override
  protected final FeatureMap createFeatureMap(EStructuralFeature eStructuralFeature)
  {
    return new CDOStoreFeatureMap(eStructuralFeature);
  }

  /**
   * @since 4.1
   */
  protected final CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature)
  {
    return new CDOStoreEcoreEMap(eStructuralFeature);
  }

  /**
   * @since 4.1
   */
  protected final CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature)
  {
    return new CDOStoreUnorderedEList<Object>(eStructuralFeature);
  }

  @Override
  protected EList<?> createList(EStructuralFeature eStructuralFeature)
  {
    if (isMap(eStructuralFeature))
    {
      return createMap(eStructuralFeature);
    }

    if (!eStructuralFeature.isOrdered())
    {
      return createUnorderedList(eStructuralFeature);
    }

    return super.createList(eStructuralFeature);
  }

  private boolean isMap(EStructuralFeature eStructuralFeature)
  {
    // Answer from Christian Damus:
    // Java ensures that string constants are interned, so == is actually more efficient than equals() and it's correct
    return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$
  }

  private void initClassInfo(EClass eClass)
  {
    InternalCDOClassInfo classInfo = (InternalCDOClassInfo)CDOModelUtil.getClassInfo(eClass);
    revision = classInfo.getRevisionForID(null);
  }

  /**
   * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
   * was not {@link CDOState#NEW}.
   */
  private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject opposite,
      EReference oppositeReference)
  {
    if (opposite != null)
    {
      InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(opposite);
      if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
      {
        if (oppositeReference.isMany())
        {
          EStore eStore = cdoObject.eStore();
          int index = eStore.indexOf(cdoObject, oppositeReference, instance.cdoID());
          if (index != -1)
          {
            eStore.set(cdoObject, oppositeReference, index, instance);
          }
        }
        else
        {
          EStore eStore = cdoObject.eStore();
          eStore.set(cdoObject, oppositeReference, 0, instance);
        }
      }
      else
      {
        if (oppositeReference.isResolveProxies())
        {
          // We should not trigger events. But we have no choice :-(.
          if (oppositeReference.isMany())
          {
            @SuppressWarnings("unchecked")
            List<Object> list = (List<Object>)opposite.eGet(oppositeReference);
            int index = list.indexOf(instance);
            if (index != -1)
            {
              list.set(index, instance);
            }
          }
          else
          {
            opposite.eSet(oppositeReference, instance);
          }
        }
      }
    }
  }

  /**
   * @since 3.0
   */
  public static void instanceToRevisionFeature(InternalCDOView view, InternalCDOObject object,
      EStructuralFeature feature, Object setting)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Populating feature {0}", feature); //$NON-NLS-1$
    }

    PersistenceFilter filter = ((InternalCDOClassInfo)CDOModelUtil.getClassInfo(feature.getEContainingClass()))
        .getPersistenceFilter(feature);
    if (filter != null)
    {
      if (TRACER.isEnabled())
      {
        TRACER.format("Filtering value of feature {0}", feature); //$NON-NLS-1$
      }

      setting = filter.getPersistableValue(object, setting);
    }

    CDOStore cdoStore = view.getStore();
    InternalCDORevision revision = object.cdoRevision();

    if (feature.isMany())
    {
      if (setting != null)
      {
        int index = 0;
        @SuppressWarnings("unchecked")
        EList<Object> list = (EList<Object>)setting;
        for (Object value : list)
        {
          Object cdoValue = cdoStore.convertToCDO(object, feature, value);
          revision.add(feature, index++, cdoValue);
        }
      }
    }
    else
    {
      Object cdoValue = cdoStore.convertToCDO(object, feature, setting);
      revision.set(feature, 0, cdoValue);
    }
  }

  /**
   * @since 2.0
   */
  public static void revisionToInstanceFeature(InternalCDOObject instance, InternalCDORevision revision,
      EStructuralFeature eFeature)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Depopulating feature {0}", eFeature); //$NON-NLS-1$
    }

    EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature;
    InternalCDOView view = instance.cdoView();
    EReference oppositeReference = view.isObjectNew(instance.cdoID()) ? null : internalFeature.getEOpposite();

    CDOStore cdoStore = view.getStore();
    EStore eStore = instance.eStore();

    if (eFeature.isMany())
    {
      int size = cdoStore.size(instance, eFeature);
      for (int index = 0; index < size; index++)
      {
        // Do not trigger events
        // Do not trigger inverse updates
        Object opposite = cdoStore.get(instance, eFeature, index);
        eStore.add(instance, eFeature, index, opposite);
        if (oppositeReference != null)
        {
          adjustOppositeReference(instance, (InternalEObject)opposite, oppositeReference);
        }
      }
    }
    else
    {
      Object opposite = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
      eStore.set(instance, eFeature, EStore.NO_INDEX, opposite);
      if (oppositeReference != null)
      {
        adjustOppositeReference(instance, (InternalEObject)opposite, oppositeReference);
      }
    }
  }

  /**
   * @since 4.1
   */
  public static CDOLock createLock(InternalCDOObject object, LockType type)
  {
    if (FSMUtil.isTransient(object))
    {
      throw new IllegalStateException("Call CDOView.lockObjects() for transient object " + object);
    }

    return new CDOLockImpl(object, type);
  }

  /**
   * @since 4.1
   */
  public static CDOLockState getLockState(InternalCDOObject object)
  {
    if (!FSMUtil.isTransient(object))
    {
      InternalCDOView view = object.cdoView();
      CDOID id = object.cdoID();

      return view.getLockStates(Collections.singletonList(id))[0];
    }

    return null;
  }

  /**
   * Implements an internal EStore for TRANSIENT objects, where there is no view or {@link CDOStore}.
   * <p>
   * Feature values are actually stored in {@link CDOObjectImpl#cdoSettings}.
   *
   * @author Simon McDuff
   * @since 2.0
   */
  private static final class TransientStore implements InternalEObject.EStore
  {
    public static TransientStore INSTANCE = new TransientStore();

    private TransientStore()
    {
    }

    private Object getValue(InternalEObject eObject, int transientIndex)
    {
      Object[] settings = getSettings(eObject);
      return settings[transientIndex];
    }

    private EList<Object> getValueAsList(InternalEObject eObject, int transientIndex)
    {
      Object[] settings = getSettings(eObject);

      @SuppressWarnings("unchecked")
      EList<Object> result = (EList<Object>)settings[transientIndex];
      if (result == null)
      {
        result = new BasicEList<Object>();
        settings[transientIndex] = result;
      }

      return result;
    }

    private Object setValue(InternalEObject eObject, int transientIndex, Object newValue)
    {
      Object[] settings = getSettings(eObject);
      Object oldValue = settings[transientIndex];
      settings[transientIndex] = newValue;
      return oldValue;
    }

    private Object[] getSettings(InternalEObject eObject)
    {
      CDOObjectImpl object = (CDOObjectImpl)eObject;
      object.eSettings(); // Ensure that the array is created
      return object.eSettings;
    }

    private int getTransientFeatureIndex(InternalEObject eObject, EStructuralFeature feature)
    {
      CDOObjectImpl object = (CDOObjectImpl)eObject;
      InternalCDOClassInfo classInfo = object.cdoClassInfo();
      return classInfo.getTransientFeatureIndex(feature);
    }

    public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      if (index != NO_INDEX)
      {
        return getValueAsList(eObject, transientIndex).get(index);
      }

      return getValue(eObject, transientIndex);
    }

    public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      if (index != NO_INDEX)
      {
        return getValueAsList(eObject, transientIndex).set(index, value);
      }

      return setValue(eObject, transientIndex, value);
    }

    public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      getValueAsList(eObject, transientIndex).add(index, value);
    }

    public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).remove(index);
    }

    public Object move(InternalEObject eObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).move(targetIndex, sourceIndex);
    }

    public void clear(InternalEObject eObject, EStructuralFeature feature)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      if (feature.isMany())
      {
        getValueAsList(eObject, transientIndex).clear();
      }

      setValue(eObject, transientIndex, null);
    }

    public int size(InternalEObject eObject, EStructuralFeature feature)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).size();
    }

    public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).indexOf(value);
    }

    public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).lastIndexOf(value);
    }

    public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).toArray();
    }

    public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] array)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).toArray(array);
    }

    public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).isEmpty();
    }

    public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).contains(value);
    }

    public int hashCode(InternalEObject eObject, EStructuralFeature feature)
    {
      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return getValueAsList(eObject, transientIndex).hashCode();
    }

    public InternalEObject getContainer(InternalEObject eObject)
    {
      return null;
    }

    public EStructuralFeature getContainingFeature(InternalEObject eObject)
    {
      throw new UnsupportedOperationException("Should never be called");
    }

    public EObject create(EClass eClass)
    {
      throw new UnsupportedOperationException("Should never be called");
    }

    public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
    {
      if (!feature.isUnsettable())
      {
        if (feature.isMany())
        {
          @SuppressWarnings("unchecked")
          List<Object> list = (InternalEList<Object>)eObject.eGet(feature, false);
          return list != null && !list.isEmpty();
        }

        return !ObjectUtil.equals(eObject.eGet(feature, false), feature.getDefaultValue());
      }

      Object[] settings = ((CDOObjectImpl)eObject).eSettings;
      if (settings == null)
      {
        return false;
      }

      int transientIndex = getTransientFeatureIndex(eObject, feature);
      return settings[transientIndex] != null;
    }

    public void unset(InternalEObject eObject, EStructuralFeature feature)
    {
      CDOObjectImpl cdoObject = (CDOObjectImpl)eObject;

      if (feature.isMany())
      {
        // Object object = get(eObject, feature, NO_INDEX);
        Object object = cdoObject.eGet(feature, false);
        if (object instanceof List<?>)
        {
          List<?> list = (List<?>)object;
          list.clear();
        }
      }
      else
      {

        Object[] settings = cdoObject.eSettings;
        if (settings == null)
        {
          // Is already unset
          return;
        }

        int transientIndex = getTransientFeatureIndex(eObject, feature);
        settings[transientIndex] = null;
      }
    }
  }

  /**
   * For internal use only.
   *
   * @author Eike Stepper
   * @since 4.1
   */
  private final class CDOStoreEcoreEMap extends EcoreEMap<Object, Object>implements InternalCDOLoadable
  {
    private static final long serialVersionUID = 1L;

    public CDOStoreEcoreEMap(EStructuralFeature eStructuralFeature)
    {
      super((EClass)eStructuralFeature.getEType(), BasicEMap.Entry.class, null);
      delegateEList = new EStoreEObjectImpl.BasicEStoreEList<BasicEMap.Entry<Object, Object>>(CDOObjectImpl.this,
          eStructuralFeature)
      {
        private static final long serialVersionUID = 1L;

        @Override
        public void unset()
        {
          super.unset();
          doClear();
        }

        @Override
        protected void didAdd(int index, BasicEMap.Entry<Object, Object> newObject)
        {
          CDOStoreEcoreEMap.this.doPut(newObject);
        }

        @Override
        protected void didSet(int index, BasicEMap.Entry<Object, Object> newObject,
            BasicEMap.Entry<Object, Object> oldObject)
        {
          didRemove(index, oldObject);
          didAdd(index, newObject);
        }

        @Override
        protected void didRemove(int index, BasicEMap.Entry<Object, Object> oldObject)
        {
          CDOStoreEcoreEMap.this.doRemove(oldObject);
        }

        @Override
        protected void didClear(int size, Object[] oldObjects)
        {
          CDOStoreEcoreEMap.this.doClear();
        }

        @Override
        protected void didMove(int index, BasicEMap.Entry<Object, Object> movedObject, int oldIndex)
        {
          CDOStoreEcoreEMap.this.doMove(movedObject);
        }
      };

      size = delegateEList.size();
    }

    private void checkListForReading()
    {
      if (!FSMUtil.isTransient(CDOObjectImpl.this))
      {
        CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
      }
    }

    /**
     * Ensures that the entry data is created and is populated with contents of the delegate list.
     */
    @Override
    protected synchronized void ensureEntryDataExists()
    {
      checkListForReading();
      super.ensureEntryDataExists();
    }

    @Override
    public int size()
    {
      checkListForReading();
      return size;
    }

    @Override
    public boolean isEmpty()
    {
      checkListForReading();
      return size == 0;
    }

    @Override
    public boolean contains(Object object)
    {
      checkListForReading();
      return super.contains(object);
    }

    @Override
    public boolean containsAll(Collection<?> collection)
    {
      checkListForReading();
      return super.containsAll(collection);
    }

    @Override
    public boolean containsKey(Object key)
    {
      checkListForReading();
      return super.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value)
    {
      checkListForReading();
      return super.containsValue(value);
    }

    public void cdoInternalPreLoad()
    {
    }

    public void cdoInternalPostLoad()
    {
      entryData = null;
      size = delegateEList.size();
    }
  }

  /**
   * For internal use only.
   *
   * @author Andras Peteri
   * @since 4.1
   */
  private final class CDOStoreUnorderedEList<E> extends EStoreEObjectImpl.BasicEStoreEList<E>
  {
    private static final long serialVersionUID = 1L;

    public CDOStoreUnorderedEList(EStructuralFeature feature)
    {
      super(CDOObjectImpl.this, feature);
    }

    @Override
    public E remove(int index)
    {
      boolean oldObjectIsLast = index == size() - 1;
      E oldObject = super.remove(index);

      if (!oldObjectIsLast)
      {
        move(index, size() - 1);
      }

      return oldObject;
    }
  }

  /**
   * For internal use only.
   *
   * @author Eike Stepper
   */
  private final class CDOStoreFeatureMap extends BasicEStoreFeatureMap
  {
    private static final long serialVersionUID = 1L;

    public CDOStoreFeatureMap(EStructuralFeature eStructuralFeature)
    {
      super(CDOObjectImpl.this, eStructuralFeature);
    }
  }
}
