/**
 * Copyright (c) 2011, 2014 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *  All rights reserved. This program and the accompanying materials 
 *  are made available under the terms of the Eclipse Public License 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.provider;

import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.AbstractOverrideableCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.osbp.dsl.semantic.common.types.LImport;
import org.eclipse.osbp.dsl.semantic.common.types.LScalarType;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesFactory;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;
import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute;
import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityFactory;
import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityPackage;
import org.eclipse.xtext.xbase.XbaseFactory;
import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotationsFactory;

/**
 * This is the item provider adapter for a
 * {@link org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute} object. <!--
 * begin-user-doc --> <!-- end-user-doc -->
 * 
 * @generated
 */
public class LEntityAttributeItemProvider extends LEntityFeatureItemProvider {
	/**
	 * This constructs an instance from a factory and a notifier. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public LEntityAttributeItemProvider(AdapterFactory adapterFactory) {
		super(adapterFactory);
	}

	/**
	 * This returns the property descriptors for the adapted class. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public List<IItemPropertyDescriptor> getPropertyDescriptors(Object object) {
		if (itemPropertyDescriptors == null) {
			super.getPropertyDescriptors(object);

			addIdPropertyDescriptor(object);
			addUuidPropertyDescriptor(object);
			addVersionPropertyDescriptor(object);
			addLazyPropertyDescriptor(object);
			addCascadingPropertyDescriptor(object);
			addTransientPropertyDescriptor(object);
			addDerivedPropertyDescriptor(object);
			addDirtyPropertyDescriptor(object);
			addDomainKeyPropertyDescriptor(object);
			addDomainDescriptionPropertyDescriptor(object);
			addFilteringPropertyDescriptor(object);
			addRangeFilteringPropertyDescriptor(object);
			addUniqueEntryPropertyDescriptor(object);
			addTypePropertyDescriptor(object);
			addIsGroupedPropertyDescriptor(object);
			addGroupNamePropertyDescriptor(object);
			addAsKanbanStatePropertyDescriptor(object);
			addOnKanbanCardPropertyDescriptor(object);
			addAsKanbanOrderingPropertyDescriptor(object);
			addDecentKanbanOrderPropertyDescriptor(object);
			addOppositePropertyDescriptor(object);
			addTypedNamePropertyDescriptor(object);
		}
		return itemPropertyDescriptors;
	}

	/**
	 * This adds a property descriptor for the Id feature.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	protected void addIdPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_id_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_id_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__ID,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Uuid feature.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	protected void addUuidPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_uuid_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_uuid_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__UUID,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Version feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addVersionPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_version_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_version_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__VERSION,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Lazy feature.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	protected void addLazyPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_lazy_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_lazy_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__LAZY,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Cascading feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addCascadingPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_cascading_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_cascading_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__CASCADING,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Transient feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addTransientPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_transient_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_transient_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__TRANSIENT,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Derived feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addDerivedPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_derived_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_derived_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Dirty feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addDirtyPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_dirty_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_dirty_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__DIRTY,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Domain Key feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addDomainKeyPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_domainKey_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_domainKey_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_KEY,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Domain Description feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addDomainDescriptionPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_domainDescription_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_domainDescription_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__DOMAIN_DESCRIPTION,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Filtering feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addFilteringPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_filtering_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_filtering_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__FILTERING,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Range Filtering feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addRangeFilteringPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_rangeFiltering_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_rangeFiltering_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__RANGE_FILTERING,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Unique Entry feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addUniqueEntryPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_uniqueEntry_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_uniqueEntry_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__UNIQUE_ENTRY,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Type feature.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	protected void addTypePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_type_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_type_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__TYPE,
				 true,
				 false,
				 true,
				 null,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Is Grouped feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addIsGroupedPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_isGrouped_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_isGrouped_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__IS_GROUPED,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Group Name feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addGroupNamePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LAttribute_groupName_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LAttribute_groupName_feature", "_UI_LAttribute_type"),
				 OSBPTypesPackage.Literals.LATTRIBUTE__GROUP_NAME,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.GENERIC_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the As Kanban State feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addAsKanbanStatePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_asKanbanState_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_asKanbanState_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__AS_KANBAN_STATE,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the On Kanban Card feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addOnKanbanCardPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_onKanbanCard_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_onKanbanCard_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__ON_KANBAN_CARD,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the As Kanban Ordering feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addAsKanbanOrderingPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_asKanbanOrdering_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_asKanbanOrdering_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__AS_KANBAN_ORDERING,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Decent Kanban Order feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addDecentKanbanOrderPropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_decentKanbanOrder_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_decentKanbanOrder_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__DECENT_KANBAN_ORDER,
				 true,
				 false,
				 false,
				 ItemPropertyDescriptor.BOOLEAN_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Opposite feature.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected void addOppositePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_opposite_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_opposite_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__OPPOSITE,
				 true,
				 false,
				 true,
				 null,
				 null,
				 null));
	}

	/**
	 * This adds a property descriptor for the Typed Name feature. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected void addTypedNamePropertyDescriptor(Object object) {
		itemPropertyDescriptors.add
			(createItemPropertyDescriptor
				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
				 getResourceLocator(),
				 getString("_UI_LEntityAttribute_typedName_feature"),
				 getString("_UI_PropertyDescriptor_description", "_UI_LEntityAttribute_typedName_feature", "_UI_LEntityAttribute_type"),
				 OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__TYPED_NAME,
				 false,
				 false,
				 false,
				 ItemPropertyDescriptor.GENERIC_VALUE_IMAGE,
				 null,
				 null));
	}

	/**
	 * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an
	 * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or
	 * {@link org.eclipse.emf.edit.command.MoveCommand} in {@link #createCommand}.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Collection<? extends EStructuralFeature> getChildrenFeatures(
			Object object) {
		if (childrenFeatures == null) {
			super.getChildrenFeatures(object);
			childrenFeatures.add(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION);
			childrenFeatures.add(OSBPTypesPackage.Literals.LATTRIBUTE__PROPERTIES);
			childrenFeatures.add(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS);
			childrenFeatures.add(OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__ON_KANBAN_CARD_STATES);
		}
		return childrenFeatures;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EStructuralFeature getChildFeature(Object object, Object child) {
		// Check the type of the specified child object and return the proper feature to use for
		// adding (see {@link AddCommand}) it as a child.

		return super.getChildFeature(object, child);
	}

	/**
	 * This returns LEntity.gif. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated NOT
	 */
	@Override
	public Object getImage(Object object) {
		return composeImage(getImage((LEntityAttribute) object),
				getOverlay((LEntityAttribute) object));
	}

	private Object getOverlay(LEntityAttribute object) {
		if (object.isTransient()) {
			return getResourceLocator().getImage("full/ovr/transient.gif");
		}
		return null;
	}

	private Object getImage(LEntityAttribute object) {
		if (object.isId() || object.isUuid()) {
			return getResourceLocator().getImage("full/obj/LAttribute_id.gif");
		}
		return getResourceLocator().getImage("full/obj16/LEntityAttribute.gif");
	}

	/**
	 * This returns the label text for the adapted class.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String getText(Object object) {
		String label = ((LEntityAttribute)object).getName();
		return label == null || label.length() == 0 ?
			getString("_UI_LEntityAttribute_type") :
			getString("_UI_LEntityAttribute_type") + " " + label;
	}

	/**
	 * This handles model notifications by calling {@link #updateChildren} to update any cached
	 * children and by creating a viewer notification, which it passes to {@link #fireNotifyChanged}.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @generated
	 */
	@Override
	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		switch (notification.getFeatureID(LEntityAttribute.class)) {
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__ID:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__UUID:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__VERSION:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__LAZY:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__CASCADING:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__TRANSIENT:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DERIVED:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DIRTY:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DOMAIN_KEY:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DOMAIN_DESCRIPTION:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__FILTERING:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__RANGE_FILTERING:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__UNIQUE_ENTRY:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__IS_GROUPED:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__GROUP_NAME:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__AS_KANBAN_STATE:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__ON_KANBAN_CARD:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__AS_KANBAN_ORDERING:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DECENT_KANBAN_ORDER:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__TYPED_NAME:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
				return;
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__DERIVED_GETTER_EXPRESSION:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__PROPERTIES:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__CONSTRAINTS:
			case OSBPEntityPackage.LENTITY_ATTRIBUTE__ON_KANBAN_CARD_STATES:
				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
				return;
		}
		super.notifyChanged(notification);
	}

	/**
	 * This adds {@link org.eclipse.emf.edit.command.CommandParameter}s
	 * describing the children that can be created under this object. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	protected void collectNewChildDescriptors(
			Collection<Object> newChildDescriptors, Object object) {
		super.collectNewChildDescriptors(newChildDescriptors, object);

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XAnnotationsFactory.eINSTANCE.createXAnnotation()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXIfExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXSwitchExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXBlockExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXVariableDeclaration()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXMemberFeatureCall()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXFeatureCall()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXConstructorCall()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXBooleanLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXNullLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXNumberLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXStringLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXListLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXSetLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXClosure()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXCastedExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXBinaryOperation()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXUnaryOperation()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXPostfixOperation()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXForLoopExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXBasicForLoopExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXDoWhileExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXWhileExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXTypeLiteral()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXInstanceOfExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXThrowExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXTryCatchFinallyExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXAssignment()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXReturnExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__DERIVED_GETTER_EXPRESSION,
				 XbaseFactory.eINSTANCE.createXSynchronizedExpression()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__PROPERTIES,
				 OSBPTypesFactory.eINSTANCE.createLKeyAndValue()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCAssertFalse()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCAssertTrue()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCDecimalMax()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCDecimalMin()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCDigits()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCFuture()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCPast()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCNumericMax()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCNumericMin()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCNotNull()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCNull()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCRegEx()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPTypesPackage.Literals.LATTRIBUTE__CONSTRAINTS,
				 OSBPTypesFactory.eINSTANCE.createLDtCSize()));

		newChildDescriptors.add
			(createChildParameter
				(OSBPEntityPackage.Literals.LENTITY_ATTRIBUTE__ON_KANBAN_CARD_STATES,
				 OSBPEntityFactory.eINSTANCE.createLKanbanStateDetail()));
	}

	@Override
	protected Command createSetCommand(EditingDomain domain, EObject owner,
			EStructuralFeature feature, Object value, int index) {
		if (feature == OSBPTypesPackage.Literals.LATTRIBUTE__TYPE) {
			CompoundCommand compound = new CompoundCommand();
			compound.append(super.createSetCommand(domain, owner, feature,
					value, index));
			compound.append(new AddImportForDatatypeCommand(domain,
					(LEntityAttribute) owner, (LScalarType) value));
			return compound;
		} else {
			return super.createSetCommand(domain, owner, feature, value, index);
		}
	}

	private static final class AddImportForDatatypeCommand extends
			AbstractOverrideableCommand {

		private LEntityAttribute lAttribute;
		private LTypedPackage typedPackage;
		private boolean contains;
		private String typePackageName;
		private LImport newImport;
		private LScalarType type;

		protected AddImportForDatatypeCommand(EditingDomain domain,
				LEntityAttribute lAttribute, LScalarType type) {
			super(domain, "Create import statements",
					"Creates import statements for added LDatatypes");
			this.lAttribute = lAttribute;
			this.type = type;
			typedPackage = (LTypedPackage) lAttribute.getEntity().eContainer();
		}

		protected boolean prepare() {
			return true;
		}

		@Override
		public void doExecute() {
			LTypedPackage typePackage = (LTypedPackage) type.eContainer();
			typePackageName = typePackage.getName();
// TODO neon
//			for (LImport lImport : typePackage.getImports()) {
//				if (lImport.getImportedNamespace().replace(".*", "")
//						.equals(typePackageName)) {
//					contains = true;
//				}
//			}

			if (!contains) {
				newImport = OSBPTypesFactory.eINSTANCE.createLImport();
				newImport.setImportedNamespace(typePackageName + ".*");
			}

			doRedo();
		}

		@Override
		public void doUndo() {
			if (newImport != null) {
//				typedPackage.getImports().remove(newImport);
			}
		}

		@Override
		public void doRedo() {
			if (newImport != null) {
//				typedPackage.getImports().add(newImport);
			}
		}
	}
}
