/**
 *                                                                            
 *  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.memento.impl;

import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMemento;
import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoColumn;
import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoPackage;
import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoSortable;
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.common.util.EMap;
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.impl.MinimalEObjectImpl;
import org.eclipse.emf.ecore.util.EDataTypeUniqueEList;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.EcoreEMap;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.osbp.ecview.core.common.model.core.CoreModelPackage;
import org.eclipse.osbp.ecview.core.common.model.core.impl.YStringToStringMapImpl;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Cx Grid Memento</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getTags <em>Tags</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getId <em>Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getName <em>Name</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getProperties <em>Properties</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getGridId <em>Grid Id</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#isHeaderVisible <em>Header Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#isFilterVisible <em>Filter Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#isFooterVisible <em>Footer Visible</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#isEditorEnabled <em>Editor Enabled</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getColumns <em>Columns</em>}</li>
 *   <li>{@link org.eclipse.osbp.ecview.extension.grid.memento.impl.CxGridMementoImpl#getSortOrders <em>Sort Orders</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CxGridMementoImpl extends MinimalEObjectImpl.Container implements CxGridMemento {
	
	/**
	 * The cached value of the '{@link #getTags() <em>Tags</em>}' attribute list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTags()
	 * @generated
	 * @ordered
	 */
	protected EList<String> tags;

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

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

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

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

	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' map.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected EMap<String, String> properties;

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

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

	/**
	 * 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 = false;

	/**
	 * 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 default value of the '{@link #isFilterVisible() <em>Filter Visible</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #isFilterVisible()
	 * @generated
	 * @ordered
	 */
	protected static final boolean FILTER_VISIBLE_EDEFAULT = false;

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

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

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

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

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

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newId
	 *            the new cached value of the '{@link #getId() <em>Id</em>}'
	 *            attribute
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridMementoPackage.CX_GRID_MEMENTO__ID, oldId, id));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newName
	 *            the new cached value of the '{@link #getName() <em>Name</em>}'
	 *            attribute
	 * @generated
	 */
	public void setName(String newName) {
		String oldName = name;
		name = newName;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridMementoPackage.CX_GRID_MEMENTO__NAME, oldName, name));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getTags() <em>Tags</em>}'
	 *         attribute list
	 * @generated
	 */
	public EList<String> getTags() {
		if (tags == null) {
			tags = new EDataTypeUniqueEList<String>(String.class, this, CxGridMementoPackage.CX_GRID_MEMENTO__TAGS);
		}
		return tags;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getProperties()
	 *         <em>Properties</em>}' map
	 * @generated
	 */
	public EMap<String, String> getProperties() {
		if (properties == null) {
			properties = new EcoreEMap<String,String>(CoreModelPackage.Literals.YSTRING_TO_STRING_MAP, YStringToStringMapImpl.class, this, CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES);
		}
		return properties;
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newGridId
	 *            the new cached value of the '{@link #getGridId()
	 *            <em>Grid Id</em>}' attribute
	 * @generated
	 */
	public void setGridId(String newGridId) {
		String oldGridId = gridId;
		gridId = newGridId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridMementoPackage.CX_GRID_MEMENTO__GRID_ID, oldGridId, gridId));
	}

	/**
	 * <!-- 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, CxGridMementoPackage.CX_GRID_MEMENTO__HEADER_VISIBLE, oldHeaderVisible, headerVisible));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @param newFilterVisible
	 *            the new cached value of the '{@link #isFilterVisible()
	 *            <em>Filter Visible</em>}' attribute
	 * @generated
	 */
	public void setFilterVisible(boolean newFilterVisible) {
		boolean oldFilterVisible = filterVisible;
		filterVisible = newFilterVisible;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CxGridMementoPackage.CX_GRID_MEMENTO__FILTER_VISIBLE, oldFilterVisible, filterVisible));
	}

	/**
	 * <!-- 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, CxGridMementoPackage.CX_GRID_MEMENTO__FOOTER_VISIBLE, oldFooterVisible, footerVisible));
	}

	/**
	 * <!-- 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, CxGridMementoPackage.CX_GRID_MEMENTO__EDITOR_ENABLED, oldEditorEnabled, editorEnabled));
	}

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

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->.
	 *
	 * @return the cached value of the '{@link #getSortOrders()
	 *         <em>Sort Orders</em>}' containment reference list
	 * @generated
	 */
	public EList<CxGridMementoSortable> getSortOrders() {
		if (sortOrders == null) {
			sortOrders = new EObjectContainmentEList<CxGridMementoSortable>(CxGridMementoSortable.class, this, CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS);
		}
		return sortOrders;
	}

	/**
	 * <!-- 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 CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES:
				return ((InternalEList<?>)getProperties()).basicRemove(otherEnd, msgs);
			case CxGridMementoPackage.CX_GRID_MEMENTO__COLUMNS:
				return ((InternalEList<?>)getColumns()).basicRemove(otherEnd, msgs);
			case CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS:
				return ((InternalEList<?>)getSortOrders()).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 CxGridMementoPackage.CX_GRID_MEMENTO__TAGS:
				return getTags();
			case CxGridMementoPackage.CX_GRID_MEMENTO__ID:
				return getId();
			case CxGridMementoPackage.CX_GRID_MEMENTO__NAME:
				return getName();
			case CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES:
				if (coreType) return getProperties();
				else return getProperties().map();
			case CxGridMementoPackage.CX_GRID_MEMENTO__GRID_ID:
				return getGridId();
			case CxGridMementoPackage.CX_GRID_MEMENTO__HEADER_VISIBLE:
				return isHeaderVisible();
			case CxGridMementoPackage.CX_GRID_MEMENTO__FILTER_VISIBLE:
				return isFilterVisible();
			case CxGridMementoPackage.CX_GRID_MEMENTO__FOOTER_VISIBLE:
				return isFooterVisible();
			case CxGridMementoPackage.CX_GRID_MEMENTO__EDITOR_ENABLED:
				return isEditorEnabled();
			case CxGridMementoPackage.CX_GRID_MEMENTO__COLUMNS:
				return getColumns();
			case CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS:
				return getSortOrders();
		}
		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 CxGridMementoPackage.CX_GRID_MEMENTO__TAGS:
				getTags().clear();
				getTags().addAll((Collection<? extends String>)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__ID:
				setId((String)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__NAME:
				setName((String)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES:
				((EStructuralFeature.Setting)getProperties()).set(newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__GRID_ID:
				setGridId((String)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__HEADER_VISIBLE:
				setHeaderVisible((Boolean)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FILTER_VISIBLE:
				setFilterVisible((Boolean)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FOOTER_VISIBLE:
				setFooterVisible((Boolean)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__EDITOR_ENABLED:
				setEditorEnabled((Boolean)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__COLUMNS:
				getColumns().clear();
				getColumns().addAll((Collection<? extends CxGridMementoColumn>)newValue);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS:
				getSortOrders().clear();
				getSortOrders().addAll((Collection<? extends CxGridMementoSortable>)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 CxGridMementoPackage.CX_GRID_MEMENTO__TAGS:
				getTags().clear();
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__ID:
				setId(ID_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__NAME:
				setName(NAME_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES:
				getProperties().clear();
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__GRID_ID:
				setGridId(GRID_ID_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__HEADER_VISIBLE:
				setHeaderVisible(HEADER_VISIBLE_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FILTER_VISIBLE:
				setFilterVisible(FILTER_VISIBLE_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FOOTER_VISIBLE:
				setFooterVisible(FOOTER_VISIBLE_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__EDITOR_ENABLED:
				setEditorEnabled(EDITOR_ENABLED_EDEFAULT);
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__COLUMNS:
				getColumns().clear();
				return;
			case CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS:
				getSortOrders().clear();
				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 CxGridMementoPackage.CX_GRID_MEMENTO__TAGS:
				return tags != null && !tags.isEmpty();
			case CxGridMementoPackage.CX_GRID_MEMENTO__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
			case CxGridMementoPackage.CX_GRID_MEMENTO__NAME:
				return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name);
			case CxGridMementoPackage.CX_GRID_MEMENTO__PROPERTIES:
				return properties != null && !properties.isEmpty();
			case CxGridMementoPackage.CX_GRID_MEMENTO__GRID_ID:
				return GRID_ID_EDEFAULT == null ? gridId != null : !GRID_ID_EDEFAULT.equals(gridId);
			case CxGridMementoPackage.CX_GRID_MEMENTO__HEADER_VISIBLE:
				return headerVisible != HEADER_VISIBLE_EDEFAULT;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FILTER_VISIBLE:
				return filterVisible != FILTER_VISIBLE_EDEFAULT;
			case CxGridMementoPackage.CX_GRID_MEMENTO__FOOTER_VISIBLE:
				return footerVisible != FOOTER_VISIBLE_EDEFAULT;
			case CxGridMementoPackage.CX_GRID_MEMENTO__EDITOR_ENABLED:
				return editorEnabled != EDITOR_ENABLED_EDEFAULT;
			case CxGridMementoPackage.CX_GRID_MEMENTO__COLUMNS:
				return columns != null && !columns.isEmpty();
			case CxGridMementoPackage.CX_GRID_MEMENTO__SORT_ORDERS:
				return sortOrders != null && !sortOrders.isEmpty();
		}
		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(" (tags: ");
		result.append(tags);
		result.append(", id: ");
		result.append(id);
		result.append(", name: ");
		result.append(name);
		result.append(", gridId: ");
		result.append(gridId);
		result.append(", headerVisible: ");
		result.append(headerVisible);
		result.append(", filterVisible: ");
		result.append(filterVisible);
		result.append(", footerVisible: ");
		result.append(footerVisible);
		result.append(", editorEnabled: ");
		result.append(editorEnabled);
		result.append(')');
		return result.toString();
	}

}