/**
 *   Copyright (c) 2016 CEA LIST and others.
 *   
 *   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:
 *     CEA LIST - Initial API and implementation
 * 
 */
package org.eclipse.papyrus.interoperability.rpy.rpymetamodel.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.EDataTypeEList;

import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIAnnotation;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CGIText;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.CompartmentsType;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.IColor;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.IPropertyContainer;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.IUnit;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.M_pRootType;
import org.eclipse.papyrus.interoperability.rpy.rpymetamodel.UMLRpyPackage;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>CGI Annotation</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getProperties <em>Properties</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_pParent <em>MpParent</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_transform <em>Mtransform</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_AdditionalLabel <em>MAdditional Label</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_polygon <em>Mpolygon</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_nNameFormat <em>MnName Format</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_nIsNameFormat <em>MnIs Name Format</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getITempdisplayTextFlag <em>ITempdisplay Text Flag</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_bIsBoxStyle <em>MbIs Box Style</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_pModelObject <em>MpModel Object</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_color <em>Mcolor</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_lineWidth <em>Mline Width</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getFrameset <em>Frameset</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getCompartments <em>Compartments</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_bIsStructured <em>MbIs Structured</em>}</li>
 *   <li>{@link org.eclipse.papyrus.interoperability.rpy.rpymetamodel.impl.CGIAnnotationImpl#getM_bFramesetModified <em>MbFrameset Modified</em>}</li>
 * </ul>
 *
 * @generated
 */
public class CGIAnnotationImpl extends GraphElementsTypeImpl implements CGIAnnotation {
	/**
	 * The cached value of the '{@link #getProperties() <em>Properties</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getProperties()
	 * @generated
	 * @ordered
	 */
	protected IPropertyContainer properties;

	/**
	 * The cached value of the '{@link #getM_pParent() <em>MpParent</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_pParent()
	 * @generated
	 * @ordered
	 */
	protected M_pRootType m_pParent;

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

	/**
	 * The cached value of the '{@link #getM_AdditionalLabel() <em>MAdditional Label</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_AdditionalLabel()
	 * @generated
	 * @ordered
	 */
	protected CGIText m_AdditionalLabel;

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

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

	/**
	 * The cached value of the '{@link #getM_nNameFormat() <em>MnName Format</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_nNameFormat()
	 * @generated
	 * @ordered
	 */
	protected String m_nNameFormat = MNNAME_FORMAT_EDEFAULT;

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

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

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

	/**
	 * The cached value of the '{@link #getITempdisplayTextFlag() <em>ITempdisplay Text Flag</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getITempdisplayTextFlag()
	 * @generated
	 * @ordered
	 */
	protected String iTempdisplayTextFlag = ITEMPDISPLAY_TEXT_FLAG_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getM_bIsBoxStyle() <em>MbIs Box Style</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_bIsBoxStyle()
	 * @generated
	 * @ordered
	 */
	protected String m_bIsBoxStyle = MBIS_BOX_STYLE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getM_pModelObject() <em>MpModel Object</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_pModelObject()
	 * @generated
	 * @ordered
	 */
	protected IUnit m_pModelObject;

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

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

	/**
	 * The cached value of the '{@link #getM_lineWidth() <em>Mline Width</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_lineWidth()
	 * @generated
	 * @ordered
	 */
	protected String m_lineWidth = MLINE_WIDTH_EDEFAULT;

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

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

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

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

	/**
	 * The cached value of the '{@link #getM_bIsStructured() <em>MbIs Structured</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_bIsStructured()
	 * @generated
	 * @ordered
	 */
	protected String m_bIsStructured = MBIS_STRUCTURED_EDEFAULT;

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

	/**
	 * The cached value of the '{@link #getM_bFramesetModified() <em>MbFrameset Modified</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getM_bFramesetModified()
	 * @generated
	 * @ordered
	 */
	protected String m_bFramesetModified = MBFRAMESET_MODIFIED_EDEFAULT;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return UMLRpyPackage.eINSTANCE.getCGIAnnotation();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IPropertyContainer getProperties() {
		if (properties != null && properties.eIsProxy()) {
			InternalEObject oldProperties = (InternalEObject)properties;
			properties = (IPropertyContainer)eResolveProxy(oldProperties);
			if (properties != oldProperties) {
				InternalEObject newProperties = (InternalEObject)properties;
				NotificationChain msgs = oldProperties.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, null, null);
				if (newProperties.eInternalContainer() == null) {
					msgs = newProperties.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, null, msgs);
				}
				if (msgs != null) msgs.dispatch();
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, oldProperties, properties));
			}
		}
		return properties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IPropertyContainer basicGetProperties() {
		return properties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetProperties(IPropertyContainer newProperties, NotificationChain msgs) {
		IPropertyContainer oldProperties = properties;
		properties = newProperties;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, oldProperties, newProperties);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setProperties(IPropertyContainer newProperties) {
		if (newProperties != properties) {
			NotificationChain msgs = null;
			if (properties != null)
				msgs = ((InternalEObject)properties).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, null, msgs);
			if (newProperties != null)
				msgs = ((InternalEObject)newProperties).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, null, msgs);
			msgs = basicSetProperties(newProperties, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__PROPERTIES, newProperties, newProperties));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public M_pRootType getM_pParent() {
		if (m_pParent != null && m_pParent.eIsProxy()) {
			InternalEObject oldM_pParent = (InternalEObject)m_pParent;
			m_pParent = (M_pRootType)eResolveProxy(oldM_pParent);
			if (m_pParent != oldM_pParent) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__MPPARENT, oldM_pParent, m_pParent));
			}
		}
		return m_pParent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public M_pRootType basicGetM_pParent() {
		return m_pParent;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_pParent(M_pRootType newM_pParent) {
		M_pRootType oldM_pParent = m_pParent;
		m_pParent = newM_pParent;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MPPARENT, oldM_pParent, m_pParent));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<String> getM_transform() {
		if (m_transform == null) {
			m_transform = new EDataTypeEList<String>(String.class, this, UMLRpyPackage.CGI_ANNOTATION__MTRANSFORM);
		}
		return m_transform;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CGIText getM_AdditionalLabel() {
		if (m_AdditionalLabel != null && m_AdditionalLabel.eIsProxy()) {
			InternalEObject oldM_AdditionalLabel = (InternalEObject)m_AdditionalLabel;
			m_AdditionalLabel = (CGIText)eResolveProxy(oldM_AdditionalLabel);
			if (m_AdditionalLabel != oldM_AdditionalLabel) {
				InternalEObject newM_AdditionalLabel = (InternalEObject)m_AdditionalLabel;
				NotificationChain msgs = oldM_AdditionalLabel.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, null, null);
				if (newM_AdditionalLabel.eInternalContainer() == null) {
					msgs = newM_AdditionalLabel.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, null, msgs);
				}
				if (msgs != null) msgs.dispatch();
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, oldM_AdditionalLabel, m_AdditionalLabel));
			}
		}
		return m_AdditionalLabel;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CGIText basicGetM_AdditionalLabel() {
		return m_AdditionalLabel;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetM_AdditionalLabel(CGIText newM_AdditionalLabel, NotificationChain msgs) {
		CGIText oldM_AdditionalLabel = m_AdditionalLabel;
		m_AdditionalLabel = newM_AdditionalLabel;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, oldM_AdditionalLabel, newM_AdditionalLabel);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_AdditionalLabel(CGIText newM_AdditionalLabel) {
		if (newM_AdditionalLabel != m_AdditionalLabel) {
			NotificationChain msgs = null;
			if (m_AdditionalLabel != null)
				msgs = ((InternalEObject)m_AdditionalLabel).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, null, msgs);
			if (newM_AdditionalLabel != null)
				msgs = ((InternalEObject)newM_AdditionalLabel).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, null, msgs);
			msgs = basicSetM_AdditionalLabel(newM_AdditionalLabel, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL, newM_AdditionalLabel, newM_AdditionalLabel));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<String> getM_polygon() {
		if (m_polygon == null) {
			m_polygon = new EDataTypeEList<String>(String.class, this, UMLRpyPackage.CGI_ANNOTATION__MPOLYGON);
		}
		return m_polygon;
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_nNameFormat(String newM_nNameFormat) {
		String oldM_nNameFormat = m_nNameFormat;
		m_nNameFormat = newM_nNameFormat;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MNNAME_FORMAT, oldM_nNameFormat, m_nNameFormat));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_nIsNameFormat(String newM_nIsNameFormat) {
		String oldM_nIsNameFormat = m_nIsNameFormat;
		m_nIsNameFormat = newM_nIsNameFormat;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MNIS_NAME_FORMAT, oldM_nIsNameFormat, m_nIsNameFormat));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setITempdisplayTextFlag(String newITempdisplayTextFlag) {
		String oldITempdisplayTextFlag = iTempdisplayTextFlag;
		iTempdisplayTextFlag = newITempdisplayTextFlag;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__ITEMPDISPLAY_TEXT_FLAG, oldITempdisplayTextFlag, iTempdisplayTextFlag));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_bIsBoxStyle(String newM_bIsBoxStyle) {
		String oldM_bIsBoxStyle = m_bIsBoxStyle;
		m_bIsBoxStyle = newM_bIsBoxStyle;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MBIS_BOX_STYLE, oldM_bIsBoxStyle, m_bIsBoxStyle));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IUnit getM_pModelObject() {
		if (m_pModelObject != null && m_pModelObject.eIsProxy()) {
			InternalEObject oldM_pModelObject = (InternalEObject)m_pModelObject;
			m_pModelObject = (IUnit)eResolveProxy(oldM_pModelObject);
			if (m_pModelObject != oldM_pModelObject) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT, oldM_pModelObject, m_pModelObject));
			}
		}
		return m_pModelObject;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IUnit basicGetM_pModelObject() {
		return m_pModelObject;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_pModelObject(IUnit newM_pModelObject) {
		IUnit oldM_pModelObject = m_pModelObject;
		m_pModelObject = newM_pModelObject;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT, oldM_pModelObject, m_pModelObject));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IColor getM_color() {
		if (m_color != null && m_color.eIsProxy()) {
			InternalEObject oldM_color = (InternalEObject)m_color;
			m_color = (IColor)eResolveProxy(oldM_color);
			if (m_color != oldM_color) {
				InternalEObject newM_color = (InternalEObject)m_color;
				NotificationChain msgs = oldM_color.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MCOLOR, null, null);
				if (newM_color.eInternalContainer() == null) {
					msgs = newM_color.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MCOLOR, null, msgs);
				}
				if (msgs != null) msgs.dispatch();
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__MCOLOR, oldM_color, m_color));
			}
		}
		return m_color;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IColor basicGetM_color() {
		return m_color;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetM_color(IColor newM_color, NotificationChain msgs) {
		IColor oldM_color = m_color;
		m_color = newM_color;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MCOLOR, oldM_color, newM_color);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_color(IColor newM_color) {
		if (newM_color != m_color) {
			NotificationChain msgs = null;
			if (m_color != null)
				msgs = ((InternalEObject)m_color).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MCOLOR, null, msgs);
			if (newM_color != null)
				msgs = ((InternalEObject)newM_color).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__MCOLOR, null, msgs);
			msgs = basicSetM_color(newM_color, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MCOLOR, newM_color, newM_color));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_lineWidth(String newM_lineWidth) {
		String oldM_lineWidth = m_lineWidth;
		m_lineWidth = newM_lineWidth;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MLINE_WIDTH, oldM_lineWidth, m_lineWidth));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setFrameset(String newFrameset) {
		String oldFrameset = frameset;
		frameset = newFrameset;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__FRAMESET, oldFrameset, frameset));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CompartmentsType getCompartments() {
		if (compartments != null && compartments.eIsProxy()) {
			InternalEObject oldCompartments = (InternalEObject)compartments;
			compartments = (CompartmentsType)eResolveProxy(oldCompartments);
			if (compartments != oldCompartments) {
				InternalEObject newCompartments = (InternalEObject)compartments;
				NotificationChain msgs = oldCompartments.eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, null, null);
				if (newCompartments.eInternalContainer() == null) {
					msgs = newCompartments.eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, null, msgs);
				}
				if (msgs != null) msgs.dispatch();
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, oldCompartments, compartments));
			}
		}
		return compartments;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public CompartmentsType basicGetCompartments() {
		return compartments;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetCompartments(CompartmentsType newCompartments, NotificationChain msgs) {
		CompartmentsType oldCompartments = compartments;
		compartments = newCompartments;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, oldCompartments, newCompartments);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setCompartments(CompartmentsType newCompartments) {
		if (newCompartments != compartments) {
			NotificationChain msgs = null;
			if (compartments != null)
				msgs = ((InternalEObject)compartments).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, null, msgs);
			if (newCompartments != null)
				msgs = ((InternalEObject)newCompartments).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, null, msgs);
			msgs = basicSetCompartments(newCompartments, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS, newCompartments, newCompartments));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_bIsStructured(String newM_bIsStructured) {
		String oldM_bIsStructured = m_bIsStructured;
		m_bIsStructured = newM_bIsStructured;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MBIS_STRUCTURED, oldM_bIsStructured, m_bIsStructured));
	}

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setM_bFramesetModified(String newM_bFramesetModified) {
		String oldM_bFramesetModified = m_bFramesetModified;
		m_bFramesetModified = newM_bFramesetModified;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, UMLRpyPackage.CGI_ANNOTATION__MBFRAMESET_MODIFIED, oldM_bFramesetModified, m_bFramesetModified));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case UMLRpyPackage.CGI_ANNOTATION__PROPERTIES:
				return basicSetProperties(null, msgs);
			case UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL:
				return basicSetM_AdditionalLabel(null, msgs);
			case UMLRpyPackage.CGI_ANNOTATION__MCOLOR:
				return basicSetM_color(null, msgs);
			case UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS:
				return basicSetCompartments(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case UMLRpyPackage.CGI_ANNOTATION__PROPERTIES:
				if (resolve) return getProperties();
				return basicGetProperties();
			case UMLRpyPackage.CGI_ANNOTATION__MPPARENT:
				if (resolve) return getM_pParent();
				return basicGetM_pParent();
			case UMLRpyPackage.CGI_ANNOTATION__MTRANSFORM:
				return getM_transform();
			case UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL:
				if (resolve) return getM_AdditionalLabel();
				return basicGetM_AdditionalLabel();
			case UMLRpyPackage.CGI_ANNOTATION__MPOLYGON:
				return getM_polygon();
			case UMLRpyPackage.CGI_ANNOTATION__MNNAME_FORMAT:
				return getM_nNameFormat();
			case UMLRpyPackage.CGI_ANNOTATION__MNIS_NAME_FORMAT:
				return getM_nIsNameFormat();
			case UMLRpyPackage.CGI_ANNOTATION__ITEMPDISPLAY_TEXT_FLAG:
				return getITempdisplayTextFlag();
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_BOX_STYLE:
				return getM_bIsBoxStyle();
			case UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT:
				if (resolve) return getM_pModelObject();
				return basicGetM_pModelObject();
			case UMLRpyPackage.CGI_ANNOTATION__MCOLOR:
				if (resolve) return getM_color();
				return basicGetM_color();
			case UMLRpyPackage.CGI_ANNOTATION__MLINE_WIDTH:
				return getM_lineWidth();
			case UMLRpyPackage.CGI_ANNOTATION__FRAMESET:
				return getFrameset();
			case UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS:
				if (resolve) return getCompartments();
				return basicGetCompartments();
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_STRUCTURED:
				return getM_bIsStructured();
			case UMLRpyPackage.CGI_ANNOTATION__MBFRAMESET_MODIFIED:
				return getM_bFramesetModified();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case UMLRpyPackage.CGI_ANNOTATION__PROPERTIES:
				setProperties((IPropertyContainer)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPPARENT:
				setM_pParent((M_pRootType)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MTRANSFORM:
				getM_transform().clear();
				getM_transform().addAll((Collection<? extends String>)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL:
				setM_AdditionalLabel((CGIText)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPOLYGON:
				getM_polygon().clear();
				getM_polygon().addAll((Collection<? extends String>)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MNNAME_FORMAT:
				setM_nNameFormat((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MNIS_NAME_FORMAT:
				setM_nIsNameFormat((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__ITEMPDISPLAY_TEXT_FLAG:
				setITempdisplayTextFlag((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_BOX_STYLE:
				setM_bIsBoxStyle((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT:
				setM_pModelObject((IUnit)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MCOLOR:
				setM_color((IColor)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MLINE_WIDTH:
				setM_lineWidth((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__FRAMESET:
				setFrameset((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS:
				setCompartments((CompartmentsType)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_STRUCTURED:
				setM_bIsStructured((String)newValue);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBFRAMESET_MODIFIED:
				setM_bFramesetModified((String)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case UMLRpyPackage.CGI_ANNOTATION__PROPERTIES:
				setProperties((IPropertyContainer)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPPARENT:
				setM_pParent((M_pRootType)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MTRANSFORM:
				getM_transform().clear();
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL:
				setM_AdditionalLabel((CGIText)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPOLYGON:
				getM_polygon().clear();
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MNNAME_FORMAT:
				setM_nNameFormat(MNNAME_FORMAT_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MNIS_NAME_FORMAT:
				setM_nIsNameFormat(MNIS_NAME_FORMAT_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__ITEMPDISPLAY_TEXT_FLAG:
				setITempdisplayTextFlag(ITEMPDISPLAY_TEXT_FLAG_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_BOX_STYLE:
				setM_bIsBoxStyle(MBIS_BOX_STYLE_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT:
				setM_pModelObject((IUnit)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MCOLOR:
				setM_color((IColor)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MLINE_WIDTH:
				setM_lineWidth(MLINE_WIDTH_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__FRAMESET:
				setFrameset(FRAMESET_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS:
				setCompartments((CompartmentsType)null);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_STRUCTURED:
				setM_bIsStructured(MBIS_STRUCTURED_EDEFAULT);
				return;
			case UMLRpyPackage.CGI_ANNOTATION__MBFRAMESET_MODIFIED:
				setM_bFramesetModified(MBFRAMESET_MODIFIED_EDEFAULT);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case UMLRpyPackage.CGI_ANNOTATION__PROPERTIES:
				return properties != null;
			case UMLRpyPackage.CGI_ANNOTATION__MPPARENT:
				return m_pParent != null;
			case UMLRpyPackage.CGI_ANNOTATION__MTRANSFORM:
				return m_transform != null && !m_transform.isEmpty();
			case UMLRpyPackage.CGI_ANNOTATION__MADDITIONAL_LABEL:
				return m_AdditionalLabel != null;
			case UMLRpyPackage.CGI_ANNOTATION__MPOLYGON:
				return m_polygon != null && !m_polygon.isEmpty();
			case UMLRpyPackage.CGI_ANNOTATION__MNNAME_FORMAT:
				return MNNAME_FORMAT_EDEFAULT == null ? m_nNameFormat != null : !MNNAME_FORMAT_EDEFAULT.equals(m_nNameFormat);
			case UMLRpyPackage.CGI_ANNOTATION__MNIS_NAME_FORMAT:
				return MNIS_NAME_FORMAT_EDEFAULT == null ? m_nIsNameFormat != null : !MNIS_NAME_FORMAT_EDEFAULT.equals(m_nIsNameFormat);
			case UMLRpyPackage.CGI_ANNOTATION__ITEMPDISPLAY_TEXT_FLAG:
				return ITEMPDISPLAY_TEXT_FLAG_EDEFAULT == null ? iTempdisplayTextFlag != null : !ITEMPDISPLAY_TEXT_FLAG_EDEFAULT.equals(iTempdisplayTextFlag);
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_BOX_STYLE:
				return MBIS_BOX_STYLE_EDEFAULT == null ? m_bIsBoxStyle != null : !MBIS_BOX_STYLE_EDEFAULT.equals(m_bIsBoxStyle);
			case UMLRpyPackage.CGI_ANNOTATION__MPMODEL_OBJECT:
				return m_pModelObject != null;
			case UMLRpyPackage.CGI_ANNOTATION__MCOLOR:
				return m_color != null;
			case UMLRpyPackage.CGI_ANNOTATION__MLINE_WIDTH:
				return MLINE_WIDTH_EDEFAULT == null ? m_lineWidth != null : !MLINE_WIDTH_EDEFAULT.equals(m_lineWidth);
			case UMLRpyPackage.CGI_ANNOTATION__FRAMESET:
				return FRAMESET_EDEFAULT == null ? frameset != null : !FRAMESET_EDEFAULT.equals(frameset);
			case UMLRpyPackage.CGI_ANNOTATION__COMPARTMENTS:
				return compartments != null;
			case UMLRpyPackage.CGI_ANNOTATION__MBIS_STRUCTURED:
				return MBIS_STRUCTURED_EDEFAULT == null ? m_bIsStructured != null : !MBIS_STRUCTURED_EDEFAULT.equals(m_bIsStructured);
			case UMLRpyPackage.CGI_ANNOTATION__MBFRAMESET_MODIFIED:
				return MBFRAMESET_MODIFIED_EDEFAULT == null ? m_bFramesetModified != null : !MBFRAMESET_MODIFIED_EDEFAULT.equals(m_bFramesetModified);
		}
		return super.eIsSet(featureID);
	}

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

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (m_transform: "); //$NON-NLS-1$
		result.append(m_transform);
		result.append(", m_polygon: "); //$NON-NLS-1$
		result.append(m_polygon);
		result.append(", m_nNameFormat: "); //$NON-NLS-1$
		result.append(m_nNameFormat);
		result.append(", m_nIsNameFormat: "); //$NON-NLS-1$
		result.append(m_nIsNameFormat);
		result.append(", iTempdisplayTextFlag: "); //$NON-NLS-1$
		result.append(iTempdisplayTextFlag);
		result.append(", m_bIsBoxStyle: "); //$NON-NLS-1$
		result.append(m_bIsBoxStyle);
		result.append(", m_lineWidth: "); //$NON-NLS-1$
		result.append(m_lineWidth);
		result.append(", frameset: "); //$NON-NLS-1$
		result.append(frameset);
		result.append(", m_bIsStructured: "); //$NON-NLS-1$
		result.append(m_bIsStructured);
		result.append(", m_bFramesetModified: "); //$NON-NLS-1$
		result.append(m_bFramesetModified);
		result.append(')');
		return result.toString();
	}

} //CGIAnnotationImpl
