/**
 * Copyright (c) 2011, 2016 - Lunifera GmbH (Gross Enzersdorf), 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:  
 *  		Florian Pirchner - Initial implementation 
 *  
 */
package org.eclipse.osbp.dsl.semantic.entity.impl;

import com.google.common.collect.Iterables;

import java.lang.reflect.InvocationTargetException;

import java.util.Collection;
import java.util.List;

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.EObject;
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.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.dsl.semantic.common.types.LDateType;
import org.eclipse.osbp.dsl.semantic.common.types.LFeaturesHolder;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;

import org.eclipse.osbp.dsl.semantic.common.types.impl.LClassImpl;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature;
import org.eclipse.osbp.dsl.semantic.entity.LEntityInheritanceStrategy;
import org.eclipse.osbp.dsl.semantic.entity.LEntityPersistenceInfo;
import org.eclipse.osbp.dsl.semantic.entity.LEntityReference;
import org.eclipse.osbp.dsl.semantic.entity.LEntitySuperIndex;
import org.eclipse.osbp.dsl.semantic.entity.LIndex;
import org.eclipse.osbp.dsl.semantic.entity.LOperation;
import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityPackage;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;

import org.eclipse.xtext.xbase.lib.Functions.Function1;

import org.eclipse.xtext.xbase.lib.IterableExtensions;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>LEntity</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#isCacheable <em>Cacheable</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#isHistorized <em>Historized</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#isTimedependent <em>Timedependent</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getTimedependentDateType <em>Timedependent Date Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#isMappedSuperclass <em>Mapped Superclass</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getPersistenceInfo <em>Persistence Info</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getInheritanceStrategy <em>Inheritance Strategy</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getFeatures <em>Features</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getIndexes <em>Indexes</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getSuperType <em>Super Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getSubTypes <em>Sub Types</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getPersistenceUnit <em>Persistence Unit</em>}</li>
 *   <li>{@link org.eclipse.osbp.dsl.semantic.entity.impl.LEntityImpl#getSuperIndex <em>Super Index</em>}</li>
 * </ul>
 *
 * @generated
 */
public class LEntityImpl extends LClassImpl implements LEntity {
	/**
	 * The default value of the '{@link #isCacheable() <em>Cacheable</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isCacheable()
	 * @generated
	 * @ordered
	 */
	protected static final boolean CACHEABLE_EDEFAULT = false;

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

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

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

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

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

	/**
	 * The default value of the '{@link #getTimedependentDateType() <em>Timedependent Date Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimedependentDateType()
	 * @generated
	 * @ordered
	 */
	protected static final LDateType TIMEDEPENDENT_DATE_TYPE_EDEFAULT = LDateType.DATE;

	/**
	 * The cached value of the '{@link #getTimedependentDateType() <em>Timedependent Date Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTimedependentDateType()
	 * @generated
	 * @ordered
	 */
	protected LDateType timedependentDateType = TIMEDEPENDENT_DATE_TYPE_EDEFAULT;

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

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

	/**
	 * The cached value of the '{@link #getPersistenceInfo() <em>Persistence Info</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPersistenceInfo()
	 * @generated
	 * @ordered
	 */
	protected LEntityPersistenceInfo persistenceInfo;

	/**
	 * The cached value of the '{@link #getInheritanceStrategy() <em>Inheritance Strategy</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInheritanceStrategy()
	 * @generated
	 * @ordered
	 */
	protected LEntityInheritanceStrategy inheritanceStrategy;

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

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

	/**
	 * The cached value of the '{@link #getSuperType() <em>Super Type</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSuperType()
	 * @generated
	 * @ordered
	 */
	protected LEntity superType;

	/**
	 * The cached value of the '{@link #getSubTypes() <em>Sub Types</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSubTypes()
	 * @generated
	 * @ordered
	 */
	protected EList<LEntity> subTypes;

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

	/**
	 * The cached value of the '{@link #getPersistenceUnit() <em>Persistence Unit</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getPersistenceUnit()
	 * @generated
	 * @ordered
	 */
	protected String persistenceUnit = PERSISTENCE_UNIT_EDEFAULT;

	/**
	 * The cached value of the '{@link #getSuperIndex() <em>Super Index</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSuperIndex()
	 * @generated
	 * @ordered
	 */
	protected EList<LEntitySuperIndex> superIndex;

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

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCacheable(boolean newCacheable) {
		boolean oldCacheable = cacheable;
		cacheable = newCacheable;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__CACHEABLE, oldCacheable, cacheable));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setHistorized(boolean newHistorized) {
		boolean oldHistorized = historized;
		historized = newHistorized;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__HISTORIZED, oldHistorized, historized));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTimedependent(boolean newTimedependent) {
		boolean oldTimedependent = timedependent;
		timedependent = newTimedependent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__TIMEDEPENDENT, oldTimedependent, timedependent));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LDateType getTimedependentDateType() {
		return timedependentDateType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTimedependentDateType(LDateType newTimedependentDateType) {
		LDateType oldTimedependentDateType = timedependentDateType;
		timedependentDateType = newTimedependentDateType == null ? TIMEDEPENDENT_DATE_TYPE_EDEFAULT : newTimedependentDateType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__TIMEDEPENDENT_DATE_TYPE, oldTimedependentDateType, timedependentDateType));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMappedSuperclass(boolean newMappedSuperclass) {
		boolean oldMappedSuperclass = mappedSuperclass;
		mappedSuperclass = newMappedSuperclass;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__MAPPED_SUPERCLASS, oldMappedSuperclass, mappedSuperclass));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityPersistenceInfo getPersistenceInfo() {
		return persistenceInfo;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetPersistenceInfo(LEntityPersistenceInfo newPersistenceInfo, NotificationChain msgs) {
		LEntityPersistenceInfo oldPersistenceInfo = persistenceInfo;
		persistenceInfo = newPersistenceInfo;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__PERSISTENCE_INFO, oldPersistenceInfo, newPersistenceInfo);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPersistenceInfo(LEntityPersistenceInfo newPersistenceInfo) {
		if (newPersistenceInfo != persistenceInfo) {
			NotificationChain msgs = null;
			if (persistenceInfo != null)
				msgs = ((InternalEObject)persistenceInfo).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OSBPEntityPackage.LENTITY__PERSISTENCE_INFO, null, msgs);
			if (newPersistenceInfo != null)
				msgs = ((InternalEObject)newPersistenceInfo).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OSBPEntityPackage.LENTITY__PERSISTENCE_INFO, null, msgs);
			msgs = basicSetPersistenceInfo(newPersistenceInfo, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__PERSISTENCE_INFO, newPersistenceInfo, newPersistenceInfo));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityInheritanceStrategy getInheritanceStrategy() {
		return inheritanceStrategy;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetInheritanceStrategy(LEntityInheritanceStrategy newInheritanceStrategy, NotificationChain msgs) {
		LEntityInheritanceStrategy oldInheritanceStrategy = inheritanceStrategy;
		inheritanceStrategy = newInheritanceStrategy;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY, oldInheritanceStrategy, newInheritanceStrategy);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setInheritanceStrategy(LEntityInheritanceStrategy newInheritanceStrategy) {
		if (newInheritanceStrategy != inheritanceStrategy) {
			NotificationChain msgs = null;
			if (inheritanceStrategy != null)
				msgs = ((InternalEObject)inheritanceStrategy).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY, null, msgs);
			if (newInheritanceStrategy != null)
				msgs = ((InternalEObject)newInheritanceStrategy).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY, null, msgs);
			msgs = basicSetInheritanceStrategy(newInheritanceStrategy, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY, newInheritanceStrategy, newInheritanceStrategy));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LEntityFeature> getFeatures() {
		if (features == null) {
			features = new EObjectContainmentEList<LEntityFeature>(LEntityFeature.class, this, OSBPEntityPackage.LENTITY__FEATURES);
		}
		return features;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LIndex> getIndexes() {
		if (indexes == null) {
			indexes = new EObjectContainmentEList<LIndex>(LIndex.class, this, OSBPEntityPackage.LENTITY__INDEXES);
		}
		return indexes;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntity getSuperType() {
		if (superType != null && superType.eIsProxy()) {
			InternalEObject oldSuperType = (InternalEObject)superType;
			superType = (LEntity)eResolveProxy(oldSuperType);
			if (superType != oldSuperType) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, OSBPEntityPackage.LENTITY__SUPER_TYPE, oldSuperType, superType));
			}
		}
		return superType;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetSuperType(LEntity newSuperType, NotificationChain msgs) {
		LEntity oldSuperType = superType;
		superType = newSuperType;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__SUPER_TYPE, oldSuperType, newSuperType);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSuperType(LEntity newSuperType) {
		if (newSuperType != superType) {
			NotificationChain msgs = null;
			if (superType != null)
				msgs = ((InternalEObject)superType).eInverseRemove(this, OSBPEntityPackage.LENTITY__SUB_TYPES, LEntity.class, msgs);
			if (newSuperType != null)
				msgs = ((InternalEObject)newSuperType).eInverseAdd(this, OSBPEntityPackage.LENTITY__SUB_TYPES, LEntity.class, msgs);
			msgs = basicSetSuperType(newSuperType, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__SUPER_TYPE, newSuperType, newSuperType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LEntity> getSubTypes() {
		if (subTypes == null) {
			subTypes = new EObjectWithInverseResolvingEList<LEntity>(LEntity.class, this, OSBPEntityPackage.LENTITY__SUB_TYPES, OSBPEntityPackage.LENTITY__SUPER_TYPE);
		}
		return subTypes;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setPersistenceUnit(String newPersistenceUnit) {
		String oldPersistenceUnit = persistenceUnit;
		persistenceUnit = newPersistenceUnit;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, OSBPEntityPackage.LENTITY__PERSISTENCE_UNIT, oldPersistenceUnit, persistenceUnit));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<LEntitySuperIndex> getSuperIndex() {
		if (superIndex == null) {
			superIndex = new EObjectContainmentEList<LEntitySuperIndex>(LEntitySuperIndex.class, this, OSBPEntityPackage.LENTITY__SUPER_INDEX);
		}
		return superIndex;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LOperation> getOperations() {
		return IterableExtensions.<LOperation>toList(Iterables.<LOperation>filter(this.getFeatures(), LOperation.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityReference> getReferences() {
		return IterableExtensions.<LEntityReference>toList(Iterables.<LEntityReference>filter(this.getFeatures(), LEntityReference.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityAttribute> getAttributes() {
		return IterableExtensions.<LEntityAttribute>toList(Iterables.<LEntityAttribute>filter(this.getFeatures(), LEntityAttribute.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityFeature> getAllFeatures() {
		final List<LEntityFeature> result = CollectionLiterals.<LEntityFeature>newArrayList();
		this.collectAllOSBPFeatures(this, result);
		return result;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityAttribute> getAllAttributes() {
		final List<LEntityFeature> result = CollectionLiterals.<LEntityFeature>newArrayList();
		this.collectAllOSBPFeatures(this, result);
		return IterableExtensions.<LEntityAttribute>toList(Iterables.<LEntityAttribute>filter(result, LEntityAttribute.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityReference> getAllReferences() {
		final List<LEntityFeature> result = CollectionLiterals.<LEntityFeature>newArrayList();
		this.collectAllOSBPFeatures(this, result);
		return IterableExtensions.<LEntityReference>toList(Iterables.<LEntityReference>filter(result, LEntityReference.class));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void collectAllOSBPFeatures(final LEntity current, final List<LEntityFeature> result) {
		if ((current == null)) {
			return;
		}
		result.addAll(current.getFeatures());
		this.collectAllOSBPFeatures(current.getSuperType(), result);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void collectNormalOSBPFeatures(final LEntity current, final List<LEntityFeature> result) {
		if ((current == null)) {
			return;
		}
		final Function1<LEntityFeature, Boolean> _function = new Function1<LEntityFeature, Boolean>() {
			public Boolean apply(final LEntityFeature it) {
				return Boolean.valueOf(LEntityImpl.this.isNormalAttribute(it));
			}
		};
		Iterables.<LEntityFeature>addAll(result, IterableExtensions.<LEntityFeature>filter(current.getFeatures(), _function));
		this.collectNormalOSBPFeatures(current.getSuperType(), result);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getPrimaryKeyAttribute() {
		final Function1<LEntityAttribute, Boolean> _function = new Function1<LEntityAttribute, Boolean>() {
			public Boolean apply(final LEntityAttribute it) {
				return Boolean.valueOf((it.isId() || it.isUuid()));
			}
		};
		return IterableExtensions.<LEntityAttribute>findFirst(Iterables.<LEntityAttribute>filter(this.getAllFeatures(), LEntityAttribute.class), _function);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getIdAttributeName() {
		LEntityAttribute _primaryKeyAttribute = this.getPrimaryKeyAttribute();
		String _name = null;
		if (_primaryKeyAttribute!=null) {
			_name=_primaryKeyAttribute.getName();
		}
		return _name;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LScalarType getIdAttributeType() {
		LEntityAttribute _primaryKeyAttribute = this.getPrimaryKeyAttribute();
		LScalarType _type = null;
		if (_primaryKeyAttribute!=null) {
			_type=_primaryKeyAttribute.getType();
		}
		LScalarType tp = _type;
		if ((tp != null)) {
			boolean _eIsProxy = tp.eIsProxy();
			if (_eIsProxy) {
				EObject _eResolveProxy = this.eResolveProxy(((InternalEObject) tp));
				return ((LScalarType) _eResolveProxy);
			}
		}
		LEntityAttribute _primaryKeyAttribute_1 = this.getPrimaryKeyAttribute();
		LScalarType _type_1 = null;
		if (_primaryKeyAttribute_1!=null) {
			_type_1=_primaryKeyAttribute_1.getType();
		}
		return _type_1;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getCurrentAttribute() {
		final Function1<LEntityAttribute, Boolean> _function = new Function1<LEntityAttribute, Boolean>() {
			public Boolean apply(final LEntityAttribute it) {
				return Boolean.valueOf(LEntityImpl.this.isHistCurrentAttribute(it));
			}
		};
		return IterableExtensions.<LEntityAttribute>findFirst(Iterables.<LEntityAttribute>filter(this.getAllFeatures(), LEntityAttribute.class), _function);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LEntityAttribute getVersionAttribute() {
		final Function1<LEntityAttribute, Boolean> _function = new Function1<LEntityAttribute, Boolean>() {
			public Boolean apply(final LEntityAttribute it) {
				return Boolean.valueOf(it.isVersion());
			}
		};
		return IterableExtensions.<LEntityAttribute>findFirst(Iterables.<LEntityAttribute>filter(this.getAllFeatures(), LEntityAttribute.class), _function);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getVersionAttributeName() {
		LEntityAttribute _versionAttribute = this.getVersionAttribute();
		String _name = null;
		if (_versionAttribute!=null) {
			_name=_versionAttribute.getName();
		}
		return _name;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LScalarType getVersionAttributeType() {
		LEntityAttribute _versionAttribute = this.getVersionAttribute();
		LScalarType _type = null;
		if (_versionAttribute!=null) {
			_type=_versionAttribute.getType();
		}
		LScalarType tp = _type;
		if ((tp != null)) {
			boolean _eIsProxy = tp.eIsProxy();
			if (_eIsProxy) {
				EObject _eResolveProxy = this.eResolveProxy(((InternalEObject) tp));
				return ((LScalarType) _eResolveProxy);
			}
		}
		LEntityAttribute _versionAttribute_1 = this.getVersionAttribute();
		LScalarType _type_1 = null;
		if (_versionAttribute_1!=null) {
			_type_1=_versionAttribute_1.getType();
		}
		return _type_1;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public List<LEntityFeature> getNormalFeatures() {
		final List<LEntityFeature> result = CollectionLiterals.<LEntityFeature>newArrayList();
		this.collectNormalOSBPFeatures(this, result);
		return result;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHistorizedWithParent() {
		LEntity entity = this;
		while ((entity != null)) {
			{
				boolean _isHistorized = entity.isHistorized();
				if (_isHistorized) {
					return true;
				}
				entity = entity.getSuperType();
			}
		}
		return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isTimedependentWithParent() {
		LEntity entity = this;
		while ((entity != null)) {
			{
				boolean _isTimedependent = entity.isTimedependent();
				if (_isTimedependent) {
					return true;
				}
				entity = entity.getSuperType();
			}
		}
		return false;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean isHistorizedOrTimedependentWithParent() {
		return (this.isHistorizedWithParent() || this.isTimedependentWithParent());
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				if (superType != null)
					msgs = ((InternalEObject)superType).eInverseRemove(this, OSBPEntityPackage.LENTITY__SUB_TYPES, LEntity.class, msgs);
				return basicSetSuperType((LEntity)otherEnd, msgs);
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getSubTypes()).basicAdd(otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case OSBPEntityPackage.LENTITY__PERSISTENCE_INFO:
				return basicSetPersistenceInfo(null, msgs);
			case OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY:
				return basicSetInheritanceStrategy(null, msgs);
			case OSBPEntityPackage.LENTITY__FEATURES:
				return ((InternalEList<?>)getFeatures()).basicRemove(otherEnd, msgs);
			case OSBPEntityPackage.LENTITY__INDEXES:
				return ((InternalEList<?>)getIndexes()).basicRemove(otherEnd, msgs);
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				return basicSetSuperType(null, msgs);
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				return ((InternalEList<?>)getSubTypes()).basicRemove(otherEnd, msgs);
			case OSBPEntityPackage.LENTITY__SUPER_INDEX:
				return ((InternalEList<?>)getSuperIndex()).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 OSBPEntityPackage.LENTITY__CACHEABLE:
				return isCacheable();
			case OSBPEntityPackage.LENTITY__HISTORIZED:
				return isHistorized();
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT:
				return isTimedependent();
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT_DATE_TYPE:
				return getTimedependentDateType();
			case OSBPEntityPackage.LENTITY__MAPPED_SUPERCLASS:
				return isMappedSuperclass();
			case OSBPEntityPackage.LENTITY__PERSISTENCE_INFO:
				return getPersistenceInfo();
			case OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY:
				return getInheritanceStrategy();
			case OSBPEntityPackage.LENTITY__FEATURES:
				return getFeatures();
			case OSBPEntityPackage.LENTITY__INDEXES:
				return getIndexes();
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				if (resolve) return getSuperType();
				return basicGetSuperType();
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				return getSubTypes();
			case OSBPEntityPackage.LENTITY__PERSISTENCE_UNIT:
				return getPersistenceUnit();
			case OSBPEntityPackage.LENTITY__SUPER_INDEX:
				return getSuperIndex();
		}
		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 OSBPEntityPackage.LENTITY__CACHEABLE:
				setCacheable((Boolean)newValue);
				return;
			case OSBPEntityPackage.LENTITY__HISTORIZED:
				setHistorized((Boolean)newValue);
				return;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT:
				setTimedependent((Boolean)newValue);
				return;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT_DATE_TYPE:
				setTimedependentDateType((LDateType)newValue);
				return;
			case OSBPEntityPackage.LENTITY__MAPPED_SUPERCLASS:
				setMappedSuperclass((Boolean)newValue);
				return;
			case OSBPEntityPackage.LENTITY__PERSISTENCE_INFO:
				setPersistenceInfo((LEntityPersistenceInfo)newValue);
				return;
			case OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY:
				setInheritanceStrategy((LEntityInheritanceStrategy)newValue);
				return;
			case OSBPEntityPackage.LENTITY__FEATURES:
				getFeatures().clear();
				getFeatures().addAll((Collection<? extends LEntityFeature>)newValue);
				return;
			case OSBPEntityPackage.LENTITY__INDEXES:
				getIndexes().clear();
				getIndexes().addAll((Collection<? extends LIndex>)newValue);
				return;
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				setSuperType((LEntity)newValue);
				return;
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				getSubTypes().clear();
				getSubTypes().addAll((Collection<? extends LEntity>)newValue);
				return;
			case OSBPEntityPackage.LENTITY__PERSISTENCE_UNIT:
				setPersistenceUnit((String)newValue);
				return;
			case OSBPEntityPackage.LENTITY__SUPER_INDEX:
				getSuperIndex().clear();
				getSuperIndex().addAll((Collection<? extends LEntitySuperIndex>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case OSBPEntityPackage.LENTITY__CACHEABLE:
				setCacheable(CACHEABLE_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__HISTORIZED:
				setHistorized(HISTORIZED_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT:
				setTimedependent(TIMEDEPENDENT_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT_DATE_TYPE:
				setTimedependentDateType(TIMEDEPENDENT_DATE_TYPE_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__MAPPED_SUPERCLASS:
				setMappedSuperclass(MAPPED_SUPERCLASS_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__PERSISTENCE_INFO:
				setPersistenceInfo((LEntityPersistenceInfo)null);
				return;
			case OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY:
				setInheritanceStrategy((LEntityInheritanceStrategy)null);
				return;
			case OSBPEntityPackage.LENTITY__FEATURES:
				getFeatures().clear();
				return;
			case OSBPEntityPackage.LENTITY__INDEXES:
				getIndexes().clear();
				return;
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				setSuperType((LEntity)null);
				return;
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				getSubTypes().clear();
				return;
			case OSBPEntityPackage.LENTITY__PERSISTENCE_UNIT:
				setPersistenceUnit(PERSISTENCE_UNIT_EDEFAULT);
				return;
			case OSBPEntityPackage.LENTITY__SUPER_INDEX:
				getSuperIndex().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case OSBPEntityPackage.LENTITY__CACHEABLE:
				return cacheable != CACHEABLE_EDEFAULT;
			case OSBPEntityPackage.LENTITY__HISTORIZED:
				return historized != HISTORIZED_EDEFAULT;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT:
				return timedependent != TIMEDEPENDENT_EDEFAULT;
			case OSBPEntityPackage.LENTITY__TIMEDEPENDENT_DATE_TYPE:
				return timedependentDateType != TIMEDEPENDENT_DATE_TYPE_EDEFAULT;
			case OSBPEntityPackage.LENTITY__MAPPED_SUPERCLASS:
				return mappedSuperclass != MAPPED_SUPERCLASS_EDEFAULT;
			case OSBPEntityPackage.LENTITY__PERSISTENCE_INFO:
				return persistenceInfo != null;
			case OSBPEntityPackage.LENTITY__INHERITANCE_STRATEGY:
				return inheritanceStrategy != null;
			case OSBPEntityPackage.LENTITY__FEATURES:
				return features != null && !features.isEmpty();
			case OSBPEntityPackage.LENTITY__INDEXES:
				return indexes != null && !indexes.isEmpty();
			case OSBPEntityPackage.LENTITY__SUPER_TYPE:
				return superType != null;
			case OSBPEntityPackage.LENTITY__SUB_TYPES:
				return subTypes != null && !subTypes.isEmpty();
			case OSBPEntityPackage.LENTITY__PERSISTENCE_UNIT:
				return PERSISTENCE_UNIT_EDEFAULT == null ? persistenceUnit != null : !PERSISTENCE_UNIT_EDEFAULT.equals(persistenceUnit);
			case OSBPEntityPackage.LENTITY__SUPER_INDEX:
				return superIndex != null && !superIndex.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public int eDerivedOperationID(int baseOperationID, Class<?> baseClass) {
		if (baseClass == LFeaturesHolder.class) {
			switch (baseOperationID) {
				case OSBPTypesPackage.LFEATURES_HOLDER___GET_FEATURES: return OSBPEntityPackage.LENTITY___GET_FEATURES;
				case OSBPTypesPackage.LFEATURES_HOLDER___GET_ALL_FEATURES: return OSBPEntityPackage.LENTITY___GET_ALL_FEATURES;
				default: return -1;
			}
		}
		return super.eDerivedOperationID(baseOperationID, baseClass);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	@SuppressWarnings("unchecked")
	public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException {
		switch (operationID) {
			case OSBPEntityPackage.LENTITY___GET_OPERATIONS:
				return getOperations();
			case OSBPEntityPackage.LENTITY___GET_REFERENCES:
				return getReferences();
			case OSBPEntityPackage.LENTITY___GET_ATTRIBUTES:
				return getAttributes();
			case OSBPEntityPackage.LENTITY___GET_ALL_FEATURES:
				return getAllFeatures();
			case OSBPEntityPackage.LENTITY___GET_ALL_ATTRIBUTES:
				return getAllAttributes();
			case OSBPEntityPackage.LENTITY___GET_ALL_REFERENCES:
				return getAllReferences();
			case OSBPEntityPackage.LENTITY___COLLECT_ALL_OSBP_FEATURES__LENTITY_LIST:
				collectAllOSBPFeatures((LEntity)arguments.get(0), (List<LEntityFeature>)arguments.get(1));
				return null;
			case OSBPEntityPackage.LENTITY___COLLECT_NORMAL_OSBP_FEATURES__LENTITY_LIST:
				collectNormalOSBPFeatures((LEntity)arguments.get(0), (List<LEntityFeature>)arguments.get(1));
				return null;
			case OSBPEntityPackage.LENTITY___GET_PRIMARY_KEY_ATTRIBUTE:
				return getPrimaryKeyAttribute();
			case OSBPEntityPackage.LENTITY___GET_ID_ATTRIBUTE_NAME:
				return getIdAttributeName();
			case OSBPEntityPackage.LENTITY___GET_ID_ATTRIBUTE_TYPE:
				return getIdAttributeType();
			case OSBPEntityPackage.LENTITY___GET_CURRENT_ATTRIBUTE:
				return getCurrentAttribute();
			case OSBPEntityPackage.LENTITY___GET_VERSION_ATTRIBUTE:
				return getVersionAttribute();
			case OSBPEntityPackage.LENTITY___GET_VERSION_ATTRIBUTE_NAME:
				return getVersionAttributeName();
			case OSBPEntityPackage.LENTITY___GET_VERSION_ATTRIBUTE_TYPE:
				return getVersionAttributeType();
			case OSBPEntityPackage.LENTITY___GET_NORMAL_FEATURES:
				return getNormalFeatures();
			case OSBPEntityPackage.LENTITY___IS_HISTORIZED_WITH_PARENT:
				return isHistorizedWithParent();
			case OSBPEntityPackage.LENTITY___IS_TIMEDEPENDENT_WITH_PARENT:
				return isTimedependentWithParent();
			case OSBPEntityPackage.LENTITY___IS_HISTORIZED_OR_TIMEDEPENDENT_WITH_PARENT:
				return isHistorizedOrTimedependentWithParent();
		}
		return super.eInvoke(operationID, arguments);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (cacheable: ");
		result.append(cacheable);
		result.append(", historized: ");
		result.append(historized);
		result.append(", timedependent: ");
		result.append(timedependent);
		result.append(", timedependentDateType: ");
		result.append(timedependentDateType);
		result.append(", mappedSuperclass: ");
		result.append(mappedSuperclass);
		result.append(", persistenceUnit: ");
		result.append(persistenceUnit);
		result.append(')');
		return result.toString();
	}

} //LEntityImpl
