/**
 * *******************************************************************************
 *  Copyright (c) 2017 Timing-Architects Embedded Systems GmbH 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
 * 
 *     Generated using Eclipse EMF
 * 
 * *******************************************************************************
 */
package org.eclipse.app4mc.amalthea.generator.configuration.impl;

import org.eclipse.app4mc.amalthea.generator.configuration.IntegerDistribution;
import org.eclipse.app4mc.amalthea.generator.configuration.PercentageDistribution;
import org.eclipse.app4mc.amalthea.generator.configuration.RTMGCPackage;
import org.eclipse.app4mc.amalthea.generator.configuration.RunnableProperties;
import org.eclipse.app4mc.amalthea.generator.configuration.RuntimeType;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.MinimalEObjectImpl;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Runnable Properties</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * </p>
 * <ul>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getRuntimeType <em>Runtime Type</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getInstructionsPerRunnables <em>Instructions Per Runnables</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getRunnablesPerCallSequence <em>Runnables Per Call Sequence</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getRunnablesPerSWC <em>Runnables Per SWC</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getMinStatisticsDistance <em>Min Statistics Distance</em>}</li>
 *   <li>{@link org.eclipse.app4mc.amalthea.generator.configuration.impl.RunnablePropertiesImpl#getMaxStatisticsDistance <em>Max Statistics Distance</em>}</li>
 * </ul>
 *
 * @generated
 */
public class RunnablePropertiesImpl extends MinimalEObjectImpl.Container implements RunnableProperties {
	/**
	 * The default value of the '{@link #getRuntimeType() <em>Runtime Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRuntimeType()
	 * @generated
	 * @ordered
	 */
	protected static final RuntimeType RUNTIME_TYPE_EDEFAULT = RuntimeType.INSTRUCTIONS_CONST;

	/**
	 * The cached value of the '{@link #getRuntimeType() <em>Runtime Type</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRuntimeType()
	 * @generated
	 * @ordered
	 */
	protected RuntimeType runtimeType = RUNTIME_TYPE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getInstructionsPerRunnables() <em>Instructions Per Runnables</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getInstructionsPerRunnables()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution instructionsPerRunnables;

	/**
	 * The cached value of the '{@link #getRunnablesPerCallSequence() <em>Runnables Per Call Sequence</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRunnablesPerCallSequence()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution runnablesPerCallSequence;

	/**
	 * The cached value of the '{@link #getRunnablesPerSWC() <em>Runnables Per SWC</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getRunnablesPerSWC()
	 * @generated
	 * @ordered
	 */
	protected IntegerDistribution runnablesPerSWC;

	/**
	 * The cached value of the '{@link #getMinStatisticsDistance() <em>Min Statistics Distance</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMinStatisticsDistance()
	 * @generated
	 * @ordered
	 */
	protected PercentageDistribution minStatisticsDistance;

	/**
	 * The cached value of the '{@link #getMaxStatisticsDistance() <em>Max Statistics Distance</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getMaxStatisticsDistance()
	 * @generated
	 * @ordered
	 */
	protected PercentageDistribution maxStatisticsDistance;

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

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return RTMGCPackage.Literals.RUNNABLE_PROPERTIES;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public RuntimeType getRuntimeType() {
		return runtimeType;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRuntimeType(RuntimeType newRuntimeType) {
		RuntimeType oldRuntimeType = runtimeType;
		runtimeType = newRuntimeType == null ? RUNTIME_TYPE_EDEFAULT : newRuntimeType;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__RUNTIME_TYPE, oldRuntimeType, runtimeType));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerDistribution getInstructionsPerRunnables() {
		return instructionsPerRunnables;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetInstructionsPerRunnables(IntegerDistribution newInstructionsPerRunnables, NotificationChain msgs) {
		IntegerDistribution oldInstructionsPerRunnables = instructionsPerRunnables;
		instructionsPerRunnables = newInstructionsPerRunnables;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES, oldInstructionsPerRunnables, newInstructionsPerRunnables);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setInstructionsPerRunnables(IntegerDistribution newInstructionsPerRunnables) {
		if (newInstructionsPerRunnables != instructionsPerRunnables) {
			NotificationChain msgs = null;
			if (instructionsPerRunnables != null)
				msgs = ((InternalEObject)instructionsPerRunnables).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES, null, msgs);
			if (newInstructionsPerRunnables != null)
				msgs = ((InternalEObject)newInstructionsPerRunnables).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES, null, msgs);
			msgs = basicSetInstructionsPerRunnables(newInstructionsPerRunnables, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES, newInstructionsPerRunnables, newInstructionsPerRunnables));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerDistribution getRunnablesPerCallSequence() {
		return runnablesPerCallSequence;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetRunnablesPerCallSequence(IntegerDistribution newRunnablesPerCallSequence, NotificationChain msgs) {
		IntegerDistribution oldRunnablesPerCallSequence = runnablesPerCallSequence;
		runnablesPerCallSequence = newRunnablesPerCallSequence;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE, oldRunnablesPerCallSequence, newRunnablesPerCallSequence);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRunnablesPerCallSequence(IntegerDistribution newRunnablesPerCallSequence) {
		if (newRunnablesPerCallSequence != runnablesPerCallSequence) {
			NotificationChain msgs = null;
			if (runnablesPerCallSequence != null)
				msgs = ((InternalEObject)runnablesPerCallSequence).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE, null, msgs);
			if (newRunnablesPerCallSequence != null)
				msgs = ((InternalEObject)newRunnablesPerCallSequence).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE, null, msgs);
			msgs = basicSetRunnablesPerCallSequence(newRunnablesPerCallSequence, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE, newRunnablesPerCallSequence, newRunnablesPerCallSequence));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public IntegerDistribution getRunnablesPerSWC() {
		return runnablesPerSWC;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetRunnablesPerSWC(IntegerDistribution newRunnablesPerSWC, NotificationChain msgs) {
		IntegerDistribution oldRunnablesPerSWC = runnablesPerSWC;
		runnablesPerSWC = newRunnablesPerSWC;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC, oldRunnablesPerSWC, newRunnablesPerSWC);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setRunnablesPerSWC(IntegerDistribution newRunnablesPerSWC) {
		if (newRunnablesPerSWC != runnablesPerSWC) {
			NotificationChain msgs = null;
			if (runnablesPerSWC != null)
				msgs = ((InternalEObject)runnablesPerSWC).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC, null, msgs);
			if (newRunnablesPerSWC != null)
				msgs = ((InternalEObject)newRunnablesPerSWC).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC, null, msgs);
			msgs = basicSetRunnablesPerSWC(newRunnablesPerSWC, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC, newRunnablesPerSWC, newRunnablesPerSWC));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PercentageDistribution getMinStatisticsDistance() {
		return minStatisticsDistance;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMinStatisticsDistance(PercentageDistribution newMinStatisticsDistance, NotificationChain msgs) {
		PercentageDistribution oldMinStatisticsDistance = minStatisticsDistance;
		minStatisticsDistance = newMinStatisticsDistance;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE, oldMinStatisticsDistance, newMinStatisticsDistance);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMinStatisticsDistance(PercentageDistribution newMinStatisticsDistance) {
		if (newMinStatisticsDistance != minStatisticsDistance) {
			NotificationChain msgs = null;
			if (minStatisticsDistance != null)
				msgs = ((InternalEObject)minStatisticsDistance).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE, null, msgs);
			if (newMinStatisticsDistance != null)
				msgs = ((InternalEObject)newMinStatisticsDistance).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE, null, msgs);
			msgs = basicSetMinStatisticsDistance(newMinStatisticsDistance, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE, newMinStatisticsDistance, newMinStatisticsDistance));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PercentageDistribution getMaxStatisticsDistance() {
		return maxStatisticsDistance;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public NotificationChain basicSetMaxStatisticsDistance(PercentageDistribution newMaxStatisticsDistance, NotificationChain msgs) {
		PercentageDistribution oldMaxStatisticsDistance = maxStatisticsDistance;
		maxStatisticsDistance = newMaxStatisticsDistance;
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE, oldMaxStatisticsDistance, newMaxStatisticsDistance);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setMaxStatisticsDistance(PercentageDistribution newMaxStatisticsDistance) {
		if (newMaxStatisticsDistance != maxStatisticsDistance) {
			NotificationChain msgs = null;
			if (maxStatisticsDistance != null)
				msgs = ((InternalEObject)maxStatisticsDistance).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE, null, msgs);
			if (newMaxStatisticsDistance != null)
				msgs = ((InternalEObject)newMaxStatisticsDistance).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE, null, msgs);
			msgs = basicSetMaxStatisticsDistance(newMaxStatisticsDistance, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE, newMaxStatisticsDistance, newMaxStatisticsDistance));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES:
				return basicSetInstructionsPerRunnables(null, msgs);
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE:
				return basicSetRunnablesPerCallSequence(null, msgs);
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC:
				return basicSetRunnablesPerSWC(null, msgs);
			case RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE:
				return basicSetMinStatisticsDistance(null, msgs);
			case RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE:
				return basicSetMaxStatisticsDistance(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 RTMGCPackage.RUNNABLE_PROPERTIES__RUNTIME_TYPE:
				return getRuntimeType();
			case RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES:
				return getInstructionsPerRunnables();
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE:
				return getRunnablesPerCallSequence();
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC:
				return getRunnablesPerSWC();
			case RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE:
				return getMinStatisticsDistance();
			case RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE:
				return getMaxStatisticsDistance();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNTIME_TYPE:
				setRuntimeType((RuntimeType)newValue);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES:
				setInstructionsPerRunnables((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE:
				setRunnablesPerCallSequence((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC:
				setRunnablesPerSWC((IntegerDistribution)newValue);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE:
				setMinStatisticsDistance((PercentageDistribution)newValue);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE:
				setMaxStatisticsDistance((PercentageDistribution)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNTIME_TYPE:
				setRuntimeType(RUNTIME_TYPE_EDEFAULT);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES:
				setInstructionsPerRunnables((IntegerDistribution)null);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE:
				setRunnablesPerCallSequence((IntegerDistribution)null);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC:
				setRunnablesPerSWC((IntegerDistribution)null);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE:
				setMinStatisticsDistance((PercentageDistribution)null);
				return;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE:
				setMaxStatisticsDistance((PercentageDistribution)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNTIME_TYPE:
				return runtimeType != RUNTIME_TYPE_EDEFAULT;
			case RTMGCPackage.RUNNABLE_PROPERTIES__INSTRUCTIONS_PER_RUNNABLES:
				return instructionsPerRunnables != null;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_CALL_SEQUENCE:
				return runnablesPerCallSequence != null;
			case RTMGCPackage.RUNNABLE_PROPERTIES__RUNNABLES_PER_SWC:
				return runnablesPerSWC != null;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MIN_STATISTICS_DISTANCE:
				return minStatisticsDistance != null;
			case RTMGCPackage.RUNNABLE_PROPERTIES__MAX_STATISTICS_DISTANCE:
				return maxStatisticsDistance != null;
		}
		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(" (runtimeType: ");
		result.append(runtimeType);
		result.append(')');
		return result.toString();
	}

} //RunnablePropertiesImpl
