/**
 * 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:  
 *  		Joerg Riegel - Initial implementation 
 *  
 */
package org.eclipse.osbp.xtext.datainterchange.impl;

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

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

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

import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference;

import org.eclipse.osbp.xtext.datainterchange.DataDSLPackage;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookup;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeMarkerPath;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Data Interchange Lookup</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getEntity <em>Entity</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getTargetProperty <em>Target Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getQueryProperty <em>Query Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getElementMap <em>Element Map</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getDataMap <em>Data Map</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#isAllowNoResult <em>Allow No Result</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#isAllowNonuniqueResult <em>Allow Nonunique Result</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#isCached <em>Cached</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getCacheSize <em>Cache Size</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeLookupImpl#getMarkerPath <em>Marker Path</em>}</li>
 * </ul>
 *
 * @generated
 */
public class DataInterchangeLookupImpl extends DataInterchangeLazyResolverImpl implements DataInterchangeLookup {
	/**
	 * The cached value of the '{@link #getEntity() <em>Entity</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEntity()
	 * @generated
	 * @ordered
	 */
	protected LEntity entity;

	/**
	 * The cached value of the '{@link #getTargetProperty() <em>Target Property</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTargetProperty()
	 * @generated
	 * @ordered
	 */
	protected LEntityReference targetProperty;

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

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

	/**
	 * The cached value of the '{@link #getElementMap() <em>Element Map</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getElementMap()
	 * @generated
	 * @ordered
	 */
	protected String elementMap = ELEMENT_MAP_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getDataMap() <em>Data Map</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDataMap()
	 * @generated
	 * @ordered
	 */
	protected String dataMap = DATA_MAP_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isAllowNoResult() <em>Allow No Result</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAllowNoResult()
	 * @generated
	 * @ordered
	 */
	protected boolean allowNoResult = ALLOW_NO_RESULT_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isAllowNonuniqueResult() <em>Allow Nonunique Result</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isAllowNonuniqueResult()
	 * @generated
	 * @ordered
	 */
	protected boolean allowNonuniqueResult = ALLOW_NONUNIQUE_RESULT_EDEFAULT;

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

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

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

	/**
	 * The cached value of the '{@link #getCacheSize() <em>Cache Size</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCacheSize()
	 * @generated
	 * @ordered
	 */
	protected int cacheSize = CACHE_SIZE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getMarkerPath() <em>Marker Path</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMarkerPath()
	 * @generated
	 * @ordered
	 */
	protected DataInterchangeMarkerPath markerPath;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity getEntity() {
		if (entity != null && entity.eIsProxy()) {
			InternalEObject oldEntity = (InternalEObject)entity;
			entity = (LEntity)eResolveProxy(oldEntity);
			if (entity != oldEntity) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY, oldEntity, entity));
			}
		}
		return entity;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setEntity(LEntity newEntity) {
		LEntity oldEntity = entity;
		entity = newEntity;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY, oldEntity, entity));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityReference getTargetProperty() {
		if (targetProperty != null && targetProperty.eIsProxy()) {
			InternalEObject oldTargetProperty = (InternalEObject)targetProperty;
			targetProperty = (LEntityReference)eResolveProxy(oldTargetProperty);
			if (targetProperty != oldTargetProperty) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY, oldTargetProperty, targetProperty));
			}
		}
		return targetProperty;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityReference basicGetTargetProperty() {
		return targetProperty;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTargetProperty(LEntityReference newTargetProperty) {
		LEntityReference oldTargetProperty = targetProperty;
		targetProperty = newTargetProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY, oldTargetProperty, targetProperty));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getQueryProperty() {
		if (queryProperty != null && queryProperty.eIsProxy()) {
			InternalEObject oldQueryProperty = (InternalEObject)queryProperty;
			queryProperty = (LEntityAttribute)eResolveProxy(oldQueryProperty);
			if (queryProperty != oldQueryProperty) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY, oldQueryProperty, queryProperty));
			}
		}
		return queryProperty;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setQueryProperty(LEntityAttribute newQueryProperty) {
		LEntityAttribute oldQueryProperty = queryProperty;
		queryProperty = newQueryProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY, oldQueryProperty, queryProperty));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setElementMap(String newElementMap) {
		String oldElementMap = elementMap;
		elementMap = newElementMap;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ELEMENT_MAP, oldElementMap, elementMap));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDataMap(String newDataMap) {
		String oldDataMap = dataMap;
		dataMap = newDataMap;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__DATA_MAP, oldDataMap, dataMap));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAllowNoResult(boolean newAllowNoResult) {
		boolean oldAllowNoResult = allowNoResult;
		allowNoResult = newAllowNoResult;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NO_RESULT, oldAllowNoResult, allowNoResult));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAllowNonuniqueResult(boolean newAllowNonuniqueResult) {
		boolean oldAllowNonuniqueResult = allowNonuniqueResult;
		allowNonuniqueResult = newAllowNonuniqueResult;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NONUNIQUE_RESULT, oldAllowNonuniqueResult, allowNonuniqueResult));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCached(boolean newCached) {
		boolean oldCached = cached;
		cached = newCached;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHED, oldCached, cached));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCacheSize(int newCacheSize) {
		int oldCacheSize = cacheSize;
		cacheSize = newCacheSize;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHE_SIZE, oldCacheSize, cacheSize));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DataInterchangeMarkerPath getMarkerPath() {
		return markerPath;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMarkerPath(DataInterchangeMarkerPath newMarkerPath, NotificationChain msgs) {
		DataInterchangeMarkerPath oldMarkerPath = markerPath;
		markerPath = newMarkerPath;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH, oldMarkerPath, newMarkerPath);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMarkerPath(DataInterchangeMarkerPath newMarkerPath) {
		if (newMarkerPath != markerPath) {
			NotificationChain msgs = null;
			if (markerPath != null)
				msgs = ((InternalEObject)markerPath).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH, null, msgs);
			if (newMarkerPath != null)
				msgs = ((InternalEObject)newMarkerPath).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH, null, msgs);
			msgs = basicSetMarkerPath(newMarkerPath, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH, newMarkerPath, newMarkerPath));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH:
				return basicSetMarkerPath(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY:
				if (resolve) return getEntity();
				return basicGetEntity();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY:
				if (resolve) return getTargetProperty();
				return basicGetTargetProperty();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY:
				if (resolve) return getQueryProperty();
				return basicGetQueryProperty();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ELEMENT_MAP:
				return getElementMap();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__DATA_MAP:
				return getDataMap();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NO_RESULT:
				return isAllowNoResult();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NONUNIQUE_RESULT:
				return isAllowNonuniqueResult();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHED:
				return isCached();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHE_SIZE:
				return getCacheSize();
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH:
				return getMarkerPath();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY:
				setEntity((LEntity)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY:
				setTargetProperty((LEntityReference)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY:
				setQueryProperty((LEntityAttribute)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ELEMENT_MAP:
				setElementMap((String)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__DATA_MAP:
				setDataMap((String)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NO_RESULT:
				setAllowNoResult((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NONUNIQUE_RESULT:
				setAllowNonuniqueResult((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHED:
				setCached((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHE_SIZE:
				setCacheSize((Integer)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH:
				setMarkerPath((DataInterchangeMarkerPath)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY:
				setEntity((LEntity)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY:
				setTargetProperty((LEntityReference)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY:
				setQueryProperty((LEntityAttribute)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ELEMENT_MAP:
				setElementMap(ELEMENT_MAP_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__DATA_MAP:
				setDataMap(DATA_MAP_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NO_RESULT:
				setAllowNoResult(ALLOW_NO_RESULT_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NONUNIQUE_RESULT:
				setAllowNonuniqueResult(ALLOW_NONUNIQUE_RESULT_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHED:
				setCached(CACHED_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHE_SIZE:
				setCacheSize(CACHE_SIZE_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH:
				setMarkerPath((DataInterchangeMarkerPath)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ENTITY:
				return entity != null;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__TARGET_PROPERTY:
				return targetProperty != null;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__QUERY_PROPERTY:
				return queryProperty != null;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ELEMENT_MAP:
				return ELEMENT_MAP_EDEFAULT == null ? elementMap != null : !ELEMENT_MAP_EDEFAULT.equals(elementMap);
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__DATA_MAP:
				return DATA_MAP_EDEFAULT == null ? dataMap != null : !DATA_MAP_EDEFAULT.equals(dataMap);
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NO_RESULT:
				return allowNoResult != ALLOW_NO_RESULT_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__ALLOW_NONUNIQUE_RESULT:
				return allowNonuniqueResult != ALLOW_NONUNIQUE_RESULT_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHED:
				return cached != CACHED_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__CACHE_SIZE:
				return cacheSize != CACHE_SIZE_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_LOOKUP__MARKER_PATH:
				return markerPath != null;
		}
		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(" (elementMap: ");
		result.append(elementMap);
		result.append(", dataMap: ");
		result.append(dataMap);
		result.append(", allowNoResult: ");
		result.append(allowNoResult);
		result.append(", allowNonuniqueResult: ");
		result.append(allowNonuniqueResult);
		result.append(", cached: ");
		result.append(cached);
		result.append(", cacheSize: ");
		result.append(cacheSize);
		result.append(')');
		return result.toString();
	}

} //DataInterchangeLookupImpl
