/**
 * <copyright>
 *
 * Copyright (c) 2002-2007 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
 *
 * </copyright>
 *
 * $Id: EOperationImpl.java,v 1.19.2.1 2007/12/14 23:03:42 emerks Exp $
 */
package org.eclipse.emf.ecore.impl;


import java.lang.reflect.Array;
import java.util.AbstractSequentialList;
import java.util.Collection;
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.EList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.DelegatingEcoreEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectContainmentWithInverseEList;
// import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>EOperation</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.emf.ecore.impl.EOperationImpl#getEContainingClass <em>EContaining Class</em>}</li>
 *   <li>{@link org.eclipse.emf.ecore.impl.EOperationImpl#getETypeParameters <em>EType Parameters</em>}</li>
 *   <li>{@link org.eclipse.emf.ecore.impl.EOperationImpl#getEParameters <em>EParameters</em>}</li>
 *   <li>{@link org.eclipse.emf.ecore.impl.EOperationImpl#getEExceptions <em>EExceptions</em>}</li>
 *   <li>{@link org.eclipse.emf.ecore.impl.EOperationImpl#getEGenericExceptions <em>EGeneric Exceptions</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class EOperationImpl extends ETypedElementImpl implements EOperation
{
  /**
   * The cached value of the '{@link #getETypeParameters() <em>EType Parameters</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getETypeParameters()
   * @generated
   * @ordered
   */
  protected EList<ETypeParameter> eTypeParameters;

  /**
   * The cached value of the '{@link #getEParameters() <em>EParameters</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEParameters()
   * @generated
   * @ordered
   */
  protected EList<EParameter> eParameters;

  /**
   * The cached value of the '{@link #getEExceptions() <em>EExceptions</em>}' reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEExceptions()
   * @generated
   * @ordered
   */
  protected EList<EClassifier> eExceptions;

  /**
   * The cached value of the '{@link #getEGenericExceptions() <em>EGeneric Exceptions</em>}' containment reference list.
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @see #getEGenericExceptions()
   * @generated
   * @ordered
   */
  protected EList<EGenericType> eGenericExceptions;

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  protected EOperationImpl()
  {
    super();
  }

  @Override
  protected void freeze()
  {
    if (eParameters != null)
    {
      for (int i = 0, size = eParameters.size(); i < size; ++i)
      {
        freeze(eParameters.get(i));
      }
    }
    super.freeze();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  protected EClass eStaticClass()
  {
    return EcorePackage.Literals.EOPERATION;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated modifiable
   */
  public EClass getEContainingClass()
  {
    return (eContainerFeatureID == EcorePackage.EOPERATION__ECONTAINING_CLASS) ? (EClass)eContainer : null;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<EParameter> getEParameters()
  {
    if (eParameters == null)
    {
      eParameters = new EObjectContainmentWithInverseEList<EParameter>(EParameter.class, this, EcorePackage.EOPERATION__EPARAMETERS, EcorePackage.EPARAMETER__EOPERATION);
    }
    return eParameters;
  }

  public EList<EClassifier> getEExceptions()
  {
    if (eExceptions == null)
    {
      eExceptions = 
        new DelegatingEcoreEList<EClassifier>(this)
        {
          private static final long serialVersionUID = 1L;

          @Override
          protected List<EClassifier> delegateList()
          {
            return null;
          }

          @Override
          protected List<EClassifier> delegateBasicList()
          {
            return 
              new AbstractSequentialList<EClassifier>() 
              {
                @Override
                public ListIterator<EClassifier> listIterator(int index)
                {
                  return basicListIterator();
                }

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

          @Override
          protected Iterator<EClassifier> delegateIterator()
          {
            return iterator();
          }

          @Override
          protected ListIterator<EClassifier> delegateListIterator()
          {
            return listIterator();
          }

          protected EGenericType wrap(EClassifier eClassifier)
          {
            EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
            eGenericType.setEClassifier(eClassifier);
            return eGenericType;
          }

          protected EClassifier unwrap(EGenericType eGenericType)
          {
            EClassifier result = ((EGenericTypeImpl)eGenericType).basicGetERawType();
            if (result  != null)
            {
              return result;
            }
            else
            {
              return EcorePackage.Literals.EJAVA_OBJECT;
            }
          }

          @Override
          protected void delegateAdd(int index, EClassifier eClassifier)
          {
            getEGenericExceptions().add(index, wrap(eClassifier));
          }

          @Override
          protected void delegateClear()
          {
            getEGenericExceptions().clear();
          }

          @Override
          protected void delegateAdd(EClassifier eClassifier)
          {
            getEGenericExceptions().add(wrap(eClassifier));
          }

          @Override
          protected boolean delegateContains(Object object)
          {
            for (EClassifier eClassifier : this)
            {
              if (object == eClassifier)
              {
                return true;
              }
            }
            return false;
          }

          @Override
          protected boolean delegateContainsAll(Collection<?> collection)
          {
            for (Object object : collection)
            {
              if (!delegateContains(object))
              {
                return false;
              }
            }
            return true;
          }

          @Override
          protected boolean delegateEquals(Object object)
          {
            if (object instanceof List)
            {
              List<?> list = (List<?>)object;
              if (list.size() == delegateSize())
              {
                for (Iterator<?> i = list.iterator(), j = iterator(); i.hasNext(); )
                {
                  if (i.next() != j.next())
                  {
                    return false;
                  }
                }
                return true;
              }
            }
            return false;
          }

          @Override
          protected EClassifier delegateGet(int index)
          {
            EGenericType eGenericType = getEGenericExceptions().get(index);
            return unwrap(eGenericType);
          }

          @Override
          protected int delegateHashCode()
          {
            int hashCode = 1;
            for (EGenericType eGenericType : getEGenericExceptions())
            {
              Object object = unwrap(eGenericType);
              hashCode = 31 * hashCode + (object == null ? 0 : object.hashCode());
            }
            return hashCode;
          }

          @Override
          protected int delegateIndexOf(Object object)
          {
            int index = 0;
            for (EGenericType eGenericType : getEGenericExceptions())
            {
              if (object == unwrap(eGenericType))
              {
                return index;
              }
              ++index;
            }
            return -1;
          }

          @Override
          protected boolean delegateIsEmpty()
          {
            return getEGenericExceptions().isEmpty();
          }

          @Override
          protected int delegateLastIndexOf(Object object)
          {
            EList<EGenericType> eGenericExceptions = getEGenericExceptions();
            for (int i = eGenericExceptions.size() - 1; i >= 0; --i)
            {
              if (unwrap(eGenericExceptions.get(i)) == object)
              {
                return i;
              }
            }
            return -1;
          }

          @Override
          protected EClassifier delegateRemove(int index)
          {
            EGenericType eGenericType = getEGenericExceptions().remove(index);
            return unwrap(eGenericType);
          }

          @Override
          protected EClassifier delegateSet(int index, EClassifier eClassifier)
          {
            EGenericType eGenericType = getEGenericExceptions().get(index);
            EClassifier result = unwrap(eGenericType);

            // If this is just a proxy being resolved...
            //
            if (resolveProxy(result) == eClassifier)
            {
              // Force the raw type to be resolved so we don't resolve this endlessly.
              //
              eGenericType.getERawType();
            }
            else
            {
              // Update the classifier and hence the raw type as normal.
              //
              eGenericType.setEClassifier(eClassifier);
            }
            return result;
          }

          @Override
          protected int delegateSize()
          {
            return getEGenericExceptions().size();
          }

          @Override
          protected Object[] delegateToArray()
          {
            int size = delegateSize();
            Object[] result = new Object[size];
            
            int index = 0;
            for (EGenericType eGenericType : getEGenericExceptions())
            {
              result[index++] = unwrap(eGenericType);
            }
            return result;
          }

          @Override
          protected <T> T[] delegateToArray(T[] array)
          {
            int size = delegateSize();
            if (array.length < size)
            {
              @SuppressWarnings("unchecked") T[] newArray = (T[])Array.newInstance(array.getClass().getComponentType(), size);
              array = newArray;
            }
          
            if (array.length > size)
            {
              array[size] = null;
            }

            int index = 0;
            for (EGenericType eGenericType : getEGenericExceptions())
            {
              @SuppressWarnings("unchecked") T rawType = (T)unwrap(eGenericType);
              array[index++] = rawType;
            }

            return array;
          }

          @Override
          protected String delegateToString()
          {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("[");
            EList<EGenericType> eGenericExceptions = getEGenericExceptions();
            for (int i = 0, size = delegateSize(); i < size; )
            {
              stringBuffer.append(String.valueOf(unwrap(eGenericExceptions.get(i))));
              if (++i < size)
              {
                stringBuffer.append(", ");
              }
            }
            stringBuffer.append("]");
            return stringBuffer.toString();
          }

          @Override
          protected boolean isInstance(Object object)
          {
            return object instanceof EClassifier;
          }

          @Override
          public int getFeatureID()
          {
            return EcorePackage.EOPERATION__EEXCEPTIONS;
          }

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

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

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

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

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

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

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

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

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

          @Override
          protected boolean hasInstanceClass()
          {
            return true;
          }
          
          @Override
          public boolean isSet()
          {
            return isSetEExceptions();
          }
          
          @Override
          protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index, boolean wasSet)
          {
            // The notification for this list is being thrown by the
            // delegating list
            //
            return null;
          }
          
          @Override
          protected void dispatchNotification(Notification notification)
          {
            // Do nothing
          }          
        };
    }
    return eExceptions;
  }
  
  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetEExceptions()
  {
    if (eExceptions != null) ((InternalEList.Unsettable<?>)eExceptions).unset();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public boolean isSetEExceptions()
  {
    return  eExceptions != null && !eExceptions.isEmpty() && !isSetEGenericExceptions();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated NOT
   */
  public EList<EGenericType> getEGenericExceptions()
  {
    if (eGenericExceptions == null)
    {
      eGenericExceptions = 
        new EObjectContainmentEList.Unsettable<EGenericType>(EGenericType.class, this, EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS)
        {
          private static final long serialVersionUID = 1L;

          @Override
          public boolean isSet()
          {
            for (EGenericType eGenericType : this)
            {
              if (eGenericType.getETypeParameter() != null || !eGenericType.getETypeArguments().isEmpty())
              {
                return true;
              }
            }
            return false;
          }
          
          protected EClassifier unwrap(EGenericType eGenericType)
          {
            EClassifier result = eGenericType.getERawType();
            if (result != null)
            {
              return result;
            }
            else
            {
              return EcorePackage.Literals.EJAVA_OBJECT;
            }
          }

          @Override
          protected boolean hasShadow()
          {
            return true;
          }
          
          @Override
          protected NotificationChain shadowAdd(EGenericType eGenericType, NotificationChain notifications)
          {
            ENotificationImpl notification =
              new ENotificationImpl
                (owner, Notification.ADD, EcorePackage.EOPERATION__EEXCEPTIONS, null, unwrap(eGenericType), indexOf(eGenericType), false);
            if (notifications == null)
            {
              notifications = notification;
            }
            else
            {
              notifications.add(notification);
            }
            return notifications;
          }
          
          @Override
          protected NotificationChain shadowRemove(EGenericType eGenericType, NotificationChain notifications)
          {
            ENotificationImpl notification =
              new ENotificationImpl
                (owner, Notification.REMOVE, EcorePackage.EOPERATION__EEXCEPTIONS, unwrap(eGenericType), null, indexOf(eGenericType), false);
            if (notifications == null)
            {
              notifications = notification;
            }
            else
            {
              notifications.add(notification);
            }
            return notifications;
          }
          
          @Override
          protected NotificationChain shadowSet(EGenericType oldEGenericType, EGenericType newEGenericType, NotificationChain notifications)
          {
            ENotificationImpl notification =
              new ENotificationImpl
                (owner, 
                 Notification.SET, 
                 EcorePackage.EOPERATION__EEXCEPTIONS, 
                 unwrap(oldEGenericType), 
                 unwrap(newEGenericType), 
                 indexOf(oldEGenericType), 
                 false);
            if (notifications == null)
            {
              notifications = notification;
            }
            else
            {
              notifications.add(notification);
            }
            return notifications;
          }
          
          @Override
          public EGenericType move(int targetIndex, int sourceIndex)
          {
            EGenericType result = super.move(targetIndex, sourceIndex);
            if (isNotificationRequired())
            {
              dispatchNotification
                (new ENotificationImpl
                   (EOperationImpl.this,
                    Notification.MOVE, 
                    EcorePackage.Literals.EOPERATION__EEXCEPTIONS,
                    new Integer(sourceIndex),
                    unwrap(result), 
                    targetIndex));
            }
            return result;
          }

          @Override
          public void unset()
          {
            // Don't really unset it.
            clear();
          }

          @Override
          protected NotificationImpl createNotification(int eventType, Object oldObject, Object newObject, int index, boolean wasSet)
          {
            switch (eventType)
            {
              case Notification.ADD:
              {
                return super.createNotification(eventType, oldObject, newObject, index, size > 1);
              }
              case Notification.ADD_MANY:
              {
                return super.createNotification(eventType, oldObject, newObject, index, size - ((List<?>)newObject).size() > 0);
              }
              default:
              {
                return super.createNotification(eventType, oldObject, newObject, index, true);
              }
            }
          }
        };

      // Force this to be initialized as well.
      getEExceptions();
    }
    return eGenericExceptions;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public void unsetEGenericExceptions()
  {
    if (eGenericExceptions != null) ((InternalEList.Unsettable<?>)eGenericExceptions).unset();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public boolean isSetEGenericExceptions()
  {
    return eGenericExceptions != null && ((InternalEList.Unsettable<?>)eGenericExceptions).isSet();
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  public EList<ETypeParameter> getETypeParameters()
  {
    if (eTypeParameters == null)
    {
      eTypeParameters = new EObjectContainmentEList.Resolving<ETypeParameter>(ETypeParameter.class, this, EcorePackage.EOPERATION__ETYPE_PARAMETERS);
    }
    return eTypeParameters;
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @SuppressWarnings("unchecked")
  @Override
  public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        return ((InternalEList<InternalEObject>)(InternalEList<?>)getEAnnotations()).basicAdd(otherEnd, msgs);
      case EcorePackage.EOPERATION__ECONTAINING_CLASS:
        if (eInternalContainer() != null)
          msgs = eBasicRemoveFromContainer(msgs);
        return eBasicSetContainer(otherEnd, EcorePackage.EOPERATION__ECONTAINING_CLASS, msgs);
      case EcorePackage.EOPERATION__EPARAMETERS:
        return ((InternalEList<InternalEObject>)(InternalEList<?>)getEParameters()).basicAdd(otherEnd, msgs);
    }
    return eDynamicInverseAdd(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        return ((InternalEList<?>)getEAnnotations()).basicRemove(otherEnd, msgs);
      case EcorePackage.EOPERATION__EGENERIC_TYPE:
        return basicUnsetEGenericType(msgs);
      case EcorePackage.EOPERATION__ECONTAINING_CLASS:
        return eBasicSetContainer(null, EcorePackage.EOPERATION__ECONTAINING_CLASS, msgs);
      case EcorePackage.EOPERATION__ETYPE_PARAMETERS:
        return ((InternalEList<?>)getETypeParameters()).basicRemove(otherEnd, msgs);
      case EcorePackage.EOPERATION__EPARAMETERS:
        return ((InternalEList<?>)getEParameters()).basicRemove(otherEnd, msgs);
      case EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS:
        return ((InternalEList<?>)getEGenericExceptions()).basicRemove(otherEnd, msgs);
    }
    return eDynamicInverseRemove(otherEnd, featureID, msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public NotificationChain eBasicRemoveFromContainerFeature(NotificationChain msgs)
  {
    switch (eContainerFeatureID)
    {
      case EcorePackage.EOPERATION__ECONTAINING_CLASS:
        return eInternalContainer().eInverseRemove(this, EcorePackage.ECLASS__EOPERATIONS, EClass.class, msgs);
    }
    return eDynamicBasicRemoveFromContainer(msgs);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public Object eGet(int featureID, boolean resolve, boolean coreType)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        return getEAnnotations();
      case EcorePackage.EOPERATION__NAME:
        return getName();
      case EcorePackage.EOPERATION__ORDERED:
        return isOrdered() ? Boolean.TRUE : Boolean.FALSE;
      case EcorePackage.EOPERATION__UNIQUE:
        return isUnique() ? Boolean.TRUE : Boolean.FALSE;
      case EcorePackage.EOPERATION__LOWER_BOUND:
        return new Integer(getLowerBound());
      case EcorePackage.EOPERATION__UPPER_BOUND:
        return new Integer(getUpperBound());
      case EcorePackage.EOPERATION__MANY:
        return isMany() ? Boolean.TRUE : Boolean.FALSE;
      case EcorePackage.EOPERATION__REQUIRED:
        return isRequired() ? Boolean.TRUE : Boolean.FALSE;
      case EcorePackage.EOPERATION__ETYPE:
        if (resolve) return getEType();
        return basicGetEType();
      case EcorePackage.EOPERATION__EGENERIC_TYPE:
        return getEGenericType();
      case EcorePackage.EOPERATION__ECONTAINING_CLASS:
        return getEContainingClass();
      case EcorePackage.EOPERATION__ETYPE_PARAMETERS:
        return getETypeParameters();
      case EcorePackage.EOPERATION__EPARAMETERS:
        return getEParameters();
      case EcorePackage.EOPERATION__EEXCEPTIONS:
        return getEExceptions();
      case EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS:
        return getEGenericExceptions();
    }
    return eDynamicGet(featureID, resolve, coreType);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @SuppressWarnings("unchecked")
  @Override
  public void eSet(int featureID, Object newValue)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        getEAnnotations().clear();
        getEAnnotations().addAll((Collection<? extends EAnnotation>)newValue);
        return;
      case EcorePackage.EOPERATION__NAME:
        setName((String)newValue);
        return;
      case EcorePackage.EOPERATION__ORDERED:
        setOrdered(((Boolean)newValue).booleanValue());
        return;
      case EcorePackage.EOPERATION__UNIQUE:
        setUnique(((Boolean)newValue).booleanValue());
        return;
      case EcorePackage.EOPERATION__LOWER_BOUND:
        setLowerBound(((Integer)newValue).intValue());
        return;
      case EcorePackage.EOPERATION__UPPER_BOUND:
        setUpperBound(((Integer)newValue).intValue());
        return;
      case EcorePackage.EOPERATION__ETYPE:
        setEType((EClassifier)newValue);
        return;
      case EcorePackage.EOPERATION__EGENERIC_TYPE:
        setEGenericType((EGenericType)newValue);
        return;
      case EcorePackage.EOPERATION__ETYPE_PARAMETERS:
        getETypeParameters().clear();
        getETypeParameters().addAll((Collection<? extends ETypeParameter>)newValue);
        return;
      case EcorePackage.EOPERATION__EPARAMETERS:
        getEParameters().clear();
        getEParameters().addAll((Collection<? extends EParameter>)newValue);
        return;
      case EcorePackage.EOPERATION__EEXCEPTIONS:
        getEExceptions().clear();
        getEExceptions().addAll((Collection<? extends EClassifier>)newValue);
        return;
      case EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS:
        getEGenericExceptions().clear();
        getEGenericExceptions().addAll((Collection<? extends EGenericType>)newValue);
        return;
    }
    eDynamicSet(featureID, newValue);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public void eUnset(int featureID)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        getEAnnotations().clear();
        return;
      case EcorePackage.EOPERATION__NAME:
        setName(NAME_EDEFAULT);
        return;
      case EcorePackage.EOPERATION__ORDERED:
        setOrdered(ORDERED_EDEFAULT);
        return;
      case EcorePackage.EOPERATION__UNIQUE:
        setUnique(UNIQUE_EDEFAULT);
        return;
      case EcorePackage.EOPERATION__LOWER_BOUND:
        setLowerBound(LOWER_BOUND_EDEFAULT);
        return;
      case EcorePackage.EOPERATION__UPPER_BOUND:
        setUpperBound(UPPER_BOUND_EDEFAULT);
        return;
      case EcorePackage.EOPERATION__ETYPE:
        unsetEType();
        return;
      case EcorePackage.EOPERATION__EGENERIC_TYPE:
        unsetEGenericType();
        return;
      case EcorePackage.EOPERATION__ETYPE_PARAMETERS:
        getETypeParameters().clear();
        return;
      case EcorePackage.EOPERATION__EPARAMETERS:
        getEParameters().clear();
        return;
      case EcorePackage.EOPERATION__EEXCEPTIONS:
        unsetEExceptions();
        return;
      case EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS:
        unsetEGenericExceptions();
        return;
    }
    eDynamicUnset(featureID);
  }

  /**
   * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
   * @generated
   */
  @Override
  public boolean eIsSet(int featureID)
  {
    switch (featureID)
    {
      case EcorePackage.EOPERATION__EANNOTATIONS:
        return eAnnotations != null && !eAnnotations.isEmpty();
      case EcorePackage.EOPERATION__NAME:
        return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
      case EcorePackage.EOPERATION__ORDERED:
        return ((eFlags & ORDERED_EFLAG) != 0) != ORDERED_EDEFAULT;
      case EcorePackage.EOPERATION__UNIQUE:
        return ((eFlags & UNIQUE_EFLAG) != 0) != UNIQUE_EDEFAULT;
      case EcorePackage.EOPERATION__LOWER_BOUND:
        return lowerBound != LOWER_BOUND_EDEFAULT;
      case EcorePackage.EOPERATION__UPPER_BOUND:
        return upperBound != UPPER_BOUND_EDEFAULT;
      case EcorePackage.EOPERATION__MANY:
        return isMany() != MANY_EDEFAULT;
      case EcorePackage.EOPERATION__REQUIRED:
        return isRequired() != REQUIRED_EDEFAULT;
      case EcorePackage.EOPERATION__ETYPE:
        return isSetEType();
      case EcorePackage.EOPERATION__EGENERIC_TYPE:
        return isSetEGenericType();
      case EcorePackage.EOPERATION__ECONTAINING_CLASS:
        return getEContainingClass() != null;
      case EcorePackage.EOPERATION__ETYPE_PARAMETERS:
        return eTypeParameters != null && !eTypeParameters.isEmpty();
      case EcorePackage.EOPERATION__EPARAMETERS:
        return eParameters != null && !eParameters.isEmpty();
      case EcorePackage.EOPERATION__EEXCEPTIONS:
        return isSetEExceptions();
      case EcorePackage.EOPERATION__EGENERIC_EXCEPTIONS:
        return isSetEGenericExceptions();
    }
    return eDynamicIsSet(featureID);
  }

}
