/**
 *                                                                            
 *  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.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.EObjectWithInverseResolvingEList;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.core.YConverter;
import org.eclipse.osbp.ecview.core.common.model.core.YField;
import org.eclipse.osbp.ecview.core.common.model.core.YHelperLayout;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSearchField;
import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridColumn;
import org.eclipse.osbp.ecview.extension.grid.CxGridMetaCell;
import org.eclipse.osbp.ecview.extension.grid.CxGridPackage;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRenderer;
import org.eclipse.osbp.ecview.extension.grid.util.CxGridUtil;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>Column</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getPropertyId <em>Property Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getLabel <em>Label</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getLabelI18nKey <em>Label I1 8n Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#isEditable <em>Editable</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getConverter <em>Converter</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getRenderer <em>Renderer</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getEditorField <em>Editor Field</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getSearchField <em>Search Field</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getHeaderCaption <em>Header Caption</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getHeaderCaptionI18nKey <em>Header Caption I1 8n Key</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getExpandRatio <em>Expand Ratio</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#isHidden <em>Hidden</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#isHideable <em>Hideable</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#isSortable <em>Sortable</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getPropertyPath <em>Property Path</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getWidth <em>Width</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getMinWidthPixels <em>Min Width Pixels</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getMaxWidthPixels <em>Max Width Pixels</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getUsedInMetaCells <em>Used In Meta Cells</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getType <em>Type</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.impl.CxGridColumnImpl#getTypeQualifiedName <em>Type Qualified Name</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class CxGridColumnImpl extends CxGridGroupableImpl implements
		CxGridColumn {
	
	/**
	 * The default value of the '{@link #getPropertyId() <em>Property Id</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getPropertyId()
	 * @generated
	 * @ordered
	 */
	protected static final String PROPERTY_ID_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getPropertyId() <em>Property Id</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getPropertyId()
	 * @generated
	 * @ordered
	 */
	protected String propertyId = PROPERTY_ID_EDEFAULT;

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

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

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

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

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

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

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

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

	/**
	 * The cached value of the '{@link #getEditorField() <em>Editor Field</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEditorField()
	 * @generated
	 * @ordered
	 */
	protected YField editorField;

	/**
	 * The cached value of the '{@link #getSearchField() <em>Search Field</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getSearchField()
	 * @generated
	 * @ordered
	 */
	protected YSearchField searchField;

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

	/**
	 * The cached value of the '{@link #getHeaderCaption() <em>Header Caption</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getHeaderCaption()
	 * @generated
	 * @ordered
	 */
	protected String headerCaption = HEADER_CAPTION_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getHeaderCaptionI18nKey() <em>Header Caption I1 8n Key</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getHeaderCaptionI18nKey()
	 * @generated
	 * @ordered
	 */
	protected String headerCaptionI18nKey = HEADER_CAPTION_I1_8N_KEY_EDEFAULT;

	/**
	 * The default value of the '{@link #getExpandRatio() <em>Expand Ratio</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getExpandRatio()
	 * @generated
	 * @ordered
	 */
	protected static final int EXPAND_RATIO_EDEFAULT = -1;

	/**
	 * The cached value of the '{@link #getExpandRatio() <em>Expand Ratio</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getExpandRatio()
	 * @generated
	 * @ordered
	 */
	protected int expandRatio = EXPAND_RATIO_EDEFAULT;

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

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

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

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

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

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

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

	/**
	 * The cached value of the '{@link #getPropertyPath() <em>Property Path</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getPropertyPath()
	 * @generated
	 * @ordered
	 */
	protected String propertyPath = PROPERTY_PATH_EDEFAULT;

	/**
	 * The default value of the '{@link #getWidth() <em>Width</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getWidth()
	 * @generated
	 * @ordered
	 */
	protected static final int WIDTH_EDEFAULT = -1;

	/**
	 * The cached value of the '{@link #getWidth() <em>Width</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getWidth()
	 * @generated
	 * @ordered
	 */
	protected int width = WIDTH_EDEFAULT;

	/**
	 * The default value of the '{@link #getMinWidthPixels() <em>Min Width Pixels</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getMinWidthPixels()
	 * @generated
	 * @ordered
	 */
	protected static final int MIN_WIDTH_PIXELS_EDEFAULT = -1;

	/**
	 * The cached value of the '{@link #getMinWidthPixels() <em>Min Width Pixels</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getMinWidthPixels()
	 * @generated
	 * @ordered
	 */
	protected int minWidthPixels = MIN_WIDTH_PIXELS_EDEFAULT;

	/**
	 * The default value of the '{@link #getMaxWidthPixels() <em>Max Width Pixels</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getMaxWidthPixels()
	 * @generated
	 * @ordered
	 */
	protected static final int MAX_WIDTH_PIXELS_EDEFAULT = -1;

	/**
	 * The cached value of the '{@link #getMaxWidthPixels() <em>Max Width Pixels</em>}' attribute.
	 * <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * @see #getMaxWidthPixels()
	 * @generated
	 * @ordered
	 */
	protected int maxWidthPixels = MAX_WIDTH_PIXELS_EDEFAULT;

	/**
	 * The cached value of the '{@link #getUsedInMetaCells() <em>Used In Meta Cells</em>}' reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getUsedInMetaCells()
	 * @generated
	 * @ordered
	 */
	protected EList<CxGridMetaCell> usedInMetaCells;

	/**
	 * 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 #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;

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getPropertyId()
	 *         <em>Property Id</em>}' attribute
	 * @generated
	 */
	public String getPropertyId() {
		return propertyId;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newPropertyId
	 *            the new cached value of the '{@link #getPropertyId()
	 *            <em>Property Id</em>}' attribute
	 * @generated
	 */
	public void setPropertyId(String newPropertyId) {
		String oldPropertyId = propertyId;
		propertyId = newPropertyId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__PROPERTY_ID, oldPropertyId, propertyId));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getConverter()
	 *         <em>Converter</em>}' containment reference
	 * @generated
	 */
	public YConverter getConverter() {
		return converter;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newConverter
	 *            the new converter
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetConverter(YConverter newConverter,
			NotificationChain msgs) {
		YConverter oldConverter = converter;
		converter = newConverter;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__CONVERTER, oldConverter, newConverter);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newConverter
	 *            the new cached value of the '{@link #getConverter()
	 *            <em>Converter</em>}' containment reference
	 * @generated
	 */
	public void setConverter(YConverter newConverter) {
		if (newConverter != converter) {
			NotificationChain msgs = null;
			if (converter != null)
				msgs = ((InternalEObject)converter).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__CONVERTER, null, msgs);
			if (newConverter != null)
				msgs = ((InternalEObject)newConverter).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__CONVERTER, null, msgs);
			msgs = basicSetConverter(newConverter, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__CONVERTER, newConverter, newConverter));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getRenderer() <em>Renderer</em>}
	 *         ' containment reference
	 * @generated
	 */
	public CxGridRenderer getRenderer() {
		return renderer;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newRenderer
	 *            the new renderer
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetRenderer(CxGridRenderer newRenderer,
			NotificationChain msgs) {
		CxGridRenderer oldRenderer = renderer;
		renderer = newRenderer;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__RENDERER, oldRenderer, newRenderer);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newRenderer
	 *            the new cached value of the '{@link #getRenderer()
	 *            <em>Renderer</em>}' containment reference
	 * @generated
	 */
	public void setRenderer(CxGridRenderer newRenderer) {
		if (newRenderer != renderer) {
			NotificationChain msgs = null;
			if (renderer != null)
				msgs = ((InternalEObject)renderer).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__RENDERER, null, msgs);
			if (newRenderer != null)
				msgs = ((InternalEObject)newRenderer).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__RENDERER, null, msgs);
			msgs = basicSetRenderer(newRenderer, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__RENDERER, newRenderer, newRenderer));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getEditorField()
	 *         <em>Editor Field</em>}' containment reference
	 * @generated
	 */
	public YField getEditorField() {
		return editorField;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorField
	 *            the new editor field
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetEditorField(YField newEditorField,
			NotificationChain msgs) {
		YField oldEditorField = editorField;
		editorField = newEditorField;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD, oldEditorField, newEditorField);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditorField
	 *            the new cached value of the '{@link #getEditorField()
	 *            <em>Editor Field</em>}' containment reference
	 * @generated
	 */
	public void setEditorField(YField newEditorField) {
		if (newEditorField != editorField) {
			NotificationChain msgs = null;
			if (editorField != null)
				msgs = ((InternalEObject)editorField).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD, null, msgs);
			if (newEditorField != null)
				msgs = ((InternalEObject)newEditorField).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD, null, msgs);
			msgs = basicSetEditorField(newEditorField, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD, newEditorField, newEditorField));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSearchField()
	 *         <em>Search Field</em>}' containment reference
	 * @generated
	 */
	public YSearchField getSearchField() {
		return searchField;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSearchField
	 *            the new search field
	 * @param msgs
	 *            the msgs
	 * @return the notification chain
	 * @generated
	 */
	public NotificationChain basicSetSearchField(YSearchField newSearchField,
			NotificationChain msgs) {
		YSearchField oldSearchField = searchField;
		searchField = newSearchField;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD, oldSearchField, newSearchField);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSearchField
	 *            the new cached value of the '{@link #getSearchField()
	 *            <em>Search Field</em>}' containment reference
	 * @generated
	 */
	public void setSearchField(YSearchField newSearchField) {
		if (newSearchField != searchField) {
			NotificationChain msgs = null;
			if (searchField != null)
				msgs = ((InternalEObject)searchField).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD, null, msgs);
			if (newSearchField != null)
				msgs = ((InternalEObject)newSearchField).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD, null, msgs);
			msgs = basicSetSearchField(newSearchField, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD, newSearchField, newSearchField));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getHeaderCaption()
	 *         <em>Header Caption</em>}' attribute
	 * @generated
	 */
	public String getHeaderCaption() {
		return headerCaption;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHeaderCaption
	 *            the new cached value of the '{@link #getHeaderCaption()
	 *            <em>Header Caption</em>}' attribute
	 * @generated
	 */
	public void setHeaderCaption(String newHeaderCaption) {
		String oldHeaderCaption = headerCaption;
		headerCaption = newHeaderCaption;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION, oldHeaderCaption, headerCaption));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getHeaderCaptionI18nKey()
	 *         <em>Header Caption I1 8n Key</em>}' attribute
	 * @generated
	 */
	public String getHeaderCaptionI18nKey() {
		return headerCaptionI18nKey;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHeaderCaptionI18nKey
	 *            the new cached value of the '
	 *            {@link #getHeaderCaptionI18nKey()
	 *            <em>Header Caption I1 8n Key</em>}' attribute
	 * @generated
	 */
	public void setHeaderCaptionI18nKey(String newHeaderCaptionI18nKey) {
		String oldHeaderCaptionI18nKey = headerCaptionI18nKey;
		headerCaptionI18nKey = newHeaderCaptionI18nKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION_I1_8N_KEY, oldHeaderCaptionI18nKey, headerCaptionI18nKey));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getExpandRatio()
	 *         <em>Expand Ratio</em>}' attribute
	 * @generated
	 */
	public int getExpandRatio() {
		return expandRatio;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newExpandRatio
	 *            the new cached value of the '{@link #getExpandRatio()
	 *            <em>Expand Ratio</em>}' attribute
	 * @generated
	 */
	public void setExpandRatio(int newExpandRatio) {
		int oldExpandRatio = expandRatio;
		expandRatio = newExpandRatio;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__EXPAND_RATIO, oldExpandRatio, expandRatio));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHidden
	 *            the new cached value of the '{@link #isHidden()
	 *            <em>Hidden</em>}' attribute
	 * @generated
	 */
	public void setHidden(boolean newHidden) {
		boolean oldHidden = hidden;
		hidden = newHidden;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__HIDDEN, oldHidden, hidden));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newHideable
	 *            the new cached value of the '{@link #isHideable()
	 *            <em>Hideable</em>}' attribute
	 * @generated
	 */
	public void setHideable(boolean newHideable) {
		boolean oldHideable = hideable;
		hideable = newHideable;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__HIDEABLE, oldHideable, hideable));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newSortable
	 *            the new cached value of the '{@link #isSortable()
	 *            <em>Sortable</em>}' attribute
	 * @generated
	 */
	public void setSortable(boolean newSortable) {
		boolean oldSortable = sortable;
		sortable = newSortable;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__SORTABLE, oldSortable, sortable));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getPropertyPath()
	 *         <em>Property Path</em>}' attribute
	 * @generated
	 */
	public String getPropertyPath() {
		return propertyPath;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newPropertyPath
	 *            the new cached value of the '{@link #getPropertyPath()
	 *            <em>Property Path</em>}' attribute
	 * @generated
	 */
	public void setPropertyPath(String newPropertyPath) {
		String oldPropertyPath = propertyPath;
		propertyPath = newPropertyPath;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__PROPERTY_PATH, oldPropertyPath, propertyPath));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getWidth() <em>Width</em>}'
	 *         attribute
	 * @generated
	 */
	public int getWidth() {
		return width;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newWidth
	 *            the new cached value of the '{@link #getWidth()
	 *            <em>Width</em>}' attribute
	 * @generated
	 */
	public void setWidth(int newWidth) {
		int oldWidth = width;
		width = newWidth;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__WIDTH, oldWidth, width));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getLabel() <em>Label</em>}'
	 *         attribute
	 * @generated
	 */
	public String getLabel() {
		return label;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLabel
	 *            the new cached value of the '{@link #getLabel()
	 *            <em>Label</em>}' attribute
	 * @generated
	 */
	public void setLabel(String newLabel) {
		String oldLabel = label;
		label = newLabel;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__LABEL, oldLabel, label));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newLabelI18nKey
	 *            the new cached value of the '{@link #getLabelI18nKey()
	 *            <em>Label I1 8n Key</em>}' attribute
	 * @generated
	 */
	public void setLabelI18nKey(String newLabelI18nKey) {
		String oldLabelI18nKey = labelI18nKey;
		labelI18nKey = newLabelI18nKey;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__LABEL_I1_8N_KEY, oldLabelI18nKey, labelI18nKey));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newEditable
	 *            the new cached value of the '{@link #isEditable()
	 *            <em>Editable</em>}' attribute
	 * @generated
	 */
	public void setEditable(boolean newEditable) {
		boolean oldEditable = editable;
		editable = newEditable;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__EDITABLE, oldEditable, editable));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getMinWidthPixels()
	 *         <em>Min Width Pixels</em>}' attribute
	 * @generated
	 */
	public int getMinWidthPixels() {
		return minWidthPixels;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newMinWidthPixels
	 *            the new cached value of the '{@link #getMinWidthPixels()
	 *            <em>Min Width Pixels</em>}' attribute
	 * @generated
	 */
	public void setMinWidthPixels(int newMinWidthPixels) {
		int oldMinWidthPixels = minWidthPixels;
		minWidthPixels = newMinWidthPixels;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__MIN_WIDTH_PIXELS, oldMinWidthPixels, minWidthPixels));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getMaxWidthPixels()
	 *         <em>Max Width Pixels</em>}' attribute
	 * @generated
	 */
	public int getMaxWidthPixels() {
		return maxWidthPixels;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newMaxWidthPixels
	 *            the new cached value of the '{@link #getMaxWidthPixels()
	 *            <em>Max Width Pixels</em>}' attribute
	 * @generated
	 */
	public void setMaxWidthPixels(int newMaxWidthPixels) {
		int oldMaxWidthPixels = maxWidthPixels;
		maxWidthPixels = newMaxWidthPixels;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridPackage.CX_GRID_COLUMN__MAX_WIDTH_PIXELS, oldMaxWidthPixels, maxWidthPixels));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getUsedInMetaCells()
	 *         <em>Used In Meta Cells</em>}' reference list
	 * @generated
	 */
	public EList<CxGridMetaCell> getUsedInMetaCells() {
		if (usedInMetaCells == null) {
			usedInMetaCells = new EObjectWithInverseResolvingEList<CxGridMetaCell>(CxGridMetaCell.class, this, CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS, CxGridPackage.CX_GRID_META_CELL__TARGET);
		}
		return usedInMetaCells;
	}

	/**
	 * <!-- 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_COLUMN__TYPE, oldType, type));
	}

	/**
	 * <!-- 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_COLUMN__TYPE_QUALIFIED_NAME, oldTypeQualifiedName, typeQualifiedName));
	}

	/**
	 * <!-- begin-user-doc --> Returns the layout which contains the editor
	 * fields. <!-- end-user-doc -->
	 *
	 * @return the helper layout
	 */
	public YHelperLayout getHelperLayout() {
		return getGrid() != null ? getGrid().createEditorFieldHelperLayout() : null;
	}

	/**
	 * <!-- 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
	 */
	@SuppressWarnings("unchecked")
	@Override
	public NotificationChain eInverseAdd(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				return ((InternalEList<InternalEObject>)(InternalEList<?>)getUsedInMetaCells()).basicAdd(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_COLUMN__CONVERTER:
				return basicSetConverter(null, msgs);
			case CxGridPackage.CX_GRID_COLUMN__RENDERER:
				return basicSetRenderer(null, msgs);
			case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
				return basicSetEditorField(null, msgs);
			case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
				return basicSetSearchField(null, msgs);
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				return ((InternalEList<?>)getUsedInMetaCells()).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_COLUMN__PROPERTY_ID:
				return getPropertyId();
			case CxGridPackage.CX_GRID_COLUMN__LABEL:
				return getLabel();
			case CxGridPackage.CX_GRID_COLUMN__LABEL_I1_8N_KEY:
				return getLabelI18nKey();
			case CxGridPackage.CX_GRID_COLUMN__EDITABLE:
				return isEditable();
			case CxGridPackage.CX_GRID_COLUMN__CONVERTER:
				return getConverter();
			case CxGridPackage.CX_GRID_COLUMN__RENDERER:
				return getRenderer();
			case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
				return getEditorField();
			case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
				return getSearchField();
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION:
				return getHeaderCaption();
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION_I1_8N_KEY:
				return getHeaderCaptionI18nKey();
			case CxGridPackage.CX_GRID_COLUMN__EXPAND_RATIO:
				return getExpandRatio();
			case CxGridPackage.CX_GRID_COLUMN__HIDDEN:
				return isHidden();
			case CxGridPackage.CX_GRID_COLUMN__HIDEABLE:
				return isHideable();
			case CxGridPackage.CX_GRID_COLUMN__SORTABLE:
				return isSortable();
			case CxGridPackage.CX_GRID_COLUMN__PROPERTY_PATH:
				return getPropertyPath();
			case CxGridPackage.CX_GRID_COLUMN__WIDTH:
				return getWidth();
			case CxGridPackage.CX_GRID_COLUMN__MIN_WIDTH_PIXELS:
				return getMinWidthPixels();
			case CxGridPackage.CX_GRID_COLUMN__MAX_WIDTH_PIXELS:
				return getMaxWidthPixels();
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				return getUsedInMetaCells();
			case CxGridPackage.CX_GRID_COLUMN__TYPE:
				return getType();
			case CxGridPackage.CX_GRID_COLUMN__TYPE_QUALIFIED_NAME:
				return getTypeQualifiedName();
		}
		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_COLUMN__PROPERTY_ID:
				setPropertyId((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__LABEL:
				setLabel((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__LABEL_I1_8N_KEY:
				setLabelI18nKey((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EDITABLE:
				setEditable((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__CONVERTER:
				setConverter((YConverter)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__RENDERER:
				setRenderer((CxGridRenderer)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
				setEditorField((YField)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
				setSearchField((YSearchField)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION:
				setHeaderCaption((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION_I1_8N_KEY:
				setHeaderCaptionI18nKey((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EXPAND_RATIO:
				setExpandRatio((Integer)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HIDDEN:
				setHidden((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HIDEABLE:
				setHideable((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__SORTABLE:
				setSortable((Boolean)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__PROPERTY_PATH:
				setPropertyPath((String)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__WIDTH:
				setWidth((Integer)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__MIN_WIDTH_PIXELS:
				setMinWidthPixels((Integer)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__MAX_WIDTH_PIXELS:
				setMaxWidthPixels((Integer)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				getUsedInMetaCells().clear();
				getUsedInMetaCells().addAll((Collection<? extends CxGridMetaCell>)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__TYPE:
				setType((Class<?>)newValue);
				return;
			case CxGridPackage.CX_GRID_COLUMN__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName((String)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_COLUMN__PROPERTY_ID:
				setPropertyId(PROPERTY_ID_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__LABEL:
				setLabel(LABEL_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__LABEL_I1_8N_KEY:
				setLabelI18nKey(LABEL_I1_8N_KEY_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EDITABLE:
				setEditable(EDITABLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__CONVERTER:
				setConverter((YConverter)null);
				return;
			case CxGridPackage.CX_GRID_COLUMN__RENDERER:
				setRenderer((CxGridRenderer)null);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
				setEditorField((YField)null);
				return;
			case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
				setSearchField((YSearchField)null);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION:
				setHeaderCaption(HEADER_CAPTION_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION_I1_8N_KEY:
				setHeaderCaptionI18nKey(HEADER_CAPTION_I1_8N_KEY_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__EXPAND_RATIO:
				setExpandRatio(EXPAND_RATIO_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HIDDEN:
				setHidden(HIDDEN_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__HIDEABLE:
				setHideable(HIDEABLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__SORTABLE:
				setSortable(SORTABLE_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__PROPERTY_PATH:
				setPropertyPath(PROPERTY_PATH_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__WIDTH:
				setWidth(WIDTH_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__MIN_WIDTH_PIXELS:
				setMinWidthPixels(MIN_WIDTH_PIXELS_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__MAX_WIDTH_PIXELS:
				setMaxWidthPixels(MAX_WIDTH_PIXELS_EDEFAULT);
				return;
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				getUsedInMetaCells().clear();
				return;
			case CxGridPackage.CX_GRID_COLUMN__TYPE:
				setType((Class<?>)null);
				return;
			case CxGridPackage.CX_GRID_COLUMN__TYPE_QUALIFIED_NAME:
				setTypeQualifiedName(TYPE_QUALIFIED_NAME_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_COLUMN__PROPERTY_ID:
				return PROPERTY_ID_EDEFAULT == null ? propertyId != null : !PROPERTY_ID_EDEFAULT.equals(propertyId);
			case CxGridPackage.CX_GRID_COLUMN__LABEL:
				return LABEL_EDEFAULT == null ? label != null : !LABEL_EDEFAULT.equals(label);
			case CxGridPackage.CX_GRID_COLUMN__LABEL_I1_8N_KEY:
				return LABEL_I1_8N_KEY_EDEFAULT == null ? labelI18nKey != null : !LABEL_I1_8N_KEY_EDEFAULT.equals(labelI18nKey);
			case CxGridPackage.CX_GRID_COLUMN__EDITABLE:
				return editable != EDITABLE_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__CONVERTER:
				return converter != null;
			case CxGridPackage.CX_GRID_COLUMN__RENDERER:
				return renderer != null;
			case CxGridPackage.CX_GRID_COLUMN__EDITOR_FIELD:
				return editorField != null;
			case CxGridPackage.CX_GRID_COLUMN__SEARCH_FIELD:
				return searchField != null;
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION:
				return HEADER_CAPTION_EDEFAULT == null ? headerCaption != null : !HEADER_CAPTION_EDEFAULT.equals(headerCaption);
			case CxGridPackage.CX_GRID_COLUMN__HEADER_CAPTION_I1_8N_KEY:
				return HEADER_CAPTION_I1_8N_KEY_EDEFAULT == null ? headerCaptionI18nKey != null : !HEADER_CAPTION_I1_8N_KEY_EDEFAULT.equals(headerCaptionI18nKey);
			case CxGridPackage.CX_GRID_COLUMN__EXPAND_RATIO:
				return expandRatio != EXPAND_RATIO_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__HIDDEN:
				return hidden != HIDDEN_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__HIDEABLE:
				return hideable != HIDEABLE_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__SORTABLE:
				return sortable != SORTABLE_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__PROPERTY_PATH:
				return PROPERTY_PATH_EDEFAULT == null ? propertyPath != null : !PROPERTY_PATH_EDEFAULT.equals(propertyPath);
			case CxGridPackage.CX_GRID_COLUMN__WIDTH:
				return width != WIDTH_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__MIN_WIDTH_PIXELS:
				return minWidthPixels != MIN_WIDTH_PIXELS_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__MAX_WIDTH_PIXELS:
				return maxWidthPixels != MAX_WIDTH_PIXELS_EDEFAULT;
			case CxGridPackage.CX_GRID_COLUMN__USED_IN_META_CELLS:
				return usedInMetaCells != null && !usedInMetaCells.isEmpty();
			case CxGridPackage.CX_GRID_COLUMN__TYPE:
				return type != null;
			case CxGridPackage.CX_GRID_COLUMN__TYPE_QUALIFIED_NAME:
				return TYPE_QUALIFIED_NAME_EDEFAULT == null ? typeQualifiedName != null : !TYPE_QUALIFIED_NAME_EDEFAULT.equals(typeQualifiedName);
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- 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(" (propertyId: ");
		result.append(propertyId);
		result.append(", label: ");
		result.append(label);
		result.append(", labelI18nKey: ");
		result.append(labelI18nKey);
		result.append(", editable: ");
		result.append(editable);
		result.append(", headerCaption: ");
		result.append(headerCaption);
		result.append(", headerCaptionI18nKey: ");
		result.append(headerCaptionI18nKey);
		result.append(", expandRatio: ");
		result.append(expandRatio);
		result.append(", hidden: ");
		result.append(hidden);
		result.append(", hideable: ");
		result.append(hideable);
		result.append(", sortable: ");
		result.append(sortable);
		result.append(", propertyPath: ");
		result.append(propertyPath);
		result.append(", width: ");
		result.append(width);
		result.append(", minWidthPixels: ");
		result.append(minWidthPixels);
		result.append(", maxWidthPixels: ");
		result.append(maxWidthPixels);
		result.append(", type: ");
		result.append(type);
		result.append(", typeQualifiedName: ");
		result.append(typeQualifiedName);
		result.append(')');
		return result.toString();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.osbp.ecview.extension.grid.impl.CxGridGroupableImpl#getGrid()
	 */
	@Override
	public CxGrid getGrid() {
		return CxGridUtil.getGrid(this);
	}

}