/**
 * 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.entitymock.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.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;

import org.eclipse.osbp.xtext.entitymock.EntityMockByResourceAttribute;
import org.eclipse.osbp.xtext.entitymock.EntityMockDSLPackage;
import org.eclipse.osbp.xtext.entitymock.EntityMockEntity;
import org.eclipse.osbp.xtext.entitymock.EntityMockEntityFunction;
import org.eclipse.osbp.xtext.entitymock.EntityMockResource;
import org.eclipse.osbp.xtext.entitymock.EntityMockTemplate;
import org.eclipse.osbp.xtext.entitymock.IEntityMockAttribute;
import org.eclipse.osbp.xtext.entitymock.IIterate;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Entity Mock Entity</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getEntityRef <em>Entity Ref</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getMinRows <em>Min Rows</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getMaxRows <em>Max Rows</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getIterate <em>Iterate</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getIterator <em>Iterator</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getTemplates <em>Templates</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getAttributes <em>Attributes</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getCalculations <em>Calculations</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getByResource <em>By Resource</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#getByResourceAttributes <em>By Resource Attributes</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.entitymock.impl.EntityMockEntityImpl#isCreateBlobMapping <em>Create Blob Mapping</em>}</li>
 * </ul>
 *
 * @generated
 */
public class EntityMockEntityImpl extends EntityMockLazyResolverImpl implements EntityMockEntity {
	/**
	 * 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 #getEntityRef() <em>Entity Ref</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEntityRef()
	 * @generated
	 * @ordered
	 */
	protected LEntity entityRef;

	/**
	 * The default value of the '{@link #getMinRows() <em>Min Rows</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMinRows()
	 * @generated
	 * @ordered
	 */
	protected static final int MIN_ROWS_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getMinRows() <em>Min Rows</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMinRows()
	 * @generated
	 * @ordered
	 */
	protected int minRows = MIN_ROWS_EDEFAULT;

	/**
	 * The default value of the '{@link #getMaxRows() <em>Max Rows</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMaxRows()
	 * @generated
	 * @ordered
	 */
	protected static final int MAX_ROWS_EDEFAULT = 0;

	/**
	 * The cached value of the '{@link #getMaxRows() <em>Max Rows</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMaxRows()
	 * @generated
	 * @ordered
	 */
	protected int maxRows = MAX_ROWS_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getIterator() <em>Iterator</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIterator()
	 * @generated
	 * @ordered
	 */
	protected LEntityAttribute iterator;

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

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

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

	/**
	 * The cached value of the '{@link #getByResource() <em>By Resource</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getByResource()
	 * @generated
	 * @ordered
	 */
	protected EntityMockResource byResource;

	/**
	 * The cached value of the '{@link #getByResourceAttributes() <em>By Resource Attributes</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getByResourceAttributes()
	 * @generated
	 * @ordered
	 */
	protected EList<EntityMockByResourceAttribute> byResourceAttributes;

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

	/**
	 * The cached value of the '{@link #isCreateBlobMapping() <em>Create Blob Mapping</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isCreateBlobMapping()
	 * @generated
	 * @ordered
	 */
	protected boolean createBlobMapping = CREATE_BLOB_MAPPING_EDEFAULT;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity getEntityRef() {
		if (entityRef != null && entityRef.eIsProxy()) {
			InternalEObject oldEntityRef = (InternalEObject)entityRef;
			entityRef = (LEntity)eResolveProxy(oldEntityRef);
			if (entityRef != oldEntityRef) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF, oldEntityRef, entityRef));
			}
		}
		return entityRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity basicGetEntityRef() {
		return entityRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEntityRef(LEntity newEntityRef) {
		LEntity oldEntityRef = entityRef;
		entityRef = newEntityRef;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF, oldEntityRef, entityRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public int getMinRows() {
		return minRows;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMinRows(int newMinRows) {
		int oldMinRows = minRows;
		minRows = newMinRows;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MIN_ROWS, oldMinRows, minRows));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public int getMaxRows() {
		return maxRows;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMaxRows(int newMaxRows) {
		int oldMaxRows = maxRows;
		maxRows = newMaxRows;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MAX_ROWS, oldMaxRows, maxRows));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IIterate getIterate() {
		return iterate;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetIterate(IIterate newIterate, NotificationChain msgs) {
		IIterate oldIterate = iterate;
		iterate = newIterate;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE, oldIterate, newIterate);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIterate(IIterate newIterate) {
		if (newIterate != iterate) {
			NotificationChain msgs = null;
			if (iterate != null)
				msgs = ((InternalEObject)iterate).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE, null, msgs);
			if (newIterate != null)
				msgs = ((InternalEObject)newIterate).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE, null, msgs);
			msgs = basicSetIterate(newIterate, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE, newIterate, newIterate));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getIterator() {
		if (iterator != null && iterator.eIsProxy()) {
			InternalEObject oldIterator = (InternalEObject)iterator;
			iterator = (LEntityAttribute)eResolveProxy(oldIterator);
			if (iterator != oldIterator) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR, oldIterator, iterator));
			}
		}
		return iterator;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute basicGetIterator() {
		return iterator;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIterator(LEntityAttribute newIterator) {
		LEntityAttribute oldIterator = iterator;
		iterator = newIterator;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR, oldIterator, iterator));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<EntityMockTemplate> getTemplates() {
		if (templates == null) {
			templates = new EObjectContainmentEList<EntityMockTemplate>(EntityMockTemplate.class, this, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES);
		}
		return templates;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<IEntityMockAttribute> getAttributes() {
		if (attributes == null) {
			attributes = new EObjectContainmentEList<IEntityMockAttribute>(IEntityMockAttribute.class, this, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES);
		}
		return attributes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<EntityMockEntityFunction> getCalculations() {
		if (calculations == null) {
			calculations = new EObjectContainmentEList<EntityMockEntityFunction>(EntityMockEntityFunction.class, this, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS);
		}
		return calculations;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EntityMockResource getByResource() {
		if (byResource != null && byResource.eIsProxy()) {
			InternalEObject oldByResource = (InternalEObject)byResource;
			byResource = (EntityMockResource)eResolveProxy(oldByResource);
			if (byResource != oldByResource) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE, oldByResource, byResource));
			}
		}
		return byResource;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EntityMockResource basicGetByResource() {
		return byResource;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setByResource(EntityMockResource newByResource) {
		EntityMockResource oldByResource = byResource;
		byResource = newByResource;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE, oldByResource, byResource));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<EntityMockByResourceAttribute> getByResourceAttributes() {
		if (byResourceAttributes == null) {
			byResourceAttributes = new EObjectContainmentEList<EntityMockByResourceAttribute>(EntityMockByResourceAttribute.class, this, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES);
		}
		return byResourceAttributes;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCreateBlobMapping(boolean newCreateBlobMapping) {
		boolean oldCreateBlobMapping = createBlobMapping;
		createBlobMapping = newCreateBlobMapping;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CREATE_BLOB_MAPPING, oldCreateBlobMapping, createBlobMapping));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE:
				return basicSetIterate(null, msgs);
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES:
				return ((InternalEList<?>)getTemplates()).basicRemove(otherEnd, msgs);
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES:
				return ((InternalEList<?>)getAttributes()).basicRemove(otherEnd, msgs);
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS:
				return ((InternalEList<?>)getCalculations()).basicRemove(otherEnd, msgs);
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES:
				return ((InternalEList<?>)getByResourceAttributes()).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 EntityMockDSLPackage.ENTITY_MOCK_ENTITY__NAME:
				return getName();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF:
				if (resolve) return getEntityRef();
				return basicGetEntityRef();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MIN_ROWS:
				return getMinRows();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MAX_ROWS:
				return getMaxRows();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE:
				return getIterate();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR:
				if (resolve) return getIterator();
				return basicGetIterator();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES:
				return getTemplates();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES:
				return getAttributes();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS:
				return getCalculations();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE:
				if (resolve) return getByResource();
				return basicGetByResource();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES:
				return getByResourceAttributes();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CREATE_BLOB_MAPPING:
				return isCreateBlobMapping();
		}
		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 EntityMockDSLPackage.ENTITY_MOCK_ENTITY__NAME:
				setName((String)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF:
				setEntityRef((LEntity)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MIN_ROWS:
				setMinRows((Integer)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MAX_ROWS:
				setMaxRows((Integer)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE:
				setIterate((IIterate)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR:
				setIterator((LEntityAttribute)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES:
				getTemplates().clear();
				getTemplates().addAll((Collection<? extends EntityMockTemplate>)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES:
				getAttributes().clear();
				getAttributes().addAll((Collection<? extends IEntityMockAttribute>)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS:
				getCalculations().clear();
				getCalculations().addAll((Collection<? extends EntityMockEntityFunction>)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE:
				setByResource((EntityMockResource)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES:
				getByResourceAttributes().clear();
				getByResourceAttributes().addAll((Collection<? extends EntityMockByResourceAttribute>)newValue);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CREATE_BLOB_MAPPING:
				setCreateBlobMapping((Boolean)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__NAME:
				setName(NAME_EDEFAULT);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF:
				setEntityRef((LEntity)null);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MIN_ROWS:
				setMinRows(MIN_ROWS_EDEFAULT);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MAX_ROWS:
				setMaxRows(MAX_ROWS_EDEFAULT);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE:
				setIterate((IIterate)null);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR:
				setIterator((LEntityAttribute)null);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES:
				getTemplates().clear();
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES:
				getAttributes().clear();
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS:
				getCalculations().clear();
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE:
				setByResource((EntityMockResource)null);
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES:
				getByResourceAttributes().clear();
				return;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CREATE_BLOB_MAPPING:
				setCreateBlobMapping(CREATE_BLOB_MAPPING_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ENTITY_REF:
				return entityRef != null;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MIN_ROWS:
				return minRows != MIN_ROWS_EDEFAULT;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__MAX_ROWS:
				return maxRows != MAX_ROWS_EDEFAULT;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATE:
				return iterate != null;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ITERATOR:
				return iterator != null;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__TEMPLATES:
				return templates != null && !templates.isEmpty();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__ATTRIBUTES:
				return attributes != null && !attributes.isEmpty();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CALCULATIONS:
				return calculations != null && !calculations.isEmpty();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE:
				return byResource != null;
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__BY_RESOURCE_ATTRIBUTES:
				return byResourceAttributes != null && !byResourceAttributes.isEmpty();
			case EntityMockDSLPackage.ENTITY_MOCK_ENTITY__CREATE_BLOB_MAPPING:
				return createBlobMapping != CREATE_BLOB_MAPPING_EDEFAULT;
		}
		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(" (name: ");
		result.append(name);
		result.append(", minRows: ");
		result.append(minRows);
		result.append(", maxRows: ");
		result.append(maxRows);
		result.append(", createBlobMapping: ");
		result.append(createBlobMapping);
		result.append(')');
		return result.toString();
	}

} //EntityMockEntityImpl
