/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Florian Pirchner - Initial implementation
 * 
 */

package org.eclipse.osbp.ecview.extension.grid.impl;

import java.util.Collection;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.binding.BindingFactory;
import org.eclipse.osbp.ecview.core.common.model.binding.YECViewModelValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.binding.YValueBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelFactory;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.YBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableMultiSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YHelperLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YMultiSelectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YSelectionBindable;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YBeanServiceConsumer;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSelectionType;
import org.eclipse.osbp.ecview.core.extension.model.extension.impl.YInputImpl;

import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridCellStyleGenerator;
import org.eclipse.osbp.ecview.extension.grid.CxGridColumn;
import org.eclipse.osbp.ecview.extension.grid.CxGridFooterRow;
import org.eclipse.osbp.ecview.extension.grid.CxGridHeaderRow;
import org.eclipse.osbp.ecview.extension.grid.CxGridPackage;
import org.eclipse.osbp.ecview.extension.grid.CxGridSortable;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>Cx Grid</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getCollectionBindingEndpoint <em>Collection Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSelectionBindingEndpoint <em>Selection Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getMultiSelectionBindingEndpoint <em>Multi Selection Binding Endpoint</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isUseBeanService <em>Use Bean Service</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSelectionType <em>Selection Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSelectionEventTopic <em>Selection Event Topic</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSelection <em>Selection</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getMultiSelection <em>Multi Selection</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getCollection <em>Collection</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getType <em>Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getEmfNsURI <em>Emf Ns URI</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getTypeQualifiedName <em>Type Qualified Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getColumns <em>Columns</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSortOrder <em>Sort Order</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isColumnReorderingAllowed <em>Column Reordering Allowed</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getCellStyleGenerator <em>Cell Style Generator</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isFilteringVisible <em>Filtering Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isCustomFilters <em>Custom Filters</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getHeaders <em>Headers</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isHeaderVisible <em>Header Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getFooters <em>Footers</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isFooterVisible <em>Footer Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#isEditorEnabled <em>Editor Enabled</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getEditorCancelI18nLabelKey <em>Editor Cancel I1 8n Label Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getEditorSaveI18nLabelKey <em>Editor Save I1 8n Label Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getEditorSaved <em>Editor Saved</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridImpl#getSetLastRefreshTime <em>Set Last Refresh Time</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CxGridImpl extends YInputImpl implements CxGrid {
	
	/**
	 * The cached value of the '{@link #getCollectionBindingEndpoint() <em>Collection Binding Endpoint</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCollectionBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableCollectionEndpoint collectionBindingEndpoint;

	/**
	 * The cached value of the '{@link #getSelectionBindingEndpoint() <em>Selection Binding Endpoint</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSelectionBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableSelectionEndpoint selectionBindingEndpoint;

	/**
	 * The cached value of the '{@link #getMultiSelectionBindingEndpoint()
	 * <em>Multi Selection Binding Endpoint</em>}' reference. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @see #getMultiSelectionBindingEndpoint()
	 * @generated
	 * @ordered
	 */
	protected YEmbeddableMultiSelectionEndpoint multiSelectionBindingEndpoint;

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

	/**
	 * The cached value of the '{@link #isUseBeanService() <em>Use Bean Service</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isUseBeanService()
	 * @generated
	 * @ordered
	 */
	protected boolean useBeanService = USE_BEAN_SERVICE_EDEFAULT;

	/**
	 * The default value of the '{@link #getSelectionType() <em>Selection Type</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getSelectionType()
	 * @generated
	 * @ordered
	 */
	protected static final YSelectionType SELECTION_TYPE_EDEFAULT = YSelectionType.SINGLE;

	/**
	 * The cached value of the '{@link #getSelectionType() <em>Selection Type</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getSelectionType()
	 * @generated
	 * @ordered
	 */
	protected YSelectionType selectionType = SELECTION_TYPE_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getSelectionEventTopic() <em>Selection Event Topic</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getSelectionEventTopic()
	 * @generated
	 * @ordered
	 */
	protected String selectionEventTopic = SELECTION_EVENT_TOPIC_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getSelection() <em>Selection</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSelection()
	 * @generated
	 * @ordered
	 */
	protected Object selection = SELECTION_EDEFAULT;

	/**
	 * The cached value of the '{@link #getMultiSelection() <em>Multi Selection</em>}' attribute list.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getMultiSelection()
	 * @generated
	 * @ordered
	 */
	protected EList<Object> multiSelection;

	/**
	 * The cached value of the '{@link #getCollection() <em>Collection</em>}' attribute list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getCollection()
	 * @generated
	 * @ordered
	 */
	protected EList<Object> collection;

	/**
	 * The cached value of the '{@link #getType() <em>Type</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getType()
	 * @generated
	 * @ordered
	 */
	protected Class<?> type;

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

	/**
	 * The cached value of the '{@link #getEmfNsURI() <em>Emf Ns URI</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEmfNsURI()
	 * @generated
	 * @ordered
	 */
	protected String emfNsURI = EMF_NS_URI_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getTypeQualifiedName() <em>Type Qualified Name</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getTypeQualifiedName()
	 * @generated
	 * @ordered
	 */
	protected String typeQualifiedName = TYPE_QUALIFIED_NAME_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getSortOrder() <em>Sort Order</em>}' containment reference list.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSortOrder()
	 * @generated
	 * @ordered
	 */
	protected EList<CxGridSortable> sortOrder;

	/**
	 * The default value of the '{@link #isColumnReorderingAllowed() <em>Column Reordering Allowed</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isColumnReorderingAllowed()
	 * @generated
	 * @ordered
	 */
	protected static final boolean COLUMN_REORDERING_ALLOWED_EDEFAULT = true;

	/**
	 * The cached value of the '{@link #isColumnReorderingAllowed() <em>Column Reordering Allowed</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isColumnReorderingAllowed()
	 * @generated
	 * @ordered
	 */
	protected boolean columnReorderingAllowed = COLUMN_REORDERING_ALLOWED_EDEFAULT;

	/**
	 * The cached value of the '{@link #getCellStyleGenerator()
	 * <em>Cell Style Generator</em>}' containment reference. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @see #getCellStyleGenerator()
	 * @generated
	 * @ordered
	 */
	protected CxGridCellStyleGenerator cellStyleGenerator;

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

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

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

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

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

	/**
	 * The default value of the '{@link #isHeaderVisible() <em>Header Visible</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #isHeaderVisible()
	 * @generated
	 * @ordered
	 */
	protected static final boolean HEADER_VISIBLE_EDEFAULT = true;

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

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

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

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

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

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

	/**
	 * The default value of the '{@link #getEditorCancelI18nLabelKey() <em>Editor Cancel I1 8n Label Key</em>}' attribute.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @see #getEditorCancelI18nLabelKey()
	 * @generated
	 * @ordered
	 */
	protected static final String EDITOR_CANCEL_I1_8N_LABEL_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getEditorCancelI18nLabelKey() <em>Editor Cancel I1 8n Label Key</em>}' attribute.
	 * <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * @see #getEditorCancelI18nLabelKey()
	 * @generated
	 * @ordered
	 */
	protected String editorCancelI18nLabelKey = EDITOR_CANCEL_I1_8N_LABEL_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getEditorSaveI18nLabelKey() <em>Editor Save I1 8n Label Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEditorSaveI18nLabelKey()
	 * @generated
	 * @ordered
	 */
	protected static final String EDITOR_SAVE_I1_8N_LABEL_KEY_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getEditorSaveI18nLabelKey() <em>Editor Save I1 8n Label Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEditorSaveI18nLabelKey()
	 * @generated
	 * @ordered
	 */
	protected String editorSaveI18nLabelKey = EDITOR_SAVE_I1_8N_LABEL_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getEditorSaved() <em>Editor Saved</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEditorSaved()
	 * @generated
	 * @ordered
	 */
	protected static final Object EDITOR_SAVED_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getEditorSaved() <em>Editor Saved</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEditorSaved()
	 * @generated
	 * @ordered
	 */
	protected Object editorSaved = EDITOR_SAVED_EDEFAULT;

	/**
	 * The default value of the '{@link #getSetLastRefreshTime() <em>Set Last Refresh Time</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSetLastRefreshTime()
	 * @generated
	 * @ordered
	 */
	protected static final long SET_LAST_REFRESH_TIME_EDEFAULT = 0L;

	/**
	 * The cached value of the '{@link #getSetLastRefreshTime() <em>Set Last Refresh Time</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getSetLastRefreshTime()
	 * @generated
	 * @ordered
	 */
	protected long setLastRefreshTime = SET_LAST_REFRESH_TIME_EDEFAULT;

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the e class
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return CxGridPackage.Literals.CX_GRID;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCollectionBindingEndpoint()
	 *         <em>Collection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public YEmbeddableCollectionEndpoint getCollectionBindingEndpoint() {
		if (collectionBindingEndpoint != null && collectionBindingEndpoint.eIsProxy()) {
			InternalEObject oldCollectionBindingEndpoint = (InternalEObject)collectionBindingEndpoint;
			collectionBindingEndpoint = (YEmbeddableCollectionEndpoint)eResolveProxy(oldCollectionBindingEndpoint);
			if (collectionBindingEndpoint != oldCollectionBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT, oldCollectionBindingEndpoint, collectionBindingEndpoint));
			}
		}
		return collectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable collection endpoint
	 * @generated
	 */
	public YEmbeddableCollectionEndpoint basicGetCollectionBindingEndpoint() {
		return collectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCollectionBindingEndpoint
	 *            the new collection binding endpoint
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetCollectionBindingEndpoint(
			YEmbeddableCollectionEndpoint newCollectionBindingEndpoint,
			NotificationChain msgs) {
		YEmbeddableCollectionEndpoint oldCollectionBindingEndpoint = collectionBindingEndpoint;
		collectionBindingEndpoint = newCollectionBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT, oldCollectionBindingEndpoint, newCollectionBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCollectionBindingEndpoint
	 *            the new cached value of the '
	 *            {@link #getCollectionBindingEndpoint()
	 *            <em>Collection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public void setCollectionBindingEndpoint(
			YEmbeddableCollectionEndpoint newCollectionBindingEndpoint) {
		if (newCollectionBindingEndpoint != collectionBindingEndpoint) {
			NotificationChain msgs = null;
			if (collectionBindingEndpoint != null)
				msgs = ((InternalEObject)collectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
			if (newCollectionBindingEndpoint != null)
				msgs = ((InternalEObject)newCollectionBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
			msgs = basicSetCollectionBindingEndpoint(newCollectionBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT, newCollectionBindingEndpoint, newCollectionBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSelectionBindingEndpoint()
	 *         <em>Selection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public YEmbeddableSelectionEndpoint getSelectionBindingEndpoint() {
		if (selectionBindingEndpoint != null && selectionBindingEndpoint.eIsProxy()) {
			InternalEObject oldSelectionBindingEndpoint = (InternalEObject)selectionBindingEndpoint;
			selectionBindingEndpoint = (YEmbeddableSelectionEndpoint)eResolveProxy(oldSelectionBindingEndpoint);
			if (selectionBindingEndpoint != oldSelectionBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT, oldSelectionBindingEndpoint, selectionBindingEndpoint));
			}
		}
		return selectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable selection endpoint
	 * @generated
	 */
	public YEmbeddableSelectionEndpoint basicGetSelectionBindingEndpoint() {
		return selectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSelectionBindingEndpoint
	 *            the new selection binding endpoint
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetSelectionBindingEndpoint(
			YEmbeddableSelectionEndpoint newSelectionBindingEndpoint,
			NotificationChain msgs) {
		YEmbeddableSelectionEndpoint oldSelectionBindingEndpoint = selectionBindingEndpoint;
		selectionBindingEndpoint = newSelectionBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT, oldSelectionBindingEndpoint, newSelectionBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSelectionBindingEndpoint
	 *            the new cached value of the '
	 *            {@link #getSelectionBindingEndpoint()
	 *            <em>Selection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public void setSelectionBindingEndpoint(
			YEmbeddableSelectionEndpoint newSelectionBindingEndpoint) {
		if (newSelectionBindingEndpoint != selectionBindingEndpoint) {
			NotificationChain msgs = null;
			if (selectionBindingEndpoint != null)
				msgs = ((InternalEObject)selectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
			if (newSelectionBindingEndpoint != null)
				msgs = ((InternalEObject)newSelectionBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
			msgs = basicSetSelectionBindingEndpoint(newSelectionBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT, newSelectionBindingEndpoint, newSelectionBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '
	 *         {@link #getMultiSelectionBindingEndpoint()
	 *         <em>Multi Selection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public YEmbeddableMultiSelectionEndpoint getMultiSelectionBindingEndpoint() {
		if (multiSelectionBindingEndpoint != null && multiSelectionBindingEndpoint.eIsProxy()) {
			InternalEObject oldMultiSelectionBindingEndpoint = (InternalEObject)multiSelectionBindingEndpoint;
			multiSelectionBindingEndpoint = (YEmbeddableMultiSelectionEndpoint)eResolveProxy(oldMultiSelectionBindingEndpoint);
			if (multiSelectionBindingEndpoint != oldMultiSelectionBindingEndpoint) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT, oldMultiSelectionBindingEndpoint, multiSelectionBindingEndpoint));
			}
		}
		return multiSelectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the y embeddable multi selection endpoint
	 * @generated
	 */
	public YEmbeddableMultiSelectionEndpoint basicGetMultiSelectionBindingEndpoint() {
		return multiSelectionBindingEndpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newMultiSelectionBindingEndpoint
	 *            the new multi selection binding endpoint
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetMultiSelectionBindingEndpoint(
			YEmbeddableMultiSelectionEndpoint newMultiSelectionBindingEndpoint,
			NotificationChain msgs) {
		YEmbeddableMultiSelectionEndpoint oldMultiSelectionBindingEndpoint = multiSelectionBindingEndpoint;
		multiSelectionBindingEndpoint = newMultiSelectionBindingEndpoint;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT, oldMultiSelectionBindingEndpoint, newMultiSelectionBindingEndpoint);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newMultiSelectionBindingEndpoint
	 *            the new cached value of the '
	 *            {@link #getMultiSelectionBindingEndpoint()
	 *            <em>Multi Selection Binding Endpoint</em>}' reference
	 * @generated
	 */
	public void setMultiSelectionBindingEndpoint(
			YEmbeddableMultiSelectionEndpoint newMultiSelectionBindingEndpoint) {
		if (newMultiSelectionBindingEndpoint != multiSelectionBindingEndpoint) {
			NotificationChain msgs = null;
			if (multiSelectionBindingEndpoint != null)
				msgs = ((InternalEObject)multiSelectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_MULTI_SELECTION_ENDPOINT__ELEMENT, YEmbeddableMultiSelectionEndpoint.class, msgs);
			if (newMultiSelectionBindingEndpoint != null)
				msgs = ((InternalEObject)newMultiSelectionBindingEndpoint).eInverseAdd(this, CoreModelPackage.YEMBEDDABLE_MULTI_SELECTION_ENDPOINT__ELEMENT, YEmbeddableMultiSelectionEndpoint.class, msgs);
			msgs = basicSetMultiSelectionBindingEndpoint(newMultiSelectionBindingEndpoint, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT, newMultiSelectionBindingEndpoint, newMultiSelectionBindingEndpoint));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isUseBeanService()
	 *         <em>Use Bean Service</em>}' attribute
	 * @generated
	 */
	public boolean isUseBeanService() {
		return useBeanService;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newUseBeanService
	 *            the new cached value of the '{@link #isUseBeanService()
	 *            <em>Use Bean Service</em>}' attribute
	 * @generated
	 */
	public void setUseBeanService(boolean newUseBeanService) {
		boolean oldUseBeanService = useBeanService;
		useBeanService = newUseBeanService;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__USE_BEAN_SERVICE, oldUseBeanService, useBeanService));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSelectionType()
	 *         <em>Selection Type</em>}' attribute
	 * @generated
	 */
	public YSelectionType getSelectionType() {
		return selectionType;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSelectionType
	 *            the new cached value of the '{@link #getSelectionType()
	 *            <em>Selection Type</em>}' attribute
	 * @generated
	 */
	public void setSelectionType(YSelectionType newSelectionType) {
		YSelectionType oldSelectionType = selectionType;
		selectionType = newSelectionType == null ? SELECTION_TYPE_EDEFAULT : newSelectionType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SELECTION_TYPE, oldSelectionType, selectionType));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSelectionEventTopic()
	 *         <em>Selection Event Topic</em>}' attribute
	 * @generated
	 */
	public String getSelectionEventTopic() {
		return selectionEventTopic;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSelectionEventTopic
	 *            the new cached value of the '{@link #getSelectionEventTopic()
	 *            <em>Selection Event Topic</em>}' attribute
	 * @generated
	 */
	public void setSelectionEventTopic(String newSelectionEventTopic) {
		String oldSelectionEventTopic = selectionEventTopic;
		selectionEventTopic = newSelectionEventTopic;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SELECTION_EVENT_TOPIC, oldSelectionEventTopic, selectionEventTopic));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSelection()
	 *         <em>Selection</em>}' attribute
	 * @generated
	 */
	public Object getSelection() {
		return selection;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSelection
	 *            the new cached value of the '{@link #getSelection()
	 *            <em>Selection</em>}' attribute
	 * @generated
	 */
	public void setSelection(Object newSelection) {
		Object oldSelection = selection;
		selection = newSelection;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SELECTION, oldSelection, selection));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getMultiSelection()
	 *         <em>Multi Selection</em>}' attribute list
	 * @generated
	 */
	public EList<Object> getMultiSelection() {
		if (multiSelection == null) {
			multiSelection = new EDataTypeUniqueEList<Object>(Object.class, this, CxGridPackage.CX_GRID__MULTI_SELECTION);
		}
		return multiSelection;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCollection()
	 *         <em>Collection</em>}' attribute list
	 * @generated
	 */
	public EList<Object> getCollection() {
		if (collection == null) {
			collection = new EDataTypeUniqueEList<Object>(Object.class, this, CxGridPackage.CX_GRID__COLLECTION);
		}
		return collection;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getType() <em>Type</em>}'
	 *         attribute
	 * @generated
	 */
	public Class<?> getType() {
		return type;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newType
	 *            the new cached value of the '{@link #getType() <em>Type</em>}'
	 *            attribute
	 * @generated
	 */
	public void setType(Class<?> newType) {
		Class<?> oldType = type;
		type = newType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__TYPE, oldType, type));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEmfNsURI()
	 *         <em>Emf Ns URI</em>}' attribute
	 * @generated
	 */
	public String getEmfNsURI() {
		return emfNsURI;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEmfNsURI
	 *            the new cached value of the '{@link #getEmfNsURI()
	 *            <em>Emf Ns URI</em>}' attribute
	 * @generated
	 */
	public void setEmfNsURI(String newEmfNsURI) {
		String oldEmfNsURI = emfNsURI;
		emfNsURI = newEmfNsURI;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__EMF_NS_URI, oldEmfNsURI, emfNsURI));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTypeQualifiedName()
	 *         <em>Type Qualified Name</em>}' attribute
	 * @generated
	 */
	public String getTypeQualifiedName() {
		return typeQualifiedName;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newTypeQualifiedName
	 *            the new cached value of the '{@link #getTypeQualifiedName()
	 *            <em>Type Qualified Name</em>}' attribute
	 * @generated
	 */
	public void setTypeQualifiedName(String newTypeQualifiedName) {
		String oldTypeQualifiedName = typeQualifiedName;
		typeQualifiedName = newTypeQualifiedName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__TYPE_QUALIFIED_NAME, oldTypeQualifiedName, typeQualifiedName));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isEditorEnabled()
	 *         <em>Editor Enabled</em>}' attribute
	 * @generated
	 */
	public boolean isEditorEnabled() {
		return editorEnabled;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorEnabled
	 *            the new cached value of the '{@link #isEditorEnabled()
	 *            <em>Editor Enabled</em>}' attribute
	 * @generated
	 */
	public void setEditorEnabled(boolean newEditorEnabled) {
		boolean oldEditorEnabled = editorEnabled;
		editorEnabled = newEditorEnabled;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__EDITOR_ENABLED, oldEditorEnabled, editorEnabled));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getCellStyleGenerator()
	 *         <em>Cell Style Generator</em>}' containment reference
	 * @generated
	 */
	public CxGridCellStyleGenerator getCellStyleGenerator() {
		return cellStyleGenerator;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCellStyleGenerator
	 *            the new cell style generator
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetCellStyleGenerator(
			CxGridCellStyleGenerator newCellStyleGenerator,
			NotificationChain msgs) {
		CxGridCellStyleGenerator oldCellStyleGenerator = cellStyleGenerator;
		cellStyleGenerator = newCellStyleGenerator;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR, oldCellStyleGenerator, newCellStyleGenerator);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCellStyleGenerator
	 *            the new cached value of the '{@link #getCellStyleGenerator()
	 *            <em>Cell Style Generator</em>}' containment reference
	 * @generated
	 */
	public void setCellStyleGenerator(
			CxGridCellStyleGenerator newCellStyleGenerator) {
		if (newCellStyleGenerator != cellStyleGenerator) {
			NotificationChain msgs = null;
			if (cellStyleGenerator != null)
				msgs = ((InternalEObject)cellStyleGenerator).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR, null, msgs);
			if (newCellStyleGenerator != null)
				msgs = ((InternalEObject)newCellStyleGenerator).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR, null, msgs);
			msgs = basicSetCellStyleGenerator(newCellStyleGenerator, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR, newCellStyleGenerator, newCellStyleGenerator));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isFilteringVisible()
	 *         <em>Filtering Visible</em>}' attribute
	 * @generated
	 */
	public boolean isFilteringVisible() {
		return filteringVisible;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newFilteringVisible
	 *            the new cached value of the '{@link #isFilteringVisible()
	 *            <em>Filtering Visible</em>}' attribute
	 * @generated
	 */
	public void setFilteringVisible(boolean newFilteringVisible) {
		boolean oldFilteringVisible = filteringVisible;
		filteringVisible = newFilteringVisible;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__FILTERING_VISIBLE, oldFilteringVisible, filteringVisible));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isCustomFilters()
	 *         <em>Custom Filters</em>}' attribute
	 * @generated
	 */
	public boolean isCustomFilters() {
		return customFilters;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newCustomFilters
	 *            the new cached value of the '{@link #isCustomFilters()
	 *            <em>Custom Filters</em>}' attribute
	 * @generated
	 */
	public void setCustomFilters(boolean newCustomFilters) {
		boolean oldCustomFilters = customFilters;
		customFilters = newCustomFilters;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__CUSTOM_FILTERS, oldCustomFilters, customFilters));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getHeaders() <em>Headers</em>}'
	 *         containment reference list
	 * @generated
	 */
	public EList<CxGridHeaderRow> getHeaders() {
		if (headers == null) {
			headers = new EObjectContainmentEList<CxGridHeaderRow>(CxGridHeaderRow.class, this, CxGridPackage.CX_GRID__HEADERS);
		}
		return headers;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getColumns() <em>Columns</em>}'
	 *         containment reference list
	 * @generated
	 */
	public EList<CxGridColumn> getColumns() {
		if (columns == null) {
			columns = new EObjectContainmentEList<CxGridColumn>(CxGridColumn.class, this, CxGridPackage.CX_GRID__COLUMNS);
		}
		return columns;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSortOrder()
	 *         <em>Sort Order</em>}' containment reference list
	 * @generated
	 */
	public EList<CxGridSortable> getSortOrder() {
		if (sortOrder == null) {
			sortOrder = new EObjectContainmentEList<CxGridSortable>(CxGridSortable.class, this, CxGridPackage.CX_GRID__SORT_ORDER);
		}
		return sortOrder;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isColumnReorderingAllowed()
	 *         <em>Column Reordering Allowed</em>}' attribute
	 * @generated
	 */
	public boolean isColumnReorderingAllowed() {
		return columnReorderingAllowed;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newColumnReorderingAllowed
	 *            the new cached value of the '
	 *            {@link #isColumnReorderingAllowed()
	 *            <em>Column Reordering Allowed</em>}' attribute
	 * @generated
	 */
	public void setColumnReorderingAllowed(boolean newColumnReorderingAllowed) {
		boolean oldColumnReorderingAllowed = columnReorderingAllowed;
		columnReorderingAllowed = newColumnReorderingAllowed;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__COLUMN_REORDERING_ALLOWED, oldColumnReorderingAllowed, columnReorderingAllowed));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isFooterVisible()
	 *         <em>Footer Visible</em>}' attribute
	 * @generated
	 */
	public boolean isFooterVisible() {
		return footerVisible;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newFooterVisible
	 *            the new cached value of the '{@link #isFooterVisible()
	 *            <em>Footer Visible</em>}' attribute
	 * @generated
	 */
	public void setFooterVisible(boolean newFooterVisible) {
		boolean oldFooterVisible = footerVisible;
		footerVisible = newFooterVisible;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__FOOTER_VISIBLE, oldFooterVisible, footerVisible));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #isHeaderVisible()
	 *         <em>Header Visible</em>}' attribute
	 * @generated
	 */
	public boolean isHeaderVisible() {
		return headerVisible;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHeaderVisible
	 *            the new cached value of the '{@link #isHeaderVisible()
	 *            <em>Header Visible</em>}' attribute
	 * @generated
	 */
	public void setHeaderVisible(boolean newHeaderVisible) {
		boolean oldHeaderVisible = headerVisible;
		headerVisible = newHeaderVisible;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__HEADER_VISIBLE, oldHeaderVisible, headerVisible));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getFooters() <em>Footers</em>}'
	 *         containment reference list
	 * @generated
	 */
	public EList<CxGridFooterRow> getFooters() {
		if (footers == null) {
			footers = new EObjectContainmentEList<CxGridFooterRow>(CxGridFooterRow.class, this, CxGridPackage.CX_GRID__FOOTERS);
		}
		return footers;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEditorCancelI18nLabelKey()
	 *         <em>Editor Cancel I1 8n Label Key</em>}' attribute
	 * @generated
	 */
	public String getEditorCancelI18nLabelKey() {
		return editorCancelI18nLabelKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorCancelI18nLabelKey
	 *            the new cached value of the '
	 *            {@link #getEditorCancelI18nLabelKey()
	 *            <em>Editor Cancel I1 8n Label Key</em>}' attribute
	 * @generated
	 */
	public void setEditorCancelI18nLabelKey(String newEditorCancelI18nLabelKey) {
		String oldEditorCancelI18nLabelKey = editorCancelI18nLabelKey;
		editorCancelI18nLabelKey = newEditorCancelI18nLabelKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__EDITOR_CANCEL_I1_8N_LABEL_KEY, oldEditorCancelI18nLabelKey, editorCancelI18nLabelKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEditorSaveI18nLabelKey()
	 *         <em>Editor Save I1 8n Label Key</em>}' attribute
	 * @generated
	 */
	public String getEditorSaveI18nLabelKey() {
		return editorSaveI18nLabelKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorSaveI18nLabelKey
	 *            the new cached value of the '
	 *            {@link #getEditorSaveI18nLabelKey()
	 *            <em>Editor Save I1 8n Label Key</em>}' attribute
	 * @generated
	 */
	public void setEditorSaveI18nLabelKey(String newEditorSaveI18nLabelKey) {
		String oldEditorSaveI18nLabelKey = editorSaveI18nLabelKey;
		editorSaveI18nLabelKey = newEditorSaveI18nLabelKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__EDITOR_SAVE_I1_8N_LABEL_KEY, oldEditorSaveI18nLabelKey, editorSaveI18nLabelKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEditorSaved()
	 *         <em>Editor Saved</em>}' attribute
	 * @generated
	 */
	public Object getEditorSaved() {
		return editorSaved;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorSaved
	 *            the new cached value of the '{@link #getEditorSaved()
	 *            <em>Editor Saved</em>}' attribute
	 * @generated
	 */
	public void setEditorSaved(Object newEditorSaved) {
		Object oldEditorSaved = editorSaved;
		editorSaved = newEditorSaved;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__EDITOR_SAVED, oldEditorSaved, editorSaved));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public long getSetLastRefreshTime() {
		return setLastRefreshTime;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setSetLastRefreshTime(long newSetLastRefreshTime) {
		long oldSetLastRefreshTime = setLastRefreshTime;
		setLastRefreshTime = newSetLastRefreshTime;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID__SET_LAST_REFRESH_TIME, oldSetLastRefreshTime, setLastRefreshTime));
	}

	/**
	 * <!-- begin-user-doc -->
	 * 
	 * 
	 * <!-- end-user-doc -->.
	 *
	 * @return the y helper layout
	 */
	public YHelperLayout createEditorFieldHelperLayout() {
		YHelperLayout layout = CoreModelFactory.eINSTANCE.createYHelperLayout();
		for (CxGridColumn col : getColumns()) {
			if (col.getEditorField() != null) {
				layout.addElement(col.getEditorField());
			}
		}
		return layout;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.model.core.YMultiSelectionBindable#createMultiSelectionEndpoint()
	 */
	public YEmbeddableMultiSelectionEndpoint createMultiSelectionEndpoint() {
		YEmbeddableMultiSelectionEndpoint endpoint = CoreModelFactory.eINSTANCE
				.createYEmbeddableMultiSelectionEndpoint();
		endpoint.setElement(this);
		return endpoint;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.core.common.model.core.YSelectionBindable#createSelectionEndpoint()
	 */
	public YEmbeddableSelectionEndpoint createSelectionEndpoint() {
		YEmbeddableSelectionEndpoint endpoint = CoreModelFactory.eINSTANCE
				.createYEmbeddableSelectionEndpoint();
		endpoint.setElement(this);
		return endpoint;
	}

	/**
	 * Creates a collection endpoint to bind the input collection to the grid.
	 *
	 * @return the y embeddable collection endpoint
	 */
	public YEmbeddableCollectionEndpoint createCollectionEndpoint() {
		YEmbeddableCollectionEndpoint endpoint = CoreModelFactory.eINSTANCE
				.createYEmbeddableCollectionEndpoint();
		endpoint.setElement(this);
		return endpoint;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.CxGrid#createEditorUpdatedEndpoint()
	 */
	@Override
	public YValueBindingEndpoint createEditorUpdatedEndpoint() {
		YECViewModelValueBindingEndpoint endpoint = BindingFactory.eINSTANCE
				.createYECViewModelValueBindingEndpoint();
		endpoint.setElement(this);
		endpoint.getFeatures()
				.add((EStructuralFeature) CxGridPackage.Literals.CX_GRID__EDITOR_SAVED);
		return endpoint;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				if (collectionBindingEndpoint != null)
					msgs = ((InternalEObject)collectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_COLLECTION_ENDPOINT__ELEMENT, YEmbeddableCollectionEndpoint.class, msgs);
				return basicSetCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)otherEnd, msgs);
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				if (selectionBindingEndpoint != null)
					msgs = ((InternalEObject)selectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_SELECTION_ENDPOINT__ELEMENT, YEmbeddableSelectionEndpoint.class, msgs);
				return basicSetSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)otherEnd, msgs);
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				if (multiSelectionBindingEndpoint != null)
					msgs = ((InternalEObject)multiSelectionBindingEndpoint).eInverseRemove(this, CoreModelPackage.YEMBEDDABLE_MULTI_SELECTION_ENDPOINT__ELEMENT, YEmbeddableMultiSelectionEndpoint.class, msgs);
				return basicSetMultiSelectionBindingEndpoint((YEmbeddableMultiSelectionEndpoint)otherEnd, msgs);
		}
		return super.eInverseAdd(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param otherEnd
	 *            the other end
	 * @param featureID
	 *            the feature id
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				return basicSetCollectionBindingEndpoint(null, msgs);
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				return basicSetSelectionBindingEndpoint(null, msgs);
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				return basicSetMultiSelectionBindingEndpoint(null, msgs);
			case CxGridPackage.CX_GRID__COLUMNS:
				return ((InternalEList<?>)getColumns()).basicRemove(otherEnd, msgs);
			case CxGridPackage.CX_GRID__SORT_ORDER:
				return ((InternalEList<?>)getSortOrder()).basicRemove(otherEnd, msgs);
			case CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR:
				return basicSetCellStyleGenerator(null, msgs);
			case CxGridPackage.CX_GRID__HEADERS:
				return ((InternalEList<?>)getHeaders()).basicRemove(otherEnd, msgs);
			case CxGridPackage.CX_GRID__FOOTERS:
				return ((InternalEList<?>)getFooters()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param resolve
	 *            the resolve
	 * @param coreType
	 *            the core type
	 * @return the object
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				if (resolve) return getCollectionBindingEndpoint();
				return basicGetCollectionBindingEndpoint();
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				if (resolve) return getSelectionBindingEndpoint();
				return basicGetSelectionBindingEndpoint();
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				if (resolve) return getMultiSelectionBindingEndpoint();
				return basicGetMultiSelectionBindingEndpoint();
			case CxGridPackage.CX_GRID__USE_BEAN_SERVICE:
				return isUseBeanService();
			case CxGridPackage.CX_GRID__SELECTION_TYPE:
				return getSelectionType();
			case CxGridPackage.CX_GRID__SELECTION_EVENT_TOPIC:
				return getSelectionEventTopic();
			case CxGridPackage.CX_GRID__SELECTION:
				return getSelection();
			case CxGridPackage.CX_GRID__MULTI_SELECTION:
				return getMultiSelection();
			case CxGridPackage.CX_GRID__COLLECTION:
				return getCollection();
			case CxGridPackage.CX_GRID__TYPE:
				return getType();
			case CxGridPackage.CX_GRID__EMF_NS_URI:
				return getEmfNsURI();
			case CxGridPackage.CX_GRID__TYPE_QUALIFIED_NAME:
				return getTypeQualifiedName();
			case CxGridPackage.CX_GRID__COLUMNS:
				return getColumns();
			case CxGridPackage.CX_GRID__SORT_ORDER:
				return getSortOrder();
			case CxGridPackage.CX_GRID__COLUMN_REORDERING_ALLOWED:
				return isColumnReorderingAllowed();
			case CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR:
				return getCellStyleGenerator();
			case CxGridPackage.CX_GRID__FILTERING_VISIBLE:
				return isFilteringVisible();
			case CxGridPackage.CX_GRID__CUSTOM_FILTERS:
				return isCustomFilters();
			case CxGridPackage.CX_GRID__HEADERS:
				return getHeaders();
			case CxGridPackage.CX_GRID__HEADER_VISIBLE:
				return isHeaderVisible();
			case CxGridPackage.CX_GRID__FOOTERS:
				return getFooters();
			case CxGridPackage.CX_GRID__FOOTER_VISIBLE:
				return isFooterVisible();
			case CxGridPackage.CX_GRID__EDITOR_ENABLED:
				return isEditorEnabled();
			case CxGridPackage.CX_GRID__EDITOR_CANCEL_I1_8N_LABEL_KEY:
				return getEditorCancelI18nLabelKey();
			case CxGridPackage.CX_GRID__EDITOR_SAVE_I1_8N_LABEL_KEY:
				return getEditorSaveI18nLabelKey();
			case CxGridPackage.CX_GRID__EDITOR_SAVED:
				return getEditorSaved();
			case CxGridPackage.CX_GRID__SET_LAST_REFRESH_TIME:
				return getSetLastRefreshTime();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @param newValue
	 *            the new value
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				setCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)newValue);
				return;
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				setSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)newValue);
				return;
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				setMultiSelectionBindingEndpoint((YEmbeddableMultiSelectionEndpoint)newValue);
				return;
			case CxGridPackage.CX_GRID__USE_BEAN_SERVICE:
				setUseBeanService((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__SELECTION_TYPE:
				setSelectionType((YSelectionType)newValue);
				return;
			case CxGridPackage.CX_GRID__SELECTION_EVENT_TOPIC:
				setSelectionEventTopic((String)newValue);
				return;
			case CxGridPackage.CX_GRID__SELECTION:
				setSelection(newValue);
				return;
			case CxGridPackage.CX_GRID__MULTI_SELECTION:
				getMultiSelection().clear();
				getMultiSelection().addAll((Collection<? extends Object>)newValue);
				return;
			case CxGridPackage.CX_GRID__COLLECTION:
				getCollection().clear();
				getCollection().addAll((Collection<? extends Object>)newValue);
				return;
			case CxGridPackage.CX_GRID__TYPE:
				setType((Class<?>)newValue);
				return;
			case CxGridPackage.CX_GRID__EMF_NS_URI:
				setEmfNsURI((String)newValue);
				return;
			case CxGridPackage.CX_GRID__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName((String)newValue);
				return;
			case CxGridPackage.CX_GRID__COLUMNS:
				getColumns().clear();
				getColumns().addAll((Collection<? extends CxGridColumn>)newValue);
				return;
			case CxGridPackage.CX_GRID__SORT_ORDER:
				getSortOrder().clear();
				getSortOrder().addAll((Collection<? extends CxGridSortable>)newValue);
				return;
			case CxGridPackage.CX_GRID__COLUMN_REORDERING_ALLOWED:
				setColumnReorderingAllowed((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR:
				setCellStyleGenerator((CxGridCellStyleGenerator)newValue);
				return;
			case CxGridPackage.CX_GRID__FILTERING_VISIBLE:
				setFilteringVisible((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__CUSTOM_FILTERS:
				setCustomFilters((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__HEADERS:
				getHeaders().clear();
				getHeaders().addAll((Collection<? extends CxGridHeaderRow>)newValue);
				return;
			case CxGridPackage.CX_GRID__HEADER_VISIBLE:
				setHeaderVisible((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__FOOTERS:
				getFooters().clear();
				getFooters().addAll((Collection<? extends CxGridFooterRow>)newValue);
				return;
			case CxGridPackage.CX_GRID__FOOTER_VISIBLE:
				setFooterVisible((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__EDITOR_ENABLED:
				setEditorEnabled((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID__EDITOR_CANCEL_I1_8N_LABEL_KEY:
				setEditorCancelI18nLabelKey((String)newValue);
				return;
			case CxGridPackage.CX_GRID__EDITOR_SAVE_I1_8N_LABEL_KEY:
				setEditorSaveI18nLabelKey((String)newValue);
				return;
			case CxGridPackage.CX_GRID__EDITOR_SAVED:
				setEditorSaved(newValue);
				return;
			case CxGridPackage.CX_GRID__SET_LAST_REFRESH_TIME:
				setSetLastRefreshTime((Long)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				setCollectionBindingEndpoint((YEmbeddableCollectionEndpoint)null);
				return;
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				setSelectionBindingEndpoint((YEmbeddableSelectionEndpoint)null);
				return;
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				setMultiSelectionBindingEndpoint((YEmbeddableMultiSelectionEndpoint)null);
				return;
			case CxGridPackage.CX_GRID__USE_BEAN_SERVICE:
				setUseBeanService(USE_BEAN_SERVICE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__SELECTION_TYPE:
				setSelectionType(SELECTION_TYPE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__SELECTION_EVENT_TOPIC:
				setSelectionEventTopic(SELECTION_EVENT_TOPIC_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__SELECTION:
				setSelection(SELECTION_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__MULTI_SELECTION:
				getMultiSelection().clear();
				return;
			case CxGridPackage.CX_GRID__COLLECTION:
				getCollection().clear();
				return;
			case CxGridPackage.CX_GRID__TYPE:
				setType((Class<?>)null);
				return;
			case CxGridPackage.CX_GRID__EMF_NS_URI:
				setEmfNsURI(EMF_NS_URI_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName(TYPE_QUALIFIED_NAME_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__COLUMNS:
				getColumns().clear();
				return;
			case CxGridPackage.CX_GRID__SORT_ORDER:
				getSortOrder().clear();
				return;
			case CxGridPackage.CX_GRID__COLUMN_REORDERING_ALLOWED:
				setColumnReorderingAllowed(COLUMN_REORDERING_ALLOWED_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR:
				setCellStyleGenerator((CxGridCellStyleGenerator)null);
				return;
			case CxGridPackage.CX_GRID__FILTERING_VISIBLE:
				setFilteringVisible(FILTERING_VISIBLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__CUSTOM_FILTERS:
				setCustomFilters(CUSTOM_FILTERS_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__HEADERS:
				getHeaders().clear();
				return;
			case CxGridPackage.CX_GRID__HEADER_VISIBLE:
				setHeaderVisible(HEADER_VISIBLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__FOOTERS:
				getFooters().clear();
				return;
			case CxGridPackage.CX_GRID__FOOTER_VISIBLE:
				setFooterVisible(FOOTER_VISIBLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__EDITOR_ENABLED:
				setEditorEnabled(EDITOR_ENABLED_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__EDITOR_CANCEL_I1_8N_LABEL_KEY:
				setEditorCancelI18nLabelKey(EDITOR_CANCEL_I1_8N_LABEL_KEY_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__EDITOR_SAVE_I1_8N_LABEL_KEY:
				setEditorSaveI18nLabelKey(EDITOR_SAVE_I1_8N_LABEL_KEY_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__EDITOR_SAVED:
				setEditorSaved(EDITOR_SAVED_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID__SET_LAST_REFRESH_TIME:
				setSetLastRefreshTime(SET_LAST_REFRESH_TIME_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param featureID
	 *            the feature id
	 * @return true, if successful
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT:
				return collectionBindingEndpoint != null;
			case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT:
				return selectionBindingEndpoint != null;
			case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT:
				return multiSelectionBindingEndpoint != null;
			case CxGridPackage.CX_GRID__USE_BEAN_SERVICE:
				return useBeanService != USE_BEAN_SERVICE_EDEFAULT;
			case CxGridPackage.CX_GRID__SELECTION_TYPE:
				return selectionType != SELECTION_TYPE_EDEFAULT;
			case CxGridPackage.CX_GRID__SELECTION_EVENT_TOPIC:
				return SELECTION_EVENT_TOPIC_EDEFAULT == null ? selectionEventTopic != null : !SELECTION_EVENT_TOPIC_EDEFAULT.equals(selectionEventTopic);
			case CxGridPackage.CX_GRID__SELECTION:
				return SELECTION_EDEFAULT == null ? selection != null : !SELECTION_EDEFAULT.equals(selection);
			case CxGridPackage.CX_GRID__MULTI_SELECTION:
				return multiSelection != null && !multiSelection.isEmpty();
			case CxGridPackage.CX_GRID__COLLECTION:
				return collection != null && !collection.isEmpty();
			case CxGridPackage.CX_GRID__TYPE:
				return type != null;
			case CxGridPackage.CX_GRID__EMF_NS_URI:
				return EMF_NS_URI_EDEFAULT == null ? emfNsURI != null : !EMF_NS_URI_EDEFAULT.equals(emfNsURI);
			case CxGridPackage.CX_GRID__TYPE_QUALIFIED_NAME:
				return TYPE_QUALIFIED_NAME_EDEFAULT == null ? typeQualifiedName != null : !TYPE_QUALIFIED_NAME_EDEFAULT.equals(typeQualifiedName);
			case CxGridPackage.CX_GRID__COLUMNS:
				return columns != null && !columns.isEmpty();
			case CxGridPackage.CX_GRID__SORT_ORDER:
				return sortOrder != null && !sortOrder.isEmpty();
			case CxGridPackage.CX_GRID__COLUMN_REORDERING_ALLOWED:
				return columnReorderingAllowed != COLUMN_REORDERING_ALLOWED_EDEFAULT;
			case CxGridPackage.CX_GRID__CELL_STYLE_GENERATOR:
				return cellStyleGenerator != null;
			case CxGridPackage.CX_GRID__FILTERING_VISIBLE:
				return filteringVisible != FILTERING_VISIBLE_EDEFAULT;
			case CxGridPackage.CX_GRID__CUSTOM_FILTERS:
				return customFilters != CUSTOM_FILTERS_EDEFAULT;
			case CxGridPackage.CX_GRID__HEADERS:
				return headers != null && !headers.isEmpty();
			case CxGridPackage.CX_GRID__HEADER_VISIBLE:
				return headerVisible != HEADER_VISIBLE_EDEFAULT;
			case CxGridPackage.CX_GRID__FOOTERS:
				return footers != null && !footers.isEmpty();
			case CxGridPackage.CX_GRID__FOOTER_VISIBLE:
				return footerVisible != FOOTER_VISIBLE_EDEFAULT;
			case CxGridPackage.CX_GRID__EDITOR_ENABLED:
				return editorEnabled != EDITOR_ENABLED_EDEFAULT;
			case CxGridPackage.CX_GRID__EDITOR_CANCEL_I1_8N_LABEL_KEY:
				return EDITOR_CANCEL_I1_8N_LABEL_KEY_EDEFAULT == null ? editorCancelI18nLabelKey != null : !EDITOR_CANCEL_I1_8N_LABEL_KEY_EDEFAULT.equals(editorCancelI18nLabelKey);
			case CxGridPackage.CX_GRID__EDITOR_SAVE_I1_8N_LABEL_KEY:
				return EDITOR_SAVE_I1_8N_LABEL_KEY_EDEFAULT == null ? editorSaveI18nLabelKey != null : !EDITOR_SAVE_I1_8N_LABEL_KEY_EDEFAULT.equals(editorSaveI18nLabelKey);
			case CxGridPackage.CX_GRID__EDITOR_SAVED:
				return EDITOR_SAVED_EDEFAULT == null ? editorSaved != null : !EDITOR_SAVED_EDEFAULT.equals(editorSaved);
			case CxGridPackage.CX_GRID__SET_LAST_REFRESH_TIME:
				return setLastRefreshTime != SET_LAST_REFRESH_TIME_EDEFAULT;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param derivedFeatureID
	 *            the derived feature id
	 * @param baseClass
	 *            the base class
	 * @return the int
	 * @generated
	 */
	@Override
	public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (derivedFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YCollectionBindable.class) {
			switch (derivedFeatureID) {
				case CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT: return CoreModelPackage.YCOLLECTION_BINDABLE__COLLECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YSelectionBindable.class) {
			switch (derivedFeatureID) {
				case CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT: return CoreModelPackage.YSELECTION_BINDABLE__SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YMultiSelectionBindable.class) {
			switch (derivedFeatureID) {
				case CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT: return CoreModelPackage.YMULTI_SELECTION_BINDABLE__MULTI_SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YBeanServiceConsumer.class) {
			switch (derivedFeatureID) {
				case CxGridPackage.CX_GRID__USE_BEAN_SERVICE: return ExtensionModelPackage.YBEAN_SERVICE_CONSUMER__USE_BEAN_SERVICE;
				default: return -1;
			}
		}
		return super.eBaseStructuralFeatureID(derivedFeatureID, baseClass);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param baseFeatureID
	 *            the base feature id
	 * @param baseClass
	 *            the base class
	 * @return the int
	 * @generated
	 */
	@Override
	public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) {
		if (baseClass == YBindable.class) {
			switch (baseFeatureID) {
				default: return -1;
			}
		}
		if (baseClass == YCollectionBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YCOLLECTION_BINDABLE__COLLECTION_BINDING_ENDPOINT: return CxGridPackage.CX_GRID__COLLECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YSelectionBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YSELECTION_BINDABLE__SELECTION_BINDING_ENDPOINT: return CxGridPackage.CX_GRID__SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YMultiSelectionBindable.class) {
			switch (baseFeatureID) {
				case CoreModelPackage.YMULTI_SELECTION_BINDABLE__MULTI_SELECTION_BINDING_ENDPOINT: return CxGridPackage.CX_GRID__MULTI_SELECTION_BINDING_ENDPOINT;
				default: return -1;
			}
		}
		if (baseClass == YBeanServiceConsumer.class) {
			switch (baseFeatureID) {
				case ExtensionModelPackage.YBEAN_SERVICE_CONSUMER__USE_BEAN_SERVICE: return CxGridPackage.CX_GRID__USE_BEAN_SERVICE;
				default: return -1;
			}
		}
		return super.eDerivedStructuralFeatureID(baseFeatureID, baseClass);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (useBeanService: ");
		result.append(useBeanService);
		result.append(", selectionType: ");
		result.append(selectionType);
		result.append(", selectionEventTopic: ");
		result.append(selectionEventTopic);
		result.append(", selection: ");
		result.append(selection);
		result.append(", multiSelection: ");
		result.append(multiSelection);
		result.append(", collection: ");
		result.append(collection);
		result.append(", type: ");
		result.append(type);
		result.append(", emfNsURI: ");
		result.append(emfNsURI);
		result.append(", typeQualifiedName: ");
		result.append(typeQualifiedName);
		result.append(", columnReorderingAllowed: ");
		result.append(columnReorderingAllowed);
		result.append(", filteringVisible: ");
		result.append(filteringVisible);
		result.append(", customFilters: ");
		result.append(customFilters);
		result.append(", headerVisible: ");
		result.append(headerVisible);
		result.append(", footerVisible: ");
		result.append(footerVisible);
		result.append(", editorEnabled: ");
		result.append(editorEnabled);
		result.append(", editorCancelI18nLabelKey: ");
		result.append(editorCancelI18nLabelKey);
		result.append(", editorSaveI18nLabelKey: ");
		result.append(editorSaveI18nLabelKey);
		result.append(", editorSaved: ");
		result.append(editorSaved);
		result.append(", setLastRefreshTime: ");
		result.append(setLastRefreshTime);
		result.append(')');
		return result.toString();
	}
}