/**
 */
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.YTextChangeNotifier;
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.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YPasswordField;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>YPassword 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.YPasswordFieldImpl#getValueBindingEndpoint <em>Value Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YPasswordFieldImpl#getLastFocusEvent <em>Last Focus Event</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YPasswordFieldImpl#getLastBlurEvent <em>Last Blur Event</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YPasswordFieldImpl#getLastTextChange <em>Last Text Change</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YPasswordFieldImpl#getDatadescription <em>Datadescription</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.core.extension.model.extension.impl.YPasswordFieldImpl#getValue <em>Value</em>}</li>
 * </ul>
 *
 * @generated
 */
public class YPasswordFieldImpl extends YInputImpl implements YPasswordField {
	/**
	 * 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 default value of the '{@link #getLastTextChange() <em>Last Text Change</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLastTextChange()
	 * @generated
	 * @ordered
	 */
	protected static final String LAST_TEXT_CHANGE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getLastTextChange() <em>Last Text Change</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLastTextChange()
	 * @generated
	 * @ordered
	 */
	protected String lastTextChange = LAST_TEXT_CHANGE_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 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;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @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.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT, oldValueBindingEndpoint, valueBindingEndpoint));
			}
		}
		return valueBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YEmbeddableValueEndpoint basicGetValueBindingEndpoint() {
		return valueBindingEndpoint;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @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.YPASSWORD_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.YPASSWORD_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.YPASSWORD_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.YPASSWORD_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.YPASSWORD_FIELD__LAST_BLUR_EVENT, oldLastBlurEvent, lastBlurEvent));
	}

	/**
	 * <!-- 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, ExtensionModelPackage.YPASSWORD_FIELD__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, ExtensionModelPackage.YPASSWORD_FIELD__DATADESCRIPTION, oldDatadescription, datadescription));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setValue(String newValue) {
		String oldValue = value;
		value = newValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YPASSWORD_FIELD__VALUE, oldValue, value));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLastTextChange(String newLastTextChange) {
		String oldLastTextChange = lastTextChange;
		lastTextChange = newLastTextChange;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE, oldLastTextChange, lastTextChange));
	}

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

	/**
	 * Creates a new instance of value endpoint with a reference to that
	 * embeddable.
	 *
	 * @return the y embeddable value endpoint
	 * @generated NOT
	 */
	public YEmbeddableValueEndpoint createValueEndpoint() {
		YEmbeddableValueEndpoint ep = CoreModelFactory.eINSTANCE
				.createYEmbeddableValueEndpoint();
		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 ExtensionModelPackage.YPASSWORD_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 -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT:
				return basicSetValueBindingEndpoint(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 ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT:
				if (resolve) return getValueBindingEndpoint();
				return basicGetValueBindingEndpoint();
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT:
				if (resolve) return getLastFocusEvent();
				return basicGetLastFocusEvent();
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT:
				if (resolve) return getLastBlurEvent();
				return basicGetLastBlurEvent();
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE:
				return getLastTextChange();
			case ExtensionModelPackage.YPASSWORD_FIELD__DATADESCRIPTION:
				if (resolve) return getDatadescription();
				return basicGetDatadescription();
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE:
				return getValue();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT:
				setValueBindingEndpoint((YEmbeddableValueEndpoint)newValue);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT:
				setLastFocusEvent((YEmbeddableEvent)newValue);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT:
				setLastBlurEvent((YEmbeddableEvent)newValue);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE:
				setLastTextChange((String)newValue);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__DATADESCRIPTION:
				setDatadescription((YDatadescription)newValue);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE:
				setValue((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT:
				setValueBindingEndpoint((YEmbeddableValueEndpoint)null);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT:
				setLastFocusEvent((YEmbeddableEvent)null);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT:
				setLastBlurEvent((YEmbeddableEvent)null);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE:
				setLastTextChange(LAST_TEXT_CHANGE_EDEFAULT);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__DATADESCRIPTION:
				setDatadescription((YDatadescription)null);
				return;
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE:
				setValue(VALUE_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT:
				return valueBindingEndpoint != null;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT:
				return lastFocusEvent != null;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT:
				return lastBlurEvent != null;
			case ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE:
				return LAST_TEXT_CHANGE_EDEFAULT == null ? lastTextChange != null : !LAST_TEXT_CHANGE_EDEFAULT.equals(lastTextChange);
			case ExtensionModelPackage.YPASSWORD_FIELD__DATADESCRIPTION:
				return datadescription != null;
			case ExtensionModelPackage.YPASSWORD_FIELD__VALUE:
				return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value);
		}
		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 == YValueBindable.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT: return CoreModelPackage.YVALUE_BINDABLE__VALUE_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YFocusNotifier.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT: return CoreModelPackage.YFOCUS_NOTIFIER__LAST_FOCUS_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YBlurNotifier.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT: return CoreModelPackage.YBLUR_NOTIFIER__LAST_BLUR_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YTextChangeNotifier.class) {
			switch (derivedFeatureID) {
				case ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE: return CoreModelPackage.YTEXT_CHANGE_NOTIFIER__LAST_TEXT_CHANGE;
				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 == YValueBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YVALUE_BINDABLE__VALUE_BINDING_ENDPOINT: return ExtensionModelPackage.YPASSWORD_FIELD__VALUE_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YFocusNotifier.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YFOCUS_NOTIFIER__LAST_FOCUS_EVENT: return ExtensionModelPackage.YPASSWORD_FIELD__LAST_FOCUS_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YBlurNotifier.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YBLUR_NOTIFIER__LAST_BLUR_EVENT: return ExtensionModelPackage.YPASSWORD_FIELD__LAST_BLUR_EVENT;
				default: return -1;
			}
		}
		if (baseClass == YTextChangeNotifier.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YTEXT_CHANGE_NOTIFIER__LAST_TEXT_CHANGE: return ExtensionModelPackage.YPASSWORD_FIELD__LAST_TEXT_CHANGE;
				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(" (lastTextChange: ");
		result.append(lastTextChange);
		result.append(", value: ");
		result.append(value);
		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 "";
	}
	
} //YPasswordFieldImpl
