/**
 * All rights reserved by Loetz GmbH und CoKG Heidelberg 2015.
 * 
 * Contributors:
 *       Florian Pirchner - initial API and implementation
 */
package org.eclipse.osbp.ecview.extension.model.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelFactory;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YSelectionBindable;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatadescription;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YComboBoxDatatype;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YBeanServiceConsumer;
import org.eclipse.osbp.ecview.core.extension.model.extension.impl.YInputImpl;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YPairComboBox;

/**
 * <!-- begin-user-doc --> An implementation of the model object '<em><b>YPair Combo Box</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getCollectionBindingEndpoint <em>Collection Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getSelectionBindingEndpoint <em>Selection Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#isUseBeanService <em>Use Bean Service</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getDatadescription <em>Datadescription</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getDatatype <em>Datatype</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getSelection <em>Selection</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getCollection <em>Collection</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getType <em>Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getEmfNsURI <em>Emf Ns URI</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getTypeQualifiedName <em>Type Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getCaptionProperty <em>Caption Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getImageProperty <em>Image Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getDescriptionProperty <em>Description Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YPairComboBoxImpl#getDescription <em>Description</em>}</li>
 * </ul>
 *
 * @generated
 */
public class YPairComboBoxImpl extends YInputImpl implements YPairComboBox {
	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public static final String copyright = "All rights reserved by Loetz GmbH und CoKG Heidelberg 2015.\n\nContributors:\n      Florian Pirchner - initial API and implementation";

	/**
	 * The cached value of the '{@link #getCollectionBindingEndpoint() <em>Collection Binding Endpoint</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCollectionBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableCollectionEndpoint collectionBindingEndpoint;

	/**
	 * The cached value of the '{@link #getSelectionBindingEndpoint() <em>Selection Binding Endpoint</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSelectionBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableSelectionEndpoint selectionBindingEndpoint;

	/**
	 * The default value of the '{@link #isUseBeanService() <em>Use Bean Service</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #isUseBeanService()
	 * @generated
	 * @ordered
	 */
	protected static final boolean USE_BEAN_SERVICE_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isUseBeanService() <em>Use Bean Service</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #isUseBeanService()
	 * @generated
	 * @ordered
	 */
	protected boolean useBeanService = USE_BEAN_SERVICE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getDatadescription() <em>Datadescription</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDatadescription()
	 * @generated
	 * @ordered
	 */
	protected YDatadescription datadescription;

	/**
	 * The cached value of the '{@link #getDatatype() <em>Datatype</em>}' reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDatatype()
	 * @generated
	 * @ordered
	 */
	protected YComboBoxDatatype datatype;

	/**
	 * The default value of the '{@link #getSelection() <em>Selection</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSelection()
	 * @generated
	 * @ordered
	 */
	protected static final Object SELECTION_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getSelection() <em>Selection</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSelection()
	 * @generated
	 * @ordered
	 */
	protected Object selection = SELECTION_EDEFAULT;

	/**
	 * The cached value of the '{@link #getCollection() <em>Collection</em>}' attribute list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCollection()
	 * @generated
	 * @ordered
	 */
	protected EList<Object> collection;

	/**
	 * The cached value of the '{@link #getType() <em>Type</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getType()
	 * @generated
	 * @ordered
	 */
	protected Class<?> type;

	/**
	 * The default value of the '{@link #getEmfNsURI() <em>Emf Ns URI</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEmfNsURI()
	 * @generated
	 * @ordered
	 */
	protected static final String EMF_NS_URI_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getEmfNsURI() <em>Emf Ns URI</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEmfNsURI()
	 * @generated
	 * @ordered
	 */
	protected String emfNsURI = EMF_NS_URI_EDEFAULT;

	/**
	 * The default value of the '{@link #getTypeQualifiedName() <em>Type Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTypeQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected static final String TYPE_QUALIFIED_NAME_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getTypeQualifiedName() <em>Type Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTypeQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected String typeQualifiedName = TYPE_QUALIFIED_NAME_EDEFAULT;

	/**
	 * The default value of the '{@link #getCaptionProperty() <em>Caption Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCaptionProperty()
	 * @generated
	 * @ordered
	 */
	protected static final String CAPTION_PROPERTY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getCaptionProperty() <em>Caption Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCaptionProperty()
	 * @generated
	 * @ordered
	 */
	protected String captionProperty = CAPTION_PROPERTY_EDEFAULT;

	/**
	 * The default value of the '{@link #getImageProperty() <em>Image Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImageProperty()
	 * @generated
	 * @ordered
	 */
	protected static final String IMAGE_PROPERTY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getImageProperty() <em>Image Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getImageProperty()
	 * @generated
	 * @ordered
	 */
	protected String imageProperty = IMAGE_PROPERTY_EDEFAULT;

	/**
	 * The default value of the '{@link #getDescriptionProperty() <em>Description Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDescriptionProperty()
	 * @generated
	 * @ordered
	 */
	protected static final String DESCRIPTION_PROPERTY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDescriptionProperty() <em>Description Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDescriptionProperty()
	 * @generated
	 * @ordered
	 */
	protected String descriptionProperty = DESCRIPTION_PROPERTY_EDEFAULT;

	/**
	 * The default value of the '{@link #getDescription() <em>Description</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDescription()
	 * @generated
	 * @ordered
	 */
	protected static final String DESCRIPTION_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getDescription() <em>Description</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getDescription()
	 * @generated
	 * @ordered
	 */
	protected String description = DESCRIPTION_EDEFAULT;

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableCollectionEndpoint getCollectionBindingEndpoint() {
		if (collectionBindingEndpoint != null && collectionBindingEndpoint.eIsProxy()) {
			InternalEObject oldCollectionBindingEndpoint = (InternalEObject)collectionBindingEndpoint;
			collectionBindingEndpoint = (YEmbeddableCollectionEndpoint)eResolveProxy(oldCollectionBindingEndpoint);
			if (collectionBindingEndpoint != oldCollectionBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT, oldCollectionBindingEndpoint, collectionBindingEndpoint));
			}
		}
		return collectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableCollectionEndpoint basicGetCollectionBindingEndpoint() {
		return collectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetCollectionBindingEndpoint(YEmbeddableCollectionEndpoint newCollectionBindingEndpoint, NotificationChain msgs) {
		YEmbeddableCollectionEndpoint oldCollectionBindingEndpoint = collectionBindingEndpoint;
		collectionBindingEndpoint = newCollectionBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT, oldCollectionBindingEndpoint, newCollectionBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setCollectionBindingEndpoint(YEmbeddableCollectionEndpoint newCollectionBindingEndpoint) {
		if (newCollectionBindingEndpoint != collectionBindingEndpoint) {
			NotificationChain msgs = null;
			if (collectionBindingEndpoint != null)
				msgs = ((InternalEObject)collectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
			if (newCollectionBindingEndpoint != null)
				msgs = ((InternalEObject)newCollectionBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
			msgs = basicSetCollectionBindingEndpoint(newCollectionBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT, newCollectionBindingEndpoint, newCollectionBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableSelectionEndpoint getSelectionBindingEndpoint() {
		if (selectionBindingEndpoint != null && selectionBindingEndpoint.eIsProxy()) {
			InternalEObject oldSelectionBindingEndpoint = (InternalEObject)selectionBindingEndpoint;
			selectionBindingEndpoint = (YEmbeddableSelectionEndpoint)eResolveProxy(oldSelectionBindingEndpoint);
			if (selectionBindingEndpoint != oldSelectionBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT, oldSelectionBindingEndpoint, selectionBindingEndpoint));
			}
		}
		return selectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableSelectionEndpoint basicGetSelectionBindingEndpoint() {
		return selectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSelectionBindingEndpoint(YEmbeddableSelectionEndpoint newSelectionBindingEndpoint, NotificationChain msgs) {
		YEmbeddableSelectionEndpoint oldSelectionBindingEndpoint = selectionBindingEndpoint;
		selectionBindingEndpoint = newSelectionBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT, oldSelectionBindingEndpoint, newSelectionBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setSelectionBindingEndpoint(YEmbeddableSelectionEndpoint newSelectionBindingEndpoint) {
		if (newSelectionBindingEndpoint != selectionBindingEndpoint) {
			NotificationChain msgs = null;
			if (selectionBindingEndpoint != null)
				msgs = ((InternalEObject)selectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
			if (newSelectionBindingEndpoint != null)
				msgs = ((InternalEObject)newSelectionBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
			msgs = basicSetSelectionBindingEndpoint(newSelectionBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT, newSelectionBindingEndpoint, newSelectionBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isUseBeanService() {
		return useBeanService;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setUseBeanService(boolean newUseBeanService) {
		boolean oldUseBeanService = useBeanService;
		useBeanService = newUseBeanService;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE, oldUseBeanService, useBeanService));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YDatadescription getDatadescription() {
		if (datadescription != null && datadescription.eIsProxy()) {
			InternalEObject oldDatadescription = (InternalEObject)datadescription;
			datadescription = (YDatadescription)eResolveProxy(oldDatadescription);
			if (datadescription != oldDatadescription) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION, oldDatadescription, datadescription));
			}
		}
		return datadescription;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YDatadescription basicGetDatadescription() {
		return datadescription;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setDatadescription(YDatadescription newDatadescription) {
		YDatadescription oldDatadescription = datadescription;
		datadescription = newDatadescription;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION, oldDatadescription, datadescription));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YComboBoxDatatype getDatatype() {
		if (datatype != null && datatype.eIsProxy()) {
			InternalEObject oldDatatype = (InternalEObject)datatype;
			datatype = (YComboBoxDatatype)eResolveProxy(oldDatatype);
			if (datatype != oldDatatype) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, YECviewPackage.YPAIR_COMBO_BOX__DATATYPE, oldDatatype, datatype));
			}
		}
		return datatype;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public YComboBoxDatatype basicGetDatatype() {
		return datatype;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setDatatype(YComboBoxDatatype newDatatype) {
		YComboBoxDatatype oldDatatype = datatype;
		datatype = newDatatype;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__DATATYPE, oldDatatype, datatype));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public Object getSelection() {
		return selection;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setSelection(Object newSelection) {
		Object oldSelection = selection;
		selection = newSelection;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__SELECTION, oldSelection, selection));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EList<Object> getCollection() {
		if (collection == null) {
			collection = new EDataTypeUniqueEList<Object>(Object.class, this, YECviewPackage.YPAIR_COMBO_BOX__COLLECTION);
		}
		return collection;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public Class<?> getType() {
		return type;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setType(Class<?> newType) {
		Class<?> oldType = type;
		type = newType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__TYPE, oldType, type));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getEmfNsURI() {
		return emfNsURI;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setEmfNsURI(String newEmfNsURI) {
		String oldEmfNsURI = emfNsURI;
		emfNsURI = newEmfNsURI;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__EMF_NS_URI, oldEmfNsURI, emfNsURI));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getTypeQualifiedName() {
		return typeQualifiedName;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setTypeQualifiedName(String newTypeQualifiedName) {
		String oldTypeQualifiedName = typeQualifiedName;
		typeQualifiedName = newTypeQualifiedName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__TYPE_QUALIFIED_NAME, oldTypeQualifiedName, typeQualifiedName));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getCaptionProperty() {
		return captionProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setCaptionProperty(String newCaptionProperty) {
		String oldCaptionProperty = captionProperty;
		captionProperty = newCaptionProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__CAPTION_PROPERTY, oldCaptionProperty, captionProperty));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getImageProperty() {
		return imageProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setImageProperty(String newImageProperty) {
		String oldImageProperty = imageProperty;
		imageProperty = newImageProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__IMAGE_PROPERTY, oldImageProperty, imageProperty));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getDescriptionProperty() {
		return descriptionProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescriptionProperty(String newDescriptionProperty) {
		String oldDescriptionProperty = descriptionProperty;
		descriptionProperty = newDescriptionProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION_PROPERTY, oldDescriptionProperty, descriptionProperty));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescription(String newDescription) {
		String oldDescription = description;
		description = newDescription;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION, oldDescription, description));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable selection endpoint
	 * @generated
	 */
	public YEmbeddableSelectionEndpoint createSelectionEndpointGen() {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable collection endpoint
	 * @generated
	 */
	public YEmbeddableCollectionEndpoint createCollectionEndpointGen() {
		// TODO: implement this method
		// Ensure that you remove @generated or mark it @generated NOT
		throw new UnsupportedOperationException();
	}

	/**
	 * Creates a new instance of selection endpoint with a reference to that embeddable.
	 *
	 * @return the y embeddable selection endpoint
	 * @generated NOT
	 */
	public YEmbeddableSelectionEndpoint createSelectionEndpoint() {
		YEmbeddableSelectionEndpoint ep = CoreModelFactory.eINSTANCE.createYEmbeddableSelectionEndpoint();
		ep.setElement(this);
		return ep;
	}

	/**
	 * Creates a new instance of collection endpoint with a reference to that embeddable.
	 *
	 * @return the y embeddable collection endpoint
	 * @generated NOT
	 */
	public YEmbeddableCollectionEndpoint createCollectionEndpoint() {
		YEmbeddableCollectionEndpoint ep = CoreModelFactory.eINSTANCE.createYEmbeddableCollectionEndpoint();
		ep.setElement(this);
		return ep;

	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				if (collectionBindingEndpoint != null)
					msgs = ((InternalEObject)collectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
				return basicSetCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)otherEnd, msgs);
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				if (selectionBindingEndpoint != null)
					msgs = ((InternalEObject)selectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
				return basicSetSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				return basicSetCollectionBindingEndpoint(null, msgs);
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				return basicSetSelectionBindingEndpoint(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				if (resolve) return getCollectionBindingEndpoint();
				return basicGetCollectionBindingEndpoint();
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				if (resolve) return getSelectionBindingEndpoint();
				return basicGetSelectionBindingEndpoint();
			case YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE:
				return isUseBeanService();
			case YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION:
				if (resolve) return getDatadescription();
				return basicGetDatadescription();
			case YECviewPackage.YPAIR_COMBO_BOX__DATATYPE:
				if (resolve) return getDatatype();
				return basicGetDatatype();
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION:
				return getSelection();
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION:
				return getCollection();
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE:
				return getType();
			case YECviewPackage.YPAIR_COMBO_BOX__EMF_NS_URI:
				return getEmfNsURI();
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE_QUALIFIED_NAME:
				return getTypeQualifiedName();
			case YECviewPackage.YPAIR_COMBO_BOX__CAPTION_PROPERTY:
				return getCaptionProperty();
			case YECviewPackage.YPAIR_COMBO_BOX__IMAGE_PROPERTY:
				return getImageProperty();
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION_PROPERTY:
				return getDescriptionProperty();
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION:
				return getDescription();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				setCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				setSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE:
				setUseBeanService((Boolean)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION:
				setDatadescription((YDatadescription)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DATATYPE:
				setDatatype((YComboBoxDatatype)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION:
				setSelection(newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION:
				getCollection().clear();
				getCollection().addAll((Collection<? extends Object>)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE:
				setType((Class<?>)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__EMF_NS_URI:
				setEmfNsURI((String)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName((String)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__CAPTION_PROPERTY:
				setCaptionProperty((String)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__IMAGE_PROPERTY:
				setImageProperty((String)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION_PROPERTY:
				setDescriptionProperty((String)newValue);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION:
				setDescription((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				setCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)null);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				setSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)null);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE:
				setUseBeanService(USE_BEAN_SERVICE_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION:
				setDatadescription((YDatadescription)null);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DATATYPE:
				setDatatype((YComboBoxDatatype)null);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION:
				setSelection(SELECTION_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION:
				getCollection().clear();
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE:
				setType((Class<?>)null);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__EMF_NS_URI:
				setEmfNsURI(EMF_NS_URI_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName(TYPE_QUALIFIED_NAME_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__CAPTION_PROPERTY:
				setCaptionProperty(CAPTION_PROPERTY_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__IMAGE_PROPERTY:
				setImageProperty(IMAGE_PROPERTY_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION_PROPERTY:
				setDescriptionProperty(DESCRIPTION_PROPERTY_EDEFAULT);
				return;
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION:
				setDescription(DESCRIPTION_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT:
				return collectionBindingEndpoint != null;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT:
				return selectionBindingEndpoint != null;
			case YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE:
				return useBeanService != USE_BEAN_SERVICE_EDEFAULT;
			case YECviewPackage.YPAIR_COMBO_BOX__DATADESCRIPTION:
				return datadescription != null;
			case YECviewPackage.YPAIR_COMBO_BOX__DATATYPE:
				return datatype != null;
			case YECviewPackage.YPAIR_COMBO_BOX__SELECTION:
				return SELECTION_EDEFAULT == null ? selection != null : !SELECTION_EDEFAULT.equals(selection);
			case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION:
				return collection != null && !collection.isEmpty();
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE:
				return type != null;
			case YECviewPackage.YPAIR_COMBO_BOX__EMF_NS_URI:
				return EMF_NS_URI_EDEFAULT == null ? emfNsURI != null : !EMF_NS_URI_EDEFAULT.equals(emfNsURI);
			case YECviewPackage.YPAIR_COMBO_BOX__TYPE_QUALIFIED_NAME:
				return TYPE_QUALIFIED_NAME_EDEFAULT == null ? typeQualifiedName != null : !TYPE_QUALIFIED_NAME_EDEFAULT.equals(typeQualifiedName);
			case YECviewPackage.YPAIR_COMBO_BOX__CAPTION_PROPERTY:
				return CAPTION_PROPERTY_EDEFAULT == null ? captionProperty != null : !CAPTION_PROPERTY_EDEFAULT.equals(captionProperty);
			case YECviewPackage.YPAIR_COMBO_BOX__IMAGE_PROPERTY:
				return IMAGE_PROPERTY_EDEFAULT == null ? imageProperty != null : !IMAGE_PROPERTY_EDEFAULT.equals(imageProperty);
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION_PROPERTY:
				return DESCRIPTION_PROPERTY_EDEFAULT == null ? descriptionProperty != null : !DESCRIPTION_PROPERTY_EDEFAULT.equals(descriptionProperty);
			case YECviewPackage.YPAIR_COMBO_BOX__DESCRIPTION:
				return DESCRIPTION_EDEFAULT == null ? description != null : !DESCRIPTION_EDEFAULT.equals(description);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (derivedFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YCollectionBindable.class) {
			switch (derivedFeatureID) {
				case YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT: return CoreModelPackage.YCOLLECTION_BINDABLE__COLLECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YSelectionBindable.class) {
			switch (derivedFeatureID) {
				case YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT: return CoreModelPackage.YSELECTION_BINDABLE__SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YBeanServiceConsumer.class) {
			switch (derivedFeatureID) {
				case YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE: return ExtensionModelPackage.YBEAN_SERVICE_CONSUMER__USE_BEAN_SERVICE;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (baseFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YCollectionBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YCOLLECTION_BINDABLE__COLLECTION_BINDING_ENDPOINT: return YECviewPackage.YPAIR_COMBO_BOX__COLLECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YSelectionBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YSELECTION_BINDABLE__SELECTION_BINDING_ENDPOINT: return YECviewPackage.YPAIR_COMBO_BOX__SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YBeanServiceConsumer.class) {
			switch (baseFeatureID) {
				case ExtensionModelPackage.YBEAN_SERVICE_CONSUMER__USE_BEAN_SERVICE: return YECviewPackage.YPAIR_COMBO_BOX__USE_BEAN_SERVICE;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (useBeanService: ");
		result.append(useBeanService);
		result.append(", selection: ");
		result.append(selection);
		result.append(", collection: ");
		result.append(collection);
		result.append(", type: ");
		result.append(type);
		result.append(", emfNsURI: ");
		result.append(emfNsURI);
		result.append(", typeQualifiedName: ");
		result.append(typeQualifiedName);
		result.append(", captionProperty: ");
		result.append(captionProperty);
		result.append(", imageProperty: ");
		result.append(imageProperty);
		result.append(", descriptionProperty: ");
		result.append(descriptionProperty);
		result.append(", description: ");
		result.append(description);
		result.append(')');
		return result.toString();
	}

	/**
	 * Sets the label by creating a new datadescription.
	 *
	 * @param label
	 *            the new label
	 */
	public void setLabel(String label) {
		YDatadescription ds = getDatadescription();
		if (ds == null) {
			setDatadescription(createDatadescription(label));
			getOrphanDatadescriptions().add(getDatadescription());
		} else {
			ds.setLabel(label);
		}
	}

	/**
	 * Sets the label i18nKey by creating a new datadescription.
	 *
	 * @param i18nKey
	 *            the new label i18n key
	 */
	public void setLabelI18nKey(String i18nKey) {
		YDatadescription ds = getDatadescription();
		if (ds == null) {
			setDatadescription(createDatadescriptionForI18n(i18nKey));
			getOrphanDatadescriptions().add(getDatadescription());
		} else {
			ds.setLabelI18nKey(i18nKey);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.model.core.impl.YFieldImpl#getLabel()
	 */
	@Override
	public String getLabel() {
		YDatadescription ds = getDatadescription();
		if (ds != null) {
			return ds.getLabel();
		}
		return "";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.ecview.core.common.model.core.impl.YFieldImpl#getLabelI18nKey()
	 */
	@Override
	public String getLabelI18nKey() {
		YDatadescription ds = getDatadescription();
		if (ds != null) {
			return ds.getLabelI18nKey();
		}
		return "";
	}

} // YPairComboBoxImpl
