/**
 * Copyright (c) 2003-2009 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 */
package org.eclipse.emf.ecore.util;


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

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.util.AbstractEList;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
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.ETypedElement;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;


public abstract class DelegatingFeatureMap extends DelegatingEcoreEList<FeatureMap.Entry> implements FeatureMap.Internal, FeatureMap.Internal.Wrapper
{
  private static final long serialVersionUID = 1L;

  protected FeatureMap.Internal.Wrapper wrapper = this;
  protected final FeatureMapUtil.Validator featureMapValidator;
  protected final EStructuralFeature eStructuralFeature;

  public DelegatingFeatureMap(InternalEObject owner, int featureID)
  {
    super(owner);
    this.eStructuralFeature = owner.eClass().getEStructuralFeature(featureID);
    featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
  }

  public DelegatingFeatureMap(InternalEObject owner, EStructuralFeature eStructuralFeature)
  {
    super(owner);
    this.eStructuralFeature = eStructuralFeature;
    featureMapValidator = FeatureMapUtil.getValidator(owner.eClass(), getEStructuralFeature());
  }

/*
  List theList = new java.util.ArrayList();
  protected List delegateList()
  {
    return theList;
  }
*/
  
  public Wrapper getWrapper()
  {
    return wrapper;
  }

  public void setWrapper(Wrapper wrapper)
  {
    this.wrapper = wrapper;
  }

  public FeatureMap featureMap()
  {
    return this;
  }
  
  @Override
  protected Entry validate(int index, Entry object)
  {
    if (modCount == 0) return object;

    Entry result = super.validate(index, object);
    EStructuralFeature eStructuralFeature = object.getEStructuralFeature();
    if (!eStructuralFeature.isChangeable() || !featureMapValidator.isValid(eStructuralFeature))
    {
      throw
        new RuntimeException
          ("Invalid entry feature '" + eStructuralFeature.getEContainingClass().getName() + "." + eStructuralFeature.getName() + "'");
    }
    return result;
  }

  @Override
  protected boolean isEObject()
  {
    return false;
  }

  @Override
  protected boolean isUnique()
  {
    return false;
  }

  @Override
  protected boolean canContainNull()
  {
    return false;
  }

  @Override
  protected EClassifier getFeatureType()
  {
    return org.eclipse.emf.ecore.EcorePackage.Literals.EJAVA_OBJECT;
  }

  @Override
  public EStructuralFeature getEStructuralFeature()
  {
    return eStructuralFeature;
  }

  protected FeatureMap.Entry createEntry(EStructuralFeature eStructuralFeature, Object value)
  {
    return FeatureMapUtil.createEntry(eStructuralFeature, value);
  }

  protected FeatureMap.Entry.Internal createRawEntry(EStructuralFeature eStructuralFeature, Object value)
  {
    return FeatureMapUtil.createRawEntry(eStructuralFeature, value);
  }

  protected NotificationImpl createNotification
    (int eventType, EStructuralFeature feature, Object oldObject, Object newObject, int index, boolean wasSet)
  {
    return new FeatureMapUtil.FeatureENotificationImpl(owner, eventType, feature, oldObject, newObject, index, wasSet);
  }

  protected boolean isMany(EStructuralFeature feature)
  {
    return FeatureMapUtil.isMany(owner, feature);
  }

  @Override
  protected boolean hasInverse()
  {
    return true;
  }

  @Override
  protected boolean hasShadow()
  {
    return true;
  }

  protected int entryIndex(EStructuralFeature feature, int index)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int count = 0;
    int size = delegateSize();
    int result = size;
    for (int i = 0; i < size; ++i)
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        if (index == count)
        {
          return i;
        }
        ++count;
        result = i + 1;
      }
    }

    if (index == count)
    {
      return result;
    }
    else
    {
      throw new IndexOutOfBoundsException("index=" + index + ", size=" + count);
    }
  }

  protected boolean isResolveProxies(EStructuralFeature feature)
  {
    return feature instanceof EReference && ((EReference)feature).isResolveProxies();
  }

  public Object resolveProxy(EStructuralFeature feature, int entryIndex, int index, Object object)
  {
    EObject resolved = resolveProxy((EObject)object);
    if (resolved != object)
    {
      Entry oldObject = delegateGet(entryIndex);
      Entry entry = createEntry(feature, resolved);
      delegateSet(entryIndex, validate(entryIndex, entry));
      didSet(entryIndex, entry, oldObject);

      if (isNotificationRequired())
      {
        NotificationImpl notifications = 
          createNotification
            (Notification.RESOLVE, 
             entry.getEStructuralFeature(), 
             object,
             resolved,
             index,
             false);

        notifications.add(createNotification(Notification.RESOLVE, oldObject, entry, index, false));
        notifications.dispatch();
      }

      return resolved;
    }

    return object;
  }

  @Override
  protected EObject resolveProxy(EObject eObject)
  {
    return owner.eResolveProxy((InternalEObject)eObject);
  }

  public int getModCount()
  {
    return modCount;
  }

  public EStructuralFeature getEStructuralFeature(int index)
  {
    return get(index).getEStructuralFeature();
  }

  public Object getValue(int index)
  {
    return get(index).getValue();
  }

  public Object setValue(int index, Object value)
  {
    return set(index, createEntry(getEStructuralFeature(index), value)).getValue();
  }

  @Override
  public NotificationChain shadowAdd(Entry object, NotificationChain notifications)
  {
    if (isNotificationRequired())
    {
      EStructuralFeature feature = object.getEStructuralFeature();
      Object value = object.getValue();
      // EATM must fix isSet bits.
      NotificationImpl notification = 
        feature.isMany() ?
          createNotification
            (Notification.ADD,
             feature,
             null, 
             value,
             indexOf(feature, value),
             true) :
          createNotification
            (Notification.SET, 
             feature,
             feature.getDefaultValue(), 
             value,
             Notification.NO_INDEX,
             true);
  
      if (notifications != null)
      {
        notifications.add(notification);
      }
      else
      {
        notifications = notification;
      }
    }
    return notifications;
  }

  @Override
  public NotificationChain inverseAdd(Entry object, NotificationChain notifications)
  {
    FeatureMap.Entry.Internal entry = (FeatureMap.Entry.Internal)object;
    return entry.inverseAdd(owner, getFeatureID(), notifications);
  }

  @Override
  public NotificationChain shadowRemove(Entry object, NotificationChain notifications)
  {
    if (isNotificationRequired())
    {
      EStructuralFeature feature = object.getEStructuralFeature();
      Object value = object.getValue();
      NotificationImpl notification = 
        feature.isMany() ?
          createNotification
            (Notification.REMOVE,
             feature,
             value,
             null, 
             indexOf(feature, value),
             true) :
          createNotification
            (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 
             feature,
             value,
             feature.getDefaultValue(), 
             Notification.NO_INDEX,
             true);

      if (notifications != null)
      {
        notifications.add(notification);
      }
      else
      {
        notifications = notification;
      }
    }
    return notifications;
  }

  @Override
  public NotificationChain inverseRemove(Entry object, NotificationChain notifications)
  {
    FeatureMap.Entry.Internal entry = (FeatureMap.Entry.Internal)object;
    return entry.inverseRemove(owner, getFeatureID(), notifications);
  }

  @Override
  public NotificationChain shadowSet(Entry oldObject, Entry newObject, NotificationChain notifications)
  {
    if (isNotificationRequired())
    {
      EStructuralFeature feature = oldObject.getEStructuralFeature();
      Object oldValue = oldObject.getValue();
      Object newValue = newObject.getValue();
      NotificationImpl notification = 
        createNotification
          (Notification.SET,
           feature,
           oldValue,
           newValue,
           feature.isMany() ? indexOf(feature, newValue) : Notification.NO_INDEX,
           true);

      if (notifications != null)
      {
        notifications.add(notification);
      }
      else
      {
        notifications = notification;
      }
    }
    return notifications;
  }

  public NotificationChain inverseTouch(Object object, NotificationChain notifications)
  {
    if (isNotificationRequired())
    {
      Entry entry = (Entry)object;
      EStructuralFeature feature = entry.getEStructuralFeature();
      Object value = entry.getValue();
      NotificationImpl notification = 
        createNotification
          (Notification.SET,
           feature,
           value, 
           value,
           feature.isMany() ? indexOf(feature, value) : Notification.NO_INDEX,
           true);
  
      if (notifications != null)
      {
        notifications.add(notification);
      }
      else
      {
        notifications = notification;
      }
    }

    return notifications;
  }

  @Override
  public Entry move(int targetIndex, int sourceIndex)
  {
    if (!isNotificationRequired())
    {
      return doMove(targetIndex, sourceIndex);
    }
    else if (targetIndex != sourceIndex)
    {
      Entry sourceEntry =  delegateGet(sourceIndex);
      EStructuralFeature feature = sourceEntry.getEStructuralFeature();
      if (isMany(feature))
      {
        FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
        int featureTargetIndex = -1;
        int featureSourceIndex = -1;
        int count = 0;
        for (int i = 0, maxIndex= targetIndex > sourceIndex ? targetIndex : sourceIndex; i <= maxIndex; ++i)
        {
          if (i == sourceIndex)
          {
            featureSourceIndex = count++;
          }
          else
          {
            Entry entry = delegateGet(i);
            boolean isValid = validator.isValid(entry.getEStructuralFeature());
            if (i == targetIndex)
            {
              featureTargetIndex = i == maxIndex && !isValid ? count-1 : count;
            }
            
            if (isValid)
            {
                ++count;
            }
          }
        }

        Entry result = super.move(targetIndex, sourceIndex);
        
        if (featureSourceIndex != featureTargetIndex)
        {
          dispatchNotification
            (new ENotificationImpl
               (owner, 
                Notification.MOVE, 
                feature,
                featureSourceIndex, 
                sourceEntry.getValue(),
                featureTargetIndex));
        }
        return result;
      }
    }
    return super.move(targetIndex, sourceIndex);
  }

  @Override
  public Entry set(int index, Entry object)
  {
    EStructuralFeature entryFeature = object.getEStructuralFeature();
    if (isMany(entryFeature))
    {
      if (entryFeature.isUnique())
      {
        for (int i = 0, size = delegateSize(); i < size; ++i)
        {
          Entry otherEntry = delegateGet(i);
          if (otherEntry.equals(object) && i != index)
          {
            throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
          }
        }
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry otherEntry = delegateGet(i);
        if (validator.isValid(otherEntry.getEStructuralFeature()) && i != index)
        {
          throw new IllegalArgumentException("The multiplicity constraint is violated");
        }
      }
    }

    return doSet(index, object);
  }

  public Entry doSet(int index, Entry object)
  {
    return super.set(index, object);
  }

  @Override
  public boolean add(Entry object)
  {
    EStructuralFeature entryFeature = object.getEStructuralFeature();
    if (isMany(entryFeature))
    {
      if (entryFeature.isUnique() && contains(entryFeature, object.getValue()))
      {
        return false;
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry otherEntry = delegateGet(i);
        if (validator.isValid(otherEntry.getEStructuralFeature()))
        {
          if (otherEntry.equals(object))
          {
            return false;
          }
          else
          {
            doSet(i, object);
            return true;
          }
        }
      }
    }

    return doAdd(object);
  }

  protected boolean doAdd(Entry object)
  {
    return super.add(object);
  }

  @Override
  public void add(int index, Entry object)
  {
    EStructuralFeature entryFeature = object.getEStructuralFeature();
    if (isMany(entryFeature))
    {
      if (entryFeature.isUnique())
      {
        for (int i = 0, size = delegateSize(); i < size; ++i)
        {
          Entry otherEntry = delegateGet(i);
          if (otherEntry.equals(object) && i != index)
          {
            throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
          }
        }
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry otherEntry = delegateGet(i);
        if (validator.isValid(otherEntry.getEStructuralFeature()))
        {
          throw new IllegalArgumentException("The multiplicity constraint is violated");
        }
      }
    }

    doAdd(index, object);
  }

  public void doAdd(int index, Entry object)
  {
    super.add(index, object);
  }

  @Override
  public boolean addAll(Collection<? extends Entry> collection)
  {
    Collection<Entry> uniqueCollection = new BasicEList<Entry>(collection.size());
    for (Entry entry : collection)
    {
      EStructuralFeature entryFeature = entry.getEStructuralFeature();
      if (isMany(entryFeature))
      {
        if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
        {
          uniqueCollection.add(entry);
        }
      }
      else
      {
        FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
        boolean include = true;
        for (int j = 0, size = delegateSize(); j < size; ++j)
        {
          Entry otherEntry = delegateGet(j);
          if (validator.isValid(otherEntry.getEStructuralFeature()))
          {
            doSet(j, entry);
            include = false;
            break;
          }
        }
        if (include)
        {
          uniqueCollection.add(entry);
        }
      }
    }

    return doAddAll(uniqueCollection);
  }

  public boolean doAddAll(Collection<? extends Entry> collection)
  {
    return super.addAll(collection);
  }

  @Override
  public boolean addAll(int index, Collection<? extends Entry> collection)
  {
    Collection<Entry> uniqueCollection = new BasicEList<Entry>(collection.size());
    for (Entry entry : collection)
    {
      EStructuralFeature entryFeature = entry.getEStructuralFeature();
      if (isMany(entryFeature))
      {
        if (!entryFeature.isUnique() || !contains(entryFeature, entry.getValue()) && !uniqueCollection.contains(entry))
        {
          uniqueCollection.add(entry);
        }
      }
      else
      {
        FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), entryFeature);
        boolean include = true;
        for (int j = 0, size = delegateSize(); j < size; ++j)
        {
          Entry otherEntry = delegateGet(j);
          if (validator.isValid(otherEntry.getEStructuralFeature()))
          {
            doSet(j, entry);
            include = false;
            break;
          }
        }
        if (include)
        {
          uniqueCollection.add(entry);
        }
      }
    }

    return doAddAll(index, uniqueCollection);
  }

  public boolean doAddAll(int index, Collection<? extends Entry> collection)
  {
    return super.addAll(index, collection);
  }


  public int size(EStructuralFeature feature)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int result = 0;
    for (int i = 0, size = delegateSize(); i < size; ++i)
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        ++result;
      }
    }
    return result;
  }

  public boolean isEmpty(EStructuralFeature feature)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    for (int i = 0, size = delegateSize(); i < size; ++i)
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        return false;
      }
    }
    return true;
  }

  public boolean contains(EStructuralFeature feature, Object object)
  {
    return contains(feature, object, isResolveProxies(feature));
  }

  public boolean basicContains(EStructuralFeature feature, Object object)
  {
    return contains(feature, object, false);
  }

  protected boolean contains(EStructuralFeature feature, Object object, boolean resolve)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()) && entry.equals(object))
        {
          return true;
        }
      }
    }
    else if (object != null)
    {
      int size = delegateSize();
      for (int i = 0; i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()) && object.equals(entry.getValue()))
        {
          return true;
        }
      }
      if (resolve)
      {
        for (int i = 0; i < size; ++i)
        {
          Entry entry = delegateGet(i);
          if (validator.isValid(entry.getEStructuralFeature()) && object == resolveProxy((EObject)entry.getValue()))
          {
            return true;
          }
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()) && entry.getValue() == null)
        {
          return false;
        }
      }
    }

    return false;
  }

  public boolean containsAll(EStructuralFeature feature, Collection<?> collection)
  {
    for (Object object : collection)
    {
      if (!contains(feature, object))
      {
        return false;
      }
    }

    return true;
  }

  public boolean basicContainsAll(EStructuralFeature feature, Collection<?> collection)
  {
    for (Object object : collection)
    {
      if (!basicContains(feature, object))
      {
        return false;
      }
    }

    return true;
  }

  public int indexOf(EStructuralFeature feature, Object object)
  {
    return indexOf(feature, object, isResolveProxies(feature));
  }

  public int basicIndexOf(EStructuralFeature feature, Object object)
  {
    return indexOf(feature, object, false);
  }

  protected int indexOf(EStructuralFeature feature, Object object, boolean resolve)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int result = 0;
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.equals(object))
          {
            return result;
          }
          ++result;
        }
      }
    }
    else if (object != null)
    {
      int size = delegateSize();
      for (int i = 0; i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (object.equals(entry.getValue()))
          {
            return result;
          }
          ++result;
        }
      }
      if (resolve)
      {
        result = 0;
        for (int i = 0; i < size; ++i)
        {
          Entry entry = delegateGet(i);
          if (validator.isValid(entry.getEStructuralFeature()))
          {
            if (object == resolveProxy((EObject)entry.getValue()))
            {
              return result;
            }
            ++result;
          }
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.getValue() == null)
          {
            return result;
          }
          ++result;
        }
      }
    }

    return -1;
  }

  public int lastIndexOf(EStructuralFeature feature, Object object)
  {
    return lastIndexOf(feature, object, isResolveProxies(feature));
  }

  public int basicLastIndexOf(EStructuralFeature feature, Object object)
  {
    return lastIndexOf(feature, object, false);
  }

  protected int lastIndexOf(EStructuralFeature feature, Object object, boolean resolve)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int result = -1;
    int count = 0;
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.equals(object))
          {
            result = count;
          }
          ++count;
        }
      }
    }
    else if (object != null)
    {
      int size = delegateSize();
      for (int i = 0; i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (object.equals(entry.getValue()))
          {
            result = count;
          }
          ++count;
        }
      }
      if (resolve)
      {
        result = -1;
        count = 0;
        for (int i = 0; i < size; ++i)
        {
          Entry entry = delegateGet(i);
          if (validator.isValid(entry.getEStructuralFeature()))
          {
            if (object == resolveProxy((EObject)entry.getValue()))
            {
              result = count;
            }
            ++count;
          }
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.getValue() == null)
          {
            result = count;
          }
          ++count;
        }
      }
    }

    return result;
  }

  public Iterator<Object> iterator(EStructuralFeature feature)
  {
    return 
      feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
        new ResolvingFeatureEIterator<Object>(feature, this) :
        new FeatureEIterator<Object>(feature, this);
  }

  public ListIterator<Object> listIterator(EStructuralFeature feature)
  {
    return 
      feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
        new ResolvingFeatureEIterator<Object>(feature, this) :
        new FeatureEIterator<Object>(feature, this);
  }

  public ListIterator<Object> listIterator(EStructuralFeature feature, int index)
  {
    ListIterator<Object> result =
      feature instanceof EReference && ((EReference)feature).isResolveProxies() ?
        new ResolvingFeatureEIterator<Object>(feature, this) :
        new FeatureEIterator<Object>(feature, this);
    for (int i = 0; i < index; ++i)
    {
      result.next();
    }
    return result;
  }

  public ValueListIterator<Object> valueListIterator()
  {
    return new ValueListIteratorImpl<Object>();
  }
  
  public ValueListIterator<Object> valueListIterator(int index)
  {
    return new ValueListIteratorImpl<Object>(index);
  }
  
  protected class ValueListIteratorImpl<E> extends AbstractEList<FeatureMap.Entry>.EListIterator<E> implements ValueListIterator<E>
  {
    public ValueListIteratorImpl()
    {
      super();
    }
    
    public ValueListIteratorImpl(int index)
    {
      super(index);
    }
    
    public EStructuralFeature feature()
    {
      if (lastCursor == -1)
      {
        throw new IllegalStateException();
      }
      return getEStructuralFeature(lastCursor);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public E next()
    {
      return (E)doNext().getValue();
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public E previous()
    {
      return (E)doPrevious().getValue();
    }

    @Override
    public void add(E value)
    {
      doAdd(FeatureMapUtil.createEntry(feature(), value));
    }
    
    public void add(EStructuralFeature eStructuralFeature, Object value)
    {
      doAdd(FeatureMapUtil.createEntry(eStructuralFeature, value));
    }
  }

/*
  public List subList(EStructuralFeature feature, int from, int to)
  {
    return null;
  }
*/

  @SuppressWarnings("unchecked")
  public <T> EList<T> list(EStructuralFeature feature)
  {
    return
      FeatureMapUtil.isFeatureMap(feature) ?
        (EList<T>)new FeatureMapUtil.FeatureFeatureMap(feature, this) :
        new FeatureMapUtil.FeatureEList<T>(feature, this);
  }

  public EStructuralFeature.Setting setting(EStructuralFeature feature)
  {
    return 
      isMany(feature) ?
        (EStructuralFeature.Setting)list(feature) :
        (EStructuralFeature.Setting)new FeatureMapUtil.FeatureValue(feature, this);
  }

  public List<Object> basicList(EStructuralFeature feature)
  {
    return new FeatureMapUtil.FeatureEList.Basic<Object>(feature, this);
  }

  public Iterator<Object> basicIterator(EStructuralFeature feature)
  {
    return new FeatureEIterator<Object>(feature, this);
  }

  public ListIterator<Object> basicListIterator(EStructuralFeature feature)
  {
    return new FeatureEIterator<Object>(feature, this);
  }

  public ListIterator<Object> basicListIterator(EStructuralFeature feature, int index)
  {
    ListIterator<Object> result = new FeatureEIterator<Object>(feature, this);
    for (int i = 0; i < index; ++i)
    {
      result.next();
    }
    return result;
  }

  public Object[] toArray(EStructuralFeature feature)
  {
    return toArray(feature, isResolveProxies(feature));
  }

  public Object[] basicToArray(EStructuralFeature feature)
  {
    return toArray(feature, false);
  }

  protected Object[] toArray(EStructuralFeature feature, boolean resolve)
  {
    List<Object> result = new BasicEList<Object>();
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          result.add(entry);
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          Object value = entry.getValue();
          result.add(resolve ? resolveProxy(feature, i, result.size(), value) : value);
        }
      }
    }
    return result.toArray();
  }

  public <T> T[] toArray(EStructuralFeature feature, T [] array)
  {
    return toArray(feature, array, isResolveProxies(feature));
  }

  public <T> T[] basicToArray(EStructuralFeature feature, T [] array)
  {
    return toArray(feature, array, false);
  }

  protected <T> T[] toArray(EStructuralFeature feature, T [] array, boolean resolve)
  {
    List<Object> result = new BasicEList<Object>();
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          result.add(entry);
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          Object value = entry.getValue();
          result.add(resolve ? resolveProxy(feature, i, result.size(), value) : value);
        }
      }
    }
    return result.toArray(array);
  }


  public void set(EStructuralFeature feature, Object object)
  {
    if (isMany(feature))
    {
      List<Object> list = list(feature);
      list.clear();
      list.addAll((Collection<?>)object);
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (shouldUnset(feature, object))
          {
            remove(i);
          }
          else
          {
            doSet(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
          }
          return;
        }
      }
  
      if (!shouldUnset(feature, object))
      {
        doAdd(FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
      }
    }
  }

  protected boolean shouldUnset(EStructuralFeature feature, Object value)
  {
    if (feature.getUpperBound() != ETypedElement.UNSPECIFIED_MULTIPLICITY && !feature.isUnsettable())
    {
      Object defaultValue = feature.getDefaultValue();
      return defaultValue == null ? value == null : defaultValue.equals(value);
    }
    else
    {
      return false;
    }
  }

  public void add(int index, EStructuralFeature feature, Object object)
  {
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    if (isMany(feature))
    {
      if (feature.isUnique() && contains(feature, object))
      {
        throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue()))
          {
            throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
          }
        }
      }
    }

    doAdd(index, isFeatureMap ? (Entry)object : createEntry(feature, object));
  }

  public boolean add(EStructuralFeature feature, Object object)
  {
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    if (isMany(feature))
    {
      if (feature.isUnique() && contains(feature, object))
      {
        return false;
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (isFeatureMap ? entry.equals(object) : object == null ? entry.getValue() == null : object.equals(entry.getValue()))
          {
            return false;
          }
          else
          {
            doSet(i, isFeatureMap ? (Entry)object : createEntry(feature, object));
            return true;
          }
        }
      }
    }

    return doAdd(isFeatureMap ? (Entry)object : createEntry(feature, object));
  }

  public void add(EStructuralFeature feature, int index, Object object)
  {
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    if (isMany(feature))
    {
      if (feature.isUnique() && contains(feature, object))
      {
        throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          throw new IllegalArgumentException("The multiplicity constraint is violated");
        }
      }
    }

    doAdd(entryIndex(feature, index), isFeatureMap ? (Entry)object : createEntry(feature, object));
  }

  public boolean addAll(int index, EStructuralFeature feature, Collection<?> collection)
  {
    if (collection.isEmpty())
    {
      return false;
    }
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    @SuppressWarnings("unchecked") Collection<Entry> entryCollection = 
      isFeatureMap ? (Collection<Entry>)collection : new BasicEList<Entry>(collection.size());
    if (isMany(feature))
    {
      if (feature.isUnique())
      {
        for (Object object : collection)
        {
          if (!contains(feature, object))
          {
            Entry entry = createEntry(feature, object);
            if (!entryCollection.contains(entry))
            {
              entryCollection.add(entry);
            }
          }
        }
      }
      else if (!isFeatureMap)
      {
        for (Object object : collection)
        {
          Entry entry = createEntry(feature, object);
          entryCollection.add(entry);
        }
      }
    }
    else
    {
      if (collection.size() > 1)
      {
        throw new IllegalArgumentException("The multiplicity constraint is violated");
      }

      if (isFeatureMap)
      {
        if (contains(feature, collection.iterator().next()))
        {
          return false;
        }
      }
      else
      {
        FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
        for (int i = 0, size = delegateSize(); i < size; ++i)
        {
          Entry entry = delegateGet(i);
          if (validator.isValid(entry.getEStructuralFeature()))
          {
            if (collection.contains(entry.getValue()))
            {
              return false;
            }
            else
            {
              throw new IllegalArgumentException("The multiplicity constraint is violated");
            }
          }
        }
        Entry entry = createEntry(feature, collection.iterator().next());
        entryCollection.add(entry);
      }
    }

    return doAddAll(index, entryCollection);
  }

  public boolean addAll(EStructuralFeature feature, Collection<?> collection)
  {
    if (collection.isEmpty())
    {
      return false;
    }
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    @SuppressWarnings("unchecked") Collection<Entry> entryCollection = 
      isFeatureMap ? (Collection<Entry>)collection : new BasicEList<Entry>(collection.size());
    if (isMany(feature))
    {
      if (feature.isUnique())
      {
        for (Object object : collection)
        {
          if (!contains(feature, object))
          {
            Entry entry = createEntry(feature, object);
            if (!entryCollection.contains(entry))
            {
              entryCollection.add(entry);
            }
          }
        }
      }
      else if (!isFeatureMap)
      {
        for (Object object : collection)
        {
          Entry entry = createEntry(feature, object);
          entryCollection.add(entry);
        }
      }
    }
    else
    {
      if (collection.size() > 1)
      {
        throw new IllegalArgumentException("The multiplicity constraint is violated");
      }
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (collection.contains(isFeatureMap ? entry : entry.getValue()))
          {
            return false;
          }
          else
          {
            for (Object object : collection)
            {
              doSet(i, isFeatureMap ? (Entry)object : createEntry(feature, object));
            }
            return true;
          }
        }
      }
      if (!isFeatureMap)
      {
        Entry entry = createEntry(feature, collection.iterator().next());
        entryCollection.add(entry);
      }
    }

    return doAddAll(entryCollection);
  }

  public boolean addAll(EStructuralFeature feature, int index, Collection<?> collection)
  {
    if (collection.isEmpty())
    {
      return false;
    }
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    @SuppressWarnings("unchecked") Collection<Entry> entryCollection = 
      isFeatureMap ? (Collection<Entry>)collection : new BasicEList<Entry>(collection.size());
    if (isMany(feature))
    {
      if (feature.isUnique())
      {
        for (Object object : collection)
        {
          if (!contains(feature, object))
          {
            Entry entry = createEntry(feature, object);
            entryCollection.add(entry);
          }
        }
      }
      else if (!isFeatureMap)
      {
        for (Object object : collection)
        {
          Entry entry = createEntry(feature, object);
          entryCollection.add(entry);
        }
      }
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          throw new IllegalArgumentException("The multiplicity constraint is violated");
        }
      }

      if (collection.size() > 1)
      {
        throw new IllegalArgumentException("The multiplicity constraint is violated");
      }

      if (!isFeatureMap)
      {
        Entry entry = createEntry(feature, collection.iterator().next());
        entryCollection.add(entry);
      }
    }

    return doAddAll(entryIndex(feature, index), entryCollection);
  }

  public void addUnique(EStructuralFeature feature, Object object)
  {
    modCount = -1;
    addUnique(createRawEntry(feature, object));
  }

  public void addUnique(EStructuralFeature feature, int index, Object object)
  {
    modCount = -1;
    addUnique(entryIndex(feature, index), createRawEntry(feature, object));
  }

  @Override
  public void addUnique(Entry object)
  {
    // Validate now since the call we make after will skip validating.
    ++modCount;
    validate(delegateSize(), object);

    super.addUnique(object);
  }

  public void addUnique(Entry.Internal entry)
  {
    modCount = -1;
    super.addUnique(entry);
  }

  @Override
  public boolean addAllUnique(Collection<? extends Entry> collection)
  {
    modCount = -1;
    return super.addAllUnique(collection);
  }

  public boolean addAllUnique(Entry.Internal [] entries, int start, int end)
  {
    modCount = -1;
    return super.addAllUnique(size(), entries, start, end);
  }

  public boolean addAllUnique(int index, Entry.Internal [] entries, int start, int end)
  {
    modCount = -1;
    return super.addAllUnique(index, entries, start, end);
  }

  public NotificationChain basicAdd(EStructuralFeature feature, Object object, NotificationChain notifications)
  {
    if (object == null)
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (entry.getEStructuralFeature() == feature)
        {
          return super.basicRemove(entry, notifications);
        }
      }
    }

    Entry entry = FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object);

    notifications = basicAdd(entry, notifications);
    if (isNotificationRequired())
    {
      boolean oldIsSet = !isEmpty(feature);
      NotificationImpl notification = 
        feature.isMany() ?
          createNotification
            (Notification.ADD,
             feature,
             null, 
             object,
             indexOf(feature, object),
             oldIsSet) :
          createNotification
            (Notification.SET, 
             feature,
             feature.getDefaultValue(), 
             object,
             Notification.NO_INDEX,
             oldIsSet);

      if (notifications != null)
      {
        notifications.add(notification);
      }
      else
      {
        notifications = notification;
      }
    }
    return notifications;
  }

  public boolean remove(EStructuralFeature feature, Object object)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.equals(object))
          {
            remove(i);
            return true;
          }
        }
      }
    }
    else if (object != null)
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (object.equals(entry.getValue()))
          {
            remove(i);
            return true;
          }
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.getValue() == null)
          {
            remove(i);
            return true;
          }
        }
      }
    }

    return false;
  }

  public Object remove(EStructuralFeature feature, int index)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int count = 0;
    for (int i = 0, size = delegateSize(); i < size; ++i)
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        if (count == index)
        {
          remove(i);
          return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue();
        }
        ++count;
      }
    }

    throw new IndexOutOfBoundsException("index=" + index + ", size=" + count);
  }

  public boolean removeAll(EStructuralFeature feature, Collection<?> collection)
  {
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      return removeAll(collection);
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      List<Entry> entryCollection = new BasicEList<Entry>(collection.size());
      for (int i = delegateSize(); --i >= 0; )
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (collection.contains(entry.getValue()))
          {
            entryCollection.add(entry);
          }
        }
      }

      return removeAll(entryCollection);
    }
  }

  public NotificationChain basicRemove(EStructuralFeature feature, Object object, NotificationChain notifications)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    int count = 0;
    Entry match = null;
    if (FeatureMapUtil.isFeatureMap(feature))
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.equals(object))
          {
            match = entry;
            break;
          }
          ++count;
        }
      }
    }
    if (object != null)
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (object.equals(entry.getValue()))
          {
            match = entry;
            break;
          }
          ++count;
        }
      }
    }
    else
    {
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (entry.getValue() == null)
          {
            match = entry;
            break;
          }
          ++count;
        }
      }
    }

    if (match != null)
    {
      if (isNotificationRequired())
      {
        NotificationImpl notification = 
          feature.isMany() ?
            createNotification
              (Notification.REMOVE,
               feature,
               object,
               null, 
               count,
               true) :
            createNotification
              (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 
               feature,
               object,
               feature.getDefaultValue(), 
               Notification.NO_INDEX,
               true);
  
        if (notifications != null)
        {
          notifications.add(notification);
        }
        else
        {
          notifications = notification;
        }
      }
      notifications = basicRemove(match, notifications);
    }

    return notifications;
  }

  public boolean retainAll(EStructuralFeature feature, Collection<?> collection)
  {
    boolean isFeatureMap = FeatureMapUtil.isFeatureMap(feature);
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    List<Entry> entryCollection = new BasicEList<Entry>(collection.size());
    for (int i = delegateSize(); --i >= 0; )
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        if (!collection.contains(isFeatureMap ? entry : entry.getValue()))
        {
          entryCollection.add(entry);
        }
      }
    }

    return removeAll(entryCollection);
  }

  public void clear(EStructuralFeature feature)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    List<Entry> entryCollection = new BasicEList<Entry>();
    for (int i = delegateSize(); --i >= 0; )
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        entryCollection.add(entry);
      }
    }

    if (!removeAll(entryCollection))
    {
      dispatchNotification
        (feature.isMany() ?
           createNotification
             (Notification.REMOVE_MANY,
              feature,
              Collections.EMPTY_LIST,
              null, 
              Notification.NO_INDEX,
              false) :
           createNotification
             (feature.isUnsettable() ? Notification.UNSET : Notification.SET, 
              feature,
              null,
              null, 
              Notification.NO_INDEX,
              false));
    }
  }

  public void move(EStructuralFeature feature, int index, Object object)
  {
    move(feature, index, indexOf(feature, object));
  }

  public Object move(EStructuralFeature feature, int targetIndex, int sourceIndex)
  {
    if (isMany(feature))
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      Object result = null;
      int entryTargetIndex = -1;
      int entrySourceIndex = -1;
      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (count == targetIndex)
          {
            entryTargetIndex = i;
          }
          if (count == sourceIndex)
          {
            entrySourceIndex = i;
            result = entry.getValue();
          }
          ++count;
        }
      }
      if (entryTargetIndex == -1)
      {
        throw new IndexOutOfBoundsException("targetIndex=" + targetIndex + ", size=" + count);
      }
      if (entrySourceIndex == -1)
      {
        throw new IndexOutOfBoundsException("sourceIndex=" + sourceIndex + ", size=" + count);
      }

      super.move(entryTargetIndex, entrySourceIndex);

      if (isNotificationRequired())
      {
        dispatchNotification
          (createNotification
             (Notification.MOVE, 
              feature,
              sourceIndex, 
              result,
              targetIndex,
              true));
      }

      return result;
    }
    else
    {
      throw new IllegalArgumentException("The feature must be many-valued to support move");
    }
  }

  public Object get(EStructuralFeature feature, boolean resolve)
  {
    if (isMany(feature))
    {
      return list(feature);
    }
    else
    {
      FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (FeatureMapUtil.isFeatureMap(feature))
          {
            return entry;
          }
          else
          {
            Object value = entry.getValue();
            if (value != null && resolve && isResolveProxies(feature))
            {
              value = resolveProxy(feature, i, count, value);
            }
            return value;
          }
        }
        ++count;
      }

      return feature.getDefaultValue();
    }
  }

  public Object get(EStructuralFeature feature, int index, boolean resolve)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (isMany(feature))
    {
      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (count == index)
          {
            if (FeatureMapUtil.isFeatureMap(feature))
            {
              return entry;
            }
            else
            {
              Object value = entry.getValue();
              if (value != null && resolve && isResolveProxies(feature))
              {
                value = resolveProxy(feature, i, count, entry.getValue());
              }
              return value;
            }
          }
          ++count;
        }
      }
      throw new IndexOutOfBoundsException("index=" + index + ", size=" + count);
    }
    else
    {
      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (FeatureMapUtil.isFeatureMap(feature))
          {
            return entry;
          }
          else
          {
            Object value = entry.getValue();
            if (value != null && resolve && isResolveProxies(feature))
            {
              value = resolveProxy(feature, i, count, value);
            }
            return value;
          }
        }
        ++count;
      }

      return feature.getDefaultValue();
    }
  }

  public Object set(EStructuralFeature feature, int index, Object object)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (isMany(feature))
    {
      if (feature.isUnique())
      {
        int currentIndex = indexOf(feature, object);
        if (currentIndex >=0 && currentIndex != index)
        {
          throw new IllegalArgumentException("The 'no duplicates' constraint is violated");
        }
      }

      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (count == index)
          {
            return doSet(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
          }
          ++count;
        }
      }
      throw new IndexOutOfBoundsException("index=" + index + ", size=" + count);
    }
    else
    {
      // Index should be -1.

      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          return FeatureMapUtil.isFeatureMap(feature) ? entry : entry.getValue();
        }
      }

      return null;
    }
  }

  public Object setUnique(EStructuralFeature feature, int index, Object object)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    if (isMany(feature))
    {
      int count = 0;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          if (count == index)
          {
            return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
          }
          ++count;
        }
      }
      throw new IndexOutOfBoundsException("index=" + index + ", size=" + count);
    }
    else
    {
      // Index should be -1.

      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          return setUnique(i, FeatureMapUtil.isFeatureMap(feature) ? (Entry)object : createEntry(feature, object));
        }
      }

      return feature.getDefaultValue();
    }
  }

  public boolean isSet(EStructuralFeature feature)
  {
    return !isEmpty(feature);
  }

  public void unset(EStructuralFeature feature)
  {
    FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
    List<Entry> removals = null;
    for (int i = 0, size = delegateSize(); i < size; ++i)
    {
      Entry entry = delegateGet(i);
      if (validator.isValid(entry.getEStructuralFeature()))
      {
        if (removals == null)
        {
          removals = new BasicEList<Entry>();
        }
        removals.add(entry);
      }
    }

    if (removals != null)
    {
      removeAll(removals);
    }
  }

  @Override
  public NotificationChain basicRemove(Object object, NotificationChain notifications)
  {
    // This may be called directly on an EObject for the case of a containment.
    //
    if (object instanceof FeatureMap.Entry)
    {
      return super.basicRemove(object, notifications);
    }
    else
    {
      Entry match = null;
      EStructuralFeature feature = null;
      for (int i = 0, size = delegateSize(); i < size; ++i)
      {
        Entry entry = delegateGet(i); 
        if (object.equals(entry.getValue()))
        {
          feature = entry.getEStructuralFeature();
          if (feature instanceof EReference && ((EReference)feature).isContainment())
          {
            match = entry;
            break;
          }
        }
      }

      if (match != null)
      {
        if (isNotificationRequired())
        {
          NotificationImpl notification =
            feature.isMany() ?
              createNotification
                (Notification.REMOVE,
                 feature,
                 object,
                 null,
                 indexOf(feature, object),
                 true) :
              createNotification
                (feature.isUnsettable() ? Notification.UNSET : Notification.SET,
                 feature,
                 object,
                 feature.getDefaultValue(),
                 Notification.NO_INDEX,
                 true);

          if (notifications != null)
          {
            notifications.add(notification);
          }
          else
          {
            notifications = notification;
          }
        }
        notifications = basicRemove(match, notifications);
      }

      return notifications;
    }
  }

  /**
   * -------------------------------------------
   */
  public static class FeatureEIterator<E> extends FeatureMapUtil.BasicFeatureEIterator<E>
  {
    public FeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap)
    {
      super(eStructuralFeature, featureMap);
    }

    @Override
    protected boolean scanNext()
    {
      int size = featureMap.size();
      while (entryCursor < size)
      {
        Entry entry = featureMap.get(entryCursor);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          preparedResult = extractValue(entry);
          prepared = 2;
          return true;
        }
        ++entryCursor;
      }

      prepared = 1;
      lastCursor = -1;
      return false;
    }

    @Override
    protected boolean scanPrevious()
    {
      while (--entryCursor >= 0)
      {
        Entry entry = featureMap.get(entryCursor);
        if (validator.isValid(entry.getEStructuralFeature()))
        {
          preparedResult = extractValue(entry);
          prepared = -2;
          return true;
        }
      }

      prepared = -1;
      lastCursor = -1;
      return false;
    }
  }

  /**
   * -------------------------------------------
   */
  public static class ResolvingFeatureEIterator<E> extends FeatureEIterator<E>
  {
    public ResolvingFeatureEIterator(EStructuralFeature eStructuralFeature, FeatureMap.Internal featureMap)
    {
      super(eStructuralFeature, featureMap);
    }

    @Override
    protected boolean resolve()
    {
      return true;
    }
  }

  /**
   * Temporary for testing purposes only.
   */
  public static class FeatureMapEObjectImpl extends org.eclipse.emf.ecore.impl.EObjectImpl
  {
    protected DelegatingFeatureMap featureMap = 
      new DelegatingFeatureMap(this, -1)
      {
        private static final long serialVersionUID = 1L;

        protected List<Entry> theList = new java.util.ArrayList<Entry>();
        @Override
        protected List<Entry> delegateList()
        {
          return theList;
        }
      };


    public FeatureMapEObjectImpl()
    {
      super();
    }

    @Override
    public Object eDynamicGet(EStructuralFeature eFeature, boolean resolve)
    {
      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
      {
        return eSettingDelegate(eFeature).dynamicGet(this, null, -1, true, true);
      }
      else
      {
        return featureMap.setting(eFeature).get(resolve);
      }
    }

    @Override
    public void eDynamicSet(EStructuralFeature eFeature, Object newValue)
    {
      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
      {
        eSettingDelegate(eFeature).dynamicSet(this, null, -1, newValue);
      }
      else
      {
        if (!eFeature.isUnsettable())
        {
          Object defaultValue = eFeature.getDefaultValue();
          if (defaultValue == null ? newValue == null : defaultValue.equals(newValue))
          {
            featureMap.setting(eFeature).unset();
            return;
          }
        }
        featureMap.setting(eFeature).set(newValue);
      }
    }

    @Override
    public void eDynamicUnset(EStructuralFeature eFeature)
    {
      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
      {
        eSettingDelegate(eFeature).dynamicUnset(this, null, -1);
      }
      else
      {
        featureMap.setting(eFeature).unset();
      }
    }

    @Override
    public boolean eDynamicIsSet(EStructuralFeature eFeature)
    {
      if (eFeature instanceof EReference && ((EReference)eFeature).isContainer())
      {
        return eSettingDelegate(eFeature).dynamicIsSet(this, null, -1);
      }
      else
      {
        return featureMap.setting(eFeature).isSet();
      }
    }

    @Override
    public NotificationChain eDynamicInverseAdd(InternalEObject otherEnd, int featureID, Class<?> inverseClass, NotificationChain notifications)
    {
      EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID);
      if (feature.isMany())
      {
        return featureMap.basicAdd(feature, otherEnd, notifications);
      }
      else if (feature instanceof EReference && ((EReference)feature).isContainer())
      {
        return eSettingDelegate(feature).dynamicInverseAdd(this, null, -1, otherEnd, notifications);
      }
      else
      {
        InternalEObject oldValue = (InternalEObject)eDynamicGet(feature, false);
        if (oldValue != null)
        {
          notifications = oldValue.eInverseRemove
            (this, oldValue.eClass().getFeatureID(((EReference)feature).getEOpposite()), null, notifications);
          notifications = featureMap.basicRemove(feature, oldValue, notifications);
        }

        return featureMap.basicAdd(feature, otherEnd, notifications);
      }
    }

    @Override
    public NotificationChain eDynamicInverseRemove(InternalEObject otherEnd, int featureID, Class<?> inverseClass, NotificationChain notifications)
    {
      EStructuralFeature.Internal feature = (EStructuralFeature.Internal)eClass().getEStructuralFeature(featureID);
      if (feature instanceof EReference && ((EReference)feature).isContainer())
      {
        return eSettingDelegate(feature).dynamicInverseRemove(this, null, -1, otherEnd, notifications);
      }
      else
      {
        return featureMap.basicRemove(feature, otherEnd, notifications);
      }
    }

    public FeatureMap featureMap()
    {
      return featureMap;
    }

    @Override
    public void eNotify(Notification notification)
    {
      if (notification.getFeatureID(null) != -1)
      {
        super.eNotify(notification);
      }
    }

    @Override
    public String toString()
    {
      String result = super.toString();
      result = "org.eclipse.emf.ecore.impl.EObjectImpl" + result.substring(result.indexOf("@"));
      return result;
    }
  }

    @Override
   public void set(Object newValue)
   {
     super.set(newValue instanceof FeatureMap ? newValue : ((FeatureMap.Internal.Wrapper)newValue).featureMap());
   }

  @Override
  protected Entry resolve(int index, Entry entry) 
  {
    EStructuralFeature feature = entry.getEStructuralFeature();
    if (isResolveProxies(feature))
   {
     InternalEObject object = (InternalEObject)entry.getValue();
     EObject resolved = resolveProxy(object);
     if (resolved != object)
     {
       Entry newEntry = createEntry(feature, resolved);
       delegateSet(index, validate(index, newEntry));
       didSet(index, newEntry, entry);

       NotificationChain notifications = null;

       // Produce a proxy resolve notification for the reference feature of the owner, if there is one.
       //
       if (isNotificationRequired())
       {
         EStructuralFeature affiliatedFeature = ExtendedMetaData.INSTANCE.getAffiliation(owner.eClass(), feature);
         if (affiliatedFeature != getEStructuralFeature())
         {
           FeatureMapUtil.Validator validator = FeatureMapUtil.getValidator(owner.eClass(), feature);
           int featureIndex = 0;
           for (int i = 0; i < index; ++i)
           {
             Entry affliatedEntry = delegateGet(i);
             if (validator.isValid(affliatedEntry.getEStructuralFeature()))
             {
               ++featureIndex;
             }
           }

           notifications = 
             createNotification
               (Notification.RESOLVE, 
                affiliatedFeature,
                object,
                resolved,
                featureIndex,
                false);
        
           notifications.add(createNotification(Notification.RESOLVE, entry, newEntry, index, false));
         }
       }

       EReference reference = (EReference)feature;
       EReference opposite = reference.getEOpposite();
       if (opposite != null)
       {
         notifications = object.eInverseRemove(owner, object.eClass().getFeatureID(opposite), null, notifications);
         notifications = ((InternalEObject)resolved).eInverseAdd(owner, resolved.eClass().getFeatureID(opposite), null, notifications);
       }
       else if (reference.isContainment())
       {
         int inverseFeatureID = InternalEObject.EOPPOSITE_FEATURE_BASE - owner.eClass().getFeatureID(reference);
         notifications = object.eInverseRemove(owner, inverseFeatureID, null, null);
         if (((InternalEObject)resolved).eInternalContainer() == null)
         {
           notifications = ((InternalEObject)resolved).eInverseAdd(owner, inverseFeatureID, null, notifications);
         }
       }
       if (notifications != null)
       {
         notifications.dispatch();
       }

       return newEntry;
     }
    }
    return entry;
  }
}
