/*
 * Copyright (c) 2004 - 2011 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
 *    Martin Fluegge - bug 247226: Transparently support legacy models
 */
package org.eclipse.emf.internal.cdo.object;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.model.CDOType;
import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.common.util.CDOException;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.bundle.OM;
import org.eclipse.emf.internal.cdo.view.CDOStateMachine;

import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.om.trace.ContextTracer;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
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.InternalCDOObject;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Eike Stepper
 * @author Martin Fluegge
 * @since 2.0
 */
public abstract class CDOLegacyWrapper extends CDOObjectWrapper
{
  private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyWrapper.class);

  /**
   * This ThreadLocal map stores all pre-registered objects. This avoids a never-ending loop when setting the container
   * of an object.
   */
  private static ThreadLocal<Map<CDOID, CDOLegacyWrapper>> wrapperRegistry = new InheritableThreadLocal<Map<CDOID, CDOLegacyWrapper>>()
  {
    @Override
    protected Map<CDOID, CDOLegacyWrapper> initialValue()
    {
      return new HashMap<CDOID, CDOLegacyWrapper>();
    }
  };

  private static ThreadLocal<Counter> recursionCounter = new InheritableThreadLocal<Counter>()
  {
    @Override
    protected Counter initialValue()
    {
      return new Counter();
    }
  };

  protected CDOState state;

  protected InternalCDORevision revision;

  /**
   * It could happen that while <i>revisionToInstance()</i> is executed externally the <i>internalPostLoad()</i> method
   * will be called. This happens for example if <i>internalPostInvalidate()</i> is called. The leads to another
   * <i>revisionToInstance()</i> call while the first call has not finished. This is certainly not so cool. That's why
   * <b>underConstruction</b> will flag that <i>revisionToInstance()</i> is still running and avoid the second call.
   * 
   * @since 3.0
   */
  private boolean underConstruction;

  public CDOLegacyWrapper(InternalEObject instance)
  {
    this.instance = instance;
    state = CDOState.TRANSIENT;
  }

  public CDOState cdoState()
  {
    return state;
  }

  public InternalCDORevision cdoRevision()
  {
    return revision;
  }

  @Override
  public CDOResourceImpl cdoResource()
  {
    revisionToInstanceResource();
    return super.cdoResource();
  }

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

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

      CDOState oldState = this.state;
      this.state = state;
      adjustEProxy();

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

      return oldState;
    }

    return null;
  }

  public void cdoInternalSetRevision(CDORevision revision)
  {
    if (TRACER.isEnabled())
    {
      TRACER.trace("Setting revision: " + revision); //$NON-NLS-1$
    }

    this.revision = (InternalCDORevision)revision;
  }

  public void cdoInternalPostAttach()
  {
    instanceToRevision();

    for (Adapter adapter : eAdapters())
    {
      if (!(adapter instanceof CDOObjectWrapper))
      {
        view.handleAddAdapter(this, adapter);
        view.subscribe(this, adapter);
      }
    }
  }

  public void cdoInternalPostDetach(boolean remote)
  {
    if (remote)
    {
      // Do nothing??
      return;
    }

    EClass eClass = revision.getEClass();

    // This loop adjusts the opposite wrapper objects to support dangling references. See Bugzilla_251263_Test
    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
    {
      EReference oppositeReference = ((EStructuralFeature.Internal)feature).getEOpposite();
      if (oppositeReference != null && !oppositeReference.isContainment() && EMFUtil.isPersistent(oppositeReference))
      {
        if (feature.isMany())
        {
          int size = revision.size(feature);
          for (int i = 0; i < size; i++)
          {
            EObject object = (EObject)getValueFromRevision(feature, i);
            adjustPersistentOppositeReference(this, object, oppositeReference);
          }
        }
        else
        {
          EObject oppositeObject = (EObject)instance.eGet(feature);
          if (oppositeObject != null)
          {
            adjustPersistentOppositeReference(this, oppositeObject, oppositeReference);
          }
        }
      }
    }
  }

  /**
   * @since 3.0
   */
  public void cdoInternalPostRollback()
  {
    CDOStateMachine.INSTANCE.read(this);
  }

  /**
   * CDO persists the isUnset state of an eObject in the database. The indicator for this is that the feature is null in
   * the revision (see CDOStore.isSet()). When committing a legacy object all values in the instance for native
   * attributes are set with the java default values. So, these values will be stored in the revision and CDO cannot
   * distinguish whether the feature is set or not. This method must ensure that the value will be set to null if the
   * feature is not set.
   */
  public void cdoInternalPreCommit()
  {
    // We have to set this here because the CDOLegacyAdapter will not be notified when the instance is the target of a
    // single-directional containment reference.
    // If the container is not an legacy Object the system will get no information
    instanceToRevisionContainment();

    EClass eClass = revision.getEClass();
    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
    {
      if (feature.isUnsettable())
      {
        if (!instance.eIsSet(feature))
        {
          if (feature.isMany())
          {
            @SuppressWarnings("unchecked")
            InternalEList<Object> list = (InternalEList<Object>)instance.eGet(feature);
            clearEList(list);
          }
          else
          {
            revision.set(feature, EStore.NO_INDEX, null);
          }
        }
        else if (instance.eGet(feature) == null)
        {
          // Must be single-valued!
          revision.set(feature, EStore.NO_INDEX, CDORevisionData.NIL);
        }
      }
    }
  }

  public void cdoInternalPreLoad()
  {
    // Do nothing
  }

  public void cdoInternalPostLoad()
  {
    // TODO Consider not remembering the revision after copying it to the instance (spare 1/2 of the space)
    revisionToInstance();
  }

  public void cdoInternalPostInvalidate()
  {
    if (cdoState() != CDOState.CLEAN)
    {
      InternalCDORevision revision = cdoView().getRevision(cdoID(), true);
      cdoInternalSetRevision(revision);
    }

    revisionToInstance();
    cdoInternalSetState(CDOState.CLEAN);
  }

  @Override
  public boolean equals(Object obj)
  {
    return obj == this || obj == instance;
  }

  @Override
  public int hashCode()
  {
    if (instance != null)
    {
      return instance.hashCode();
    }

    return super.hashCode();
  }

  @Override
  public String toString()
  {
    return "CDOLegacyWrapper[" + instance.getClass().getSimpleName() + "@" + id + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  }

  protected void instanceToRevision()
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Transfering instance to revision: {0} --> {1}", instance, revision); //$NON-NLS-1$
    }

    // Handle containment
    instanceToRevisionContainment();

    // Handle values
    CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry();
    EClass eClass = revision.getEClass();
    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
    {
      instanceToRevisionFeature(feature, packageRegistry);
    }
  }

  protected void instanceToRevisionContainment()
  {
    CDOResource resource = (CDOResource)getInstanceResource(instance);
    revision.setResourceID(resource == null ? CDOID.NULL : resource.cdoID());

    InternalEObject eContainer = getInstanceContainer(instance);
    if (eContainer == null)
    {
      revision.setContainerID(CDOID.NULL);
      revision.setContainingFeatureID(0);
    }
    else
    {
      CDOObject cdoContainer = FSMUtil.adapt(eContainer, view);
      revision.setContainerID(cdoContainer);
      revision.setContainingFeatureID(getInstanceContainerFeatureID(instance));
    }
  }

  protected void instanceToRevisionFeature(EStructuralFeature feature, CDOPackageRegistry packageRegistry)
  {
    Object instanceValue = getInstanceValue(instance, feature, packageRegistry);
    CDOObjectImpl.instanceToRevisionFeature(view, this, feature, instanceValue);
  }

  protected void revisionToInstance()
  {
    if (underConstruction)
    {
      // Return if revisionToInstance was called before to avoid doubled calls
      return;
    }

    underConstruction = true;

    if (TRACER.isEnabled())
    {
      TRACER.format("Transfering revision to instance: {0} --> {1}", revision, instance); //$NON-NLS-1$
    }

    boolean deliver = instance.eDeliver();
    if (deliver)
    {
      instance.eSetDeliver(false);
    }

    Counter counter = recursionCounter.get();
    try
    {
      registerWrapper(this);
      counter.increment();
      view.registerObject(this);

      revisionToInstanceContainer();

      for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
      {
        revisionToInstanceFeature(feature);
      }

      revisionToInstanceResource();
    }
    catch (RuntimeException ex)
    {
      OM.LOG.error(ex);
      throw ex;
    }
    catch (Exception ex)
    {
      OM.LOG.error(ex);
      throw new CDOException(ex);
    }
    finally
    {
      if (deliver)
      {
        instance.eSetDeliver(true);
      }

      counter.decrement();
      unregisterWrapper(this);
      underConstruction = false;
    }
  }

  /**
   * @since 4.0
   */
  protected void revisionToInstanceContainer()
  {
    Object containerID = revision.getContainerID();
    InternalEObject container = getEObjectFromPotentialID(view, null, containerID);

    EObject oldContainer = instance.eContainer();
    if (oldContainer != container)
    {
      setInstanceContainer(container, revision.getContainingFeatureID());
    }
  }

  /**
   * @since 4.0
   */
  protected void revisionToInstanceResource()
  {
    if (revision != null)
    {
      CDOID resourceID = revision.getResourceID();
      InternalEObject resource = getEObjectFromPotentialID(view, null, resourceID);
      setInstanceResource((Resource.Internal)resource);
      if (resource != null)
      {
        view.registerObject((InternalCDOObject)resource);
      }
    }
  }

  /**
   * @since 3.0
   */
  protected void revisionToInstanceFeature(EStructuralFeature feature)
  {
    if (feature.isUnsettable() && !view.getStore().isSet(this, feature))
    {
      // Clarify if this is sufficient for bidirectional references
      instance.eUnset(feature);
      return;
    }

    if (feature.isMany())
    {
      if (TRACER.isEnabled())
      {
        TRACER.format("State of Object (" + this + "/" + instance + ") is : " + state); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }

      if (state == CDOState.CLEAN || state == CDOState.PROXY || state == CDOState.NEW || state == CDOState.DIRTY)
      {
        int size = revision.size(feature);

        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>)instance.eGet(feature);

        clearEList(list);
        for (int i = 0; i < size; i++)
        {
          Object object = getValueFromRevision(feature, i);

          if (TRACER.isEnabled())
          {
            TRACER.format("Adding " + object + " to feature " + feature + "in instance " + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
          }

          list.basicAdd(object, null);
        }
      }
    }
    else
    {
      // !feature.isMany()
      Object object = getValueFromRevision(feature, 0);
      if (feature instanceof EAttribute)
      {
        if (TRACER.isEnabled())
        {
          TRACER.format("Setting attribute value " + object + " to feature " + feature + " in instance " + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }

        // Just fake it for the store :(
        if (feature.isUnsettable() && object.equals(CDORevisionData.NIL))
        {
          eSet(feature, null);
        }
        else
        {
          eSet(feature, object);
        }
      }
      else
      {
        // EReferences
        if (TRACER.isEnabled())
        {
          TRACER.format("Adding object " + object + " to feature " + feature + " in instance " + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }

        int featureID = instance.eClass().getFeatureID(feature);
        Class<? extends Object> baseClass = object == null ? null : object.getClass();
        EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)feature;
        EReference oppositeReference = internalFeature.getEOpposite();

        if (oppositeReference != null)
        {
          if (object != null)
          {
            // If you have a containment reference but the container is not set, but the object is attached to a
            // resource
            // do not set the feature to null. Otherwise the object will be removed from the container which is the
            // resource instead of the original container. As a result the object will be detached. See
            // MapTest.testEObjectToEObjectValueContainedMap for more information
            if (object != instance.eContainer())
            {
              instance.eInverseAdd((InternalEObject)object, featureID, baseClass, null);
            }

            if (!EMFUtil.isPersistent(oppositeReference))
            {
              adjustTransientOppositeReference(instance, (InternalEObject)object, oppositeReference);
            }
          }
        }
        else
        {
          if (object != CDORevisionData.NIL)
          {
            EReference reference = (EReference)feature;
            if (reference.isContainment())
            {
              if (object != null)
              {
                // Calling eSet it not the optimal approach, but currently there is no other way to set the value here.
                // To avoid attaching already processed (clean) objects a check was introduced to
                // CDOResourceImpl.attached(EObject).
                // If we find a way to avoid the call of eSet and if we are able to only set the feature value directly
                // this check can be removed from CDOResourceImpl. See also Bug 352204.
                instance.eSet(feature, object);
              }
              else
              {
                instance.eSet(feature, null);
              }
            }
            else
            {
              instance.eSet(feature, object);
            }
          }
          else
          {
            instance.eSet(feature, null);
          }
        }

        if (TRACER.isEnabled())
        {
          TRACER.format("Added object " + object + " to feature " + feature + " in instance " + instance); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
      }
    }
  }

  /**
   * This method retrieves the value from the feature at the given index. It retrieves the value either from the views's
   * store or the internal pre-registration Map.
   * 
   * @param feature
   *          the feature to retrieve the value from
   * @param index
   *          the given index of the object in the feature
   * @return the value from the feature at the given index
   */
  private Object getValueFromRevision(EStructuralFeature feature, int index)
  {
    Object object = revision.get(feature, index);
    if (object == null)
    {
      return null;
    }

    if (object instanceof CDOElementProxy)
    {
      // Resolve proxy
      CDOElementProxy proxy = (CDOElementProxy)object;
      object = view.getSession().resolveElementProxy(revision, feature, index, proxy.getIndex());
    }

    if (object instanceof CDOLegacyWrapper)
    {
      return ((CDOLegacyWrapper)object).cdoInternalInstance();
    }

    CDOType type = CDOModelUtil.getType(feature.getEType());
    object = view.getStore().convertToEMF(instance, revision, feature, index, object);

    if (type == CDOType.OBJECT)
    {
      if (object instanceof CDOID)
      {
        CDOID id = (CDOID)object;
        if (id.isNull())
        {
          return null;
        }

        object = getRegisteredWrapper(id);
        if (object != null)
        {
          return ((CDOLegacyWrapper)object).cdoInternalInstance();
        }

        if (id.isExternal())
        {
          object = view.getResourceSet().getEObject(URI.createURI(id.toURIFragment()), true);
        }
        else
        {
          object = view.getObject(id);
        }

        if (object instanceof CDOObjectWrapper)
        {
          return ((CDOObjectWrapper)object).cdoInternalInstance();
        }
      }
    }

    return object;
  }

  protected Resource.Internal getInstanceResource(InternalEObject instance)
  {
    return instance.eDirectResource();
  }

  protected InternalEObject getInstanceContainer(InternalEObject instance)
  {
    return instance.eInternalContainer();
  }

  protected int getInstanceContainerFeatureID(InternalEObject instance)
  {
    return instance.eContainerFeatureID();
  }

  protected Object getInstanceValue(InternalEObject instance, EStructuralFeature feature,
      CDOPackageRegistry packageRegistry)
  {
    return instance.eGet(feature);
  }

  protected void setInstanceResource(Resource.Internal resource)
  {
    Method method = ReflectUtil.getMethod(instance.getClass(), "eSetDirectResource", Resource.Internal.class); //$NON-NLS-1$
    ReflectUtil.invokeMethod(method, instance, resource);
  }

  protected void setInstanceContainer(InternalEObject container, int containerFeatureID)
  {
    Method method = ReflectUtil.getMethod(instance.getClass(), "eBasicSetContainer", InternalEObject.class, int.class); //$NON-NLS-1$
    ReflectUtil.invokeMethod(method, instance, container, containerFeatureID);
  }

  protected void setInstanceValue(InternalEObject instance, EStructuralFeature feature, Object value)
  {
    instance.eSet(feature, value);
  }

  /**
   * @param feature
   *          in case that a proxy has to be created the feature that will determine the interface type of the proxy and
   *          that will be used later to resolve the proxy. <code>null</code> indicates that proxy creation will be
   *          avoided!
   */
  protected InternalEObject getEObjectFromPotentialID(InternalCDOView view, EStructuralFeature feature,
      Object potentialID)
  {
    CDOLegacyWrapper wrapper;
    if (potentialID instanceof CDOID && (wrapper = getRegisteredWrapper((CDOID)potentialID)) != null)
    {
      potentialID = wrapper.instance;

      if (TRACER.isEnabled())
      {
        TRACER.format("Getting Object (" + potentialID + ") from localThread instead of the view"); //$NON-NLS-1$ //$NON-NLS-2$
      }
    }
    else
    {
      if (potentialID instanceof CDOID)
      {
        CDOID id = (CDOID)potentialID;
        if (id.isNull())
        {
          return null;
        }

        if (id.isExternal())
        {
          URI uri = URI.createURI(id.toURIFragment());
          InternalEObject eObject = (InternalEObject)view.getResourceSet().getEObject(uri, true);
          return eObject;
        }

        boolean loadOnDemand = feature == null;
        potentialID = view.getObject(id, loadOnDemand);
        if (potentialID == null && !loadOnDemand)
        {
          return createProxy(view, feature, id);
        }
      }

      if (potentialID instanceof InternalCDOObject)
      {
        return ((InternalCDOObject)potentialID).cdoInternalInstance();
      }
    }

    return (InternalEObject)potentialID;
  }

  /**
   * Creates and returns a <em>proxy</em> object. The usage of a proxy object is strongly limited. The only guarantee
   * that can be made is that the following methods are callable and will behave in the expected way:
   * <ul>
   * <li>{@link CDOObject#cdoID()} will return the {@link CDOID} of the target object
   * <li>{@link CDOObject#cdoState()} will return {@link CDOState#PROXY PROXY}
   * <li>{@link InternalEObject#eIsProxy()} will return <code>true</code>
   * <li>{@link InternalEObject#eProxyURI()} will return the EMF proxy URI of the target object
   * </ul>
   * Calling any other method on the proxy object will result in an {@link UnsupportedOperationException} being thrown
   * at runtime. Note also that the proxy object might even not be cast to the concrete type of the target object. The
   * proxy can only guaranteed to be of <em>any</em> concrete subtype of the declared type of the given feature.
   * <p>
   * TODO {@link InternalEObject#eResolveProxy(InternalEObject)}
   */
  protected InternalEObject createProxy(InternalCDOView view, EStructuralFeature feature, CDOID id)
  {
    EClassifier eType = feature.getEType();
    Class<?> instanceClass = eType.getInstanceClass();

    Class<?>[] interfaces = { instanceClass, InternalEObject.class, LegacyProxy.class };
    ClassLoader classLoader = CDOLegacyWrapper.class.getClassLoader();
    LegacyProxyInvocationHandler handler = new LegacyProxyInvocationHandler(this, id);
    return (InternalEObject)Proxy.newProxyInstance(classLoader, interfaces, handler);
  }

  protected void clearEList(InternalEList<?> list)
  {
    for (int i = list.size() - 1; i >= 0; --i)
    {
      Object obj = list.get(i);
      list.basicRemove(obj, null);
    }
  }

  /**
   * TODO Consider using only EMF concepts for resolving proxies!
   */
  protected void resolveAllProxies()
  {
    CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry();
    EClass eClass = revision.getEClass();
    for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
    {
      if (feature instanceof EReference)
      {
        resolveProxies(feature, packageRegistry);
      }
    }
  }

  /**
   * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for
   * EMF with fixed bug #247130. These compile errors do not affect native models!
   */
  protected void resolveProxies(EStructuralFeature feature, CDOPackageRegistry packageRegistry)
  {
    Object value = getInstanceValue(instance, feature, packageRegistry);
    if (value != null)
    {
      if (feature.isMany())
      {
        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>)value;
        int size = list.size();

        boolean deliver = instance.eDeliver();
        if (deliver)
        {
          instance.eSetDeliver(false);
        }

        for (int i = 0; i < size; i++)
        {
          Object element = list.get(i);
          if (element instanceof LegacyProxy)
          {
            CDOID id = ((LegacyProxy)element).getID();
            InternalCDOObject resolved = (InternalCDOObject)view.getObject(id);
            InternalEObject instance = resolved.cdoInternalInstance();

            // TODO LEGACY
            // // TODO Is InternalEList.basicSet() needed???
            // if (list instanceof
            // org.eclipse.emf.ecore.util.DelegatingInternalEList)
            // {
            // list =
            // ((org.eclipse.emf.ecore.util.DelegatingInternalEList)list).getDelegateInternalEList();
            // }

            // if (list instanceof NotifyingListImpl<?>)
            // {
            // ((NotifyingListImpl<Object>)list).basicSet(i, instance, null);
            // }
            // else
            // {
            list.set(i, instance);
            // }
          }
        }

        if (deliver)
        {
          instance.eSetDeliver(true);
        }
      }
      else
      {
        if (value instanceof LegacyProxy)
        {
          CDOID id = ((LegacyProxy)value).getID();
          InternalCDOObject resolved = (InternalCDOObject)view.getObject(id);
          InternalEObject instance = resolved.cdoInternalInstance();
          setInstanceValue(instance, feature, instance);
        }
      }
    }
  }

  protected void adjustEProxy()
  {
    // Setting eProxyURI is necessary to prevent content adapters from
    // loading the whole content tree.
    // TODO Does not have the desired effect ;-( see CDOEditor.createModel()
    if (state == CDOState.PROXY)
    {
      if (!instance.eIsProxy())
      {
        URI uri = URI.createURI(CDOProtocolConstants.PROTOCOL_NAME + ":proxy#" + id); //$NON-NLS-1$
        if (TRACER.isEnabled())
        {
          TRACER.format("Setting proxyURI {0} for {1}", uri, instance); //$NON-NLS-1$
        }

        instance.eSetProxyURI(uri);
      }
    }
    else
    {
      if (instance.eIsProxy())
      {
        if (TRACER.isEnabled())
        {
          TRACER.format("Unsetting proxyURI for {0}", instance); //$NON-NLS-1$
        }

        instance.eSetProxyURI(null);
      }
    }
  }

  @Override
  public synchronized EList<Adapter> eAdapters()
  {
    EList<Adapter> adapters = instance.eAdapters();
    for (Adapter adapter : adapters)
    {
      if (!FSMUtil.isTransient(this) && !(adapter instanceof CDOLegacyWrapper))
      {
        cdoView().handleAddAdapter(this, adapter);
      }
    }

    return adapters;
  }

  public static boolean isLegacyProxy(Object object)
  {
    return object instanceof LegacyProxy;
  }

  protected static int getEFlagMask(Class<?> instanceClass, String flagName)
  {
    Field field = ReflectUtil.getField(instanceClass, flagName);
    if (!field.isAccessible())
    {
      field.setAccessible(true);
    }

    try
    {
      return (Integer)field.get(null);
    }
    catch (IllegalAccessException ex)
    {
      throw WrappedException.wrap(ex);
    }
  }

  /**
   * @since 3.0
   */
  protected static CDOLegacyWrapper getRegisteredWrapper(CDOID id)
  {
    return wrapperRegistry.get().get(id);
  }

  /**
   * Adds an object to the pre-registered objects list which hold all created objects even if they are not registered in
   * the view
   * 
   * @since 3.0
   */
  protected static void registerWrapper(CDOLegacyWrapper wrapper)
  {
    wrapperRegistry.get().put(wrapper.cdoID(), wrapper);
  }

  /**
   * @since 3.0
   */
  protected static void unregisterWrapper(CDOLegacyWrapper wrapper)
  {
    wrapperRegistry.get().remove(wrapper.cdoID());
  }

  /**
   * @since 3.0
   */
  protected static boolean isRegisteredWrapper(CDOLegacyWrapper wrapper)
  {
    return wrapperRegistry.get().containsKey(wrapper.cdoID());
  }

  // TODO: Remove this method if it is ensured that ist is not needed anymore
  // private void adjustOppositeReference(InternalCDOObject cdoObject, EObject oppositeObject, EReference
  // oppositeReference)
  // {
  // if (oppositeObject != null)
  // {
  // InternalCDOObject oppositeCDOObject = (InternalCDOObject)CDOUtil.getCDOObject(oppositeObject);
  //
  // if (!FSMUtil.isTransient(oppositeCDOObject) && !EMFUtil.isPersistent(oppositeReference))
  // {
  // adjustPersistentOppositeReference(cdoObject, oppositeObject, oppositeReference);
  // }
  // else
  // {
  // if (oppositeReference.isResolveProxies())
  // {
  // adjustTransientOppositeReference(instance, (InternalEObject)oppositeObject, oppositeReference);
  // }
  // }
  // }
  // }

  private void adjustPersistentOppositeReference(InternalCDOObject cdoObject, EObject oppositeObject,
      EReference oppositeReference)
  {
    InternalCDOObject oppositeCDOObject = (InternalCDOObject)CDOUtil.getCDOObject(oppositeObject);
    if (oppositeCDOObject != null)
    {
      InternalCDOView view = oppositeCDOObject.cdoView();
      if (view != null)
      {
        CDOStore store = view.getStore();
        if (store != null)
        {
          if (oppositeReference.isMany())
          {
            EObject eObject = oppositeCDOObject.cdoInternalInstance();

            @SuppressWarnings("unchecked")
            EList<Object> list = (EList<Object>)eObject.eGet(oppositeReference);
            int index = list.indexOf(instance);

            if (!store.isEmpty(oppositeCDOObject, oppositeReference) && index != EStore.NO_INDEX)
            {
              store.set(oppositeCDOObject, oppositeReference, index, cdoObject);
            }
          }
          else
          {
            store.set(oppositeCDOObject, oppositeReference, 0, cdoObject);
          }
        }
      }
    }
  }

  private void adjustTransientOppositeReference(InternalEObject instance, InternalEObject object,
      EReference oppositeReference)
  {
    boolean wasDeliver = object.eDeliver(); // Disable notifications
    if (wasDeliver)
    {
      object.eSetDeliver(false);
    }

    try
    {
      if (oppositeReference.isMany())
      {
        @SuppressWarnings("unchecked")
        InternalEList<Object> list = (InternalEList<Object>)object.eGet(oppositeReference);
        list.basicAdd(instance, null);
      }
      else
      {
        if (object.eGet(oppositeReference) != instance)
        {
          object.eInverseAdd(instance, oppositeReference.getFeatureID(), ((EObject)instance).getClass(), null);
        }
      }
    }
    finally
    {
      if (wasDeliver)
      {
        object.eSetDeliver(true);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  private static interface LegacyProxy
  {
    public CDOID getID();
  }

  /**
   * @author Eike Stepper
   */
  private static final class LegacyProxyInvocationHandler implements InvocationHandler, LegacyProxy
  {
    private static final Method getIDMethod = ReflectUtil.getMethod(LegacyProxy.class, "getID"); //$NON-NLS-1$

    private static final Method eIsProxyMethod = ReflectUtil.getMethod(EObject.class, "eIsProxy"); //$NON-NLS-1$

    private static final Method eProxyURIMethod = ReflectUtil.getMethod(InternalEObject.class, "eProxyURI"); //$NON-NLS-1$

    private CDOLegacyWrapper wrapper;

    private CDOID id;

    public LegacyProxyInvocationHandler(CDOLegacyWrapper wrapper, CDOID id)
    {
      this.wrapper = wrapper;
      this.id = id;
    }

    public CDOID getID()
    {
      return id;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
      if (method.equals(getIDMethod))
      {
        return id;
      }

      if (method.equals(eIsProxyMethod))
      {
        return true;
      }

      if (method.equals(eProxyURIMethod))
      {
        // Use container's resource because it's guaranteed to be in the same CDOView as the resource of the target!
        Resource resource = wrapper.eResource();

        // TODO Consider using a "fake" Resource implementation. See Resource.getEObject(...)
        return resource.getURI().appendFragment(id.toURIFragment());
      }

      // A client must have invoked the proxy while being told not to do so!
      throw new UnsupportedOperationException(method.getName());
    }
  }

  /**
   * @author Martin Fluegge
   */
  private static final class Counter
  {
    private int value;

    public Counter()
    {
    }

    public void increment()
    {
      ++value;
    }

    public int decrement()
    {
      return --value;
    }
  }
}
