/**
 * 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 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.datainterchange.DataDSLPackage;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeBean;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeExportFilter;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeExpose;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeExpression;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeFormat;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeKey;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeLookup;
import org.eclipse.osbp.xtext.datainterchange.DataInterchangeMapping;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Data Interchange Bean</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getEntity <em>Entity</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#isMarkLatestImport <em>Mark Latest Import</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#isMarkLatestExport <em>Mark Latest Export</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#isHasBlobMapping <em>Has Blob Mapping</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getLatestProperty <em>Latest Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getLatestExpProperty <em>Latest Exp Property</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getElementMap <em>Element Map</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getNodeName <em>Node Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getLookup <em>Lookup</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getFormat <em>Format</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getExpression <em>Expression</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getMappings <em>Mappings</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getLookupKeys <em>Lookup Keys</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getExportExposes <em>Export Exposes</em>}</li>
 *   <li>{@link org.eclipse.osbp.xtext.datainterchange.impl.DataInterchangeBeanImpl#getExportFilter <em>Export Filter</em>}</li>
 * </ul>
 *
 * @generated
 */
public class DataInterchangeBeanImpl extends DataInterchangeLazyResolverImpl implements DataInterchangeBean {
	/**
	 * 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 default value of the '{@link #isMarkLatestImport() <em>Mark Latest Import</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isMarkLatestImport()
	 * @generated
	 * @ordered
	 */
	protected static final boolean MARK_LATEST_IMPORT_EDEFAULT = false;

	/**
	 * The cached value of the '{@link #isMarkLatestImport() <em>Mark Latest Import</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isMarkLatestImport()
	 * @generated
	 * @ordered
	 */
	protected boolean markLatestImport = MARK_LATEST_IMPORT_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #isMarkLatestExport() <em>Mark Latest Export</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isMarkLatestExport()
	 * @generated
	 * @ordered
	 */
	protected boolean markLatestExport = MARK_LATEST_EXPORT_EDEFAULT;

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

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

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

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

	/**
	 * 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 #getNodeName() <em>Node Name</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNodeName()
	 * @generated
	 * @ordered
	 */
	protected static final String NODE_NAME_EDEFAULT = null;

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

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

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

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

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

	/**
	 * The cached value of the '{@link #getLookupKeys() <em>Lookup Keys</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLookupKeys()
	 * @generated
	 * @ordered
	 */
	protected EList<DataInterchangeKey> lookupKeys;

	/**
	 * The cached value of the '{@link #getExportExposes() <em>Export Exposes</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getExportExposes()
	 * @generated
	 * @ordered
	 */
	protected EList<DataInterchangeExpose> exportExposes;

	/**
	 * The cached value of the '{@link #getExportFilter() <em>Export Filter</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getExportFilter()
	 * @generated
	 * @ordered
	 */
	protected DataInterchangeExportFilter exportFilter;

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

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

	/**
	 * <!-- 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_BEAN__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_BEAN__ENTITY, oldEntity, entity));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMarkLatestImport(boolean newMarkLatestImport) {
		boolean oldMarkLatestImport = markLatestImport;
		markLatestImport = newMarkLatestImport;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_IMPORT, oldMarkLatestImport, markLatestImport));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMarkLatestExport(boolean newMarkLatestExport) {
		boolean oldMarkLatestExport = markLatestExport;
		markLatestExport = newMarkLatestExport;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_EXPORT, oldMarkLatestExport, markLatestExport));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHasBlobMapping(boolean newHasBlobMapping) {
		boolean oldHasBlobMapping = hasBlobMapping;
		hasBlobMapping = newHasBlobMapping;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__HAS_BLOB_MAPPING, oldHasBlobMapping, hasBlobMapping));
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLatestProperty(LEntityAttribute newLatestProperty) {
		LEntityAttribute oldLatestProperty = latestProperty;
		latestProperty = newLatestProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY, oldLatestProperty, latestProperty));
	}

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLatestExpProperty(LEntityAttribute newLatestExpProperty) {
		LEntityAttribute oldLatestExpProperty = latestExpProperty;
		latestExpProperty = newLatestExpProperty;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_EXP_PROPERTY, oldLatestExpProperty, latestExpProperty));
	}

	/**
	 * <!-- 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_BEAN__ELEMENT_MAP, oldElementMap, elementMap));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setNodeName(String newNodeName) {
		String oldNodeName = nodeName;
		nodeName = newNodeName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__NODE_NAME, oldNodeName, nodeName));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeLookup> getLookup() {
		if (lookup == null) {
			lookup = new EObjectContainmentEList<DataInterchangeLookup>(DataInterchangeLookup.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP);
		}
		return lookup;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeFormat> getFormat() {
		if (format == null) {
			format = new EObjectContainmentEList<DataInterchangeFormat>(DataInterchangeFormat.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT);
		}
		return format;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeExpression> getExpression() {
		if (expression == null) {
			expression = new EObjectContainmentEList<DataInterchangeExpression>(DataInterchangeExpression.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION);
		}
		return expression;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeMapping> getMappings() {
		if (mappings == null) {
			mappings = new EObjectContainmentEList<DataInterchangeMapping>(DataInterchangeMapping.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS);
		}
		return mappings;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeKey> getLookupKeys() {
		if (lookupKeys == null) {
			lookupKeys = new EObjectContainmentEList<DataInterchangeKey>(DataInterchangeKey.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS);
		}
		return lookupKeys;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<DataInterchangeExpose> getExportExposes() {
		if (exportExposes == null) {
			exportExposes = new EObjectContainmentEList<DataInterchangeExpose>(DataInterchangeExpose.class, this, DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES);
		}
		return exportExposes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public DataInterchangeExportFilter getExportFilter() {
		return exportFilter;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetExportFilter(DataInterchangeExportFilter newExportFilter, NotificationChain msgs) {
		DataInterchangeExportFilter oldExportFilter = exportFilter;
		exportFilter = newExportFilter;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER, oldExportFilter, newExportFilter);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setExportFilter(DataInterchangeExportFilter newExportFilter) {
		if (newExportFilter != exportFilter) {
			NotificationChain msgs = null;
			if (exportFilter != null)
				msgs = ((InternalEObject)exportFilter).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER, null, msgs);
			if (newExportFilter != null)
				msgs = ((InternalEObject)newExportFilter).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER, null, msgs);
			msgs = basicSetExportFilter(newExportFilter, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER, newExportFilter, newExportFilter));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP:
				return ((InternalEList<?>)getLookup()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT:
				return ((InternalEList<?>)getFormat()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION:
				return ((InternalEList<?>)getExpression()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS:
				return ((InternalEList<?>)getMappings()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS:
				return ((InternalEList<?>)getLookupKeys()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES:
				return ((InternalEList<?>)getExportExposes()).basicRemove(otherEnd, msgs);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER:
				return basicSetExportFilter(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_BEAN__ENTITY:
				if (resolve) return getEntity();
				return basicGetEntity();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_IMPORT:
				return isMarkLatestImport();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_EXPORT:
				return isMarkLatestExport();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__HAS_BLOB_MAPPING:
				return isHasBlobMapping();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY:
				if (resolve) return getLatestProperty();
				return basicGetLatestProperty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_EXP_PROPERTY:
				if (resolve) return getLatestExpProperty();
				return basicGetLatestExpProperty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__ELEMENT_MAP:
				return getElementMap();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__NODE_NAME:
				return getNodeName();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP:
				return getLookup();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT:
				return getFormat();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION:
				return getExpression();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS:
				return getMappings();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS:
				return getLookupKeys();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES:
				return getExportExposes();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER:
				return getExportFilter();
		}
		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 DataDSLPackage.DATA_INTERCHANGE_BEAN__ENTITY:
				setEntity((LEntity)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_IMPORT:
				setMarkLatestImport((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_EXPORT:
				setMarkLatestExport((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__HAS_BLOB_MAPPING:
				setHasBlobMapping((Boolean)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY:
				setLatestProperty((LEntityAttribute)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_EXP_PROPERTY:
				setLatestExpProperty((LEntityAttribute)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__ELEMENT_MAP:
				setElementMap((String)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__NODE_NAME:
				setNodeName((String)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP:
				getLookup().clear();
				getLookup().addAll((Collection<? extends DataInterchangeLookup>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT:
				getFormat().clear();
				getFormat().addAll((Collection<? extends DataInterchangeFormat>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION:
				getExpression().clear();
				getExpression().addAll((Collection<? extends DataInterchangeExpression>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS:
				getMappings().clear();
				getMappings().addAll((Collection<? extends DataInterchangeMapping>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS:
				getLookupKeys().clear();
				getLookupKeys().addAll((Collection<? extends DataInterchangeKey>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES:
				getExportExposes().clear();
				getExportExposes().addAll((Collection<? extends DataInterchangeExpose>)newValue);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER:
				setExportFilter((DataInterchangeExportFilter)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_BEAN__ENTITY:
				setEntity((LEntity)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_IMPORT:
				setMarkLatestImport(MARK_LATEST_IMPORT_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_EXPORT:
				setMarkLatestExport(MARK_LATEST_EXPORT_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__HAS_BLOB_MAPPING:
				setHasBlobMapping(HAS_BLOB_MAPPING_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY:
				setLatestProperty((LEntityAttribute)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_EXP_PROPERTY:
				setLatestExpProperty((LEntityAttribute)null);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__ELEMENT_MAP:
				setElementMap(ELEMENT_MAP_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__NODE_NAME:
				setNodeName(NODE_NAME_EDEFAULT);
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP:
				getLookup().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT:
				getFormat().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION:
				getExpression().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS:
				getMappings().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS:
				getLookupKeys().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES:
				getExportExposes().clear();
				return;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER:
				setExportFilter((DataInterchangeExportFilter)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__ENTITY:
				return entity != null;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_IMPORT:
				return markLatestImport != MARK_LATEST_IMPORT_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MARK_LATEST_EXPORT:
				return markLatestExport != MARK_LATEST_EXPORT_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__HAS_BLOB_MAPPING:
				return hasBlobMapping != HAS_BLOB_MAPPING_EDEFAULT;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_PROPERTY:
				return latestProperty != null;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LATEST_EXP_PROPERTY:
				return latestExpProperty != null;
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__ELEMENT_MAP:
				return ELEMENT_MAP_EDEFAULT == null ? elementMap != null : !ELEMENT_MAP_EDEFAULT.equals(elementMap);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__NODE_NAME:
				return NODE_NAME_EDEFAULT == null ? nodeName != null : !NODE_NAME_EDEFAULT.equals(nodeName);
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP:
				return lookup != null && !lookup.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__FORMAT:
				return format != null && !format.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPRESSION:
				return expression != null && !expression.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__MAPPINGS:
				return mappings != null && !mappings.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__LOOKUP_KEYS:
				return lookupKeys != null && !lookupKeys.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_EXPOSES:
				return exportExposes != null && !exportExposes.isEmpty();
			case DataDSLPackage.DATA_INTERCHANGE_BEAN__EXPORT_FILTER:
				return exportFilter != 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(" (markLatestImport: ");
		result.append(markLatestImport);
		result.append(", markLatestExport: ");
		result.append(markLatestExport);
		result.append(", hasBlobMapping: ");
		result.append(hasBlobMapping);
		result.append(", elementMap: ");
		result.append(elementMap);
		result.append(", nodeName: ");
		result.append(nodeName);
		result.append(')');
		return result.toString();
	}

} //DataInterchangeBeanImpl
