/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.core.extension.model.extension.impl;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
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.YBlurNotifier;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableEvent;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableValueEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YFocusNotifier;
import org.eclipse.osbp.ecview.core.common.model.core.YValueBindable;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatadescription;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YTextDatatype;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextFieldEvents;

// TODO: Auto-generated Javadoc
/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>YSuggest Text Field</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getValueBindingEndpoint <em>Value Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getLastFocusEvent <em>Last Focus Event</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getLastBlurEvent <em>Last Blur Event</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getDatatype <em>Datatype</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getDatadescription <em>Datadescription</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getValue <em>Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getKeys <em>Keys</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#isUseSuggestions <em>Use Suggestions</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#isAutoHidePopup <em>Auto Hide Popup</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getLastSuggestion <em>Last Suggestion</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getType <em>Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getEmfNsURI <em>Emf Ns URI</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getTypeQualifiedName <em>Type Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getItemCaptionProperty <em>Item Caption Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getItemFilterProperty <em>Item Filter Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getItemUUIDProperty <em>Item UUID Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YSuggestTextFieldImpl#getEvent <em>Event</em>}</li>
 * </ul>
 *
 * @generated
 */
public class YSuggestTextFieldImpl extends YInputImpl implements
		YSuggestTextField {
	/**
	 * The cached value of the '{@link #getValueBindingEndpoint() <em>Value Binding Endpoint</em>}' reference.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getValueBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableValueEndpoint valueBindingEndpoint;

	/**
	 * The cached value of the '{@link #getLastFocusEvent() <em>Last Focus Event</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLastFocusEvent()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableEvent lastFocusEvent;

	/**
	 * The cached value of the '{@link #getLastBlurEvent() <em>Last Blur Event</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLastBlurEvent()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableEvent lastBlurEvent;

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

	/**
	 * 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 default value of the '{@link #getValue() <em>Value</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getValue()
	 * @generated
	 * @ordered
	 */
	protected static final String VALUE_EDEFAULT = null;

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

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

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

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

	/**
	 * The cached value of the '{@link #isUseSuggestions() <em>Use Suggestions</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isUseSuggestions()
	 * @generated
	 * @ordered
	 */
	protected boolean useSuggestions = USE_SUGGESTIONS_EDEFAULT;

	/**
	 * The default value of the '{@link #isAutoHidePopup() <em>Auto Hide Popup</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAutoHidePopup()
	 * @generated
	 * @ordered
	 */
	protected static final boolean AUTO_HIDE_POPUP_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isAutoHidePopup() <em>Auto Hide Popup</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAutoHidePopup()
	 * @generated
	 * @ordered
	 */
	protected boolean autoHidePopup = AUTO_HIDE_POPUP_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getLastSuggestion() <em>Last Suggestion</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getLastSuggestion()
	 * @generated
	 * @ordered
	 */
	protected Object lastSuggestion = LAST_SUGGESTION_EDEFAULT;

	/**
	 * 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 #getItemCaptionProperty() <em>Item Caption Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getItemCaptionProperty()
	 * @generated
	 * @ordered
	 */
	protected static final String ITEM_CAPTION_PROPERTY_EDEFAULT = null;

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

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

	/**
	 * The cached value of the '{@link #getItemFilterProperty() <em>Item Filter Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getItemFilterProperty()
	 * @generated
	 * @ordered
	 */
	protected String itemFilterProperty = ITEM_FILTER_PROPERTY_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getItemUUIDProperty() <em>Item UUID Property</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getItemUUIDProperty()
	 * @generated
	 * @ordered
	 */
	protected String itemUUIDProperty = ITEM_UUID_PROPERTY_EDEFAULT;

	/**
	 * The default value of the '{@link #getEvent() <em>Event</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEvent()
	 * @generated
	 * @ordered
	 */
	protected static final YSuggestTextFieldEvents EVENT_EDEFAULT = YSuggestTextFieldEvents.OPEN_POPUP;

	/**
	 * The cached value of the '{@link #getEvent() <em>Event</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEvent()
	 * @generated
	 * @ordered
	 */
	protected YSuggestTextFieldEvents event = EVENT_EDEFAULT;

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the e class
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getValueBindingEndpoint()
	 *         <em>Value Binding Endpoint</em>}' reference
	 * @generated
	 */
	public YEmbeddableValueEndpoint getValueBindingEndpoint() {
		if (valueBindingEndpoint != null && valueBindingEndpoint.eIsProxy()) {
			InternalEObject oldValueBindingEndpoint = (InternalEObject)valueBindingEndpoint;
			valueBindingEndpoint = (YEmbeddableValueEndpoint)eResolveProxy(oldValueBindingEndpoint);
			if (valueBindingEndpoint != oldValueBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT, oldValueBindingEndpoint, valueBindingEndpoint));
			}
		}
		return valueBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable value endpoint
	 * @generated
	 */
	public YEmbeddableValueEndpoint basicGetValueBindingEndpoint() {
		return valueBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newValueBindingEndpoint
	 *            the new value binding endpoint
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetValueBindingEndpoint(
			YEmbeddableValueEndpoint newValueBindingEndpoint,
			NotificationChain msgs) {
		YEmbeddableValueEndpoint oldValueBindingEndpoint = valueBindingEndpoint;
		valueBindingEndpoint = newValueBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT, oldValueBindingEndpoint, newValueBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newValueBindingEndpoint
	 *            the new cached value of the '
	 *            {@link #getValueBindingEndpoint()
	 *            <em>Value Binding Endpoint</em>}' reference
	 * @generated
	 */
	public void setValueBindingEndpoint(
			YEmbeddableValueEndpoint newValueBindingEndpoint) {
		if (newValueBindingEndpoint != valueBindingEndpoint) {
			NotificationChain msgs = null;
			if (valueBindingEndpoint != null)
				msgs = ((InternalEObject)valueBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_VALUE_ENDPOINT__ELEMENT, YEmbeddableValueEndpoint.class, msgs);
			if (newValueBindingEndpoint != null)
				msgs = ((InternalEObject)newValueBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_VALUE_ENDPOINT__ELEMENT, YEmbeddableValueEndpoint.class, msgs);
			msgs = basicSetValueBindingEndpoint(newValueBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT, newValueBindingEndpoint, newValueBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableEvent getLastFocusEvent() {
		if (lastFocusEvent != null && lastFocusEvent.eIsProxy()) {
			InternalEObject oldLastFocusEvent = (InternalEObject)lastFocusEvent;
			lastFocusEvent = (YEmbeddableEvent)eResolveProxy(oldLastFocusEvent);
			if (lastFocusEvent != oldLastFocusEvent) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT, oldLastFocusEvent, lastFocusEvent));
			}
		}
		return lastFocusEvent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableEvent basicGetLastFocusEvent() {
		return lastFocusEvent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLastFocusEvent(YEmbeddableEvent newLastFocusEvent) {
		YEmbeddableEvent oldLastFocusEvent = lastFocusEvent;
		lastFocusEvent = newLastFocusEvent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT, oldLastFocusEvent, lastFocusEvent));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableEvent getLastBlurEvent() {
		if (lastBlurEvent != null && lastBlurEvent.eIsProxy()) {
			InternalEObject oldLastBlurEvent = (InternalEObject)lastBlurEvent;
			lastBlurEvent = (YEmbeddableEvent)eResolveProxy(oldLastBlurEvent);
			if (lastBlurEvent != oldLastBlurEvent) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT, oldLastBlurEvent, lastBlurEvent));
			}
		}
		return lastBlurEvent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableEvent basicGetLastBlurEvent() {
		return lastBlurEvent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLastBlurEvent(YEmbeddableEvent newLastBlurEvent) {
		YEmbeddableEvent oldLastBlurEvent = lastBlurEvent;
		lastBlurEvent = newLastBlurEvent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT, oldLastBlurEvent, lastBlurEvent));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getDatatype() <em>Datatype</em>}
	 *         ' reference
	 * @generated
	 */
	public YTextDatatype getDatatype() {
		if (datatype != null && datatype.eIsProxy()) {
			InternalEObject oldDatatype = (InternalEObject)datatype;
			datatype = (YTextDatatype)eResolveProxy(oldDatatype);
			if (datatype != oldDatatype) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE, oldDatatype, datatype));
			}
		}
		return datatype;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y text datatype
	 * @generated
	 */
	public YTextDatatype basicGetDatatype() {
		return datatype;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newDatatype
	 *            the new cached value of the '{@link #getDatatype()
	 *            <em>Datatype</em>}' reference
	 * @generated
	 */
	public void setDatatype(YTextDatatype newDatatype) {
		YTextDatatype oldDatatype = datatype;
		datatype = newDatatype;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE, oldDatatype, datatype));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getDatadescription()
	 *         <em>Datadescription</em>}' reference
	 * @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, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION, oldDatadescription, datadescription));
			}
		}
		return datadescription;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newDatadescription
	 *            the new cached value of the '{@link #getDatadescription()
	 *            <em>Datadescription</em>}' reference
	 * @generated
	 */
	public void setDatadescription(YDatadescription newDatadescription) {
		YDatadescription oldDatadescription = datadescription;
		datadescription = newDatadescription;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION, oldDatadescription, datadescription));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getValue() <em>Value</em>}'
	 *         attribute
	 * @generated
	 */
	public String getValue() {
		return value;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newValue
	 *            the new cached value of the '{@link #getValue()
	 *            <em>Value</em>}' attribute
	 * @generated
	 */
	public void setValue(String newValue) {
		String oldValue = value;
		value = newValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE, oldValue, value));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKeys(String newKeys) {
		String oldKeys = keys;
		keys = newKeys;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__KEYS, oldKeys, keys));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isUseSuggestions()
	 *         <em>Use Suggestions</em>}' attribute
	 * @generated
	 */
	public boolean isUseSuggestions() {
		return useSuggestions;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newUseSuggestions
	 *            the new cached value of the '{@link #isUseSuggestions()
	 *            <em>Use Suggestions</em>}' attribute
	 * @generated
	 */
	public void setUseSuggestions(boolean newUseSuggestions) {
		boolean oldUseSuggestions = useSuggestions;
		useSuggestions = newUseSuggestions;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS, oldUseSuggestions, useSuggestions));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAutoHidePopup(boolean newAutoHidePopup) {
		boolean oldAutoHidePopup = autoHidePopup;
		autoHidePopup = newAutoHidePopup;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP, oldAutoHidePopup, autoHidePopup));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getLastSuggestion()
	 *         <em>Last Suggestion</em>}' attribute
	 * @generated
	 */
	public Object getLastSuggestion() {
		return lastSuggestion;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLastSuggestion
	 *            the new cached value of the '{@link #getLastSuggestion()
	 *            <em>Last Suggestion</em>}' attribute
	 * @generated
	 */
	public void setLastSuggestion(Object newLastSuggestion) {
		Object oldLastSuggestion = lastSuggestion;
		lastSuggestion = newLastSuggestion;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_SUGGESTION, oldLastSuggestion, lastSuggestion));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newType
	 *            the new cached value of the '{@link #getType() <em>Type</em>}'
	 *            attribute
	 * @generated
	 */
	public void setType(Class<?> newType) {
		Class<?> oldType = type;
		type = newType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE, oldType, type));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEmfNsURI
	 *            the new cached value of the '{@link #getEmfNsURI()
	 *            <em>Emf Ns URI</em>}' attribute
	 * @generated
	 */
	public void setEmfNsURI(String newEmfNsURI) {
		String oldEmfNsURI = emfNsURI;
		emfNsURI = newEmfNsURI;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EMF_NS_URI, oldEmfNsURI, emfNsURI));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newTypeQualifiedName
	 *            the new cached value of the '{@link #getTypeQualifiedName()
	 *            <em>Type Qualified Name</em>}' attribute
	 * @generated
	 */
	public void setTypeQualifiedName(String newTypeQualifiedName) {
		String oldTypeQualifiedName = typeQualifiedName;
		typeQualifiedName = newTypeQualifiedName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE_QUALIFIED_NAME, oldTypeQualifiedName, typeQualifiedName));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getItemCaptionProperty()
	 *         <em>Item Caption Property</em>}' attribute
	 * @generated
	 */
	public String getItemCaptionProperty() {
		return itemCaptionProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newItemCaptionProperty
	 *            the new cached value of the '{@link #getItemCaptionProperty()
	 *            <em>Item Caption Property</em>}' attribute
	 * @generated
	 */
	public void setItemCaptionProperty(String newItemCaptionProperty) {
		String oldItemCaptionProperty = itemCaptionProperty;
		itemCaptionProperty = newItemCaptionProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_CAPTION_PROPERTY, oldItemCaptionProperty, itemCaptionProperty));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getItemFilterProperty()
	 *         <em>Item Filter Property</em>}' attribute
	 * @generated
	 */
	public String getItemFilterProperty() {
		return itemFilterProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newItemFilterProperty
	 *            the new cached value of the '{@link #getItemFilterProperty()
	 *            <em>Item Filter Property</em>}' attribute
	 * @generated
	 */
	public void setItemFilterProperty(String newItemFilterProperty) {
		String oldItemFilterProperty = itemFilterProperty;
		itemFilterProperty = newItemFilterProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_FILTER_PROPERTY, oldItemFilterProperty, itemFilterProperty));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getItemUUIDProperty()
	 *         <em>Item UUID Property</em>}' attribute
	 * @generated
	 */
	public String getItemUUIDProperty() {
		return itemUUIDProperty;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newItemUUIDProperty
	 *            the new cached value of the '{@link #getItemUUIDProperty()
	 *            <em>Item UUID Property</em>}' attribute
	 * @generated
	 */
	public void setItemUUIDProperty(String newItemUUIDProperty) {
		String oldItemUUIDProperty = itemUUIDProperty;
		itemUUIDProperty = newItemUUIDProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_UUID_PROPERTY, oldItemUUIDProperty, itemUUIDProperty));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YSuggestTextFieldEvents getEvent() {
		return event;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEvent(YSuggestTextFieldEvents newEvent) {
		YSuggestTextFieldEvents oldEvent = event;
		event = newEvent == null ? EVENT_EDEFAULT : newEvent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EVENT, oldEvent, event));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable value endpoint
	 */
	public YEmbeddableValueEndpoint createValueEndpoint() {
		YEmbeddableValueEndpoint ep = CoreModelFactory.eINSTANCE
				.createYEmbeddableValueEndpoint();
		ep.setElement(this);
		return ep;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				if (valueBindingEndpoint != null)
					msgs = ((InternalEObject)valueBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_VALUE_ENDPOINT__ELEMENT, YEmbeddableValueEndpoint.class, msgs);
				return basicSetValueBindingEndpoint((YEmbeddableValueEndpoint)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				return basicSetValueBindingEndpoint(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param resolve
	 *            the resolve
	 * @param coreType
	 *            the core type
	 * @return the object
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				if (resolve) return getValueBindingEndpoint();
				return basicGetValueBindingEndpoint();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT:
				if (resolve) return getLastFocusEvent();
				return basicGetLastFocusEvent();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT:
				if (resolve) return getLastBlurEvent();
				return basicGetLastBlurEvent();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE:
				if (resolve) return getDatatype();
				return basicGetDatatype();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION:
				if (resolve) return getDatadescription();
				return basicGetDatadescription();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE:
				return getValue();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__KEYS:
				return getKeys();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS:
				return isUseSuggestions();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP:
				return isAutoHidePopup();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_SUGGESTION:
				return getLastSuggestion();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE:
				return getType();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EMF_NS_URI:
				return getEmfNsURI();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE_QUALIFIED_NAME:
				return getTypeQualifiedName();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_CAPTION_PROPERTY:
				return getItemCaptionProperty();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_FILTER_PROPERTY:
				return getItemFilterProperty();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_UUID_PROPERTY:
				return getItemUUIDProperty();
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EVENT:
				return getEvent();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				setValueBindingEndpoint((YEmbeddableValueEndpoint)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT:
				setLastFocusEvent((YEmbeddableEvent)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT:
				setLastBlurEvent((YEmbeddableEvent)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE:
				setDatatype((YTextDatatype)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION:
				setDatadescription((YDatadescription)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE:
				setValue((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__KEYS:
				setKeys((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS:
				setUseSuggestions((Boolean)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP:
				setAutoHidePopup((Boolean)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_SUGGESTION:
				setLastSuggestion(newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE:
				setType((Class<?>)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EMF_NS_URI:
				setEmfNsURI((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_CAPTION_PROPERTY:
				setItemCaptionProperty((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_FILTER_PROPERTY:
				setItemFilterProperty((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_UUID_PROPERTY:
				setItemUUIDProperty((String)newValue);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EVENT:
				setEvent((YSuggestTextFieldEvents)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				setValueBindingEndpoint((YEmbeddableValueEndpoint)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT:
				setLastFocusEvent((YEmbeddableEvent)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT:
				setLastBlurEvent((YEmbeddableEvent)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE:
				setDatatype((YTextDatatype)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION:
				setDatadescription((YDatadescription)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE:
				setValue(VALUE_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__KEYS:
				setKeys(KEYS_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS:
				setUseSuggestions(USE_SUGGESTIONS_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP:
				setAutoHidePopup(AUTO_HIDE_POPUP_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_SUGGESTION:
				setLastSuggestion(LAST_SUGGESTION_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE:
				setType((Class<?>)null);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EMF_NS_URI:
				setEmfNsURI(EMF_NS_URI_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName(TYPE_QUALIFIED_NAME_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_CAPTION_PROPERTY:
				setItemCaptionProperty(ITEM_CAPTION_PROPERTY_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_FILTER_PROPERTY:
				setItemFilterProperty(ITEM_FILTER_PROPERTY_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_UUID_PROPERTY:
				setItemUUIDProperty(ITEM_UUID_PROPERTY_EDEFAULT);
				return;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EVENT:
				setEvent(EVENT_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @return true, if successful
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT:
				return valueBindingEndpoint != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT:
				return lastFocusEvent != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT:
				return lastBlurEvent != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATATYPE:
				return datatype != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__DATADESCRIPTION:
				return datadescription != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE:
				return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__KEYS:
				return KEYS_EDEFAULT == null ? keys != null : !KEYS_EDEFAULT.equals(keys);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS:
				return useSuggestions != USE_SUGGESTIONS_EDEFAULT;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP:
				return autoHidePopup != AUTO_HIDE_POPUP_EDEFAULT;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_SUGGESTION:
				return LAST_SUGGESTION_EDEFAULT == null ? lastSuggestion != null : !LAST_SUGGESTION_EDEFAULT.equals(lastSuggestion);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE:
				return type != null;
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EMF_NS_URI:
				return EMF_NS_URI_EDEFAULT == null ? emfNsURI != null : !EMF_NS_URI_EDEFAULT.equals(emfNsURI);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__TYPE_QUALIFIED_NAME:
				return TYPE_QUALIFIED_NAME_EDEFAULT == null ? typeQualifiedName != null : !TYPE_QUALIFIED_NAME_EDEFAULT.equals(typeQualifiedName);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_CAPTION_PROPERTY:
				return ITEM_CAPTION_PROPERTY_EDEFAULT == null ? itemCaptionProperty != null : !ITEM_CAPTION_PROPERTY_EDEFAULT.equals(itemCaptionProperty);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_FILTER_PROPERTY:
				return ITEM_FILTER_PROPERTY_EDEFAULT == null ? itemFilterProperty != null : !ITEM_FILTER_PROPERTY_EDEFAULT.equals(itemFilterProperty);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__ITEM_UUID_PROPERTY:
				return ITEM_UUID_PROPERTY_EDEFAULT == null ? itemUUIDProperty != null : !ITEM_UUID_PROPERTY_EDEFAULT.equals(itemUUIDProperty);
			case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__EVENT:
				return event != EVENT_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param derivedFeatureID
	 *            the derived feature id
	 * @param baseClass
	 *            the base class
	 * @return the int
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (derivedFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YValueBindable.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT: return CoreModelPackage.YVALUE_BINDABLE__VALUE_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YFocusNotifier.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT: return CoreModelPackage.YFOCUS_NOTIFIER__LAST_FOCUS_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YBlurNotifier.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT: return CoreModelPackage.YBLUR_NOTIFIER__LAST_BLUR_EVENT;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param baseFeatureID
	 *            the base feature id
	 * @param baseClass
	 *            the base class
	 * @return the int
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (baseFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YValueBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YVALUE_BINDABLE__VALUE_BINDING_ENDPOINT: return ExtensionModelPackage.YSUGGEST_TEXT_FIELD__VALUE_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YFocusNotifier.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YFOCUS_NOTIFIER__LAST_FOCUS_EVENT: return ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_FOCUS_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YBlurNotifier.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YBLUR_NOTIFIER__LAST_BLUR_EVENT: return ExtensionModelPackage.YSUGGEST_TEXT_FIELD__LAST_BLUR_EVENT;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (value: ");
		result.append(value);
		result.append(", keys: ");
		result.append(keys);
		result.append(", useSuggestions: ");
		result.append(useSuggestions);
		result.append(", autoHidePopup: ");
		result.append(autoHidePopup);
		result.append(", lastSuggestion: ");
		result.append(lastSuggestion);
		result.append(", type: ");
		result.append(type);
		result.append(", emfNsURI: ");
		result.append(emfNsURI);
		result.append(", typeQualifiedName: ");
		result.append(typeQualifiedName);
		result.append(", itemCaptionProperty: ");
		result.append(itemCaptionProperty);
		result.append(", itemFilterProperty: ");
		result.append(itemFilterProperty);
		result.append(", itemUUIDProperty: ");
		result.append(itemUUIDProperty);
		result.append(", event: ");
		result.append(event);
		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 "";
	}

} // YSuggestTextFieldImpl
