/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial 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.common.util.EMap;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EObjectResolvingEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.binding.YBinding;
import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YAuthorizationable;
import org.eclipse.osbp.ecview.core.common.model.core.YCommand;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.core.impl.YStringToStringMapImpl;
import org.eclipse.osbp.ecview.core.common.model.visibility.YVisibilityProcessor;
import org.eclipse.osbp.ecview.extension.model.YECviewPackage;
import org.eclipse.osbp.ecview.extension.model.YSuspect;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>YSuspect</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getId <em>Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getProperties <em>Properties</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getAuthorizationGroup <em>Authorization Group</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getAuthorizationId <em>Authorization Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getLabelI18nKey <em>Label I1 8n Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getImageI18nKey <em>Image I1 8n Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getValueBindingEndpoints <em>Value Binding Endpoints</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getVisibilityProcessors <em>Visibility Processors</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getCommands <em>Commands</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getAssocNewiatedElements <em>Assoc Newiated Elements</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getAssociatedBindings <em>Associated Bindings</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getLabel <em>Label</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getContainerValueBindingEndpoint <em>Container Value Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.model.impl.YSuspectImpl#getGroupName <em>Group Name</em>}</li>
 * </ul>
 *
 * @generated
 */
public class YSuspectImpl extends MinimalEObjectImpl.Container implements YSuspect {
	
	/**
	 * <!-- 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 #getTags() <em>Tags</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<String> tags;

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

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

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

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

	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected EMap<String, String> properties;

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

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

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

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

	/**
	 * The default value of the '{@link #getLabelI18nKey() <em>Label I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabelI18nKey()
	 * @generated
	 * @ordered
	 */
	protected static final String LABEL_I1_8N_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getLabelI18nKey() <em>Label I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLabelI18nKey()
	 * @generated
	 * @ordered
	 */
	protected String labelI18nKey = LABEL_I1_8N_KEY_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getImageI18nKey() <em>Image I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getImageI18nKey()
	 * @generated
	 * @ordered
	 */
	protected String imageI18nKey = IMAGE_I1_8N_KEY_EDEFAULT;

	/**
	 * The cached value of the '{@link #getValueBindingEndpoints() <em>Value Binding Endpoints</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getValueBindingEndpoints()
	 * @generated
	 * @ordered
	 */
	protected EList<YBindingEndpoint> valueBindingEndpoints;

	/**
	 * The cached value of the '{@link #getVisibilityProcessors() <em>Visibility Processors</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getVisibilityProcessors()
	 * @generated
	 * @ordered
	 */
	protected EList<YVisibilityProcessor> visibilityProcessors;

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

	/**
	 * The cached value of the '{@link #getAssocNewiatedElements() <em>Assoc Newiated Elements</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAssocNewiatedElements()
	 * @generated
	 * @ordered
	 */
	protected EList<YEmbeddable> assocNewiatedElements;

	/**
	 * The cached value of the '{@link #getAssociatedBindings() <em>Associated Bindings</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAssociatedBindings()
	 * @generated
	 * @ordered
	 */
	protected EList<YBinding> associatedBindings;

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

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

	/**
	 * The cached value of the '{@link #getContainerValueBindingEndpoint() <em>Container Value Binding Endpoint</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getContainerValueBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YValueBindingEndpoint containerValueBindingEndpoint;

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

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

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

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newId
	 *            the new cached value of the '{@link #getId() <em>Id</em>}'
	 *            attribute
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__ID, oldId, id));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newName
	 *            the new cached value of the '{@link #getName() <em>Name</em>}'
	 *            attribute
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTags() <em>Tags</em>}'
	 *         attribute list
	 * @generated
	 */
	public EList<String> getTags() {
		if (tags == null) {
			tags = new EDataTypeUniqueEList<String>(String.class, this, YECviewPackage.YSUSPECT__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getProperties()
	 *         <em>Properties</em>}' map
	 * @generated
	 */
	public EMap<String, String> getProperties() {
		if (properties == null) {
			properties = new EcoreEMap<String,String>(CoreModelPackage.Literals.YSTRING_TO_STRING_MAP, YStringToStringMapImpl.class, this, YECviewPackage.YSUSPECT__PROPERTIES);
		}
		return properties;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newAuthorizationGroup
	 *            the new cached value of the '{@link #getAuthorizationGroup()
	 *            <em>Authorization Group</em>}' attribute
	 * @generated
	 */
	public void setAuthorizationGroup(String newAuthorizationGroup) {
		String oldAuthorizationGroup = authorizationGroup;
		authorizationGroup = newAuthorizationGroup;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP, oldAuthorizationGroup, authorizationGroup));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newAuthorizationId
	 *            the new cached value of the '{@link #getAuthorizationId()
	 *            <em>Authorization Id</em>}' attribute
	 * @generated
	 */
	public void setAuthorizationId(String newAuthorizationId) {
		String oldAuthorizationId = authorizationId;
		authorizationId = newAuthorizationId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__AUTHORIZATION_ID, oldAuthorizationId, authorizationId));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getLabelI18nKey()
	 *         <em>Label I1 8n Key</em>}' attribute
	 * @generated
	 */
	public String getLabelI18nKey() {
		return labelI18nKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLabelI18nKey
	 *            the new cached value of the '{@link #getLabelI18nKey()
	 *            <em>Label I1 8n Key</em>}' attribute
	 * @generated
	 */
	public void setLabelI18nKey(String newLabelI18nKey) {
		String oldLabelI18nKey = labelI18nKey;
		labelI18nKey = newLabelI18nKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__LABEL_I1_8N_KEY, oldLabelI18nKey, labelI18nKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getImageI18nKey()
	 *         <em>Image I1 8n Key</em>}' attribute
	 * @generated
	 */
	public String getImageI18nKey() {
		return imageI18nKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newImageI18nKey
	 *            the new cached value of the '{@link #getImageI18nKey()
	 *            <em>Image I1 8n Key</em>}' attribute
	 * @generated
	 */
	public void setImageI18nKey(String newImageI18nKey) {
		String oldImageI18nKey = imageI18nKey;
		imageI18nKey = newImageI18nKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__IMAGE_I1_8N_KEY, oldImageI18nKey, imageI18nKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getValueBindingEndpoints()
	 *         <em>Value Binding Endpoints</em>}' containment reference list
	 * @generated
	 */
	public EList<YBindingEndpoint> getValueBindingEndpoints() {
		if (valueBindingEndpoints == null) {
			valueBindingEndpoints = new EObjectContainmentEList<YBindingEndpoint>(YBindingEndpoint.class, this, YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS);
		}
		return valueBindingEndpoints;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getVisibilityProcessors()
	 *         <em>Visibility Processors</em>}' containment reference list
	 * @generated
	 */
	public EList<YVisibilityProcessor> getVisibilityProcessors() {
		if (visibilityProcessors == null) {
			visibilityProcessors = new EObjectContainmentEList<YVisibilityProcessor>(YVisibilityProcessor.class, this, YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS);
		}
		return visibilityProcessors;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCommands() <em>Commands</em>}
	 *         ' containment reference list
	 * @generated
	 */
	public EList<YCommand> getCommands() {
		if (commands == null) {
			commands = new EObjectContainmentEList<YCommand>(YCommand.class, this, YECviewPackage.YSUSPECT__COMMANDS);
		}
		return commands;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getAssocNewiatedElements()
	 *         <em>Assoc Newiated Elements</em>}' reference list
	 * @generated
	 */
	public EList<YEmbeddable> getAssocNewiatedElements() {
		if (assocNewiatedElements == null) {
			assocNewiatedElements = new EObjectResolvingEList<YEmbeddable>(YEmbeddable.class, this, YECviewPackage.YSUSPECT__ASSOC_NEWIATED_ELEMENTS);
		}
		return assocNewiatedElements;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getAssociatedBindings()
	 *         <em>Associated Bindings</em>}' containment reference list
	 * @generated
	 */
	public EList<YBinding> getAssociatedBindings() {
		if (associatedBindings == null) {
			associatedBindings = new EObjectContainmentEList<YBinding>(YBinding.class, this, YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS);
		}
		return associatedBindings;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLabel
	 *            the new cached value of the '{@link #getLabel()
	 *            <em>Label</em>}' attribute
	 * @generated
	 */
	public void setLabel(String newLabel) {
		String oldLabel = label;
		label = newLabel;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__LABEL, oldLabel, label));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public YValueBindingEndpoint getContainerValueBindingEndpoint() {
		return containerValueBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetContainerValueBindingEndpoint(YValueBindingEndpoint newContainerValueBindingEndpoint, NotificationChain msgs) {
		YValueBindingEndpoint oldContainerValueBindingEndpoint = containerValueBindingEndpoint;
		containerValueBindingEndpoint = newContainerValueBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT, oldContainerValueBindingEndpoint, newContainerValueBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setContainerValueBindingEndpoint(YValueBindingEndpoint newContainerValueBindingEndpoint) {
		if (newContainerValueBindingEndpoint != containerValueBindingEndpoint) {
			NotificationChain msgs = null;
			if (containerValueBindingEndpoint != null)
				msgs = ((InternalEObject)containerValueBindingEndpoint).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT, null, msgs);
			if (newContainerValueBindingEndpoint != null)
				msgs = ((InternalEObject)newContainerValueBindingEndpoint).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT, null, msgs);
			msgs = basicSetContainerValueBindingEndpoint(newContainerValueBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT, newContainerValueBindingEndpoint, newContainerValueBindingEndpoint));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setGroupName(String newGroupName) {
		String oldGroupName = groupName;
		groupName = newGroupName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, YECviewPackage.YSUSPECT__GROUP_NAME, oldGroupName, groupName));
	}

	/**
	 * <!-- 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 YECviewPackage.YSUSPECT__PROPERTIES:
				return ((InternalEList<?>)getProperties()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
				return ((InternalEList<?>)getValueBindingEndpoints()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
				return ((InternalEList<?>)getVisibilityProcessors()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YSUSPECT__COMMANDS:
				return ((InternalEList<?>)getCommands()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS:
				return ((InternalEList<?>)getAssociatedBindings()).basicRemove(otherEnd, msgs);
			case YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT:
				return basicSetContainerValueBindingEndpoint(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 YECviewPackage.YSUSPECT__TAGS:
				return getTags();
			case YECviewPackage.YSUSPECT__ID:
				return getId();
			case YECviewPackage.YSUSPECT__NAME:
				return getName();
			case YECviewPackage.YSUSPECT__PROPERTIES:
				if (coreType) return getProperties();
				else return getProperties().map();
			case YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP:
				return getAuthorizationGroup();
			case YECviewPackage.YSUSPECT__AUTHORIZATION_ID:
				return getAuthorizationId();
			case YECviewPackage.YSUSPECT__LABEL_I1_8N_KEY:
				return getLabelI18nKey();
			case YECviewPackage.YSUSPECT__IMAGE_I1_8N_KEY:
				return getImageI18nKey();
			case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
				return getValueBindingEndpoints();
			case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
				return getVisibilityProcessors();
			case YECviewPackage.YSUSPECT__COMMANDS:
				return getCommands();
			case YECviewPackage.YSUSPECT__ASSOC_NEWIATED_ELEMENTS:
				return getAssocNewiatedElements();
			case YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS:
				return getAssociatedBindings();
			case YECviewPackage.YSUSPECT__LABEL:
				return getLabel();
			case YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT:
				return getContainerValueBindingEndpoint();
			case YECviewPackage.YSUSPECT__GROUP_NAME:
				return getGroupName();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case YECviewPackage.YSUSPECT__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends String>)newValue);
				return;
			case YECviewPackage.YSUSPECT__ID:
				setId((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__NAME:
				setName((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__PROPERTIES:
				((EStructuralFeature.Setting)getProperties()).set(newValue);
				return;
			case YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP:
				setAuthorizationGroup((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__AUTHORIZATION_ID:
				setAuthorizationId((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__LABEL_I1_8N_KEY:
				setLabelI18nKey((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__IMAGE_I1_8N_KEY:
				setImageI18nKey((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
				getValueBindingEndpoints().clear();
				getValueBindingEndpoints().addAll((Collection<? extends YBindingEndpoint>)newValue);
				return;
			case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
				getVisibilityProcessors().clear();
				getVisibilityProcessors().addAll((Collection<? extends YVisibilityProcessor>)newValue);
				return;
			case YECviewPackage.YSUSPECT__COMMANDS:
				getCommands().clear();
				getCommands().addAll((Collection<? extends YCommand>)newValue);
				return;
			case YECviewPackage.YSUSPECT__ASSOC_NEWIATED_ELEMENTS:
				getAssocNewiatedElements().clear();
				getAssocNewiatedElements().addAll((Collection<? extends YEmbeddable>)newValue);
				return;
			case YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS:
				getAssociatedBindings().clear();
				getAssociatedBindings().addAll((Collection<? extends YBinding>)newValue);
				return;
			case YECviewPackage.YSUSPECT__LABEL:
				setLabel((String)newValue);
				return;
			case YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT:
				setContainerValueBindingEndpoint((YValueBindingEndpoint)newValue);
				return;
			case YECviewPackage.YSUSPECT__GROUP_NAME:
				setGroupName((String)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 YECviewPackage.YSUSPECT__TAGS:
				getTags().clear();
				return;
			case YECviewPackage.YSUSPECT__ID:
				setId(ID_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__NAME:
				setName(NAME_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__PROPERTIES:
				getProperties().clear();
				return;
			case YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP:
				setAuthorizationGroup(AUTHORIZATION_GROUP_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__AUTHORIZATION_ID:
				setAuthorizationId(AUTHORIZATION_ID_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__LABEL_I1_8N_KEY:
				setLabelI18nKey(LABEL_I1_8N_KEY_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__IMAGE_I1_8N_KEY:
				setImageI18nKey(IMAGE_I1_8N_KEY_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
				getValueBindingEndpoints().clear();
				return;
			case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
				getVisibilityProcessors().clear();
				return;
			case YECviewPackage.YSUSPECT__COMMANDS:
				getCommands().clear();
				return;
			case YECviewPackage.YSUSPECT__ASSOC_NEWIATED_ELEMENTS:
				getAssocNewiatedElements().clear();
				return;
			case YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS:
				getAssociatedBindings().clear();
				return;
			case YECviewPackage.YSUSPECT__LABEL:
				setLabel(LABEL_EDEFAULT);
				return;
			case YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT:
				setContainerValueBindingEndpoint((YValueBindingEndpoint)null);
				return;
			case YECviewPackage.YSUSPECT__GROUP_NAME:
				setGroupName(GROUP_NAME_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 YECviewPackage.YSUSPECT__TAGS:
				return tags != null && !tags.isEmpty();
			case YECviewPackage.YSUSPECT__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
			case YECviewPackage.YSUSPECT__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case YECviewPackage.YSUSPECT__PROPERTIES:
				return properties != null && !properties.isEmpty();
			case YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP:
				return AUTHORIZATION_GROUP_EDEFAULT == null ? authorizationGroup != null : !AUTHORIZATION_GROUP_EDEFAULT.equals(authorizationGroup);
			case YECviewPackage.YSUSPECT__AUTHORIZATION_ID:
				return AUTHORIZATION_ID_EDEFAULT == null ? authorizationId != null : !AUTHORIZATION_ID_EDEFAULT.equals(authorizationId);
			case YECviewPackage.YSUSPECT__LABEL_I1_8N_KEY:
				return LABEL_I1_8N_KEY_EDEFAULT == null ? labelI18nKey != null : !LABEL_I1_8N_KEY_EDEFAULT.equals(labelI18nKey);
			case YECviewPackage.YSUSPECT__IMAGE_I1_8N_KEY:
				return IMAGE_I1_8N_KEY_EDEFAULT == null ? imageI18nKey != null : !IMAGE_I1_8N_KEY_EDEFAULT.equals(imageI18nKey);
			case YECviewPackage.YSUSPECT__VALUE_BINDING_ENDPOINTS:
				return valueBindingEndpoints != null && !valueBindingEndpoints.isEmpty();
			case YECviewPackage.YSUSPECT__VISIBILITY_PROCESSORS:
				return visibilityProcessors != null && !visibilityProcessors.isEmpty();
			case YECviewPackage.YSUSPECT__COMMANDS:
				return commands != null && !commands.isEmpty();
			case YECviewPackage.YSUSPECT__ASSOC_NEWIATED_ELEMENTS:
				return assocNewiatedElements != null && !assocNewiatedElements.isEmpty();
			case YECviewPackage.YSUSPECT__ASSOCIATED_BINDINGS:
				return associatedBindings != null && !associatedBindings.isEmpty();
			case YECviewPackage.YSUSPECT__LABEL:
				return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
			case YECviewPackage.YSUSPECT__CONTAINER_VALUE_BINDING_ENDPOINT:
				return containerValueBindingEndpoint != null;
			case YECviewPackage.YSUSPECT__GROUP_NAME:
				return GROUP_NAME_EDEFAULT == null ? groupName != null : !GROUP_NAME_EDEFAULT.equals(groupName);
		}
		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 == YAuthorizationable.class) {
			switch (derivedFeatureID) {
				case YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP: return CoreModelPackage.YAUTHORIZATIONABLE__AUTHORIZATION_GROUP;
				case YECviewPackage.YSUSPECT__AUTHORIZATION_ID: return CoreModelPackage.YAUTHORIZATIONABLE__AUTHORIZATION_ID;
				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 == YAuthorizationable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YAUTHORIZATIONABLE__AUTHORIZATION_GROUP: return YECviewPackage.YSUSPECT__AUTHORIZATION_GROUP;
				case CoreModelPackage.YAUTHORIZATIONABLE__AUTHORIZATION_ID: return YECviewPackage.YSUSPECT__AUTHORIZATION_ID;
				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(" (tags: ");
		result.append(tags);
		result.append(", id: ");
		result.append(id);
		result.append(", name: ");
		result.append(name);
		result.append(", authorizationGroup: ");
		result.append(authorizationGroup);
		result.append(", authorizationId: ");
		result.append(authorizationId);
		result.append(", labelI18nKey: ");
		result.append(labelI18nKey);
		result.append(", imageI18nKey: ");
		result.append(imageI18nKey);
		result.append(", label: ");
		result.append(label);
		result.append(", groupName: ");
		result.append(groupName);
		result.append(')');
		return result.toString();
	}

	/**
	 * Gets the view.
	 *
	 * @return the view
	 * @generated NOT
	 */
	public YView getView() {
		return findViewGeneric(eContainer());
	}

	/**
	 * Find view generic.
	 *
	 * @param container
	 *            the container
	 * @return the y view
	 * @generated NOT
	 */
	protected YView findViewGeneric(EObject container) {
		if (container == null) {
			return null;
		}
		if (container instanceof YView) {
			return (YView) container;
		} else if (container instanceof YLayout) {
			return ((YLayout) container).getView();
		} else {
			EObject parent = container.eContainer();
			return findViewGeneric(parent);
		}
	}

}
