gt:         List<Object> list = ((List<Object>)object.eGet(feature));
context: /**
   * Copyright (c) 2004-2010 IBM Corporation 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: 
   *   IBM - Initial API and implementation
   */
  package org.eclipse.emf.edit.provider;
  
  
  import java.util.Collection;
  import java.util.Collections;
  import java.util.List;
  
  import org.eclipse.emf.common.command.Command;
  import org.eclipse.emf.common.command.CommandWrapper;
  import org.eclipse.emf.common.command.UnexecutableCommand;
  import org.eclipse.emf.common.notify.AdapterFactory;
  import org.eclipse.emf.common.util.ResourceLocator;
  import org.eclipse.emf.ecore.EObject;
  import org.eclipse.emf.ecore.EStructuralFeature;
  import org.eclipse.emf.edit.EMFEditPlugin;
  import org.eclipse.emf.edit.command.AbstractOverrideableCommand;
  import org.eclipse.emf.edit.command.CommandParameter;
  import org.eclipse.emf.edit.command.CopyCommand;
  import org.eclipse.emf.edit.command.DragAndDropCommand;
  import org.eclipse.emf.edit.command.SetCommand;
  import org.eclipse.emf.edit.domain.EditingDomain;
  
  
  /**
   * A basic implementation of <code>IWrapperProvider</code> from which others can extend. This class provides
   * all the methods required to implement the following item provider interfaces:
   * <ul>
   * <li>{@link IStructuredItemContentProvider}
   * <li>{@link ITreeItemContentProvider}
   * <li>{@link IItemLabelProvider}
   * <li>{@link IItemFontProvider}
   * <li>{@link IItemColorProvider}
   * <li>{@link IItemPropertySource}
   * <li>{@link IEditingDomainItemProvider}
   * </ul>
   * <p>Subclasses should declare which of these interfaces they are meant to implement, and override methods as needed.
   * In addition, a partial implementation for {@link IUpdateableItemText} is provided, along with additional methods and
   * classes that are useful in implementing multiple subclasses.
   */
  public class WrapperItemProvider implements IWrapperItemProvider
  {
    /**
     * The wrapped value.
     */
    protected Object value;
  
    /**
     * The object that owns the value.
     */
    protected Object owner;
  
    /**
     * The structural feature, if applicable, through which the value can be set and retrieved.
     */
    protected EStructuralFeature feature;
  
    /**
     * The index at which the value is located. If {@link #feature} is non-null, this index is within that feature.
     */
    protected int index;
  
    /**
     * The adapter factory for the owner's item provider.
     */
    protected AdapterFactory adapterFactory;
  
    /**
     * Creates an instance. The adapter factory of the owner's item provider may be needed for echoing notifications and
     * providing property descriptors.
     */
    public WrapperItemProvider(Object value, Object owner, EStructuralFeature feature, int index, AdapterFactory adapterFactory)
    {
      this.value = value;
      this.owner = owner;
      this.feature = feature;
      this.index = index;
      this.adapterFactory = adapterFactory;
    }
  
    /**
     * Disposes the wrapper by deactivating any notification that this wrapper may provide. Since this implementation
     * does not provide any notification, this method does nothing. 
     */
    public void dispose()
    {
      // Do nothing.
    }
  
    /**
     * Returns the wrapped value.
     */
    public Object getValue()
    {
      return value;
    }
  
    /**
     * Returns the object that owns the value.
     */
    public Object getOwner()
    {
      return owner;
    }
  
    /**
     * Returns the structural feature through which the value can be set and retrieved, or null if the feature is
     * unknown or not applicable.
     */
    public EStructuralFeature getFeature()
    {
      return feature;
    }
  
    /**
     * The index at which the value is located, or {@link org.eclipse.emf.edit.command.CommandParameter#NO_INDEX} if the
     * index isn't known to the wrapper. If {@link #feature} is non-null, this index is within that feature. 
     */
    public int getIndex()
    {
      return index;
    }
  
    /**
     * Sets the index. Has no effect if the index isn't known to the wrapper.
     */
    public void setIndex(int index)
    {
      this.index = index;
    }
  
    /**
     * {@link IStructuredItemContentProvider#getElements IStructuredItemContentProvider.getElements} is implemented by
     * forwarding the call to {@link #getChildren getChildren}.
     */
    public Collection<?> getElements(Object object)
    {
      return getChildren(object);
    }
   
    /**
     * {@link ITreeItemContentProvider#getChildren ITreeItemContentProvider.getChildren} is implemented to return an
     * empty list. Subclasses may override it to return something else.
     */
    public Collection<?> getChildren(Object object)
    {
      return Collections.emptyList();
    }
  
    /**
     * {@link ITreeItemContentProvider#hasChildren ITreeItemContentProvider.hasChildren} is implemented by testing
     * whether the collection returned by {@link #getChildren getChildren} is non-empty.
     */
    public boolean hasChildren(Object object)
    {
      return !getChildren(object).isEmpty();
    }
  
    /**
     * {@link ITreeItemContentProvider#getParent ITreeItemContentProvider.getParent} is implemented by returning the
     * {@link #owner}.
     */
    public Object getParent(Object object)
    {
      return owner;
    }
  
    /**
     * {@link org.eclipse.emf.edit.provider.IItemLabelProvider#getText IItemLabelProvider.getText} is implemented by returning a non-null value, as a
     * string, or "null".
     */
    public String getText(Object object)
    {
      return value != null ? value.toString() : "null";
    }
  
    /**
     * {@link org.eclipse.emf.edit.provider.IItemLabelProvider#getImage IItemLabelProvider.getImage} is implemented by returning the default icon for
     * an EMF.Edit item.
     */
    public Object getImage(Object object)
    {
      return EMFEditPlugin.INSTANCE.getImage("full/obj16/Item");
    }
  
    /**
     * {@link org.eclipse.emf.edit.provider.IItemFontProvider#getFont IItemFontProvider.getFont} is implemented by returning null.
     */
    public Object getFont(Object object)
    {
      return null;
    }
  
    /**
     * {@link org.eclipse.emf.edit.provider.IItemColorProvider#getForeground IItemColorProvider.getForeground} is implemented by returning null.
     */
    public Object getForeground(Object object)
    {
      return null;
    }
  
    /**
     * {@link org.eclipse.emf.edit.provider.IItemColorProvider#getBackground IItemColorProvider.getBackground} is implemented by returning null.
     */
    public Object getBackground(Object object)
    {
      return null;
    }
  
    /**
     * {@link IUpdateableItemText#getUpdateableText IUpdateableItemText.getUpdateableText} is implemented by forwarding
     * the call to {@link #getText getText}.
     */
    public String getUpdateableText(Object object)
    {
      return getText(object);
    }
  
    /**
     * {@link IItemPropertySource#getPropertyDescriptors IItemPropertySource.getPropertyDescriptors} is implemented to
     * return an empty list. Subclasses may override it to return something else.
     */
    public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object)
    {
      return Collections.emptyList();
    }
  
    /**
     * {@link IItemPropertySource#getPropertyDescriptor IItemPropertySource.getPropertyDescriptor} is implemented by
     * iterating over the descriptors returned by {@link #getPropertyDescriptors getPropertyDescriptors}, and returning
     * the first descriptor whose {@link IItemPropertyDescriptor#getId(Object) ID} 
     * or {@link IItemPropertyDescriptor#getFeature(Object) feature} matches the specified ID,
     * or <code>null</code> if none match.
     */
    public IItemPropertyDescriptor getPropertyDescriptor(Object object, Object propertyId)
    {
      for (IItemPropertyDescriptor descriptor : getPropertyDescriptors(object))
      {
        if (propertyId.equals(descriptor.getId(object)) || propertyId.equals(descriptor.getFeature(object)))
        {
          return descriptor;
        }
      }
      return null;
    }
  
    /**
     * {@link IItemPropertySource#getEditableValue IItemPropertySource.getEditableValue} is implemented to return the
     * value, itself.
     */
    public Object getEditableValue(Object object) 
    {
      return value;
    }
  
    /**
     * Returns a name for a value's single property. Subclasses may use this in creating a property descriptor, and user
     * subclasses may override it to provide a specific name.
     */
    protected String getPropertyName()
    {
      return EMFEditPlugin.INSTANCE.getString("_UI_ValueProperty_name");
    }
  
    /**
     * Returns a description for a value's single property. Subclasses may use this in creating a property descriptor,
     * and user subclasses may override it to provide a specific name.
     */
    protected String getPropertyDescription()
    {
      return EMFEditPlugin.INSTANCE.getString("_UI_ValueProperty_description");
    }
  
    /**
     * Returns whether a value's single property is settable. By default, this returns whether the structural feature is
     * {@link org.eclipse.emf.ecore.EStructuralFeature#isChangeable changeable}. Subclasses may use this in creating a
     * property descriptor, and user subclasses may override it to restrict or allow setting of the property.
     */
    protected boolean isPropertySettable()
    {
      return feature.isChangeable();
    }
  
    /**
     * Returns whether value's single property consists of multi-line text. By default, false is returned. Subclasses may use this in
     * creating a property descriptor, and user subclasses may override it to enable multi-line text editing.
     * @since 2.2.0
     */
    protected boolean isPropertyMultiLine()
    {
      return false;
    }
  
    /**
     * Returns whether value's single property should sort its choices for selection. By default, false is returned. Subclasses
     * may use this in creating a property descriptor, and user subclasses may override it to enable sorting.
     * @since 2.2.0
     */
    protected boolean isPropertySortChoices()
    {
      return false;
    }
  
    /**
     * Returns an image for a value's single property. By default, a standard property icon is selected based on the type
     * of the structural feature. Subclasses may use this in creating a property descriptor, and user subclasses may
     * override it to select a different icon. 
     */
    protected Object getPropertyImage()
    {
      return getPropertyImage(feature.getEType().getInstanceClass());
    }
  
    /**
     * Returns the property image for the specified type. Implementations of {@link #getPropertyImage() getPropertyImage}
     * typically call this method.
     */
    protected Object getPropertyImage(Class<?> typeClass)
    {
      if (typeClass == boolean.class || typeClass == Boolean.class)
      {
        return ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE;
      }
      else if (typeClass == byte.class || typeClass == Byte.class || 
               typeClass == int.class || typeClass == Integer.class ||
               typeClass == long.class || typeClass == Long.class ||
               typeClass == short.class || typeClass == Short.class)
      {
        return ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE;
      }
      else if (typeClass == char.class || typeClass == Character.class ||
               typeClass == String.class)
      {
        return ItemPropertyDescriptor.TEXT_VALUE_IMAGE;
      }
      else if (typeClass == double.class ||  typeClass == Double.class ||
               typeClass == float.class || typeClass == Float.class)
      {
        return ItemPropertyDescriptor.REAL_VALUE_IMAGE;
      }
  
      return ItemPropertyDescriptor.GENERIC_VALUE_IMAGE;
    }
  
    /**
     * Returns a category for a value's single property. By default, null is returned. Subclasses may use this in
     * creating a property descriptor, and user subclasses may override it to actually provide a category.
     */
    protected String getPropertyCategory()
    {
      return null;
    }
  
    /**
     * Returns filter flags for a value's single property. By default, null is returned. Subclasses may use this in
     * creating a property descriptor, and user subclasses may override it to actually provide filter flags.
     */
    protected String[] getPropertyFilterFlags()
    {
      return null;
    }
  
    /**
     * {@link IEditingDomainItemProvider#getNewChildDescriptors IEditingDomainItemProvider.getNewChildDescriptors} is
     * implemented to return an empty list. Subclasses may override it to return something else.
     */
    public Collection<?> getNewChildDescriptors(Object object, EditingDomain editingDomain, Object sibling)
    {
      return Collections.emptyList();
    }
  
    /**
     * {IEditingDomainItemProvider#createCommand IEditingDomainItemProvider.createCommand} is implemented via {@link
     * #baseCreateCommand baseCreateCommand} to create set, copy, and drag-and-drop commands, only.
     */
    public Command createCommand(Object object, EditingDomain domain, Class<? extends Command> commandClass, CommandParameter commandParameter)
    {
      return baseCreateCommand(object, domain, commandClass, commandParameter);
    }
  
    /**
     * Implements creation of a set, copy, or drag-and-drop command by calling out to {@link #createSetCommand
     * createSetCommand}, {@link #createCopyCommand createCopyCommand}, or {@link #createDragAndDropCommand
     * createDragAndDropCommand}.
     */
    public Command baseCreateCommand(Object object, EditingDomain domain, Class<? extends Command> commandClass, CommandParameter commandParameter)
    {
      if (commandClass == SetCommand.class)
      {
        return 
          createSetCommand
            (domain, commandParameter.getOwner(), commandParameter.getFeature(), commandParameter.getValue(), commandParameter.getIndex());
      }
      else if (commandClass == CopyCommand.class)
      {
        return createCopyCommand(domain, commandParameter.getOwner(), (CopyCommand.Helper)commandParameter.getValue());
      }
      else if (commandClass == DragAndDropCommand.class)
      {
        DragAndDropCommand.Detail detail = (DragAndDropCommand.Detail)commandParameter.getFeature();
        return 
          createDragAndDropCommand
            (domain, commandParameter.getOwner(), detail.location, detail.operations, detail.operation, commandParameter.getCollection());
      }
      else
      {
        return UnexecutableCommand.INSTANCE;
      }
    }
  
    /**
     * Return an {@link org.eclipse.emf.common.command.UnexecutableCommand}. Subclasses should override this to map this
     * into a real set on a model object.
     */
    protected Command createSetCommand(EditingDomain domain, Object owner, Object feature, Object value, int index) 
    {
      return UnexecutableCommand.INSTANCE;
    }
  
    /**
     * Returns an {@link org.eclipse.emf.common.command.UnexecutableCommand}. An ordinary {@link
     * org.eclipse.emf.edit.command.CopyCommand} is only useful for copying model objects, so it would be inappropriate
     * here. Subclasses should override it to return something more useful, like a concrete subclass of a {@link
     * SimpleCopyCommand} or {@link WrappingCopyCommand}.
     */
    protected Command createCopyCommand(EditingDomain domain, Object owner, CopyCommand.Helper helper)
    {
      return UnexecutableCommand.INSTANCE;
    }
  
    /**
     * Creates a {@link org.eclipse.emf.edit.command.DragAndDropCommand}.
     */
    protected Command createDragAndDropCommand
      (EditingDomain domain, Object owner, float location, int operations, int operation, Collection<?> collection)
    {
      return new DragAndDropCommand(domain, owner, location, operations, operation, collection);
    }
  
    /**
     * A label for copy command inner classes, the same one used by {@link org.eclipse.emf.edit.command.CopyCommand}.
     */
    protected static final String COPY_COMMAND_LABEL = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_label");
  
    /**
     * A description for copy command inner classes, the same as in {@link org.eclipse.emf.edit.command.CopyCommand}.
     */
    protected static final String COPY_COMMAND_DESCRIPTION = EMFEditPlugin.INSTANCE.getString("_UI_CopyCommand_description");
  
    /**
     * A command base class for copying a simple value and the wrapper. This is useful when the value isn't able provide
     * an adapter to return a copy command, itself. This class just provides the scaffolding; concrete subclasses must
     * implement {@link #copy copy} to do the copying.
     */
    protected abstract class SimpleCopyCommand extends AbstractOverrideableCommand
    {
      protected Collection<?> result = Collections.EMPTY_LIST;
      protected Collection<?> affectedObjects;
  
      /**
       * Creates an instance for the given domain.
       */
      public SimpleCopyCommand(EditingDomain domain)
      {
        super(domain, COPY_COMMAND_LABEL, COPY_COMMAND_DESCRIPTION);
      }
  
      /**
       * Returns true; this command can requires now preparation and can always be executed.
       */
      @Override
      protected boolean prepare()
      {
        return true;
      }
  
      /**
       * Calls {@link #copy} to do the copying, {@link IDisposable#dispose disposes} the copy, and sets it to 
       * be the result of the command. Since the copy has not been created within the viewed model, it should never do
       * any kind of notification, which is why it is immediately disposed.
       */
      @Override
      public void doExecute()
      {
        IWrapperItemProvider copy = copy();
        copy.dispose();
        result = Collections.singletonList(copy);
      }
  
      /**
       * Concrete subclasses must implement this to copy and return the value and wrapper.
       */
      public abstract IWrapperItemProvider copy();
  
      /**
       * Does nothing.
       */
      @Override
      public void doUndo()
      {
        // no-op
      }
  
      /**
       * Does nothing.
       */
      @Override
      public void doRedo()
      {
        // no-op
      }
  
      /**
       * If the command has executed, returns a list containing only the copy of the wrapper.
       */
      @Override
      public Collection<?> doGetResult()
      {
        return result;
      }
  
      /**
       * Returns a list containing only the original wrapper itself.
       */
      @Override
      public Collection<?> doGetAffectedObjects()
      {
        if (affectedObjects == null)
        {
          affectedObjects = Collections.singletonList(WrapperItemProvider.this);
        }
        return affectedObjects;
      }
    }
  
    /**
     * A command base class for copying the wrapper for a value that is partly copied by another command. This is useful
     * when the value includes a model object that is able provide an adapter to return a copy command, but also includes
     * an element that is not adaptable, such as a feature map entry. This command copies the non-adapter element and the
     * wrapper, which ensures the copy can be copied again.
     */
    protected abstract class WrappingCopyCommand extends CommandWrapper
    {
      protected Collection<?> result = Collections.EMPTY_LIST;
      protected Collection<?> affectedObjects;
  
      /**
       * Creates an instance where some adaptable value is copied by the given command.
       */
      public WrappingCopyCommand(Command command)
      {
        super(command);
      }
  
      /**
       * Executes the adaptable-value-copying command, then calls {@link #copy copy} to copy the rest of the value and
       * the wrapper, {@link IDisposable#dispose disposes} the copy, and sets it to be the result of the
       * command. Since the copy has not been created within the viewed model, it should never do any kind of
       * notification, which is why it is immediately disposed.
       */
      @Override
      public void execute()
      {
        super.execute();
        IWrapperItemProvider copy = copy();
        copy.dispose();
        result = Collections.singletonList(copy);
      }
  
      /**
       * Concrete subclasses must implement this to copy and return the value and wrapper. The result of the
       * adaptable-value-copying command is available from <code>getCommand().getResult()</code>.
       */
      public abstract IWrapperItemProvider copy();
  
      /**
       * If the command has executed, returns a list containing only the copy of the wrapper.
       */
      @Override
      public Collection<?> getResult()
      {
        return result;
      }
  
      /**
       * Returns a list containing only the original wrapper itself.
       */
      @Override
      public Collection<?> getAffectedObjects()
      {
        if (affectedObjects == null)
        {
          affectedObjects = Collections.singletonList(WrapperItemProvider.this);
        }
        return affectedObjects;
      }
    }
  
    /**
     * Returns the {@link #adapterFactory}, if non-composeable, otherwise, returns its root adapter factory.
     */
    protected AdapterFactory getRootAdapterFactory()
    {
      return adapterFactory instanceof ComposeableAdapterFactory ?
        ((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory() :
        adapterFactory;
    }
  
    /**
     * An item property descriptor for the single property of a wrapper for a simple value. This extends the base
     * implementation and substitutes the wrapper's owner for the selected object (the wrapper itself) in the call to {@link
     * #getPropertyValue getPropertyValue}. Thus, the owner must be an EObject to use this class. The property's name,
     * description, settable flag, static image, category, and filter flags are obtained by calling out to various
     * template methods, so can be easily changed by deriving a subclass.
     */
    protected class WrapperItemPropertyDescriptor extends ItemPropertyDescriptor
    {
      public WrapperItemPropertyDescriptor(ResourceLocator resourceLocator, EStructuralFeature feature)
      {
        super(
          WrapperItemProvider.this.adapterFactory,
          resourceLocator,
          getPropertyName(),
          getPropertyDescription(),
          feature,
          isPropertySettable(),
          isPropertyMultiLine(),
          isPropertySortChoices(),
          getPropertyImage(),
          getPropertyCategory(),
          getPropertyFilterFlags());
      }
  
      /**
       * Substitutes the wrapper owner for the selected object and invokes the base implementation. The actual value
       * returned depends on the implementation of {@link #getValue getValue}.
       */
      @Override
      public Object getPropertyValue(Object object)
      {
        return super.getPropertyValue(owner);
      }
  
      /**
       * Substitutes the wrapper owner for the selected object and invokes the base implementation.
       */
      @Override
      public boolean canSetProperty(Object object)
      {
        return super.canSetProperty(owner);
      }
  
      /**
       * Returns <code>true</code>, as the property of a value wrapper is always considered to be set. 
       */
      @Override
      public boolean isPropertySet(Object object)
      {
        return true;
      }
  
      /**
       * Does nothing, as resetting the property of a value wrapper is not meaningful.
       */
      @Override
      public void resetPropertyValue(Object object)
      {
        // Do nothing
      }
  
      /**
       * Sets the property value. If an editing domain can be obtained, the command returned by {@link #createSetCommand
       * createSetcommand} is executed; otherwise, {@link #setValue setValue} is called to set the value.
       */
      @Override
      public void setPropertyValue(Object object, Object value)
      {
        EObject eObject = (EObject)owner;
        EditingDomain editingDomain = getEditingDomain(owner);
  
        if (editingDomain == null)
        {
          setValue(eObject, feature, value);
        }
        else
        {
          editingDomain.getCommandStack().execute(createSetCommand(editingDomain, eObject, feature, value));
        }
      }
  
      /**
       * Returns a value from a model object. If the feature is multi-valued, only the single value that the wrapper
       * represents is returned.
       */
      @Override
      protected Object getValue(EObject object, EStructuralFeature feature)
      {
        // When the value is changed, the property sheet page doesn't update the property sheet viewer input
        // before refreshing, and this gets called on the obsolete wrapper. So, we need to read directly from the
        // model object.
        //
        //return value;
  
        Object result = ((EObject)owner).eGet(feature);
        if (feature.isMany())
        {
          // If the last object was deleted and the selection was in the property sheet view, the obsolete wrapper will
          // reference past the end of the list.
          //
          List<?> list = (List<?>)result;
          result = index >= 0 && index < list.size() ? list.get(index) : value;
        }
        return result;
      }
  
      /**
       * Sets a value on a model object. If the feature is multi-valued, only the single value that the wrapper
       * represents is set.
       */
      protected void setValue(EObject object, EStructuralFeature feature, Object value)
      {
        if (feature.isMany())
        {
          @SuppressWarnings("unchecked")
  