Finished event converter for ATDB -> AMALTHEA. Some refactoring.

Change-Id: I7291da07729261bdf4daad311c02bd3786998d32
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
index e85e415..3d343dc 100644
--- 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
@@ -13,18 +13,39 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
+import java.lang.reflect.InvocationTargetException;
+import java.sql.SQLException;
+
 import org.eclipse.app4mc.amalthea.model.Amalthea;
 import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 
 public abstract class AConverter implements IRunnableWithProgress {
 	
 	protected final Amalthea model;
 	protected final ATDBConnection con;
+	private final String converionSubject;
 
-	public AConverter(final Amalthea model, final ATDBConnection con) {
+	protected AConverter(final Amalthea model, final ATDBConnection con, final String conversionSubject) {
 		this.model = model;
 		this.con = con;
+		this.converionSubject = conversionSubject;
 	}
+	
+	@Override
+	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
+		progressMonitor.beginTask("Converting " + this.converionSubject + "...", 1);
+		try {
+			execute();
+			progressMonitor.worked(1);
+		} catch (SQLException e) {
+			throw new InvocationTargetException(e);
+		} finally {
+			progressMonitor.done();
+		}
+	}
+	
+	abstract protected void execute() throws InvocationTargetException, InterruptedException, SQLException;
 
 }
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AmaltheaModelUtil.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AmaltheaModelUtil.java
index d11c1e8..127666b 100644
--- a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AmaltheaModelUtil.java
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/AmaltheaModelUtil.java
@@ -16,15 +16,21 @@
 import java.util.AbstractMap.SimpleEntry;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.stream.Stream;
 
 import org.eclipse.app4mc.amalthea.model.AmaltheaIndex;
 import org.eclipse.app4mc.amalthea.model.INamed;
 import org.eclipse.app4mc.amalthea.model.IReferable;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EDataType;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
 import org.eclipse.emf.ecore.util.EcoreUtil;
 
 enum AmaltheaModelUtil {;
@@ -40,7 +46,7 @@
 		final List<T> values = referenceFeature.isMany()
 				? (List<T>) amEObject.eGet(referenceFeature)
 				: Arrays.asList(clazz.cast(amEObject.eGet(referenceFeature)));
-		final T value = values.stream().filter(p -> p.getName().equals(name)).findFirst().orElseGet(() -> {
+		final T value = values.stream().filter(Objects::nonNull).filter(p -> p.getName() != null && p.getName().equals(name)).findFirst().orElseGet(() -> {
 			T ret;
 			if (referenceFeature.isContainment()) {
 				ret = clazz.cast(EcoreUtil.create(eClazz));
@@ -115,5 +121,19 @@
 		});
 		return value;
 	}
+	
+	static Optional<Enumerator> getEnumLiteralByNameForFeature(final String enumLiteralName, final EStructuralFeature esf) {
+		if (enumLiteralName == null || enumLiteralName.length() == 0) {
+			return Optional.empty();
+		}
+		if (esf == null) {
+			return Optional.empty();
+		}
+		return Optional.of(esf).filter(EAttribute.class::isInstance).map(EAttribute.class::cast)
+				.map(EAttribute::getEAttributeType).filter(Objects::nonNull)
+				.map(EDataType::getInstanceClass).filter(Objects::nonNull).filter(Class::isEnum).flatMap(c ->
+						Stream.of(c.getEnumConstants()).filter(Enumerator.class::isInstance).map(Enumerator.class::cast)
+						.filter(e -> enumLiteralName.equals(e.getName())).findFirst());
+	}
 
 }
diff --git a/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/EventConverter.java b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/EventConverter.java
new file mode 100644
index 0000000..53b94d2
--- /dev/null
+++ b/plugins/org.eclipse.app4mc.amalthea.import.atdb/src/org/eclipse/app4mc/amalthea/_import/atdb/EventConverter.java
@@ -0,0 +1,105 @@
+/**
+ ********************************************************************************
+ * 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.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
+import org.eclipse.app4mc.amalthea.model.Event;
+import org.eclipse.app4mc.amalthea.model.EventModel;
+import org.eclipse.app4mc.amalthea.model.IReferable;
+import org.eclipse.app4mc.amalthea.model.util.ModelUtil;
+import org.eclipse.app4mc.atdb.ATDBConnection;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class EventConverter extends AConverter {
+	
+	/**
+	 * Same as {@link java.util.function.Supplier}, but may throw exception of type E.
+	 * @param <T>
+	 * @param <E>
+	 */
+	@FunctionalInterface
+	public static interface ThrowingSupplier<T, E extends Exception> {
+	    T get() throws E;
+	}
+	
+	private final Map<ThrowingSupplier<List<String>, SQLException>, EClass> eventSupplier2EClass;
+	private static final Map<EClass, EReference> eClass2SourceReference = new LinkedHashMap<>();
+	static {
+		eClass2SourceReference.put(AmaltheaPackage.eINSTANCE.getRunnableEvent(), AmaltheaPackage.eINSTANCE.getRunnableEvent_Process());
+		eClass2SourceReference.put(AmaltheaPackage.eINSTANCE.getProcessEvent(), AmaltheaPackage.eINSTANCE.getProcessEvent_ProcessingUnit());
+		eClass2SourceReference.put(AmaltheaPackage.eINSTANCE.getLabelEvent(), AmaltheaPackage.eINSTANCE.getLabelEvent_Runnable());
+	}
+
+	public EventConverter(final Amalthea model, final ATDBConnection con) {
+		super(model, con, "events");
+		this.eventSupplier2EClass = new LinkedHashMap<>();
+		this.eventSupplier2EClass.put(this.con::getAllRunnableEvents, AmaltheaPackage.eINSTANCE.getRunnableEvent());
+		this.eventSupplier2EClass.put(this.con::getAllProcessEvents, AmaltheaPackage.eINSTANCE.getProcessEvent());
+		this.eventSupplier2EClass.put(this.con::getAllLabelEvents, AmaltheaPackage.eINSTANCE.getLabelEvent());
+		this.eventSupplier2EClass.put(this.con::getAllStimulusEvents, AmaltheaPackage.eINSTANCE.getStimulusEvent());
+	}
+	
+	@Override
+	protected void execute() throws SQLException {
+		final EventModel evModel = ModelUtil.getOrCreateEventModel(this.model);
+		
+		final List<Event> events = new ArrayList<>();
+		for(final Entry<ThrowingSupplier<List<String>, SQLException>, EClass> evSup2ECl: this.eventSupplier2EClass.entrySet()) {
+			evSup2ECl.getKey().get().forEach(eventName ->
+				events.add(AmaltheaModelUtil.getOrAddNew(evModel,
+						AmaltheaPackage.eINSTANCE.getEventModel_Events(), eventName, Event.class, evSup2ECl.getValue())));
+		}
+		
+		for(final Event event: events) {
+			updateEventType(event);
+			updateEntity(event);
+			updateSourceEntity(event);
+		}
+	}
+	
+	private void updateEventType(final Event event) throws SQLException {
+		final EStructuralFeature eventTypeESF = event.eClass().getEStructuralFeature("eventType");
+		final String eventType = this.con.getEventTypeForEvent(event.getName());
+		final Optional<Enumerator> eventTypeEnumLiteral = AmaltheaModelUtil.getEnumLiteralByNameForFeature(eventType, eventTypeESF);
+		eventTypeEnumLiteral.ifPresent(eLiteral -> event.eSet(eventTypeESF, eLiteral));
+	}
+	
+	private void updateEntity(final Event event) throws SQLException {
+		final EReference eventEntityESF = (EReference)event.eClass().getEStructuralFeature("entity");
+		final String entityName = this.con.getEntityForEvent(event.getName());
+		AmaltheaModelUtil.getOrAddNew(event, eventEntityESF, entityName, IReferable.class);
+	}
+	
+	private void updateSourceEntity(final Event event) throws SQLException {
+		final String sourceEntityName = this.con.getSourceEntityForEvent(event.getName());
+		if (sourceEntityName.length() == 0) return;
+		
+		if (eClass2SourceReference.containsKey(event.eClass())) {
+			AmaltheaModelUtil.getOrAddNew(event, eClass2SourceReference.get(event.eClass()), sourceEntityName, IReferable.class);
+		}
+	}
+
+}
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 493ad0e..b4b0f99 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
@@ -13,7 +13,6 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
-import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
@@ -29,71 +28,62 @@
 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.core.runtime.IProgressMonitor;
 
 public class HWConverter extends AConverter {
 
 	public HWConverter(final Amalthea model, final ATDBConnection con) {
-		super(model, con);
+		super(model, con, "hardware model");
 	}
 
 	@Override
-	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
-		progressMonitor.beginTask("Converting hardware model", 1);
+	protected void execute() throws SQLException {
 		final HWModel hwModel = ModelUtil.getOrCreateHwModel(this.model);
 		final HwStructure system = AmaltheaModelUtil.getOrAddNew(hwModel,
 				AmaltheaPackage.eINSTANCE.getHWModel_Structures(), "System", HwStructure.class);
 		system.setStructureType(StructureType.SYSTEM);
-		try {
-			final List<HwStructure> ecus = new ArrayList<>();
-			this.con.getAllECUs().forEach(ecuName -> {
-				final HwStructure ecu = AmaltheaModelUtil.getOrAddNew(system,
-						AmaltheaPackage.eINSTANCE.getHwStructure_Structures(), ecuName, HwStructure.class);
-				ecu.setStructureType(StructureType.ECU);
-				ecus.add(ecu);
+		
+		final List<HwStructure> ecus = new ArrayList<>();
+		this.con.getAllECUs().forEach(ecuName -> {
+			final HwStructure ecu = AmaltheaModelUtil.getOrAddNew(system,
+					AmaltheaPackage.eINSTANCE.getHwStructure_Structures(), ecuName, HwStructure.class);
+			ecu.setStructureType(StructureType.ECU);
+			ecus.add(ecu);
+		});
+		
+		for(final HwStructure ecu:ecus) {
+			final List<HwStructure> processors = new ArrayList<>();
+			this.con.getProcessorsOfECU(ecu.getName()).forEach(processorName -> {
+				final HwStructure processor = AmaltheaModelUtil.getOrAddNew(ecu,
+						AmaltheaPackage.eINSTANCE.getHwStructure_Structures(), processorName, HwStructure.class);
+				processor.setStructureType(StructureType.MICROCONTROLLER);
+				processors.add(processor);
 			});
 			
-			
-			for(final HwStructure ecu:ecus) {
-				final List<HwStructure> processors = new ArrayList<>();
-				this.con.getProcessorsOfECU(ecu.getName()).forEach(processorName -> {
-					final HwStructure processor = AmaltheaModelUtil.getOrAddNew(ecu,
-							AmaltheaPackage.eINSTANCE.getHwStructure_Structures(), processorName, HwStructure.class);
-					processor.setStructureType(StructureType.MICROCONTROLLER);
-					processors.add(processor);
+			for(final HwStructure processor:processors) {
+				final List<ProcessingUnit> cores = new ArrayList<>();
+				this.con.getCoresOfProcessor(processor.getName()).forEach(coreName -> {
+					final ProcessingUnit core = AmaltheaModelUtil.getOrAddNew(processor,
+							AmaltheaPackage.eINSTANCE.getHwStructure_Modules(), coreName, ProcessingUnit.class,
+							AmaltheaPackage.eINSTANCE.getProcessingUnit());
+					cores.add(core);
 				});
 				
-				for(final HwStructure processor:processors) {
-					final List<ProcessingUnit> cores = new ArrayList<>();
-					this.con.getCoresOfProcessor(processor.getName()).forEach(coreName -> {
-						final ProcessingUnit core = AmaltheaModelUtil.getOrAddNew(processor,
-								AmaltheaPackage.eINSTANCE.getHwStructure_Modules(), coreName, ProcessingUnit.class,
-								AmaltheaPackage.eINSTANCE.getProcessingUnit());
-						cores.add(core);
-					});
-					
-					for(final ProcessingUnit core:cores) {
-						final String freqInHzStr = this.con.getCoreFrequencyInHz(core.getName());
-						if (freqInHzStr.length() > 0) {
-							try {
-								final long frequencyInHz = Long.parseLong(freqInHzStr);
-								final FrequencyDomain fd = AmaltheaModelUtil.getOrAddNew(hwModel,
-										AmaltheaPackage.eINSTANCE.getHWModel_Domains(), core.getName() + "_FD", FrequencyDomain.class,
-										AmaltheaPackage.eINSTANCE.getFrequencyDomain());
-								fd.setDefaultValue(FactoryUtil.createFrequency(frequencyInHz, FrequencyUnit.HZ));
-								core.setFrequencyDomain(fd);
-							} catch (NumberFormatException e) {
-								// fail silently
-							}
+				for(final ProcessingUnit core:cores) {
+					final String freqInHzStr = this.con.getCoreFrequencyInHz(core.getName());
+					if (freqInHzStr.length() > 0) {
+						try {
+							final long frequencyInHz = Long.parseLong(freqInHzStr);
+							final FrequencyDomain fd = AmaltheaModelUtil.getOrAddNew(hwModel,
+									AmaltheaPackage.eINSTANCE.getHWModel_Domains(), core.getName() + "_FD", FrequencyDomain.class,
+									AmaltheaPackage.eINSTANCE.getFrequencyDomain());
+							fd.setDefaultValue(FactoryUtil.createFrequency(frequencyInHz, FrequencyUnit.HZ));
+							core.setFrequencyDomain(fd);
+						} 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.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 ecfa5c8..fd1799d 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
@@ -108,6 +108,8 @@
 			
 			// events
 			final SubMonitor evConvMonitor = subMon.split(1);
+			final IRunnableWithProgress eventConverter = new EventConverter(model, con);
+			eventConverter.run(evConvMonitor);
 			
 			// event chains
 			final SubMonitor ecConvMonitor = 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 b63cbb1..60ecd3f 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
@@ -13,7 +13,6 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
-import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
@@ -26,36 +25,28 @@
 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;
 
 public class LabelConverter extends AConverter {
 
 	public LabelConverter(final Amalthea model, final ATDBConnection con) {
-		super(model, con);
+		super(model, con, "labels");
 	}
 
 	@Override
-	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
-		progressMonitor.beginTask("Converting labels", 1);
+	protected void execute() throws SQLException {
 		final SWModel swModel = ModelUtil.getOrCreateSwModel(this.model);
-		try {
-			final List<Label> labels = new ArrayList<>();
-			this.con.getAllLabels().forEach(labelName -> {
-				final Label label = AmaltheaModelUtil.getOrAddNew(swModel,
-						AmaltheaPackage.eINSTANCE.getSWModel_Labels(), labelName, Label.class);
-				labels.add(label);
-			});
-			for(final Label label:labels) {
-				final String initialValue = this.con.getLabelInitialValue(label.getName());
-				if (initialValue.length() > 0) {
-					CustomPropertyUtil.customPut(label, EntityProperty.INITIAL_VALUE.camelName, initialValue);
-				}
+		
+		final List<Label> labels = new ArrayList<>();
+		this.con.getAllLabels().forEach(labelName -> {
+			final Label label = AmaltheaModelUtil.getOrAddNew(swModel,
+					AmaltheaPackage.eINSTANCE.getSWModel_Labels(), labelName, Label.class);
+			labels.add(label);
+		});
+		for(final Label label:labels) {
+			final String initialValue = this.con.getLabelInitialValue(label.getName());
+			if (initialValue.length() > 0) {
+				CustomPropertyUtil.customPut(label, EntityProperty.INITIAL_VALUE.camelName, initialValue);
 			}
-			progressMonitor.worked(1);
-		} catch (SQLException e) {
-			throw new InvocationTargetException(e);
-		} finally {
-			progressMonitor.done();
 		}
 	}
 
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 de4f3dd..c7ce348 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
@@ -13,7 +13,6 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
-import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
@@ -30,45 +29,36 @@
 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;
 
 public class ProcessConverter extends AConverter {
 
 	public ProcessConverter(final Amalthea model, final ATDBConnection con) {
-		super(model, con);
+		super(model, con, "processes");
 	}
 
 	@Override
-	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
-		progressMonitor.beginTask("Converting processes", 1);
+	protected void execute() throws SQLException {
 		final SWModel swModel = ModelUtil.getOrCreateSwModel(this.model);
-		try {
-			final List<Process> processes = new ArrayList<>();
-			this.con.getAllTasks().forEach(taskName -> processes.add(AmaltheaModelUtil.getOrAddNew(swModel, AmaltheaPackage.eINSTANCE.getSWModel_Tasks(),
-					taskName, Task.class)));
-			this.con.getAllISRs().forEach(isrName -> processes.add(AmaltheaModelUtil.getOrAddNew(swModel, AmaltheaPackage.eINSTANCE.getSWModel_Isrs(),
-					isrName, ISR.class)));
+		
+		final List<Process> processes = new ArrayList<>();
+		this.con.getAllTasks().forEach(taskName -> processes.add(AmaltheaModelUtil.getOrAddNew(swModel, AmaltheaPackage.eINSTANCE.getSWModel_Tasks(),
+				taskName, Task.class)));
+		this.con.getAllISRs().forEach(isrName -> processes.add(AmaltheaModelUtil.getOrAddNew(swModel, AmaltheaPackage.eINSTANCE.getSWModel_Isrs(),
+				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,
+						AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), RunnableCall.class,
+						AmaltheaPackage.eINSTANCE.getRunnableCall(),
+						AmaltheaPackage.eINSTANCE.getRunnableCall_Runnable(), Runnable.class,
+						AmaltheaPackage.eINSTANCE.getRunnable(), runnableName).getKey());
 			
-			for(final Process proc:processes) {
-				// fill activity graph
-				final ActivityGraph ag = ModelUtil.getOrCreateActivityGraph(proc);
-				this.con.getRunnablesOfProcess(proc.getName()).forEach(runnableName -> 
-					AmaltheaModelUtil.getOrAddNewWithContainer(ag,
-							AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), RunnableCall.class,
-							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);
-		} catch (SQLException e) {
-			throw new InvocationTargetException(e);
-		} finally {
-			progressMonitor.done();
+			// connect stimuli
+			this.con.getStimuliOfProcess(proc.getName()).forEach(stimulusName ->
+				AmaltheaModelUtil.getOrAddNew(proc, AmaltheaPackage.eINSTANCE.getProcess_Stimuli(), stimulusName, Stimulus.class));
 		}
 	}
 
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 044aa4d..0065a84 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
@@ -13,7 +13,6 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
-import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
@@ -38,7 +37,6 @@
 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.emf.ecore.util.EcoreUtil;
 
 public class RunnableConverter extends AConverter {
@@ -51,101 +49,93 @@
 
 	public RunnableConverter(final Amalthea model, final ATDBConnection con,
 			final boolean extractRuntimes, final boolean extractLabelAccesses, final double frequencyInHz) {
-		super(model, con);
+		super(model, con, "runnables");
 		this.extractRuntimes = extractRuntimes;
 		this.extractLabelAccesses = extractLabelAccesses;
 		this.frequency = FactoryUtil.createFrequency(frequencyInHz, FrequencyUnit.HZ);
 	}
 
 	@Override
-	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
-		progressMonitor.beginTask("Converting runnables", 1);
+	protected void execute() throws SQLException {
 		final SWModel swModel = ModelUtil.getOrCreateSwModel(this.model);
-		try {
-			final TimeUnit timeBase = TimeUnit.getByName(this.con.getTimeBase().toLowerCase());
-					
-			final List<Runnable> runnables = new ArrayList<>();
-			this.con.getAllRunnables().forEach(runnableName -> {
-				final Runnable runnable = AmaltheaModelUtil.getOrAddNew(swModel,
-						AmaltheaPackage.eINSTANCE.getSWModel_Runnables(), runnableName, Runnable.class);
-				runnables.add(runnable);
-			});
-			
+		final TimeUnit timeBase = TimeUnit.getByName(this.con.getTimeBase().toLowerCase());
+				
+		final List<Runnable> runnables = new ArrayList<>();
+		this.con.getAllRunnables().forEach(runnableName -> {
+			final Runnable runnable = AmaltheaModelUtil.getOrAddNew(swModel,
+					AmaltheaPackage.eINSTANCE.getSWModel_Runnables(), runnableName, Runnable.class);
+			runnables.add(runnable);
+		});
+		
 
-			for(final Runnable runnable:runnables) {
-				final ActivityGraph ag = ModelUtil.getOrCreateActivityGraph(runnable);
-				// label reads
-				if (this.extractLabelAccesses) {
-					this.con.getLabelsReadByRunnable(runnable.getName()).forEach(labelName -> {
-						final LabelAccess la = AmaltheaModelUtil.getOrAddNewWithContainer(ag,
-								AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), LabelAccess.class,
-								AmaltheaPackage.eINSTANCE.getLabelAccess(),
-								AmaltheaPackage.eINSTANCE.getLabelAccess_Data(), Label.class,
-								AmaltheaPackage.eINSTANCE.getLabel(), labelName).getKey();
-						la.setAccess(LabelAccessEnum.READ);
-					});
+		for(final Runnable runnable:runnables) {
+			final ActivityGraph ag = ModelUtil.getOrCreateActivityGraph(runnable);
+			// label reads
+			if (this.extractLabelAccesses) {
+				this.con.getLabelsReadByRunnable(runnable.getName()).forEach(labelName -> {
+					final LabelAccess la = AmaltheaModelUtil.getOrAddNewWithContainer(ag,
+							AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), LabelAccess.class,
+							AmaltheaPackage.eINSTANCE.getLabelAccess(),
+							AmaltheaPackage.eINSTANCE.getLabelAccess_Data(), Label.class,
+							AmaltheaPackage.eINSTANCE.getLabel(), labelName).getKey();
+					la.setAccess(LabelAccessEnum.READ);
+				});
+			}
+			// runtimes
+			if (this.extractRuntimes && timeBase != null && this.frequency.getValue() >= 1) {
+				double runningTimeAvg = -1;
+				double runningTimeStDev = -1;
+				try {
+					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
 				}
-				// runtimes
-				if (this.extractRuntimes && timeBase != null && this.frequency.getValue() >= 1) {
-					double runningTimeAvg = -1;
-					double runningTimeStDev = -1;
-					try {
-						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(), 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) {
-							final long constTicks = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
-									AmaltheaServices.convertToSeconds(runningTimeMin, timeBase), this.frequency);
-							dvd = FactoryUtil.createDiscreteValueConstant(constTicks);
+				try {
+					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) {
+						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);
+						final long ticksMax = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
+								AmaltheaServices.convertToSeconds(runningTimeMax, timeBase), this.frequency);
+						if (runningTimeAvg >= 0 && runningTimeStDev >= 0) {
+							final double ticksAvg = RuntimeUtil.getTicksForExecutionTimeInSeconds(
+									AmaltheaServices.convertToSeconds(runningTimeAvg, timeBase), this.frequency);
+							final double ticksStDev = RuntimeUtil.getTicksForExecutionTimeInSeconds(
+									AmaltheaServices.convertToSeconds(runningTimeStDev, timeBase), this.frequency);
+							dvd = FactoryUtil.createDiscreteValueGaussDistribution(ticksAvg, ticksStDev, ticksMin, ticksMax);
 						} else {
-							final long ticksMin = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
-									AmaltheaServices.convertToSeconds(runningTimeMin, timeBase), this.frequency);
-							final long ticksMax = (long)RuntimeUtil.getTicksForExecutionTimeInSeconds(
-									AmaltheaServices.convertToSeconds(runningTimeMax, timeBase), this.frequency);
-							if (runningTimeAvg >= 0 && runningTimeStDev >= 0) {
-								final double ticksAvg = RuntimeUtil.getTicksForExecutionTimeInSeconds(
-										AmaltheaServices.convertToSeconds(runningTimeAvg, timeBase), this.frequency);
-								final double ticksStDev = RuntimeUtil.getTicksForExecutionTimeInSeconds(
-										AmaltheaServices.convertToSeconds(runningTimeStDev, timeBase), this.frequency);
-								dvd = FactoryUtil.createDiscreteValueGaussDistribution(ticksAvg, ticksStDev, ticksMin, ticksMax);
-							} else {
-								dvd = FactoryUtil.createDiscreteValueBoundaries(ticksMin, ticksMax);
-							}
+							dvd = FactoryUtil.createDiscreteValueBoundaries(ticksMin, ticksMax);
 						}
-						ticks.setDefault(dvd);
-						RuntimeUtil.clearRuntimeOfRunnable(runnable, null);
-						ag.getItems().add(ticks);
-					} catch (NumberFormatException e) {
-						// fail silently
 					}
-				}
-				// label writes
-				if (this.extractLabelAccesses) {
-					this.con.getLabelsWrittenByRunnable(runnable.getName()).forEach(labelName -> {
-						final LabelAccess la = AmaltheaModelUtil.getOrAddNewWithContainer(ag,
-								AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), LabelAccess.class,
-								AmaltheaPackage.eINSTANCE.getLabelAccess(),
-								AmaltheaPackage.eINSTANCE.getLabelAccess_Data(), Label.class,
-								AmaltheaPackage.eINSTANCE.getLabel(), labelName).getKey();
-						la.setAccess(LabelAccessEnum.WRITE);
-					});
-				}
-				if (ag.getItems().isEmpty()) {
-					EcoreUtil.delete(ag);
+					ticks.setDefault(dvd);
+					RuntimeUtil.clearRuntimeOfRunnable(runnable, null);
+					ag.getItems().add(ticks);
+				} catch (NumberFormatException e) {
+					// fail silently
 				}
 			}
-			progressMonitor.worked(1);
-		} catch (SQLException e) {
-			throw new InvocationTargetException(e);
-		} finally {
-			progressMonitor.done();
+			// label writes
+			if (this.extractLabelAccesses) {
+				this.con.getLabelsWrittenByRunnable(runnable.getName()).forEach(labelName -> {
+					final LabelAccess la = AmaltheaModelUtil.getOrAddNewWithContainer(ag,
+							AmaltheaPackage.eINSTANCE.getIActivityGraphItemContainer_Items(), LabelAccess.class,
+							AmaltheaPackage.eINSTANCE.getLabelAccess(),
+							AmaltheaPackage.eINSTANCE.getLabelAccess_Data(), Label.class,
+							AmaltheaPackage.eINSTANCE.getLabel(), labelName).getKey();
+					la.setAccess(LabelAccessEnum.WRITE);
+				});
+			}
+			if (ag.getItems().isEmpty()) {
+				EcoreUtil.delete(ag);
+			}
 		}
 	}
 
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
index 2ec964c..dda5cd9 100644
--- 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
@@ -13,7 +13,6 @@
 
 package org.eclipse.app4mc.amalthea._import.atdb;
 
-import java.lang.reflect.InvocationTargetException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
@@ -29,76 +28,65 @@
 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);
+		super(model, con, "stimuli");
 	}
 
 	@Override
-	public void run(IProgressMonitor progressMonitor) throws InvocationTargetException {
-		progressMonitor.beginTask("Converting stimuli", 1);
+	protected void execute() throws SQLException {
 		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();
-		}
+		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
+			}
+		}
 	}
 
 }
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 8450a56..671008c 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
@@ -27,7 +27,17 @@
 	
 	private static final String METAINFORMATION_QUERY = "SELECT value FROM metaInformation WHERE name = ?;";
 	private static final String ENTITY_BY_TYPE_QUERY = "SELECT name FROM entity WHERE entityTypeId = (SELECT id FROM entityType WHERE entityType.name = ?);";
-	private static final String EVENT_BY_TYPE_QUERY = "SELECT name FROM event WHERE eventTypeId = (SELECT id FROM eventType WHERE eventType.name = ?);";
+	private static final String EVENTS_QUERY = "SELECT event.name FROM event;";
+	private static final String EVENT_BY_TYPE_QUERY = EVENTS_QUERY.substring(0, EVENTS_QUERY.length() - 1)
+			+ " WHERE eventTypeId = (SELECT id FROM eventType WHERE eventType.name = ?);";
+	private static final String EVENT_BY_ENTITY_TYPE_QUERY = EVENTS_QUERY.substring(0, EVENTS_QUERY.length() - 1) + ", entity "
+			+ "WHERE event.entityId = entity.id AND entity.entityTypeId = (SELECT id FROM entityType WHERE entityType.name = ?);";
+	private static final String EVENT_TYPE_OF_EVENT_QUERY = "SELECT eventType.name FROM event, eventType "
+			+ "WHERE event.eventTypeId = eventType.id AND event.name = ?;";
+	private static final String ENTITY_OF_EVENT_QUERY = "SELECT entity.name FROM event, entity "
+			+ "WHERE event.entityId = entity.id AND event.name = ?;";
+	private static final String SOURCE_ENTITY_OF_EVENT_QUERY = "SELECT entity.name FROM event, entity "
+			+ "WHERE event.sourceEntityId = entity.id AND event.name = ?;";
 	private static final String ENTITY_PROPERTY_ENTITYREF_QUERY = "SELECT (SELECT name FROM entity WHERE id = value) AS entities "
 			+ "FROM entity AS sourceEntity, propertyValue WHERE sourceEntity.name = ? "
 			+ "AND entityTypeId = (SELECT id FROM entityType WHERE entityType.name = ?) "
@@ -284,6 +294,15 @@
 	}
 	
 	/**
+	 * Returns all event (specification, not from the actual trace!) names of this ATDB.
+	 * @return A list of all event names.
+	 * @throws SQLException
+	 */
+	public List<String> getAllEvents() throws SQLException {
+		return getStringListFromPreparedQuery(EVENTS_QUERY, Collections.emptyList());
+	}
+	
+	/**
 	 * Returns all event (specification, not from the actual trace!) names of this ATDB of the given event type.
 	 * @param eventTypeName The event type name of which the returned event names shall be.
 	 * @return A list of all event names.
@@ -294,6 +313,75 @@
 	}
 	
 	/**
+	 * Returns all process (task or ISR) event (specification, not from the actual trace!) names of this ATDB.
+	 * @return A list of all process event names.
+	 * @throws SQLException
+	 */
+	public List<String> getAllProcessEvents() throws SQLException {
+		return Stream.concat(
+			getStringStreamFromPreparedQuery(EVENT_BY_ENTITY_TYPE_QUERY, Arrays.asList("T")),
+			getStringStreamFromPreparedQuery(EVENT_BY_ENTITY_TYPE_QUERY, Arrays.asList("I"))
+		).collect(Collectors.toList());
+	}
+	
+	/**
+	 * Returns all runnable event (specification, not from the actual trace!) names of this ATDB.
+	 * @return A list of all runnable event names.
+	 * @throws SQLException
+	 */
+	public List<String> getAllRunnableEvents() throws SQLException {
+		return getStringListFromPreparedQuery(EVENT_BY_ENTITY_TYPE_QUERY, Arrays.asList("R"));
+	}
+
+	/**
+	 * Returns all label event (specification, not from the actual trace!) names of this ATDB.
+	 * @return A list of all label event names.
+	 * @throws SQLException
+	 */
+	public List<String> getAllLabelEvents() throws SQLException {
+		return getStringListFromPreparedQuery(EVENT_BY_ENTITY_TYPE_QUERY, Arrays.asList("SIG"));
+	}
+
+	/**
+	 * Returns all stimulus event (specification, not from the actual trace!) names of this ATDB.
+	 * @return A list of all stimulus event names.
+	 * @throws SQLException
+	 */
+	public List<String> getAllStimulusEvents() throws SQLException {
+		return getStringListFromPreparedQuery(EVENT_BY_ENTITY_TYPE_QUERY, Arrays.asList("STI"));
+	}
+	
+	/**
+	 * Returns the event type name for the given event name.
+	 * @param eventName The name of the event of which we want to know the type.
+	 * @return The type name. Empty, if none was found.
+	 * @throws SQLException
+	 */
+	public String getEventTypeForEvent(final String eventName) throws SQLException {
+		return getFirstStringFromPreparedQuery(EVENT_TYPE_OF_EVENT_QUERY, Arrays.asList(eventName), "");
+	}
+	
+	/**
+	 * Returns the entity name for the given event name.
+	 * @param eventName The name of the event of which we want to know the affected entity.
+	 * @return The entity name. Empty, if none was found.
+	 * @throws SQLException
+	 */
+	public String getEntityForEvent(final String eventName) throws SQLException {
+		return getFirstStringFromPreparedQuery(ENTITY_OF_EVENT_QUERY, Arrays.asList(eventName), "");
+	}
+	
+	/**
+	 * Returns the source entity name for the given event name.
+	 * @param eventName The name of the event of which we want to know the source entity.
+	 * @return The source entity name. Empty, if none was found.
+	 * @throws SQLException
+	 */
+	public String getSourceEntityForEvent(final String eventName) throws SQLException {
+		return getFirstStringFromPreparedQuery(SOURCE_ENTITY_OF_EVENT_QUERY, Arrays.asList(eventName), "");
+	}
+	
+	/**
 	 * Returns the stimulus event name for the given event chain name. If there are multiple stimulus events, they will be separated by a ', '.
 	 * @param eventChainName The name of the event chain from which we want to know the stimulus event.
 	 * @return The stimulus event name. Empty, if none was found.