/**
 * Copyright (c) 2014, Loetz GmbH&Co.KG (Heidelberg)
 *  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 
 * 
 *  Based on ideas from Xtext, Xtend, Xcore
 *   
 *  Contributors:  
 *  		Loetz GmbH&Co.KG - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.blip.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.blip.Blip;
import org.eclipse.osbp.xtext.blip.BlipDSLPackage;
import org.eclipse.osbp.xtext.blip.BlipItem;
import org.eclipse.osbp.xtext.blip.BlipWorkload;
import org.eclipse.osbp.xtext.blip.IconsEnum;

import org.eclipse.osbp.xtext.functionlibrarydsl.FunctionLibraryBlipGroup;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Blip</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getProcess <em>Process</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#isDescription <em>Description</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getDescriptionValue <em>Description Value</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#isHasImage <em>Has Image</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getImage <em>Image</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#isHasIcon <em>Has Icon</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getIcon <em>Icon</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#isHasLogging <em>Has Logging</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getFunctionGroup <em>Function Group</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getWorkload <em>Workload</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.blip.impl.BlipImpl#getItems <em>Items</em>}</li>
 * </ul>
 *
 * @generated
 */
public class BlipImpl extends BlipBaseImpl implements Blip {
	/**
	 * The cached value of the '{@link #getProcess() <em>Process</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProcess()
	 * @generated
	 * @ordered
	 */
	protected org.eclipse.bpmn2.Process process;

	/**
	 * 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 #isHasImage() <em>Has Image</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasImage()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HAS_IMAGE_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isHasImage() <em>Has Image</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasImage()
	 * @generated
	 * @ordered
	 */
	protected boolean hasImage = HAS_IMAGE_EDEFAULT;

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

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

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

	/**
	 * The cached value of the '{@link #isHasIcon() <em>Has Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasIcon()
	 * @generated
	 * @ordered
	 */
	protected boolean hasIcon = HAS_ICON_EDEFAULT;

	/**
	 * The default value of the '{@link #getIcon() <em>Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIcon()
	 * @generated
	 * @ordered
	 */
	protected static final IconsEnum ICON_EDEFAULT = IconsEnum.ICON_PLUS;

	/**
	 * The cached value of the '{@link #getIcon() <em>Icon</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIcon()
	 * @generated
	 * @ordered
	 */
	protected IconsEnum icon = ICON_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isHasLogging() <em>Has Logging</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isHasLogging()
	 * @generated
	 * @ordered
	 */
	protected boolean hasLogging = HAS_LOGGING_EDEFAULT;

	/**
	 * The cached value of the '{@link #getFunctionGroup() <em>Function Group</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getFunctionGroup()
	 * @generated
	 * @ordered
	 */
	protected FunctionLibraryBlipGroup functionGroup;

	/**
	 * The cached value of the '{@link #getWorkload() <em>Workload</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getWorkload()
	 * @generated
	 * @ordered
	 */
	protected BlipWorkload workload;

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

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public org.eclipse.bpmn2.Process basicGetProcess() {
		return process;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setProcess(org.eclipse.bpmn2.Process newProcess) {
		org.eclipse.bpmn2.Process oldProcess = process;
		process = newProcess;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__PROCESS, oldProcess, process));
	}

	/**
	 * <!-- 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, BlipDSLPackage.BLIP__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, BlipDSLPackage.BLIP__DESCRIPTION_VALUE, oldDescriptionValue, descriptionValue));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasImage(boolean newHasImage) {
		boolean oldHasImage = hasImage;
		hasImage = newHasImage;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__HAS_IMAGE, oldHasImage, hasImage));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setImage(String newImage) {
		String oldImage = image;
		image = newImage;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__IMAGE, oldImage, image));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasIcon(boolean newHasIcon) {
		boolean oldHasIcon = hasIcon;
		hasIcon = newHasIcon;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__HAS_ICON, oldHasIcon, hasIcon));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IconsEnum getIcon() {
		return icon;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIcon(IconsEnum newIcon) {
		IconsEnum oldIcon = icon;
		icon = newIcon == null ? ICON_EDEFAULT : newIcon;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__ICON, oldIcon, icon));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasLogging(boolean newHasLogging) {
		boolean oldHasLogging = hasLogging;
		hasLogging = newHasLogging;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__HAS_LOGGING, oldHasLogging, hasLogging));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryBlipGroup getFunctionGroup() {
		if (functionGroup != null && functionGroup.eIsProxy()) {
			InternalEObject oldFunctionGroup = (InternalEObject)functionGroup;
			functionGroup = (FunctionLibraryBlipGroup)eResolveProxy(oldFunctionGroup);
			if (functionGroup != oldFunctionGroup) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, BlipDSLPackage.BLIP__FUNCTION_GROUP, oldFunctionGroup, functionGroup));
			}
		}
		return functionGroup;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public FunctionLibraryBlipGroup basicGetFunctionGroup() {
		return functionGroup;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFunctionGroup(FunctionLibraryBlipGroup newFunctionGroup) {
		FunctionLibraryBlipGroup oldFunctionGroup = functionGroup;
		functionGroup = newFunctionGroup;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__FUNCTION_GROUP, oldFunctionGroup, functionGroup));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public BlipWorkload getWorkload() {
		return workload;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetWorkload(BlipWorkload newWorkload, NotificationChain msgs) {
		BlipWorkload oldWorkload = workload;
		workload = newWorkload;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__WORKLOAD, oldWorkload, newWorkload);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setWorkload(BlipWorkload newWorkload) {
		if (newWorkload != workload) {
			NotificationChain msgs = null;
			if (workload != null)
				msgs = ((InternalEObject)workload).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - BlipDSLPackage.BLIP__WORKLOAD, null, msgs);
			if (newWorkload != null)
				msgs = ((InternalEObject)newWorkload).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - BlipDSLPackage.BLIP__WORKLOAD, null, msgs);
			msgs = basicSetWorkload(newWorkload, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, BlipDSLPackage.BLIP__WORKLOAD, newWorkload, newWorkload));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<BlipItem> getItems() {
		if (items == null) {
			items = new EObjectContainmentEList<BlipItem>(BlipItem.class, this, BlipDSLPackage.BLIP__ITEMS);
		}
		return items;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case BlipDSLPackage.BLIP__WORKLOAD:
				return basicSetWorkload(null, msgs);
			case BlipDSLPackage.BLIP__ITEMS:
				return ((InternalEList<?>)getItems()).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 BlipDSLPackage.BLIP__PROCESS:
				if (resolve) return getProcess();
				return basicGetProcess();
			case BlipDSLPackage.BLIP__DESCRIPTION:
				return isDescription();
			case BlipDSLPackage.BLIP__DESCRIPTION_VALUE:
				return getDescriptionValue();
			case BlipDSLPackage.BLIP__HAS_IMAGE:
				return isHasImage();
			case BlipDSLPackage.BLIP__IMAGE:
				return getImage();
			case BlipDSLPackage.BLIP__HAS_ICON:
				return isHasIcon();
			case BlipDSLPackage.BLIP__ICON:
				return getIcon();
			case BlipDSLPackage.BLIP__HAS_LOGGING:
				return isHasLogging();
			case BlipDSLPackage.BLIP__FUNCTION_GROUP:
				if (resolve) return getFunctionGroup();
				return basicGetFunctionGroup();
			case BlipDSLPackage.BLIP__WORKLOAD:
				return getWorkload();
			case BlipDSLPackage.BLIP__ITEMS:
				return getItems();
		}
		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 BlipDSLPackage.BLIP__PROCESS:
				setProcess((org.eclipse.bpmn2.Process)newValue);
				return;
			case BlipDSLPackage.BLIP__DESCRIPTION:
				setDescription((Boolean)newValue);
				return;
			case BlipDSLPackage.BLIP__DESCRIPTION_VALUE:
				setDescriptionValue((String)newValue);
				return;
			case BlipDSLPackage.BLIP__HAS_IMAGE:
				setHasImage((Boolean)newValue);
				return;
			case BlipDSLPackage.BLIP__IMAGE:
				setImage((String)newValue);
				return;
			case BlipDSLPackage.BLIP__HAS_ICON:
				setHasIcon((Boolean)newValue);
				return;
			case BlipDSLPackage.BLIP__ICON:
				setIcon((IconsEnum)newValue);
				return;
			case BlipDSLPackage.BLIP__HAS_LOGGING:
				setHasLogging((Boolean)newValue);
				return;
			case BlipDSLPackage.BLIP__FUNCTION_GROUP:
				setFunctionGroup((FunctionLibraryBlipGroup)newValue);
				return;
			case BlipDSLPackage.BLIP__WORKLOAD:
				setWorkload((BlipWorkload)newValue);
				return;
			case BlipDSLPackage.BLIP__ITEMS:
				getItems().clear();
				getItems().addAll((Collection<? extends BlipItem>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP__PROCESS:
				setProcess((org.eclipse.bpmn2.Process)null);
				return;
			case BlipDSLPackage.BLIP__DESCRIPTION:
				setDescription(DESCRIPTION_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__DESCRIPTION_VALUE:
				setDescriptionValue(DESCRIPTION_VALUE_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__HAS_IMAGE:
				setHasImage(HAS_IMAGE_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__IMAGE:
				setImage(IMAGE_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__HAS_ICON:
				setHasIcon(HAS_ICON_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__ICON:
				setIcon(ICON_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__HAS_LOGGING:
				setHasLogging(HAS_LOGGING_EDEFAULT);
				return;
			case BlipDSLPackage.BLIP__FUNCTION_GROUP:
				setFunctionGroup((FunctionLibraryBlipGroup)null);
				return;
			case BlipDSLPackage.BLIP__WORKLOAD:
				setWorkload((BlipWorkload)null);
				return;
			case BlipDSLPackage.BLIP__ITEMS:
				getItems().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case BlipDSLPackage.BLIP__PROCESS:
				return process != null;
			case BlipDSLPackage.BLIP__DESCRIPTION:
				return description != DESCRIPTION_EDEFAULT;
			case BlipDSLPackage.BLIP__DESCRIPTION_VALUE:
				return DESCRIPTION_VALUE_EDEFAULT == null ? descriptionValue != null : !DESCRIPTION_VALUE_EDEFAULT.equals(descriptionValue);
			case BlipDSLPackage.BLIP__HAS_IMAGE:
				return hasImage != HAS_IMAGE_EDEFAULT;
			case BlipDSLPackage.BLIP__IMAGE:
				return IMAGE_EDEFAULT == null ? image != null : !IMAGE_EDEFAULT.equals(image);
			case BlipDSLPackage.BLIP__HAS_ICON:
				return hasIcon != HAS_ICON_EDEFAULT;
			case BlipDSLPackage.BLIP__ICON:
				return icon != ICON_EDEFAULT;
			case BlipDSLPackage.BLIP__HAS_LOGGING:
				return hasLogging != HAS_LOGGING_EDEFAULT;
			case BlipDSLPackage.BLIP__FUNCTION_GROUP:
				return functionGroup != null;
			case BlipDSLPackage.BLIP__WORKLOAD:
				return workload != null;
			case BlipDSLPackage.BLIP__ITEMS:
				return items != null && !items.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(", hasImage: ");
		result.append(hasImage);
		result.append(", image: ");
		result.append(image);
		result.append(", hasIcon: ");
		result.append(hasIcon);
		result.append(", icon: ");
		result.append(icon);
		result.append(", hasLogging: ");
		result.append(hasLogging);
		result.append(')');
		return result.toString();
	}

} //BlipImpl
