diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74b91a3192327ae476c221054c6888267516fe19..1c4c17bdeae18a7ac08447e75f4a6f3a25bd4b95 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 Upcoming version:
 -----------------
+  - implemented various different types for node queue (Nikolaus Krismer)
   - externalizing dependency versions (Nikolaus Krismer)
   - added configuration for vienna (Nikolaus Krismer)
   - upgrading gradle plugin shadowjar (Nikolaus Krismer)
diff --git a/src/main/java/it/unibz/inf/isochrone/algorithm/AbstractAlgorithm.java b/src/main/java/it/unibz/inf/isochrone/algorithm/AbstractAlgorithm.java
index 6e1c2f75703f98c3e8bab6421ec0be49226b0769..c32adca1984532f39084197cd539c4fd95fea759 100644
--- a/src/main/java/it/unibz/inf/isochrone/algorithm/AbstractAlgorithm.java
+++ b/src/main/java/it/unibz/inf/isochrone/algorithm/AbstractAlgorithm.java
@@ -7,7 +7,6 @@ import java.time.temporal.ChronoUnit;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -20,6 +19,8 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import it.unibz.inf.isochrone.algorithm.AlgorithmCache.Mode;
+import it.unibz.inf.isochrone.algorithm.queue.INodeQueue;
+import it.unibz.inf.isochrone.algorithm.queue.NodeQueueFactory;
 import it.unibz.inf.isochrone.algorithm.speed.ISpeedEstimation;
 import it.unibz.inf.isochrone.algorithm.speed.SpeedEstimationFactory;
 import it.unibz.inf.isochrone.config.ConfigAlgorithm;
@@ -36,7 +37,6 @@ import it.unibz.inf.isochrone.network.NodeConnection;
 import it.unibz.inf.isochrone.network.ServiceCalendar;
 import it.unibz.inf.isochrone.output.AbstractOutput;
 import it.unibz.inf.isochrone.output.MemoryOutput;
-import it.unibz.inf.isochrone.util.FibonacciHeap;
 
 /**
  * The isochrone algorithm. As the different algorithms all have
@@ -67,8 +67,8 @@ public abstract class AbstractAlgorithm {
 
 	private final AlgorithmCacheHelper cache;
 	private final ConfigAlgorithm config;
-	private final FibonacciHeap<INode> nodeQueue;
-	private final Map<INode, FibonacciHeap.Entry<INode>> nodeQueueEntries;
+	private final INodeQueue<INode> nodeQueue;
+
 	private final Predicate<IEdge> predicateContinuous;
 	private final AtomicBoolean running = new AtomicBoolean(false);
 	private final DaySpanContainer<String> routeIds;
@@ -162,11 +162,7 @@ public abstract class AbstractAlgorithm {
 			}
 		}
 
-		// FibonacciHeap serves as a PriorityQueue here (without the need to remove entries before adding them)
-		// To find HeapEntries we use a HashMap... although we need two structures this is still way faster than using a PriorityQueue alone
-		this.nodeQueue = new FibonacciHeap<>();
-		this.nodeQueueEntries = new HashMap<>();
-
+		this.nodeQueue = NodeQueueFactory.getInstance(config.getQueueType());
 		if (cIsMultimodal) {
 			predicateContinuous = l -> l.getMode() == Edge.Mode.STREET || l.getMode() == Edge.Mode.LINK;
 		} else {
@@ -421,7 +417,7 @@ public abstract class AbstractAlgorithm {
 
 					if (isWithinDuration(newDuration)) {
 						targetNode.setDuration(newDuration);
-						updateNodeQueue(targetNode);
+						nodeQueue.update(targetNode);
 					}
 				}
 			}
@@ -547,8 +543,7 @@ public abstract class AbstractAlgorithm {
 
 		running.set(true);
 		while (running.get() && hasExpandableNodes() && (!limitNodeCount || expandedNodes < cLimit)) {
-			final INode n = nodeQueue.dequeueMin().getValue();
-			nodeQueueEntries.remove(n);
+			final INode n = nodeQueue.dequeueMin();
 			expandNode(n);
 
 			++expandedNodes;
@@ -563,20 +558,7 @@ public abstract class AbstractAlgorithm {
 	 * @param node The node that was changed
 	 */
 	protected void updateNodeQueue(final INode node) {
-		if (node == null) {
-			return;
-		}
-
-		final float newPriority = node.getDuration();
-		FibonacciHeap.Entry<INode> e = nodeQueueEntries.get(node);
-		if (e == null) {
-			e = nodeQueue.enqueue(node, newPriority);
-			nodeQueueEntries.put(node, e);
-		} else if (newPriority < e.getPriority()) {
-			// this check for decreasing priority is only needed when using incremental cache calculation.
-			nodeQueue.decreaseKey(e, newPriority);
-			e.setValue(node);
-		}
+		nodeQueue.update(node);
 	}
 
 	// Package private methods
diff --git a/src/main/java/it/unibz/inf/isochrone/algorithm/queue/FibonacciHeap.java b/src/main/java/it/unibz/inf/isochrone/algorithm/queue/FibonacciHeap.java
index 267bfc660a17be5d79e2d5487eed2279c08f553f..0e2b52dfc65b338378aac80ff791f019fc53c8fa 100644
--- a/src/main/java/it/unibz/inf/isochrone/algorithm/queue/FibonacciHeap.java
+++ b/src/main/java/it/unibz/inf/isochrone/algorithm/queue/FibonacciHeap.java
@@ -51,7 +51,7 @@
 * dequeueMin to extract it.
 */
 
-package it.unibz.inf.isochrone.util;
+package it.unibz.inf.isochrone.algorithm.queue;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -63,7 +63,7 @@ import java.util.NoSuchElementException;
  * @param T The type of elements to store in the heap.
  * @author Keith Schwarz (htiek@cs.stanford.edu)
  */
-public final class FibonacciHeap<T> {
+final class FibonacciHeap<T> {
 	/**
 	 * In order for all of the Fibonacci heap operations to complete in O(1),
 	 * clients need to have O(1) access to any element in the heap. We make
diff --git a/src/main/java/it/unibz/inf/isochrone/algorithm/queue/NodeQueueFactory.java b/src/main/java/it/unibz/inf/isochrone/algorithm/queue/NodeQueueFactory.java
index 5c18fa865839ce39f33d750f33fec048afa7da42..f9d6d25b86ea303747c91bce25ea525ff11134ec 100644
--- a/src/main/java/it/unibz/inf/isochrone/algorithm/queue/NodeQueueFactory.java
+++ b/src/main/java/it/unibz/inf/isochrone/algorithm/queue/NodeQueueFactory.java
@@ -1,6 +1,5 @@
 package it.unibz.inf.isochrone.algorithm.queue;
 
-import it.unibz.inf.isochrone.config.ConfigAlgorithm.QueueType;
 import it.unibz.inf.isochrone.network.INode;
 
 public final class NodeQueueFactory {
diff --git a/src/main/java/it/unibz/inf/isochrone/config/ConfigAlgorithm.java b/src/main/java/it/unibz/inf/isochrone/config/ConfigAlgorithm.java
index 55cbcba1a9fcd1c14bc28212f268fc88e84d898d..b46323e0b89d4dba84c10c9668866947fc86e29b 100644
--- a/src/main/java/it/unibz/inf/isochrone/config/ConfigAlgorithm.java
+++ b/src/main/java/it/unibz/inf/isochrone/config/ConfigAlgorithm.java
@@ -13,6 +13,8 @@ import java.util.stream.Collectors;
 
 import javax.annotation.concurrent.Immutable;
 
+import it.unibz.inf.isochrone.algorithm.queue.QueueType;
+
 /**
  * A query is used to compute different isochrones.  It is fed to the
  * Isochrone algorithm which will use the data to figure out what type
@@ -63,6 +65,7 @@ public final class ConfigAlgorithm implements Serializable {
 	private final boolean outputOnlyExpandedEdges;
 	private final Collection<Point2D.Double> queryPoints;
 	private final Integer queryPointSRID;
+	private final QueueType queueType;
 	private final SpeedEstimation speedEstimation;
 	private final boolean useCache;
 	private final boolean useIncrementalCache;
@@ -84,6 +87,7 @@ public final class ConfigAlgorithm implements Serializable {
 		private Mode mode = Mode.ISOCHRONE_MULTIMODAL;
 		private boolean outputOnlyExpandedEdges = false;
 		private Integer queryPointSRID = null;
+		private QueueType queueType = QueueType.FIBONACCI_HEAP;
 		private SpeedEstimation speedEstimation = SpeedEstimation.VALUE;
 		private boolean useCache = false;
 		private boolean useIncrementalCache = false;
@@ -156,6 +160,10 @@ public final class ConfigAlgorithm implements Serializable {
 		}
 
 		public ConfigAlgorithmBuilder mode(final Mode mode) {
+			if (mode == null) {
+				throw new NullPointerException("Can not set mode to null!");
+			}
+
 			this.mode = mode;
 			return this;
 		}
@@ -179,7 +187,20 @@ public final class ConfigAlgorithm implements Serializable {
 			return this;
 		}
 
+		public ConfigAlgorithmBuilder queueType(final QueueType queueType) {
+			if (queueType == null) {
+				throw new NullPointerException("Can not set queue type to null!");
+			}
+
+			this.queueType = queueType;
+			return this;
+		}
+
 		public ConfigAlgorithmBuilder speedEstimation(final SpeedEstimation speedEstimation) {
+			if (speedEstimation == null) {
+				throw new NullPointerException("Can not set speed estimation to null!");
+			}
+
 			this.speedEstimation = speedEstimation;
 			if (speedEstimation != SpeedEstimation.USER_PROFILE) {
 				this.userProfile = null;
@@ -226,6 +247,7 @@ public final class ConfigAlgorithm implements Serializable {
 		this.useCache = builder.useCache;
 		this.useIncrementalCache = builder.useIncrementalCache;
 		this.queryPoints = builder.queryPoints;
+		this.queueType = builder.queueType;
 		this.speedEstimation = builder.speedEstimation;
 		this.userProfile = builder.userProfile;
 
@@ -296,6 +318,10 @@ public final class ConfigAlgorithm implements Serializable {
 		return queryPointSRID;
 	}
 
+	public QueueType getQueueType() {
+		return queueType;
+	}
+
 	public SpeedEstimation getSpeedEstimation() {
 		return speedEstimation;
 	}
@@ -353,6 +379,7 @@ public final class ConfigAlgorithm implements Serializable {
 		if (getClass() != obj.getClass()) {
 			return false;
 		}
+
 		final ConfigAlgorithm other = (ConfigAlgorithm) obj;
 		if (activateStatistics != other.activateStatistics) {
 			return false;
@@ -400,6 +427,12 @@ public final class ConfigAlgorithm implements Serializable {
 		} else if (!queryPoints.equals(other.queryPoints)) {
 			return false;
 		}
+		if (queueType != other.queueType) {
+			return false;
+		}
+		if (speedEstimation != other.speedEstimation) {
+			return false;
+		}
 		if (toTime == null) {
 			if (other.toTime != null) {
 				return false;
@@ -407,17 +440,24 @@ public final class ConfigAlgorithm implements Serializable {
 		} else if (!toTime.equals(other.toTime)) {
 			return false;
 		}
+		if (travelSpeed == null) {
+			if (other.travelSpeed != null) {
+				return false;
+			}
+		} else if (!travelSpeed.equals(other.travelSpeed)) {
+			return false;
+		}
 		if (useCache != other.useCache) {
 			return false;
 		}
 		if (useIncrementalCache != other.useIncrementalCache) {
 			return false;
 		}
-		if (travelSpeed == null) {
-			if (other.travelSpeed != null) {
+		if (userProfile == null) {
+			if (other.userProfile != null) {
 				return false;
 			}
-		} else if (!travelSpeed.equals(other.travelSpeed)) {
+		} else if (!userProfile.equals(other.userProfile)) {
 			return false;
 		}
 
@@ -439,10 +479,12 @@ public final class ConfigAlgorithm implements Serializable {
 		result = prime * result + (outputOnlyExpandedEdges ? 1231 : 1237);
 		result = prime * result + ((queryPointSRID == null) ? 0 : queryPointSRID.hashCode());
 		result = prime * result + ((queryPoints == null) ? 0 : queryPoints.hashCode());
+		result = prime * result + ((queueType == null) ? 0 : queueType.hashCode());
+		result = prime * result + ((speedEstimation == null) ? 0 : speedEstimation.hashCode());
 		result = prime * result + ((toTime == null) ? 0 : toTime.hashCode());
+		result = prime * result + ((travelSpeed == null) ? 0 : travelSpeed.hashCode());
 		result = prime * result + (useCache ? 1231 : 1237);
 		result = prime * result + (useIncrementalCache ? 1231 : 1237);
-		result = prime * result + ((travelSpeed == null) ? 0 : travelSpeed.hashCode());
 		// CHECKSTYLE:ON MagicNumber
 
 		return result;
@@ -456,8 +498,11 @@ public final class ConfigAlgorithm implements Serializable {
 			+ ", limit=" + limit
 			+ ", limitType=" + limitType
 			+ ", mode=" + mode
+			+ ", speedEstimation=" + speedEstimation
 			+ ", travelSpeed=" + travelSpeed
+			+ ", userProfile=" + userProfile
 			+ ", queryPoints=[" + ((queryPoints == null) ? "null" : queryPoints.stream().map(p -> "[" + p.getX() + "," + p.getY() + "]").collect(Collectors.joining(", "))) + "]"
+			+ ", queueType=" + queueType
 			+ "]";
 	}
 
diff --git a/src/main/java/it/unibz/inf/isochrone/config/ConfigDatasetFinder.java b/src/main/java/it/unibz/inf/isochrone/config/ConfigDatasetFinder.java
index a35aa9e2177f859389762c758b03bd3f3fc7ed43..ef7447b281b189e4358abccf152d3d4e7d24d8d0 100644
--- a/src/main/java/it/unibz/inf/isochrone/config/ConfigDatasetFinder.java
+++ b/src/main/java/it/unibz/inf/isochrone/config/ConfigDatasetFinder.java
@@ -6,10 +6,8 @@ import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.regex.Matcher;
@@ -29,6 +27,7 @@ final class ConfigDatasetFinder {
 
 	static final String DS_ARCHIVE_PATTERN = "^(.)*isochrone([\\w-.])*\\.(\\w)*$";
 	static final String DS_CONFIG_PATTERN = "^(.)*config\\_(\\w*)\\." + DS_CONFIG_EXTENSION + "$";
+	static final String PROPERTY_FORCE_DATASETS = "forceDatasets";
 	static final String PROPERTY_SKIP_DATASETS = "skipDatasets";
 
 	// Constructor
@@ -54,11 +53,12 @@ final class ConfigDatasetFinder {
 			throw new NullPointerException("AllTableNames must not be null!");
 		}
 
+		final Collection<String> forceNames = getDatasetsToForce();
 		final Collection<String> skipNames = getDatasetsToSkip();
 		final Collection<String> configNames = getDatasetsFromConfig();
 		final List<ConfigDataset> dsConfigs = new ArrayList<>(configNames.size());
 		for (final String dsName : configNames) {
-			if (!skipNames.contains(dsName)) {
+			if (!skipNames.contains(dsName) && (forceNames == null || forceNames.contains(dsName))) {
 				LOGGER.debug("   adding dataset configuration: {}", dsName);
 				dsConfigs.add(ConfigDataset.createInstance(dsName));
 			}
@@ -67,7 +67,14 @@ final class ConfigDatasetFinder {
 		if (filterUninitialized) {
 			LOGGER.info("Skipping search for unconfigured datasets.");
 		} else {
-			final Collection<String> unconfiguredDatasets = getUnconfiguredDatasets(dsConfigs, skipNames, allTableNames);
+			final List<String> unconfiguredDatasets = new ArrayList<>(getUnconfiguredDatasets(dsConfigs, allTableNames));
+			for (final ListIterator<String> i = unconfiguredDatasets.listIterator(); i.hasNext();) {
+				final String dsName = i.next();
+				if (skipNames.contains(dsName) || (forceNames != null && !forceNames.contains(dsName))) {
+					i.remove();
+				}
+			}
+
 			if (unconfiguredDatasets.size() <= 0) {
 				LOGGER.info("There is a configuration file for every dataset in the database.");
 			} else {
@@ -92,7 +99,7 @@ final class ConfigDatasetFinder {
 		return dsConfigs.stream().filter(ds -> isValidDataset(ds, filterInvalid, filterSynthetic)).collect(Collectors.toList());
 	}
 
-	private static Collection<String> getUnconfiguredDatasets(final Collection<ConfigDataset> dsConfigs, final Collection<String> skipNames, final Collection<String> tableNames) {
+	private static Collection<String> getUnconfiguredDatasets(final Collection<ConfigDataset> dsConfigs, final Collection<String> tableNames) {
 		final List<String> unconfiguredTableNames = new ArrayList<>(tableNames);
 
 		// remove all configured tables
@@ -112,17 +119,12 @@ final class ConfigDatasetFinder {
 			);
 		}
 
-		final Set<String> unconfiguredDatasets = new HashSet<>();
+		final Collection<String> unconfiguredDatasets = new TreeSet<>();
 		for (final ListIterator<String> i = unconfiguredTableNames.listIterator(); i.hasNext();) {
 			final String tableName = i.next();
 			final int i0 = tableName.indexOf('_');
 			if (i0 > 0) {
-				final String dsName = tableName.substring(0, i0);
-				if (skipNames.contains(dsName)) {
-					i.remove();
-				} else {
-					unconfiguredDatasets.add(dsName);
-				}
+				unconfiguredDatasets.add(tableName.substring(0, i0));
 			}
 		}
 
@@ -178,6 +180,26 @@ final class ConfigDatasetFinder {
 		return datasets;
 	}
 
+	private static Collection<String> getDatasetsToForce() {
+		final Collection<String> forceNames;
+
+		final String strForced = SystemHelper.getProperty(PROPERTY_FORCE_DATASETS);
+		if (strForced == null) {
+			LOGGER.debug("No datasets will be forced (non were specified using the system property \"" + PROPERTY_FORCE_DATASETS + "\")");
+			forceNames = null;
+		} else {
+			LOGGER.info("Some datasets will be forced (specified by user using system property \"" + PROPERTY_FORCE_DATASETS + "\")");
+			final String[] dsSkipped = strForced.split(",");
+			forceNames = new ArrayList<>(dsSkipped.length);
+			for (final String dsName : dsSkipped) {
+				LOGGER.debug("   dataset \"{}\" will not be used since it was marked to be skipped!", dsName);
+				forceNames.add(dsName);
+			}
+		}
+
+		return forceNames;
+	}
+
 	private static Collection<String> getDatasetsToSkip() {
 		final Collection<String> skipNames;
 
diff --git a/src/performance/java/it/unibz/inf/isochrone/SampleHelper.java b/src/performance/java/it/unibz/inf/isochrone/SampleHelper.java
index d83d3a7a854de6c17bd9d59a7ab6156ca1c7c6f4..025f89082cabf20c93b30dd3201721ce838f39a2 100644
--- a/src/performance/java/it/unibz/inf/isochrone/SampleHelper.java
+++ b/src/performance/java/it/unibz/inf/isochrone/SampleHelper.java
@@ -17,9 +17,6 @@ public final class SampleHelper {
 		return new SampleRunnerBuilder[] {
 			new SampleRunnerBuilder()
 			.addDatasets(ConfigAlgorithmHelper.getAllDatasetsRW())
-//			.addDatasets("berlin", "bolzano", "ulm")
-//			.addDatasets("berlin")
-//			.addDatasets("bolzano")
 			.addMaxDuration(TestConfiguration.DEFAULT_MAX_DURATION)
 			.addMaxNodes(TestConfiguration.DEFAULT_MAX_NODES)
 		};
diff --git a/src/test/java/it/unibz/inf/isochrone/ConfigAlgorithmHelper.java b/src/test/java/it/unibz/inf/isochrone/ConfigAlgorithmHelper.java
index 251a1475ebbdcdd2c16bab961dd85dbacd80da21..b9e5c2e850e63f63ddeec3698e93822690816578 100644
--- a/src/test/java/it/unibz/inf/isochrone/ConfigAlgorithmHelper.java
+++ b/src/test/java/it/unibz/inf/isochrone/ConfigAlgorithmHelper.java
@@ -3,6 +3,8 @@ package it.unibz.inf.isochrone;
 import java.awt.geom.Point2D;
 import java.lang.reflect.Array;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
 import java.util.TreeMap;
@@ -18,6 +20,7 @@ import it.unibz.inf.isochrone.util.SystemHelper;
 
 public final class ConfigAlgorithmHelper {
 	private static final int DEFAULT_SYNTHETIC_LENGTH = 60;
+	private static final String PROPERTY_FORCE_DATASETS = "forceDatasets";
 	private static final String PROPERTY_SKIP_DATASETS = "skipDatasets";
 	private static final int SRID_SYNTHETIC = 3857;
 
@@ -149,6 +152,16 @@ public final class ConfigAlgorithmHelper {
 			}
 		}
 
+		final String strForced = SystemHelper.getProperty(PROPERTY_FORCE_DATASETS);
+		final String[] dsForced = (strForced == null) ? null : strForced.split(",");
+		if (dsForced != null && dsForced.length > 0) {
+			final Collection<String> toRemove = new ArrayList<>(builderMap.keySet());
+			toRemove.removeAll(Arrays.asList(dsForced));
+			for (final String dsName : toRemove) {
+				builderMap.remove(dsName);
+			}
+		}
+
 		return builderMap;
 	}