/**
 * ****************************************************************************
 *   Copyright (c) 2020 CEA LIST.
 *  
 *  
 *   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
 *  
 *   Contributors:
 *    Asma Smaoui (CEA LIST) asma.smaoui@cea.fr - Initial API and implementation
 *  
 *  ****************************************************************************
 */
package io.shell.admin.aas._1._0.impl;

import io.shell.admin.aas._1._0.AdministrationT;
import io.shell.admin.aas._1._0.AssetT;
import io.shell.admin.aas._1._0.EmbeddedDataSpecificationT;
import io.shell.admin.aas._1._0.IdShortT;
import io.shell.admin.aas._1._0.IdentificationT;
import io.shell.admin.aas._1._0.KindType;
import io.shell.admin.aas._1._0.LangStringsT;
import io.shell.admin.aas._1._0.ReferenceT;
import io.shell.admin.aas._1._0._0Package;

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.impl.MinimalEObjectImpl;

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Asset T</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getIdShort <em>Id Short</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getCategory <em>Category</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getDescription <em>Description</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getParent <em>Parent</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getIdentification <em>Identification</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getAdministration <em>Administration</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getEmbeddedDataSpecification <em>Embedded Data Specification</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getKind <em>Kind</em>}</li>
 *   <li>{@link io.shell.admin.aas._1._0.impl.AssetTImpl#getAssetIdentificationModelRef <em>Asset Identification Model Ref</em>}</li>
 * </ul>
 *
 * @generated
 */
public class AssetTImpl extends MinimalEObjectImpl.Container implements AssetT {
	/**
	 * The cached value of the '{@link #getIdShort() <em>Id Short</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getIdShort()
	 * @generated
	 * @ordered
	 */
	protected IdShortT idShort;

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

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

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

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

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

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

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

	/**
	 * The cached value of the '{@link #getEmbeddedDataSpecification() <em>Embedded Data Specification</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEmbeddedDataSpecification()
	 * @generated
	 * @ordered
	 */
	protected EList<EmbeddedDataSpecificationT> embeddedDataSpecification;

	/**
	 * The default value of the '{@link #getKind() <em>Kind</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKind()
	 * @generated
	 * @ordered
	 */
	protected static final KindType KIND_EDEFAULT = KindType.TYPE;

	/**
	 * The cached value of the '{@link #getKind() <em>Kind</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getKind()
	 * @generated
	 * @ordered
	 */
	protected KindType kind = KIND_EDEFAULT;

	/**
	 * This is true if the Kind attribute has been set.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 * @ordered
	 */
	protected boolean kindESet;

	/**
	 * The cached value of the '{@link #getAssetIdentificationModelRef() <em>Asset Identification Model Ref</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getAssetIdentificationModelRef()
	 * @generated
	 * @ordered
	 */
	protected ReferenceT assetIdentificationModelRef;

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

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IdShortT getIdShort() {
		return idShort;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetIdShort(IdShortT newIdShort, NotificationChain msgs) {
		IdShortT oldIdShort = idShort;
		idShort = newIdShort;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ID_SHORT, oldIdShort, newIdShort);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIdShort(IdShortT newIdShort) {
		if (newIdShort != idShort) {
			NotificationChain msgs = null;
			if (idShort != null)
				msgs = ((InternalEObject)idShort).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ID_SHORT, null, msgs);
			if (newIdShort != null)
				msgs = ((InternalEObject)newIdShort).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ID_SHORT, null, msgs);
			msgs = basicSetIdShort(newIdShort, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ID_SHORT, newIdShort, newIdShort));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCategory(String newCategory) {
		String oldCategory = category;
		category = newCategory;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__CATEGORY, oldCategory, category));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LangStringsT getDescription() {
		return description;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetDescription(LangStringsT newDescription, NotificationChain msgs) {
		LangStringsT oldDescription = description;
		description = newDescription;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__DESCRIPTION, oldDescription, newDescription);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDescription(LangStringsT newDescription) {
		if (newDescription != description) {
			NotificationChain msgs = null;
			if (description != null)
				msgs = ((InternalEObject)description).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__DESCRIPTION, null, msgs);
			if (newDescription != null)
				msgs = ((InternalEObject)newDescription).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__DESCRIPTION, null, msgs);
			msgs = basicSetDescription(newDescription, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__DESCRIPTION, newDescription, newDescription));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setParent(String newParent) {
		String oldParent = parent;
		parent = newParent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__PARENT, oldParent, parent));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IdentificationT getIdentification() {
		return identification;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetIdentification(IdentificationT newIdentification, NotificationChain msgs) {
		IdentificationT oldIdentification = identification;
		identification = newIdentification;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__IDENTIFICATION, oldIdentification, newIdentification);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setIdentification(IdentificationT newIdentification) {
		if (newIdentification != identification) {
			NotificationChain msgs = null;
			if (identification != null)
				msgs = ((InternalEObject)identification).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__IDENTIFICATION, null, msgs);
			if (newIdentification != null)
				msgs = ((InternalEObject)newIdentification).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__IDENTIFICATION, null, msgs);
			msgs = basicSetIdentification(newIdentification, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__IDENTIFICATION, newIdentification, newIdentification));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public AdministrationT getAdministration() {
		return administration;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetAdministration(AdministrationT newAdministration, NotificationChain msgs) {
		AdministrationT oldAdministration = administration;
		administration = newAdministration;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ADMINISTRATION, oldAdministration, newAdministration);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAdministration(AdministrationT newAdministration) {
		if (newAdministration != administration) {
			NotificationChain msgs = null;
			if (administration != null)
				msgs = ((InternalEObject)administration).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ADMINISTRATION, null, msgs);
			if (newAdministration != null)
				msgs = ((InternalEObject)newAdministration).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ADMINISTRATION, null, msgs);
			msgs = basicSetAdministration(newAdministration, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ADMINISTRATION, newAdministration, newAdministration));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<EmbeddedDataSpecificationT> getEmbeddedDataSpecification() {
		if (embeddedDataSpecification == null) {
			embeddedDataSpecification = new EObjectContainmentEList<EmbeddedDataSpecificationT>(EmbeddedDataSpecificationT.class, this, _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION);
		}
		return embeddedDataSpecification;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public KindType getKind() {
		return kind;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setKind(KindType newKind) {
		KindType oldKind = kind;
		kind = newKind == null ? KIND_EDEFAULT : newKind;
		boolean oldKindESet = kindESet;
		kindESet = true;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__KIND, oldKind, kind, !oldKindESet));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void unsetKind() {
		KindType oldKind = kind;
		boolean oldKindESet = kindESet;
		kind = KIND_EDEFAULT;
		kindESet = false;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.UNSET, _0Package.ASSET_T__KIND, oldKind, KIND_EDEFAULT, oldKindESet));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ReferenceT getAssetIdentificationModelRef() {
		return assetIdentificationModelRef;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetAssetIdentificationModelRef(ReferenceT newAssetIdentificationModelRef, NotificationChain msgs) {
		ReferenceT oldAssetIdentificationModelRef = assetIdentificationModelRef;
		assetIdentificationModelRef = newAssetIdentificationModelRef;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF, oldAssetIdentificationModelRef, newAssetIdentificationModelRef);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setAssetIdentificationModelRef(ReferenceT newAssetIdentificationModelRef) {
		if (newAssetIdentificationModelRef != assetIdentificationModelRef) {
			NotificationChain msgs = null;
			if (assetIdentificationModelRef != null)
				msgs = ((InternalEObject)assetIdentificationModelRef).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF, null, msgs);
			if (newAssetIdentificationModelRef != null)
				msgs = ((InternalEObject)newAssetIdentificationModelRef).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF, null, msgs);
			msgs = basicSetAssetIdentificationModelRef(newAssetIdentificationModelRef, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF, newAssetIdentificationModelRef, newAssetIdentificationModelRef));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case _0Package.ASSET_T__ID_SHORT:
				return basicSetIdShort(null, msgs);
			case _0Package.ASSET_T__DESCRIPTION:
				return basicSetDescription(null, msgs);
			case _0Package.ASSET_T__IDENTIFICATION:
				return basicSetIdentification(null, msgs);
			case _0Package.ASSET_T__ADMINISTRATION:
				return basicSetAdministration(null, msgs);
			case _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION:
				return ((InternalEList<?>)getEmbeddedDataSpecification()).basicRemove(otherEnd, msgs);
			case _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF:
				return basicSetAssetIdentificationModelRef(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 _0Package.ASSET_T__ID_SHORT:
				return getIdShort();
			case _0Package.ASSET_T__CATEGORY:
				return getCategory();
			case _0Package.ASSET_T__DESCRIPTION:
				return getDescription();
			case _0Package.ASSET_T__PARENT:
				return getParent();
			case _0Package.ASSET_T__IDENTIFICATION:
				return getIdentification();
			case _0Package.ASSET_T__ADMINISTRATION:
				return getAdministration();
			case _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION:
				return getEmbeddedDataSpecification();
			case _0Package.ASSET_T__KIND:
				return getKind();
			case _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF:
				return getAssetIdentificationModelRef();
		}
		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 _0Package.ASSET_T__ID_SHORT:
				setIdShort((IdShortT)newValue);
				return;
			case _0Package.ASSET_T__CATEGORY:
				setCategory((String)newValue);
				return;
			case _0Package.ASSET_T__DESCRIPTION:
				setDescription((LangStringsT)newValue);
				return;
			case _0Package.ASSET_T__PARENT:
				setParent((String)newValue);
				return;
			case _0Package.ASSET_T__IDENTIFICATION:
				setIdentification((IdentificationT)newValue);
				return;
			case _0Package.ASSET_T__ADMINISTRATION:
				setAdministration((AdministrationT)newValue);
				return;
			case _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION:
				getEmbeddedDataSpecification().clear();
				getEmbeddedDataSpecification().addAll((Collection<? extends EmbeddedDataSpecificationT>)newValue);
				return;
			case _0Package.ASSET_T__KIND:
				setKind((KindType)newValue);
				return;
			case _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF:
				setAssetIdentificationModelRef((ReferenceT)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case _0Package.ASSET_T__ID_SHORT:
				setIdShort((IdShortT)null);
				return;
			case _0Package.ASSET_T__CATEGORY:
				setCategory(CATEGORY_EDEFAULT);
				return;
			case _0Package.ASSET_T__DESCRIPTION:
				setDescription((LangStringsT)null);
				return;
			case _0Package.ASSET_T__PARENT:
				setParent(PARENT_EDEFAULT);
				return;
			case _0Package.ASSET_T__IDENTIFICATION:
				setIdentification((IdentificationT)null);
				return;
			case _0Package.ASSET_T__ADMINISTRATION:
				setAdministration((AdministrationT)null);
				return;
			case _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION:
				getEmbeddedDataSpecification().clear();
				return;
			case _0Package.ASSET_T__KIND:
				unsetKind();
				return;
			case _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF:
				setAssetIdentificationModelRef((ReferenceT)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case _0Package.ASSET_T__ID_SHORT:
				return idShort != null;
			case _0Package.ASSET_T__CATEGORY:
				return CATEGORY_EDEFAULT == null ? category != null : !CATEGORY_EDEFAULT.equals(category);
			case _0Package.ASSET_T__DESCRIPTION:
				return description != null;
			case _0Package.ASSET_T__PARENT:
				return PARENT_EDEFAULT == null ? parent != null : !PARENT_EDEFAULT.equals(parent);
			case _0Package.ASSET_T__IDENTIFICATION:
				return identification != null;
			case _0Package.ASSET_T__ADMINISTRATION:
				return administration != null;
			case _0Package.ASSET_T__EMBEDDED_DATA_SPECIFICATION:
				return embeddedDataSpecification != null && !embeddedDataSpecification.isEmpty();
			case _0Package.ASSET_T__KIND:
				return isSetKind();
			case _0Package.ASSET_T__ASSET_IDENTIFICATION_MODEL_REF:
				return assetIdentificationModelRef != null;
		}
		return super.eIsSet(featureID);
	}

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

		StringBuilder result = new StringBuilder(super.toString());
		result.append(" (category: ");
		result.append(category);
		result.append(", parent: ");
		result.append(parent);
		result.append(", kind: ");
		if (kindESet) result.append(kind); else result.append("<unset>");
		result.append(')');
		return result.toString();
	}

} //AssetTImpl
