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

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.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.id.CDOIdentifiable;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOType;
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.security.CDOPermission;
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.model.InternalCDOClassInfo;
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.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.notify.Notifier;
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.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.InternalCDOResource;
import org.eclipse.emf.spi.cdo.InternalCDOView;
import org.eclipse.emf.spi.cdo.InternalCDOView.ViewAndState;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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);

  private final InternalCDOClassInfo classInfo;

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

  private static ThreadLocal<Counter> recursionCounter = new InheritableThreadLocal<Counter>();

  protected ViewAndState viewAndState;

  protected Object idOrRevision;

  /**
   * 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;
    classInfo = (InternalCDOClassInfo)CDOModelUtil.getClassInfo(instance.eClass());
    viewAndState = ViewAndState.TRANSIENT;
  }

  public InternalCDOClassInfo cdoClassInfo()
  {
    return classInfo;
  }

  public CDOID cdoID()
  {
    if (idOrRevision == null)
    {
      return null;
    }

    if (idOrRevision instanceof CDOID)
    {
      return (CDOID)idOrRevision;
    }

    return ((InternalCDORevision)idOrRevision).getID();
  }

  public InternalCDOView cdoView()
  {
    return viewAndState.view;
  }

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

    if (idOrRevision == null || id == null)
    {
      idOrRevision = id;
    }
  }

  public void cdoInternalSetView(CDOView view)
  {
    if (TRACER.isEnabled())
    {
      TRACER.format("Setting view: {0} for {1}", view, instance); //$NON-NLS-1$
    }

    InternalCDOView newView = (InternalCDOView)view;
    if (newView != null)
    {
      viewAndState = newView.getViewAndState(viewAndState.state);
    }
    else
    {
      viewAndState = ViewAndState.TRANSIENT.getViewAndState(viewAndState.state);
    }
  }

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

  public InternalCDORevision cdoRevision()
  {
    if (idOrRevision instanceof InternalCDORevision)
    {
      return (InternalCDORevision)idOrRevision;
    }

    return null;
  }

  public InternalCDORevision cdoRevision(boolean loadOnDemand)
  {
    if (loadOnDemand)
    {
      CDOStateMachine.INSTANCE.read(this);
    }

    return cdoRevision();
  }

  public CDOPermission cdoPermission()
  {
    InternalCDORevision revision = cdoRevision(true);
    if (revision == null)
    {
      return CDOPermission.WRITE;
    }

    return revision.getPermission();
  }

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

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

  public CDOObjectHistory cdoHistory()
  {
    return viewAndState.view.getHistory(this);
  }

  public 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);
      adjustEProxy();

      if (viewAndState.view != null)
      {
        viewAndState.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$
    }

    if (revision == null)
    {
      idOrRevision = cdoID();
    }
    else
    {
      idOrRevision = revision;
    }
  }

  public void cdoInternalPostAttach()
  {
    instanceToRevision();

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

  public void cdoInternalPostDetach(boolean remote)
  {
    if (remote)
    {
      setInstanceContainer(null, eContainerFeatureID());
      setInstanceResource(null);
      return;
    }

    // This loop adjusts the opposite wrapper objects to support dangling references. See Bugzilla_251263_Test
    InternalCDORevision revision = cdoRevision();
    for (EReference reference : classInfo.getAllPersistentReferences())
    {
      if (!reference.isContainer() && classInfo.hasPersistentOpposite(reference))
      {
        if (reference.isMany())
        {
          EReference oppositeReference = reference.getEOpposite();

          int size = revision.size(reference);
          for (int i = 0; i < size; i++)
          {
            EObject object = (EObject)getValueFromRevision(reference, i);
            adjustPersistentOppositeReference(this, object, oppositeReference);
          }
        }
        else
        {
          EObject oppositeObject = (EObject)instance.eGet(reference);
          if (oppositeObject != null)
          {
            EReference oppositeReference = reference.getEOpposite();
            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();

    InternalCDORevision revision = cdoRevision();
    for (EStructuralFeature feature : classInfo.getAllPersistentFeatures())
    {
      if (feature.isUnsettable())
      {
        if (!isSetInstanceValue(instance, 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.PROXY)
    {
      throw new IllegalStateException();
    }

    InternalCDORevision revision = cdoView().getRevision(cdoID(), true);
    if (revision == null)
    {
      cdoInternalPostDetach(true);
    }
    else
    {
      cdoInternalSetRevision(revision);
      revisionToInstance();
      cdoInternalSetState(CDOState.CLEAN);
    }
  }

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

    // Handle containment
    instanceToRevisionContainment();

    // Handle values
    for (EStructuralFeature feature : classInfo.getAllPersistentFeatures())
    {
      instanceToRevisionFeature(feature);
    }

    revision.setUnchunked();
  }

  protected void instanceToRevisionContainment()
  {
    InternalCDORevision revision = cdoRevision();

    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, viewAndState.view);
      revision.setContainerID(cdoContainer);
      revision.setContainingFeatureID(getInstanceContainerFeatureID(instance));
    }
  }

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

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

      underConstruction = true;
      InternalCDORevision revision = cdoRevision();

      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();
      if (counter == null)
      {
        counter = new Counter();
        recursionCounter.set(counter);
      }

      InternalCDOResource resource = null;
      boolean bypassPermissionChecks = revision.bypassPermissionChecks(true);

      try
      {
        registerWrapper(this);
        counter.increment();
        viewAndState.view.registerObject(this);

        revisionToInstanceResource();
        revisionToInstanceContainer();

        Resource eResource = instance.eResource();
        if (eResource instanceof InternalCDOResource)
        {
          resource = (InternalCDOResource)eResource;
          resource.cdoInternalLoading(instance);
        }

        for (EStructuralFeature feature : classInfo.getAllPersistentFeatures())
        {
          revisionToInstanceFeature(feature);
        }
      }
      catch (RuntimeException ex)
      {
        OM.LOG.error(ex);
        throw ex;
      }
      catch (Exception ex)
      {
        OM.LOG.error(ex);
        throw new CDOException(ex);
      }
      finally
      {
        try
        {
          revision.bypassPermissionChecks(bypassPermissionChecks);

          if (resource != null)
          {
            resource.cdoInternalLoadingDone(instance);
          }

          if (deliver)
          {
            instance.eSetDeliver(true);
          }
        }
        finally
        {
          if (counter.decrement() == 0)
          {
            recursionCounter.remove();
          }

          unregisterWrapper(this);
          underConstruction = false;
        }
      }
    }
  }

  /**
   * @since 4.0
   */
  protected void revisionToInstanceContainer()
  {
    InternalCDORevision revision = cdoRevision();
    CDOPermission permission = revision.getPermission();
    if (permission != CDOPermission.WRITE)
    {
      revision.setPermission(CDOPermission.WRITE);
    }

    try
    {
      Object containerID = revision.getContainerID();
      InternalEObject container = getEObjectFromPotentialID(viewAndState.view, null, containerID);
      EObject oldContainer = instance.eContainer();
      if (oldContainer != container)
      {
        setInstanceContainer(container, revision.getContainingFeatureID());
      }
    }
    finally
    {
      if (permission != CDOPermission.WRITE)
      {
        revision.setPermission(permission);
      }
    }
  }

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

  /**
   * @since 3.0
   */
  protected void revisionToInstanceFeature(EStructuralFeature feature)
  {
    if (feature.isUnsettable() && !viewAndState.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 : " + viewAndState.state); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      }

      if (viewAndState.state == CDOState.CLEAN || viewAndState.state == CDOState.PROXY
          || viewAndState.state == CDOState.NEW || viewAndState.state == CDOState.DIRTY)
      {
        InternalCDORevision revision = cdoRevision();
        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$
          }

          // Disable notifications from value during the
          // invalidation in case of
          // eInverseAdd/eInverseRemove
          boolean eDeliver = false;
          if (object instanceof Notifier)
          {
            Notifier notifier = (Notifier)object;
            eDeliver = notifier.eDeliver();
            if (eDeliver)
            {
              notifier.eSetDeliver(false);
            }
          }

          list.basicAdd(object, null);

          if (object instanceof Notifier && eDeliver)
          {
            Notifier notifier = (Notifier)object;
            notifier.eSetDeliver(eDeliver);
          }
        }
      }
    }
    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
        {
          if (object != null)
          {
            eSet(feature, object);
          }
          else
          {
            // TODO Unset for features with non-null default values would not lead to null values.
            // Probably CDORevisionData.NIL has to be used, but that impacts all IStores. Deferred ;-(
            eUnset(feature);
          }
        }
      }
      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$
        }

        // Disable notifications from value during the
        // invalidation in case of
        // eInverseAdd/eInverseRemove
        boolean eDeliver = false;
        if (object instanceof Notifier)
        {
          Notifier notifier = (Notifier)object;
          eDeliver = notifier.eDeliver();
          if (eDeliver)
          {
            notifier.eSetDeliver(false);
          }
        }
        EObject oldContainerOfValue = null;
        boolean eDeliverForOldContainerOfValue = false;
        if (object instanceof InternalEObject)
        {
          InternalEObject eObject = (InternalEObject)object;
          oldContainerOfValue = eObject.eInternalContainer();
          if (oldContainerOfValue != null)
          {
            eDeliverForOldContainerOfValue = oldContainerOfValue.eDeliver();
            if (eDeliverForOldContainerOfValue)
            {
              oldContainerOfValue.eSetDeliver(false);
            }
          }
        }

        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 && object != instance.eGet(feature))
          {
            // 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() || !oppositeReference.isContainment())
            {
              instance.eInverseAdd((InternalEObject)object, featureID, baseClass, null);
            }

            if (!classInfo.hasPersistentOpposite(internalFeature))
            {
              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 (object instanceof Notifier && eDeliver)
        {
          Notifier notifier = (Notifier)object;
          notifier.eSetDeliver(eDeliver);
        }
        if (oldContainerOfValue != null && eDeliverForOldContainerOfValue)
        {
          oldContainerOfValue.eSetDeliver(eDeliverForOldContainerOfValue);
        }

        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)
  {
    InternalCDORevision revision = cdoRevision();
    Object object = revision.get(feature, index);
    if (object == null)
    {
      return null;
    }

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

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

    CDOType type = CDOModelUtil.getType(feature.getEType());
    object = viewAndState.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 = viewAndState.view.getResourceSet().getEObject(URI.createURI(id.toURIFragment()), true);
        }
        else
        {
          object = viewAndState.view.getObject(id);
        }

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

    return object;
  }

  /**
   * @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)viewAndState.view.getResourceSet().getEObject(uri, true);
          return eObject;
        }

        boolean loadOnDemand = feature == null;
        potentialID = viewAndState.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);

      // Disable notifications from value during the
      // invalidation in case of
      // eInverseAdd/eInverseRemove
      boolean eDeliver = false;
      if (obj instanceof Notifier)
      {
        Notifier notifier = (Notifier)obj;
        eDeliver = notifier.eDeliver();
        if (eDeliver)
        {
          notifier.eSetDeliver(false);
        }
      }

      list.basicRemove(obj, null);

      if (obj instanceof Notifier && eDeliver)
      {
        Notifier notifier = (Notifier)obj;
        notifier.eSetDeliver(eDeliver);
      }
    }
  }

  /**
   * TODO Consider using only EMF concepts for resolving proxies!
   */
  protected void resolveAllProxies()
  {
    for (EStructuralFeature feature : classInfo.getAllPersistentFeatures())
    {
      if (feature instanceof EReference)
      {
        resolveProxies(feature);
      }
    }
  }

  /**
   * 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)
  {
    Object value = getInstanceValue(instance, feature);
    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)viewAndState.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)viewAndState.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 (viewAndState.state == CDOState.PROXY)
    {
      if (!instance.eIsProxy())
      {
        URI uri = URI.createURI(CDOProtocolConstants.PROTOCOL_NAME + ":proxy#" + cdoID()); //$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 = super.eAdapters();
    if (!FSMUtil.isTransient(this))
    {
      InternalCDOView view = cdoView();
      for (Adapter adapter : adapters)
      {
        if (!(adapter instanceof CDOLegacyWrapper))
        {
          view.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
   */
  private static CDOLegacyWrapper getRegisteredWrapper(CDOID id)
  {
    Map<CDOID, CDOLegacyWrapper> map = wrapperRegistry.get();
    if (map == null)
    {
      return null;
    }

    return map.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
   */
  private static void registerWrapper(CDOLegacyWrapper wrapper)
  {
    Map<CDOID, CDOLegacyWrapper> map = wrapperRegistry.get();
    if (map == null)
    {
      map = CDOIDUtil.createMap();
      wrapperRegistry.set(map);
    }

    map.put(wrapper.cdoID(), wrapper);
  }

  /**
   * @since 3.0
   */
  private static void unregisterWrapper(CDOLegacyWrapper wrapper)
  {
    Map<CDOID, CDOLegacyWrapper> map = wrapperRegistry.get();
    if (map == null)
    {
      return;
    }

    CDOID id = wrapper.cdoID();
    if (map.remove(id) != null)
    {
      if (map.isEmpty())
      {
        wrapperRegistry.remove();
      }
    }

  }

  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 = viewAndState.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 (index != EStore.NO_INDEX && !store.isEmpty(oppositeCDOObject, oppositeReference))
            {
              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 extends CDOIdentifiable
  {
  }

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