Finished ATDB -> stimuli import.

Change-Id: I1d56b6e6820c144e51592a706c10fd552ba09a64
Signed-off-by: Raphael Weber <raphael.weber@vector.com>
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AConverter.java
new file mode 100644
index 0000000..e85e415
--- /dev/null
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AConverter.java
@@ -0,0 +1,30 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2020 Eclipse APP4MC contributors.
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ ********************************************************************************
+ */
+
+package org.eclipse.app4mc.amalthea._import.atdb;
+
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+public abstract class AConverter implements IRunnableWithProgress {
+	
+	protected final Amalthea model;
+	protected final ATDBConnection con;
+
+	public AConverter(final Amalthea model, final ATDBConnection con) {
+		this.model = model;
+		this.con = con;
+	}
+
+}
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/HWConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/HWConverter.java
index fd70c46..493ad0e 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/HWConverter.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/HWConverter.java
@@ -30,16 +30,11 @@
 import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
 import org.eclipse.app4mc.atdb.ATDBConnection;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 
-public class HWConverter implements IRunnableWithProgress {
-	
-	private final Amalthea model;
-	private final ATDBConnection con;
+public class HWConverter extends AConverter {
 
 	public HWConverter(final Amalthea model, final ATDBConnection con) {
-		this.model = model;
-		this.con = con;
+		super(model, con);
 	}
 
 	@Override
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ImportTransformation.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ImportTransformation.java
index e1b5d1f..c9d1306 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ImportTransformation.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ImportTransformation.java
@@ -55,7 +55,7 @@
 		if (this.atdbSource.isEmpty() || this.amxmiFile.isEmpty()) {
 			return;
 		}
-		final SubMonitor subMon = SubMonitor.convert(progressMonitor, "Creating AMALTHEA model from ATDB...", 5);
+		final SubMonitor subMon = SubMonitor.convert(progressMonitor, "Creating AMALTHEA model from ATDB...", 8);
 
 		final SubMonitor openATDBMonitor = subMon.split(1);
 		final Path amxmiFilePath = Paths.get(this.amxmiFile);
@@ -96,14 +96,16 @@
 					this.extractRunnableRuntimes, this.extractLabelsAndAccesses, freqInHz);
 			runnableConverter.run(runConvMonitor);
 			
+			// stimuli
+			final SubMonitor stimConvMonitor = subMon.split(1);
+			final IRunnableWithProgress stimulusConverter = new StimulusConverter(model, con);
+			stimulusConverter.run(stimConvMonitor);
+			
 			// processes
 			final SubMonitor procConvMonitor = subMon.split(1);
 			final IRunnableWithProgress processConverter = new ProcessConverter(model, con);
 			processConverter.run(procConvMonitor);
 			
-			// stimuli
-			final SubMonitor stimConvMonitor = subMon.split(1);
-			
 			// events
 			final SubMonitor evConvMonitor = subMon.split(1);
 			
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/LabelConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/LabelConverter.java
index f507b61..b63cbb1 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/LabelConverter.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/LabelConverter.java
@@ -25,17 +25,13 @@
 import org.eclipse.app4mc.amalthea.model.util.CustomPropertyUtil;
 import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
 import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.app4mc.atdb.EntityProperty;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 
-public class LabelConverter implements IRunnableWithProgress {
-	
-	private final Amalthea model;
-	private final ATDBConnection con;
+public class LabelConverter extends AConverter {
 
 	public LabelConverter(final Amalthea model, final ATDBConnection con) {
-		this.model = model;
-		this.con = con;
+		super(model, con);
 	}
 
 	@Override
@@ -52,7 +48,7 @@
 			for(final Label label:labels) {
 				final String initialValue = this.con.getLabelInitialValue(label.getName());
 				if (initialValue.length() > 0) {
-					CustomPropertyUtil.customPut(label, "initialValue", initialValue);
+					CustomPropertyUtil.customPut(label, EntityProperty.INITIAL_VALUE.camelName, initialValue);
 				}
 			}
 			progressMonitor.worked(1);
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ProcessConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ProcessConverter.java
index 524c2a6..de4f3dd 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ProcessConverter.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/ProcessConverter.java
@@ -1,3 +1,16 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2020 Eclipse APP4MC contributors.
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ ********************************************************************************
+ */
+
 package org.eclipse.app4mc.amalthea._import.atdb;
 
 import java.lang.reflect.InvocationTargetException;
@@ -13,20 +26,16 @@
 import org.eclipse.app4mc.amalthea.model.Runnable;
 import org.eclipse.app4mc.amalthea.model.RunnableCall;
 import org.eclipse.app4mc.amalthea.model.SWModel;
+import org.eclipse.app4mc.amalthea.model.Stimulus;
 import org.eclipse.app4mc.amalthea.model.Task;
 import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
 import org.eclipse.app4mc.atdb.ATDBConnection;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 
-public class ProcessConverter implements IRunnableWithProgress {
-	
-	private final Amalthea model;
-	private final ATDBConnection con;
+public class ProcessConverter extends AConverter {
 
 	public ProcessConverter(final Amalthea model, final ATDBConnection con) {
-		this.model = model;
-		this.con = con;
+		super(model, con);
 	}
 
 	@Override
@@ -41,6 +50,7 @@
 					isrName, ISR.class)));
 			
 			for(final Process proc:processes) {
+				// fill activity graph
 				final ActivityGraph ag = ModelUtil.getOrCreateActivityGraph(proc);
 				this.con.getRunnablesOfProcess(proc.getName()).forEach(runnableName -> 
 					AmaltheaModelUtil.getOrAddNewWithContainer(ag,
@@ -48,6 +58,10 @@
 							AmaltheaPackage.eINSTANCE.getRunnableCall(),
 							AmaltheaPackage.eINSTANCE.getRunnableCall_Runnable(), Runnable.class,
 							AmaltheaPackage.eINSTANCE.getRunnable(), runnableName).getKey());
+				
+				// connect stimuli
+				this.con.getStimuliOfProcess(proc.getName()).forEach(stimulusName ->
+					AmaltheaModelUtil.getOrAddNew(proc, AmaltheaPackage.eINSTANCE.getProcess_Stimuli(), stimulusName, Stimulus.class));
 			}
 			
 			progressMonitor.worked(1);
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/RunnableConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/RunnableConverter.java
index caf8be1..512d362 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/RunnableConverter.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/RunnableConverter.java
@@ -37,21 +37,20 @@
 import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
 import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil;
 import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.app4mc.atdb.MetricAggregation;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 
-public class RunnableConverter implements IRunnableWithProgress {
+public class RunnableConverter extends AConverter {
 	
-	private final Amalthea model;
-	private final ATDBConnection con;
+	private static final String rt = "runningTime_";
+	
 	private final boolean extractRuntimes;
 	private final boolean extractLabelAccesses;
 	private final Frequency frequency;
 
 	public RunnableConverter(final Amalthea model, final ATDBConnection con,
 			final boolean extractRuntimes, final boolean extractLabelAccesses, final double frequencyInHz) {
-		this.model = model;
-		this.con = con;
+		super(model, con);
 		this.extractRuntimes = extractRuntimes;
 		this.extractLabelAccesses = extractLabelAccesses;
 		this.frequency = FactoryUtil.createFrequency(frequencyInHz, FrequencyUnit.HZ);
@@ -90,20 +89,20 @@
 					double runningTimeAvg = -1;
 					double runningTimeStDev = -1;
 					try {
-						runningTimeAvg = Double.parseDouble(this.con.getValueForMetricAndEntity(runnable.getName(), "runningTime_Avg"));
-						runningTimeStDev = Double.parseDouble(this.con.getValueForMetricAndEntity(runnable.getName(), "runningTime_StDev"));
+						runningTimeAvg = Double.parseDouble(this.con.getValueForMetricAndEntity(runnable.getName(), rt + MetricAggregation.Avg));
+						runningTimeStDev = Double.parseDouble(this.con.getValueForMetricAndEntity(runnable.getName(), rt + MetricAggregation.StDev));
 					} catch (NumberFormatException e) {
 						// fail silently
 					}
 					try {
-						final long runningTimeMin = Long.parseLong(this.con.getValueForMetricAndEntity(runnable.getName(), "runningTime_Min"));
-						final long runningTimeMax = Long.parseLong(this.con.getValueForMetricAndEntity(runnable.getName(), "runningTime_Max"));
+						final long runningTimeMin = Long.parseLong(this.con.getValueForMetricAndEntity(runnable.getName(), rt + MetricAggregation.Min));
+						final long runningTimeMax = Long.parseLong(this.con.getValueForMetricAndEntity(runnable.getName(), rt + MetricAggregation.Max));
 						final Ticks ticks = AmaltheaFactory.eINSTANCE.createTicks();
 						IDiscreteValueDeviation dvd;
 						if (runningTimeMin == runningTimeMax) {
-							double constTicks = RuntimeUtil.getTicksForExecutionTime(FactoryUtil.createTime(runningTimeMin, timeBase),
-									this.frequency);
-							dvd = FactoryUtil.createDiscreteValueConstant((long)constTicks);
+							final long constTicks = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
+									AmaltheaServices.convertToSeconds(runningTimeMin, timeBase), this.frequency);
+							dvd = FactoryUtil.createDiscreteValueConstant(constTicks);
 						} else {
 							final long ticksMin = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
 									AmaltheaServices.convertToSeconds(runningTimeMin, timeBase), this.frequency);
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/StimulusConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/StimulusConverter.java
new file mode 100644
index 0000000..2ec964c
--- /dev/null
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/StimulusConverter.java
@@ -0,0 +1,104 @@
+/**
+ ********************************************************************************
+ * Copyright (c) 2020 Eclipse APP4MC contributors.
+ * 
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ ********************************************************************************
+ */
+
+package org.eclipse.app4mc.amalthea._import.atdb;
+
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
+import org.eclipse.app4mc.amalthea.model.ITimeDeviation;
+import org.eclipse.app4mc.amalthea.model.PeriodicStimulus;
+import org.eclipse.app4mc.amalthea.model.StimuliModel;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
+import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.app4mc.atdb.MetricAggregation;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class StimulusConverter extends AConverter {
+	
+	private static final String a2a = "activateToActivate_";
+
+	public StimulusConverter(final Amalthea model, final ATDBConnection con) {
+		super(model, con);
+	}
+
+	@Override
+	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
+		progressMonitor.beginTask("Converting stimuli", 1);
+		final StimuliModel stimuliModel = ModelUtil.getOrCreateStimuliModel(this.model);
+		try {
+			final TimeUnit timeBase = TimeUnit.getByName(this.con.getTimeBase().toLowerCase());
+			
+			final List<PeriodicStimulus> stimuli = new ArrayList<>();
+			this.con.getAllStimuli().forEach(stimulusName -> {
+				final PeriodicStimulus stimulus = AmaltheaModelUtil.getOrAddNew(stimuliModel,
+						AmaltheaPackage.eINSTANCE.getStimuliModel_Stimuli(), stimulusName, PeriodicStimulus.class,
+						AmaltheaPackage.eINSTANCE.getPeriodicStimulus());
+				stimuli.add(stimulus);
+			});
+			
+			for(final PeriodicStimulus stimulus:stimuli) {
+				double periodAvg = -1;
+				double periodStDev = -1;
+				try {
+					periodAvg = Double.parseDouble(this.con.getValueForMetricAndEntity(stimulus.getName(), a2a + MetricAggregation.Avg));
+					periodStDev = Double.parseDouble(this.con.getValueForMetricAndEntity(stimulus.getName(), a2a + MetricAggregation.StDev));
+				} catch (NumberFormatException e) {
+					// fail silently
+				}
+				try {
+					final long periodMin = Long.parseLong(this.con.getValueForMetricAndEntity(stimulus.getName(), a2a + MetricAggregation.Min));
+					final long periodMax = Long.parseLong(this.con.getValueForMetricAndEntity(stimulus.getName(), a2a + MetricAggregation.Max));
+					if (periodMin == periodMax) {
+						final Time recurrence = FactoryUtil.createTime(periodMin, timeBase).adjustUnit();
+						stimulus.setRecurrence(recurrence);
+					} else {
+						if (periodAvg <= -1) {
+							periodAvg = (double)(periodMin + periodMax) / 2d;
+						}
+						final Time avgRecurrence = FactoryUtil.createTime(periodAvg, timeBase).adjustUnit();
+						stimulus.setRecurrence(avgRecurrence);
+						final Time minJitter = FactoryUtil.createTime(periodAvg - periodMin, timeBase).adjustUnit();
+						final Time maxJitter = FactoryUtil.createTime(periodAvg - periodMax, timeBase).adjustUnit();
+						ITimeDeviation jitterDev;
+						if (periodStDev >= 0) {
+							final Time stDevJitter = FactoryUtil.createTime(periodStDev, timeBase).adjustUnit();
+							final Time avgZeroJitter = FactoryUtil.createTime(0, timeBase).adjustUnit();
+							jitterDev = FactoryUtil.createTimeGaussDistribution(avgZeroJitter, stDevJitter, minJitter, maxJitter);
+						} else {
+							jitterDev = FactoryUtil.createTimeBoundaries(minJitter, maxJitter);
+						}
+						stimulus.setJitter(jitterDev);
+					}
+				} catch (NumberFormatException e) {
+					// fail silently
+				}
+			}
+			
+			progressMonitor.worked(1);
+		} catch (SQLException e) {
+			throw new InvocationTargetException(e);
+		} finally {
+			progressMonitor.done();
+		}
+		
+	}
+
+}
diff --git a/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/ATDBMetricCalculator.java b/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/ATDBMetricCalculator.java
index efc1726..974b177 100644
--- a/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/ATDBMetricCalculator.java
+++ b/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/ATDBMetricCalculator.java
@@ -20,6 +20,7 @@
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -31,6 +32,7 @@
 import org.eclipse.app4mc.atdb._import.btf.model.BTFEntityType;
 import org.eclipse.app4mc.atdb._import.btf.model.BTFInterInstanceMetric;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.Enumerator;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 
 public class ATDBMetricCalculator implements IRunnableWithProgress {
@@ -136,6 +138,31 @@
 						+ "  " + metric + " FROM (" + String.join(" UNION ", iiMetricQueries)//
 						+ ");");
 			}
+			
+			// calculate stimuli activate2activate distances
+			final Entry<Enumerator, Enumerator> activateEventPair = BTFInterInstanceMetric.activateToActivate.entityType2FirstAndSecond
+					.entrySet().iterator().next().getValue();
+			final String query = "SELECT A.sourceEntityId, A.sourceEntityInstance, SUM(B.timestamp - A.timestamp) AS "
+					+ BTFInterInstanceMetric.activateToActivate + "\n"//
+					+ "FROM (\n"
+					+ "  SELECT * FROM " + BTFEntityType.PROCESS.getName() + "InstanceRuntimeTraceEvent) AS A "//
+					+ "INNER JOIN " + BTFEntityType.PROCESS.getName() + "InstanceRuntimeTraceEvent AS B ON "//
+					+ "B.entityId = A.entityId AND B.entityInstance = A.entityInstance + 1\n"//
+					+ "  WHERE A.eventTypeId = (SELECT id FROM eventType WHERE name = '" + activateEventPair.getKey() + "') AND\n"//
+					+ "        B.eventTypeId = (SELECT id FROM eventType WHERE name = '" + activateEventPair.getValue() + "') AND\n"//
+					+ "        A.sourceEntityId = B.sourceEntityId\n"//
+					+ "  GROUP BY A.sourceEntityId, A.sourceEntityInstance HAVING\n"
+					+ "    (SELECT isComplete FROM " + BTFEntityType.PROCESS.getName() + "InstanceTraceInfo WHERE "//
+					+ "entityId = A.entityId AND entityInstance = A.entityInstance) AND\n"//
+					+ "    (SELECT isComplete FROM " + BTFEntityType.PROCESS.getName() + "InstanceTraceInfo WHERE "//
+					+ "entityId = B.entityId AND entityInstance = B.entityInstance)";
+			statement.addBatch("INSERT INTO entityInstanceMetricValue SELECT\n"//
+					+ "  sourceEntityId,\n"//
+					+ "  sourceEntityInstance,\n"//
+					+ "  (SELECT id FROM metric WHERE name = '" + BTFInterInstanceMetric.activateToActivate + "'),\n"//
+					+ "  " + BTFInterInstanceMetric.activateToActivate + "\n"
+					+ "FROM (" + query//
+					+ ");");
 	
 			// calculate entity metrics min max avg for all time metric values
 			for (final String entityInstanceTimeMetric : entityInstanceTimeMetrics) {
diff --git a/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/BTFImporter.java b/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/BTFImporter.java
index 8be1bbe..55d386f 100644
--- a/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/BTFImporter.java
+++ b/plugins/org.eclipse.app4mc.atdb.import.btf/src/org/eclipse/app4mc/atdb/_import/btf/BTFImporter.java
@@ -216,7 +216,7 @@
 						evStmt.addBatch();
 					}
 				} else {
-					if (line.startsWith("#timeScale")) {
+					if (line.toLowerCase().startsWith("#timescale")) {
 						metaStmt.setString(1, "timeBase");
 						metaStmt.setString(2, line.substring(11));
 						metaStmt.addBatch();
diff --git a/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/ATDBConnection.java b/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/ATDBConnection.java
index a5613b8..8450a56 100644
--- a/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/ATDBConnection.java
+++ b/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/ATDBConnection.java
@@ -103,7 +103,7 @@
 	 * @throws SQLException
 	 */
 	public List<String> getProcessorsOfECU(final String ecuName) throws SQLException {
-		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(ecuName, "ECU", "processors"));
+		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(ecuName, "ECU", EntityProperty.PROCESSORS.camelName));
 	}
 	
 	/**
@@ -122,7 +122,7 @@
 	 * @throws SQLException
 	 */
 	public List<String> getCoresOfProcessor(final String processorName) throws SQLException {
-		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processorName, "Processor", "cores"));
+		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processorName, "Processor", EntityProperty.CORES.camelName));
 	}
 	
 	/**
@@ -141,7 +141,7 @@
 	 * @throws SQLException
 	 */
 	public String getCoreFrequencyInHz(final String coreName) throws SQLException {
-		return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_VALUE_QUERY, Arrays.asList(coreName, "C", "frequencyInHz"), "");
+		return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_VALUE_QUERY, Arrays.asList(coreName, "C", EntityProperty.FREQUENCY_IN_HZ.camelName), "");
 	}
 	
 	/**
@@ -182,9 +182,10 @@
 	 */
 	public String getExecutingCoreOfProcess(final String processName) throws SQLException {
 		final Optional<String> coreOfTask = getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName,
-				"T", "executingCore")).findFirst();
+				"T", EntityProperty.EXECUTING_CORE.camelName)).findFirst();
 		if (!coreOfTask.isPresent()) {
-			return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "I", "executingCore"), "");
+			return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName,
+					"I", EntityProperty.EXECUTING_CORE.camelName), "");
 		} else {
 			return coreOfTask.get();
 		}
@@ -198,8 +199,21 @@
 	 */
 	public List<String> getRunnablesOfProcess(final String processName) throws SQLException {
 		return Stream.concat(
-			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "T", "runnables")),
-			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "I", "runnables"))
+			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "T", EntityProperty.RUNNABLES.camelName)),
+			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "I", EntityProperty.RUNNABLES.camelName))
+		).collect(Collectors.toList());
+	}
+	
+	/**
+	 * Returns all stimulus names of this ATDB that activate the given process name.
+	 * @param processName The process name of which we want to retrieve all stimulus names.
+	 * @return A list of all stimulus names activating the given process.
+	 * @throws SQLException
+	 */
+	public List<String> getStimuliOfProcess(final String processName) throws SQLException {
+		return Stream.concat(
+			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "T", EntityProperty.STIMULI.camelName)),
+			getStringStreamFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(processName, "I", EntityProperty.STIMULI.camelName))
 		).collect(Collectors.toList());
 	}
 	
@@ -219,7 +233,7 @@
 	 * @throws SQLException
 	 */
 	public List<String> getLabelsReadByRunnable(final String runnableName) throws SQLException {
-		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(runnableName, "R", "readSignals"));
+		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(runnableName, "R", EntityProperty.READ_SIGNALS.camelName));
 	}
 	
 	/**
@@ -229,7 +243,7 @@
 	 * @throws SQLException
 	 */
 	public List<String> getLabelsWrittenByRunnable(final String runnableName) throws SQLException {
-		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(runnableName, "R", "writtenSignals"));
+		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(runnableName, "R", EntityProperty.WRITTEN_SIGNALS.camelName));
 	}
 	
 	/**
@@ -257,7 +271,7 @@
 	 * @throws SQLException
 	 */
 	public String getLabelInitialValue(final String labelName) throws SQLException {
-		return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_VALUE_QUERY, Arrays.asList(labelName, "SIG", "initialValue"), "");
+		return getFirstStringFromPreparedQuery(ENTITY_PROPERTY_VALUE_QUERY, Arrays.asList(labelName, "SIG", EntityProperty.INITIAL_VALUE.camelName), "");
 	}
 	
 	/**
@@ -286,7 +300,7 @@
 	 * @throws SQLException
 	 */
 	public String getEventChainStimulus(final String eventChainName) throws SQLException {
-		return getFirstStringFromPreparedQuery(EVENTCHAIN_EVENTREF_QUERY, Arrays.asList("ecStimulus", eventChainName), "");
+		return getFirstStringFromPreparedQuery(EVENTCHAIN_EVENTREF_QUERY, Arrays.asList(EntityProperty.EC_STIMULUS.camelName, eventChainName), "");
 	}
 	
 	/**
@@ -296,7 +310,7 @@
 	 * @throws SQLException
 	 */
 	public String getEventChainResponse(final String eventChainName) throws SQLException {
-		return getFirstStringFromPreparedQuery(EVENTCHAIN_EVENTREF_QUERY, Arrays.asList("ecResponse", eventChainName), "");
+		return getFirstStringFromPreparedQuery(EVENTCHAIN_EVENTREF_QUERY, Arrays.asList(EntityProperty.EC_RESPONSE.camelName, eventChainName), "");
 	}
 	
 	/**
@@ -306,7 +320,7 @@
 	 * @throws SQLException
 	 */
 	public List<String> getEventChainItems(final String eventChainName) throws SQLException {
-		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(eventChainName, "EC", "items"));
+		return getStringListFromPreparedQuery(ENTITY_PROPERTY_ENTITYREF_QUERY, Arrays.asList(eventChainName, "EC", EntityProperty.EC_ITEMS.camelName));
 	}
 	
 	/**
diff --git a/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/EntityProperty.java b/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/EntityProperty.java
new file mode 100644
index 0000000..31bc00c
--- /dev/null
+++ b/plugins/org.eclipse.app4mc.atdb/src/org/eclipse/app4mc/atdb/EntityProperty.java
@@ -0,0 +1,39 @@
+package org.eclipse.app4mc.atdb;
+
+public enum EntityProperty {
+	SIMULATION_DURATION("time"),
+	INITIAL_VALUE("object"),
+	PROCESSORS("entityIdRef"),
+	CORES("entityIdRef"),
+	SYSTEM_START_TIME("time"),
+	FREQUENCY_IN_HZ("long"),
+	STIMULI("entityIdRef"),
+	EXECUTING_CORE("entityIdRef"),
+	RUNNABLES("entityIdRef"),
+	READ_SIGNALS("entityIdRef"),
+	WRITTEN_SIGNALS("entityIdRef"),
+	SYSTEM_STOP_TIME("time"),
+	EC_ITEMS("entityIdRef"),
+	EC_STIMULUS("eventIdRef"),
+	EC_RESPONSE("eventIdRef"),
+	EC_MIN_ITEMS_COMPLETED("long");
+	
+	public final String camelName;
+	public final String type;
+	
+	private EntityProperty(final String type) {
+		final StringBuilder sb = new StringBuilder();
+		for (final String oneString : this.name().toLowerCase().toLowerCase().split("_")) {
+		    sb.append(sb.length() > 0 ? oneString.substring(0, 1).toUpperCase() : oneString.substring(0, 1));
+		    sb.append(oneString.substring(1));
+		}
+		this.camelName = sb.toString();
+		this.type = type;
+	}
+	
+	@Override
+	public String toString() {
+		return this.camelName;
+	}
+
+}