/**
 * 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 v1.0 
 *  which accompanies this distribution, and is available at 
 *  http{//www.eclipse.org/legal/epl-v10.html 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors{  
 *  		Christophe Loetz (Loetz GmbH&Co.KG) - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.perspective.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import org.eclipse.osbp.xtext.action.ActionToolbar;

import org.eclipse.osbp.xtext.blip.Blip;
import org.eclipse.osbp.xtext.blip.BlipUserTask;

import org.eclipse.osbp.xtext.perspective.Perspective;
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage;
import org.eclipse.osbp.xtext.perspective.PerspectiveElement;

import org.eclipse.xtext.common.types.JvmTypeReference;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Perspective</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#isDescription <em>Description</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getDescriptionValue <em>Description Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getIconURI <em>Icon URI</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getAccessibilityPhrase <em>Accessibility Phrase</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getProcess <em>Process</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getUserTask <em>User Task</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getToolbar <em>Toolbar</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getToolbarTypeJvm <em>Toolbar Type Jvm</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.perspective.impl.PerspectiveImpl#getElements <em>Elements</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class PerspectiveImpl extends PerspectiveBaseImpl implements Perspective {
	/**
	 * The default value of the '{@link #isDescription() <em>Description</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isDescription()
	 * @generated
	 * @ordered
	 */
	protected static final boolean DESCRIPTION_EDEFAULT = false;

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

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

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

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

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

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

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

	/**
	 * The cached value of the '{@link #getProcess() <em>Process</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProcess()
	 * @generated
	 * @ordered
	 */
	protected Blip process;

	/**
	 * The cached value of the '{@link #getUserTask() <em>User Task</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUserTask()
	 * @generated
	 * @ordered
	 */
	protected BlipUserTask userTask;

	/**
	 * The cached value of the '{@link #getToolbar() <em>Toolbar</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getToolbar()
	 * @generated
	 * @ordered
	 */
	protected ActionToolbar toolbar;

	/**
	 * The cached value of the '{@link #getToolbarTypeJvm() <em>Toolbar Type Jvm</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getToolbarTypeJvm()
	 * @generated
	 * @ordered
	 */
	protected JvmTypeReference toolbarTypeJvm;

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

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

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescriptionValue(String newDescriptionValue) {
		String oldDescriptionValue = descriptionValue;
		descriptionValue = newDescriptionValue;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION_VALUE, oldDescriptionValue, descriptionValue));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIconURI(String newIconURI) {
		String oldIconURI = iconURI;
		iconURI = newIconURI;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__ICON_URI, oldIconURI, iconURI));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAccessibilityPhrase(String newAccessibilityPhrase) {
		String oldAccessibilityPhrase = accessibilityPhrase;
		accessibilityPhrase = newAccessibilityPhrase;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__ACCESSIBILITY_PHRASE, oldAccessibilityPhrase, accessibilityPhrase));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Blip getProcess() {
		if (process != null && process.eIsProxy()) {
			InternalEObject oldProcess = (InternalEObject)process;
			process = (Blip)eResolveProxy(oldProcess);
			if (process != oldProcess) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE__PROCESS, oldProcess, process));
			}
		}
		return process;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Blip basicGetProcess() {
		return process;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setProcess(Blip newProcess) {
		Blip oldProcess = process;
		process = newProcess;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__PROCESS, oldProcess, process));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BlipUserTask getUserTask() {
		if (userTask != null && userTask.eIsProxy()) {
			InternalEObject oldUserTask = (InternalEObject)userTask;
			userTask = (BlipUserTask)eResolveProxy(oldUserTask);
			if (userTask != oldUserTask) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE__USER_TASK, oldUserTask, userTask));
			}
		}
		return userTask;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BlipUserTask basicGetUserTask() {
		return userTask;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setUserTask(BlipUserTask newUserTask) {
		BlipUserTask oldUserTask = userTask;
		userTask = newUserTask;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__USER_TASK, oldUserTask, userTask));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar getToolbar() {
		if (toolbar != null && toolbar.eIsProxy()) {
			InternalEObject oldToolbar = (InternalEObject)toolbar;
			toolbar = (ActionToolbar)eResolveProxy(oldToolbar);
			if (toolbar != oldToolbar) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE__TOOLBAR, oldToolbar, toolbar));
			}
		}
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ActionToolbar basicGetToolbar() {
		return toolbar;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setToolbar(ActionToolbar newToolbar) {
		ActionToolbar oldToolbar = toolbar;
		toolbar = newToolbar;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__TOOLBAR, oldToolbar, toolbar));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public JvmTypeReference getToolbarTypeJvm() {
		if (toolbarTypeJvm != null && toolbarTypeJvm.eIsProxy()) {
			InternalEObject oldToolbarTypeJvm = (InternalEObject)toolbarTypeJvm;
			toolbarTypeJvm = (JvmTypeReference)eResolveProxy(oldToolbarTypeJvm);
			if (toolbarTypeJvm != oldToolbarTypeJvm) {
				InternalEObject newToolbarTypeJvm = (InternalEObject)toolbarTypeJvm;
				NotificationChain msgs = oldToolbarTypeJvm.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, null, null);
				if (newToolbarTypeJvm.eInternalContainer() == null) {
					msgs = newToolbarTypeJvm.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, null, msgs);
				}
				if (msgs != null) msgs.dispatch();
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, oldToolbarTypeJvm, toolbarTypeJvm));
			}
		}
		return toolbarTypeJvm;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public JvmTypeReference basicGetToolbarTypeJvm() {
		return toolbarTypeJvm;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetToolbarTypeJvm(JvmTypeReference newToolbarTypeJvm, NotificationChain msgs) {
		JvmTypeReference oldToolbarTypeJvm = toolbarTypeJvm;
		toolbarTypeJvm = newToolbarTypeJvm;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, oldToolbarTypeJvm, newToolbarTypeJvm);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setToolbarTypeJvm(JvmTypeReference newToolbarTypeJvm) {
		if (newToolbarTypeJvm != toolbarTypeJvm) {
			NotificationChain msgs = null;
			if (toolbarTypeJvm != null)
				msgs = ((InternalEObject)toolbarTypeJvm).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, null, msgs);
			if (newToolbarTypeJvm != null)
				msgs = ((InternalEObject)newToolbarTypeJvm).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, null, msgs);
			msgs = basicSetToolbarTypeJvm(newToolbarTypeJvm, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM, newToolbarTypeJvm, newToolbarTypeJvm));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<PerspectiveElement> getElements() {
		if (elements == null) {
			elements = new EObjectContainmentEList<PerspectiveElement>(PerspectiveElement.class, this, PerspectiveDslPackage.PERSPECTIVE__ELEMENTS);
		}
		return elements;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM:
				return basicSetToolbarTypeJvm(null, msgs);
			case PerspectiveDslPackage.PERSPECTIVE__ELEMENTS:
				return ((InternalEList<?>)getElements()).basicRemove(otherEnd, 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 PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION:
				return isDescription();
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION_VALUE:
				return getDescriptionValue();
			case PerspectiveDslPackage.PERSPECTIVE__ICON_URI:
				return getIconURI();
			case PerspectiveDslPackage.PERSPECTIVE__ACCESSIBILITY_PHRASE:
				return getAccessibilityPhrase();
			case PerspectiveDslPackage.PERSPECTIVE__PROCESS:
				if (resolve) return getProcess();
				return basicGetProcess();
			case PerspectiveDslPackage.PERSPECTIVE__USER_TASK:
				if (resolve) return getUserTask();
				return basicGetUserTask();
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR:
				if (resolve) return getToolbar();
				return basicGetToolbar();
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM:
				if (resolve) return getToolbarTypeJvm();
				return basicGetToolbarTypeJvm();
			case PerspectiveDslPackage.PERSPECTIVE__ELEMENTS:
				return getElements();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION:
				setDescription((Boolean)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION_VALUE:
				setDescriptionValue((String)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ICON_URI:
				setIconURI((String)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ACCESSIBILITY_PHRASE:
				setAccessibilityPhrase((String)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__PROCESS:
				setProcess((Blip)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__USER_TASK:
				setUserTask((BlipUserTask)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR:
				setToolbar((ActionToolbar)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM:
				setToolbarTypeJvm((JvmTypeReference)newValue);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ELEMENTS:
				getElements().clear();
				getElements().addAll((Collection<? extends PerspectiveElement>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION:
				setDescription(DESCRIPTION_EDEFAULT);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION_VALUE:
				setDescriptionValue(DESCRIPTION_VALUE_EDEFAULT);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ICON_URI:
				setIconURI(ICON_URI_EDEFAULT);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ACCESSIBILITY_PHRASE:
				setAccessibilityPhrase(ACCESSIBILITY_PHRASE_EDEFAULT);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__PROCESS:
				setProcess((Blip)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__USER_TASK:
				setUserTask((BlipUserTask)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR:
				setToolbar((ActionToolbar)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM:
				setToolbarTypeJvm((JvmTypeReference)null);
				return;
			case PerspectiveDslPackage.PERSPECTIVE__ELEMENTS:
				getElements().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION:
				return description != DESCRIPTION_EDEFAULT;
			case PerspectiveDslPackage.PERSPECTIVE__DESCRIPTION_VALUE:
				return DESCRIPTION_VALUE_EDEFAULT == null ? descriptionValue != null : !DESCRIPTION_VALUE_EDEFAULT.equals(descriptionValue);
			case PerspectiveDslPackage.PERSPECTIVE__ICON_URI:
				return ICON_URI_EDEFAULT == null ? iconURI != null : !ICON_URI_EDEFAULT.equals(iconURI);
			case PerspectiveDslPackage.PERSPECTIVE__ACCESSIBILITY_PHRASE:
				return ACCESSIBILITY_PHRASE_EDEFAULT == null ? accessibilityPhrase != null : !ACCESSIBILITY_PHRASE_EDEFAULT.equals(accessibilityPhrase);
			case PerspectiveDslPackage.PERSPECTIVE__PROCESS:
				return process != null;
			case PerspectiveDslPackage.PERSPECTIVE__USER_TASK:
				return userTask != null;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR:
				return toolbar != null;
			case PerspectiveDslPackage.PERSPECTIVE__TOOLBAR_TYPE_JVM:
				return toolbarTypeJvm != null;
			case PerspectiveDslPackage.PERSPECTIVE__ELEMENTS:
				return elements != null && !elements.isEmpty();
		}
		return super.eIsSet(featureID);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (description: ");
		result.append(description);
		result.append(", descriptionValue: ");
		result.append(descriptionValue);
		result.append(", iconURI: ");
		result.append(iconURI);
		result.append(", accessibilityPhrase: ");
		result.append(accessibilityPhrase);
		result.append(')');
		return result.toString();
	}

} //PerspectiveImpl
