Repository: graphhopper/graphhopper
Pull request #1336 (2018-04-11 16:52:27)

Some minor refactoring picked from turncost_ch branch.
* Fixes some typos and whitespace
* Adds visited nodes sum to via routing template debug info.


Patch:
diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java
index 51f17bd9a..8f4ce86af 100644
--- a/core/src/main/java/com/graphhopper/GraphHopper.java
+++ b/core/src/main/java/com/graphhopper/GraphHopper.java
@@ -1066,6 +1066,7 @@ public class GraphHopper implements GraphHopperAPI {
                         hints(hints).
                         build();
 
+                // do the actual route calculation !
                 altPaths = routingTemplate.calcPaths(queryGraph, tmpAlgoFactory, algoOpts);
 
                 boolean tmpEnableInstructions = hints.getBool(Routing.INSTRUCTIONS, enableInstructions);
@@ -1219,9 +1220,9 @@ public class GraphHopper implements GraphHopperAPI {
         preparation.setMinOneWayNetworkSize(minOneWayNetworkSize);
         preparation.doWork();
         int currNodeCount = ghStorage.getNodes();
-        logger.info("edges: " + ghStorage.getAllEdges().length() + ", nodes " + currNodeCount
-                + ", there were " + preparation.getMaxSubnetworks()
-                + " subnetworks. removed them => " + (prevNodeCount - currNodeCount)
+        logger.info("edges: " + Helper.nf(ghStorage.getAllEdges().length()) + ", nodes " + Helper.nf(currNodeCount)
+                + ", there were " + Helper.nf(preparation.getMaxSubnetworks())
+                + " subnetworks. removed them => " + Helper.nf(prevNodeCount - currNodeCount)
                 + " less nodes");
     }
 
diff --git a/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java b/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java
index 8412043c2..f30b86083 100644
--- a/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java
+++ b/core/src/main/java/com/graphhopper/routing/AlgorithmOptions.java
@@ -142,7 +142,7 @@ public class AlgorithmOptions {
         }
 
         /**
-         * For possible values see Parameters.Algorithms
+         * For possible values see {@link Parameters.Algorithms}
          */
         public Builder algorithm(String algorithm) {
             this.opts.algorithm = algorithm;
diff --git a/core/src/main/java/com/graphhopper/routing/Dijkstra.java b/core/src/main/java/com/graphhopper/routing/Dijkstra.java
index b57650f9e..1d68574ea 100644
--- a/core/src/main/java/com/graphhopper/routing/Dijkstra.java
+++ b/core/src/main/java/com/graphhopper/routing/Dijkstra.java
@@ -50,8 +50,8 @@ public class Dijkstra extends AbstractRoutingAlgorithm {
     }
 
     protected void initCollections(int size) {
-        fromHeap = new PriorityQueue<SPTEntry>(size);
-        fromMap = new GHIntObjectHashMap<SPTEntry>(size);
+        fromHeap = new PriorityQueue<>(size);
+        fromMap = new GHIntObjectHashMap<>(size);
     }
 
     @Override
diff --git a/core/src/main/java/com/graphhopper/routing/PathBidirRef.java b/core/src/main/java/com/graphhopper/routing/PathBidirRef.java
index 6a1a43583..447161eed 100644
--- a/core/src/main/java/com/graphhopper/routing/PathBidirRef.java
+++ b/core/src/main/java/com/graphhopper/routing/PathBidirRef.java
@@ -61,7 +61,7 @@ public class PathBidirRef extends Path {
             return this;
 
         if (sptEntry.adjNode != edgeTo.adjNode)
-            throw new IllegalStateException("Locations of the 'to'- and 'from'-Edge has to be the same." + toString() + ", fromEntry:" + sptEntry + ", toEntry:" + edgeTo);
+            throw new IllegalStateException("Locations of the 'to'- and 'from'-Edge have to be the same. " + toString() + ", fromEntry:" + sptEntry + ", toEntry:" + edgeTo);
 
         extractSW.start();
         if (switchFromAndToSPTEntry) {
diff --git a/core/src/main/java/com/graphhopper/routing/QueryGraph.java b/core/src/main/java/com/graphhopper/routing/QueryGraph.java
index a05b15078..39e875258 100644
--- a/core/src/main/java/com/graphhopper/routing/QueryGraph.java
+++ b/core/src/main/java/com/graphhopper/routing/QueryGraph.java
@@ -52,7 +52,7 @@ import java.util.*;
  * @author Peter Karich
  */
 public class QueryGraph implements Graph {
-    final static int VE_BASE = 0, VE_BASE_REV = 1, VE_ADJ = 2, VE_ADJ_REV = 3;
+    static final int VE_BASE = 0, VE_BASE_REV = 1, VE_ADJ = 2, VE_ADJ_REV = 3;
     private static final AngleCalc AC = Helper.ANGLE_CALC;
     private final Graph mainGraph;
     private final NodeAccess mainNodeAccess;
@@ -61,7 +61,7 @@ public class QueryGraph implements Graph {
     private final QueryGraph baseGraph;
     private final GraphExtension wrappedExtension;
     // TODO when spreading it on different threads we need multiple independent explorers
-    private final Map<Integer, EdgeExplorer> cacheMap = new HashMap<Integer, EdgeExplorer>(4);
+    private final Map<Integer, EdgeExplorer> cacheMap = new HashMap<>(4);
 
     // For every virtual node there are 4 edges: base-snap, snap-base, snap-adj, adj-snap.
     List<VirtualEdgeIteratorState> virtualEdges;
diff --git a/core/src/main/java/com/graphhopper/routing/ch/CHAlgoFactoryDecorator.java b/core/src/main/java/com/graphhopper/routing/ch/CHAlgoFactoryDecorator.java
index f4898ea1a..1c389fe59 100644
--- a/core/src/main/java/com/graphhopper/routing/ch/CHAlgoFactoryDecorator.java
+++ b/core/src/main/java/com/graphhopper/routing/ch/CHAlgoFactoryDecorator.java
@@ -39,8 +39,8 @@ import static com.graphhopper.util.Helper.*;
 import static com.graphhopper.util.Parameters.CH.DISABLE;
 
 /**
- * This class implements the CH decorator and provides several helper methods related to CH
- * preparation and its vehicle profiles.
+ * This class implements the CH decorator for the routing algorithm factory and provides several
+ * helper methods related to CH preparation and its vehicle profiles.
  *
  * @author Peter Karich
  */
diff --git a/core/src/main/java/com/graphhopper/routing/ch/NodeContractor.java b/core/src/main/java/com/graphhopper/routing/ch/NodeContractor.java
index 63500bd8c..817ae8f9f 100644
--- a/core/src/main/java/com/graphhopper/routing/ch/NodeContractor.java
+++ b/core/src/main/java/com/graphhopper/routing/ch/NodeContractor.java
@@ -69,7 +69,7 @@ class NodeContractor {
     void initFromGraph() {
         // todo: do we really need this method ? the problem is that ghStorage/prepareGraph can potentially be modified
         // between the constructor call and contractNode,calcShortcutCount etc. ...
-        maxLevel = prepareGraph.getNodes() + 1;
+        maxLevel = prepareGraph.getNodes();
         maxEdgesCount = ghStorage.getAllEdges().length();
         ignoreNodeFilter = new IgnoreNodeFilter(prepareGraph, maxLevel);
         FlagEncoder prepareFlagEncoder = prepareWeighting.getFlagEncoder();
diff --git a/core/src/main/java/com/graphhopper/routing/ch/PreparationWeighting.java b/core/src/main/java/com/graphhopper/routing/ch/PreparationWeighting.java
index e937edeb4..79c6ad1b1 100644
--- a/core/src/main/java/com/graphhopper/routing/ch/PreparationWeighting.java
+++ b/core/src/main/java/com/graphhopper/routing/ch/PreparationWeighting.java
@@ -24,7 +24,7 @@ import com.graphhopper.util.CHEdgeIteratorState;
 import com.graphhopper.util.EdgeIteratorState;
 
 /**
- * Used in CH preparation and therefor assumed that all edges are of type CHEdgeIteratorState
+ * Used in CH preparation and therefore assumed that all edges are of type CHEdgeIteratorState
  * <p>
  *
  * @author Peter Karich
diff --git a/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java b/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java
index 6106deb49..2f22d8c85 100644
--- a/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java
+++ b/core/src/main/java/com/graphhopper/routing/ch/PrepareContractionHierarchies.java
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
 
 import java.util.*;
 
+import static com.graphhopper.util.Helper.nf;
 import static com.graphhopper.util.Parameters.Algorithms.ASTAR_BI;
 import static com.graphhopper.util.Parameters.Algorithms.DIJKSTRA_BI;
 
@@ -59,7 +60,7 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
     private CHEdgeExplorer vehicleAllTmpExplorer;
     private CHEdgeExplorer calcPrioAllExplorer;
     private int maxLevel;
-    // the most important nodes comes last
+    // nodes with highest priority come last
     private GHTreeMapComposed sortedNodes;
     private int oldPriorities[];
     private double meanDegree;
@@ -72,6 +73,7 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
     private double periodTime;
     private double lazyTime;
     private double neighborTime;
+    private int initSize;
 
     public PrepareContractionHierarchies(Directory dir, GraphHopperStorage ghStorage, CHGraph chGraph,
                                          Weighting weighting, TraversalMode traversalMode) {
@@ -156,14 +158,31 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
     }
 
     @Override
-    public void doWork() {
+    public void doSpecificWork() {
         allSW.start();
-        super.doWork();
-
         initFromGraph();
+        runGraphContraction();
+
+        logger.info("took:" + (int) allSW.stop().getSeconds() + "s "
+                + ", new shortcuts: " + nf(nodeContractor.getAddedShortcutsCount())
+                + ", " + prepareWeighting
+                + ", dijkstras:" + nf(nodeContractor.getDijkstraCount())
+                + ", " + getTimesAsString()
+                + ", meanDegree:" + (long) meanDegree
+                + ", initSize:" + nf(initSize)
+                + ", periodic:" + periodicUpdatesPercentage
+                + ", lazy:" + lastNodesLazyUpdatePercentage
+                + ", neighbor:" + neighborUpdatePercentage
+                + ", " + Helper.getMemInfo());
+
+        int edgeCount = ghStorage.getAllEdges().length();
+        logger.info("graph now - num edges: {}, num nodes: {}, num shortcuts: {}",
+                nf(edgeCount), nf(ghStorage.getNodes()), nf(prepareGraph.getAllEdges().length() - edgeCount));
+    }
+
+    protected void runGraphContraction() {
         if (!prepareNodes())
             return;
-
         contractNodes();
     }
 
@@ -201,7 +220,7 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
             }
         };
 
-        maxLevel = prepareGraph.getNodes() + 1;
+        maxLevel = prepareGraph.getNodes();
         vehicleAllExplorer = prepareGraph.createEdgeExplorer(allFilter);
         vehicleAllTmpExplorer = prepareGraph.createEdgeExplorer(allFilter);
         calcPrioAllExplorer = prepareGraph.createEdgeExplorer(accessWithLevelFilter);
@@ -239,10 +258,10 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
         // no witness path can be found. this is not really what we want, but changing it requires re-optimizing the
         // graph contraction parameters, because it affects the node contraction order.
         meanDegree = prepareGraph.getAllEdges().length() / prepareGraph.getNodes();
-        int level = 1;
+        initSize = sortedNodes.getSize();
+        int level = 0;
         long counter = 0;
-        int initSize = sortedNodes.getSize();
-        long logSize = Math.round(Math.max(10, sortedNodes.getSize() / 100 * logMessagesPercentage));
+        long logSize = Math.round(Math.max(10, initSize / 100d * logMessagesPercentage));
         if (logMessagesPercentage == 0)
             logSize = Integer.MAX_VALUE;
 
@@ -261,7 +280,7 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
 
         // according to paper "Polynomial-time Construction of Contraction Hierarchies for Multi-criteria Objectives" by Funke and Storandt
         // we don't need to wait for all nodes to be contracted
-        long nodesToAvoidContract = Math.round((100 - nodesContractedPercentage) / 100 * sortedNodes.getSize());
+        long nodesToAvoidContract = Math.round((100 - nodesContractedPercentage) / 100d * sortedNodes.getSize());
         StopWatch lazySW = new StopWatch();
 
         // Recompute priority of uncontracted neighbors.
@@ -297,14 +316,7 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
                 lazyTime += lazySW.getSeconds();
                 neighborTime += neighborSW.getSeconds();
 
-                logger.info(Helper.nf(counter) + ", updates:" + updateCounter
-                        + ", nodes: " + Helper.nf(sortedNodes.getSize())
-                        + ", shortcuts:" + Helper.nf(nodeContractor.getAddedShortcutsCount())
-                        + ", dijkstras:" + Helper.nf(nodeContractor.getDijkstraCount())
-                        + ", " + getTimesAsString()
-                        + ", meanDegree:" + (long) meanDegree
-                        + ", algo:" + nodeContractor.getPrepareAlgoMemoryUsage()
-                        + ", " + Helper.getMemInfo());
+                logStats(counter, updateCounter);
 
                 nodeContractor.resetDijkstraTime();
                 periodSW = new StopWatch();
@@ -364,28 +376,18 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
             }
         }
 
-        // Preparation works only once so we can release temporary data.
-        // The preparation object itself has to be intact to create the algorithm.
-        close();
-
         dijkstraTime += nodeContractor.getDijkstraSeconds();
         periodTime += periodSW.getSeconds();
         lazyTime += lazySW.getSeconds();
         neighborTime += neighborSW.getSeconds();
-        logger.info("took:" + (int) allSW.stop().getSeconds()
-                + ", new shortcuts: " + Helper.nf(nodeContractor.getAddedShortcutsCount())
-                + ", " + prepareWeighting
-                + ", dijkstras:" + nodeContractor.getDijkstraCount()
-                + ", " + getTimesAsString()
-                + ", meanDegree:" + (long) meanDegree
-                + ", initSize:" + initSize
-                + ", periodic:" + periodicUpdatesPercentage
-                + ", lazy:" + lastNodesLazyUpdatePercentage
-                + ", neighbor:" + neighborUpdatePercentage
-                + ", " + Helper.getMemInfo());
+        logStats(counter, updateCounter);
+
+        // Preparation works only once so we can release temporary data.
+        // The preparation object itself has to be intact to create the algorithm.
+        close();
     }
 
-    public void close() {
+    private void close() {
         nodeContractor.close();
         sortedNodes = null;
         oldPriorities = null;
@@ -420,10 +422,9 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
     }
 
     private String getTimesAsString() {
-        return "t(dijk):" + Helper.round2(dijkstraTime)
-                + ", t(period):" + Helper.round2(periodTime)
-                + ", t(lazy):" + Helper.round2(lazyTime)
-                + ", t(neighbor):" + Helper.round2(neighborTime);
+        return String.format(Locale.ROOT,
+                "t(dijk): %6.2f, t(period): %6.2f, t(lazy): %6.2f, t(neighbor): %6.2f",
+                dijkstraTime, periodTime, lazyTime, neighborTime);
     }
 
     /**
@@ -481,4 +482,12 @@ public class PrepareContractionHierarchies extends AbstractAlgoPreparation imple
         return "prepare|dijkstrabi|ch";
     }
 
+    private void logStats(long counter, int updateCounter) {
+        logger.info(String.format(Locale.ROOT,
+                "%10s, updates: %2d, nodes: %10s, shortcuts: %10s, dijkstras: %10s, %s, meanDegree: %2d, %s, %s",
+                nf(counter), updateCounter, nf(sortedNodes.getSize()),
+                nf(nodeContractor.getAddedShortcutsCount()), nf(nodeContractor.getDijkstraCount()),
+                getTimesAsString(), (long) meanDegree, nodeContractor.getPrepareAlgoMemoryUsage(),
+                Helper.getMemInfo()));
+    }
 }
diff --git a/core/src/main/java/com/graphhopper/routing/lm/PrepareLandmarks.java b/core/src/main/java/com/graphhopper/routing/lm/PrepareLandmarks.java
index 50b083a82..0de7f6524 100644
--- a/core/src/main/java/com/graphhopper/routing/lm/PrepareLandmarks.java
+++ b/core/src/main/java/com/graphhopper/routing/lm/PrepareLandmarks.java
@@ -122,9 +122,7 @@ public class PrepareLandmarks extends AbstractAlgoPreparation {
     }
 
     @Override
-    public void doWork() {
-        super.doWork();
-
+    public void doSpecificWork() {
         StopWatch sw = new StopWatch().start();
         LOGGER.info("Start calculating " + lms.getLandmarkCount() + " landmarks, default active lms:"
                 + defaultActiveLandmarks + ", weighting:" + lms.getLmSelectionWeighting() + ", " + Helper.getMemInfo());
@@ -141,7 +139,7 @@ public class PrepareLandmarks extends AbstractAlgoPreparation {
         int activeLM = Math.max(1, opts.getHints().getInt(Landmark.ACTIVE_COUNT, defaultActiveLandmarks));
         if (algo instanceof AStar) {
             if (!lms.isInitialized())
-                throw new IllegalStateException("Initalize landmark storage before creating algorithms");
+                throw new IllegalStateException("Initialize landmark storage before creating algorithms");
 
             double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStar.EPSILON, 1);
             AStar astar = (AStar) algo;
@@ -150,7 +148,7 @@ public class PrepareLandmarks extends AbstractAlgoPreparation {
             return algo;
         } else if (algo instanceof AStarBidirection) {
             if (!lms.isInitialized())
-                throw new IllegalStateException("Initalize landmark storage before creating algorithms");
+                throw new IllegalStateException("Initialize landmark storage before creating algorithms");
 
             double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStarBi.EPSILON, 1);
             AStarBidirection astarbi = (AStarBidirection) algo;
@@ -159,7 +157,7 @@ public class PrepareLandmarks extends AbstractAlgoPreparation {
             return algo;
         } else if (algo instanceof AlternativeRoute) {
             if (!lms.isInitialized())
-                throw new IllegalStateException("Initalize landmark storage before creating algorithms");
+                throw new IllegalStateException("Initialize landmark storage before creating algorithms");
 
             double epsilon = opts.getHints().getDouble(Parameters.Algorithms.AStarBi.EPSILON, 1);
             AlternativeRoute altRoute = (AlternativeRoute) algo;
diff --git a/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java b/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java
index 749ca67c3..fc516f659 100644
--- a/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java
+++ b/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java
@@ -112,6 +112,8 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
             String debug = ", algoInit:" + sw.stop().getSeconds() + "s";
 
             sw = new StopWatch().start();
+
+            // calculate paths
             List<Path> tmpPathList = algo.calcPaths(fromQResult.getClosestNode(), toQResult.getClosestNode());
             debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s";
             if (tmpPathList.isEmpty())
@@ -136,6 +138,7 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
                 throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
 
             visitedNodesSum += algo.getVisitedNodes();
+            altResponse.addDebugInfo("visited nodes sum: " + visitedNodesSum);
             fromQResult = toQResult;
         }
 
diff --git a/core/src/main/java/com/graphhopper/routing/util/AbstractAlgoPreparation.java b/core/src/main/java/com/graphhopper/routing/util/AbstractAlgoPreparation.java
index 7d2715e11..eabb9e109 100644
--- a/core/src/main/java/com/graphhopper/routing/util/AbstractAlgoPreparation.java
+++ b/core/src/main/java/com/graphhopper/routing/util/AbstractAlgoPreparation.java
@@ -26,10 +26,12 @@ public abstract class AbstractAlgoPreparation {
     public void doWork() {
         if (prepared)
             throw new IllegalStateException("Call doWork only once!");
-
         prepared = true;
+        doSpecificWork();
     }
 
+    protected abstract void doSpecificWork();
+
     public boolean isPrepared() {
         return prepared;
     }
diff --git a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java
index 42ee44989..37252a55a 100644
--- a/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java
+++ b/core/src/main/java/com/graphhopper/routing/util/AbstractFlagEncoder.java
@@ -599,7 +599,7 @@ public abstract class AbstractFlagEncoder implements FlagEncoder, TurnCostEncode
             if (costs != 0 || Double.isInfinite(costs))
                 throw new IllegalArgumentException("Restricted turn can only have infinite costs (or use 0)");
         } else if (costs >= maxTurnCosts)
-            throw new IllegalArgumentException("Cost is too high. Or specifiy restricted == true");
+            throw new IllegalArgumentException("Cost is too high. Or specify restricted == true");
 
         if (costs < 0)
             throw new IllegalArgumentException("Turn costs cannot be negative");
@@ -682,7 +682,7 @@ public abstract class AbstractFlagEncoder implements FlagEncoder, TurnCostEncode
      */
     protected double applyMaxSpeed(ReaderWay way, double speed) {
         double maxSpeed = getMaxSpeed(way);
-        // We obay speed limits
+        // We obey speed limits
         if (maxSpeed >= 0) {
             // We assume that the average speed is 90% of the allowed maximum
             return maxSpeed * 0.9;
diff --git a/core/src/main/java/com/graphhopper/routing/util/LevelEdgeFilter.java b/core/src/main/java/com/graphhopper/routing/util/LevelEdgeFilter.java
index d3bbdaf56..4ce54b06e 100644
--- a/core/src/main/java/com/graphhopper/routing/util/LevelEdgeFilter.java
+++ b/core/src/main/java/com/graphhopper/routing/util/LevelEdgeFilter.java
@@ -22,7 +22,7 @@ import com.graphhopper.util.CHEdgeIteratorState;
 import com.graphhopper.util.EdgeIteratorState;
 
 /**
- * Only certain nodes are accepted and therefor the others are ignored.
+ * Only accepts edges leading to equal and higher level nodes. Used in CH preparation.
  * <p>
  *
  * @author Peter Karich
diff --git a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java b/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
index 00693d2dc..68286c0d8 100644
--- a/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
+++ b/core/src/main/java/com/graphhopper/storage/GraphBuilder.java
@@ -23,7 +23,7 @@ import com.graphhopper.routing.weighting.Weighting;
 import java.util.Arrays;
 
 /**
- * For now this is just a helper class to quickly create a GraphStorage.
+ * For now this is just a helper class to quickly create a {@link GraphHopperStorage}
  * <p>
  *
  * @author Peter Karich
@@ -86,16 +86,14 @@ public class GraphBuilder {
     }
 
     /**
-     * Default graph is a GraphStorage with an in memory directory and disabled storing on flush.
-     * Afterwards you'll need to call GraphStorage. Create to have a usable object. Better use
-     * create.
+     * Default graph is a {@link GraphHopperStorage} with an in memory directory and disabled storing on flush.
+     * Afterwards you'll need to call {@link GraphHopperStorage#create} to have a usable object. Better use
+     * {@link GraphHopperStorage#create} directly.
      */
     public GraphHopperStorage build() {
-        Directory dir;
-        if (mmap)
-            dir = new MMapDirectory(location);
-        else
-            dir = new RAMDirectory(location, store);
+        Directory dir = mmap ?
+                new MMapDirectory(location) :
+                new RAMDirectory(location, store);
 
         GraphHopperStorage graph;
         if (encodingManager.needsTurnCostsSupport() || singleCHWeighting == null)
@@ -107,7 +105,7 @@ public class GraphBuilder {
     }
 
     /**
-     * Default graph is a GraphStorage with an in memory directory and disabled storing on flush.
+     * Default graph is a {@link GraphHopperStorage} with an in memory directory and disabled storing on flush.
      */
     public GraphHopperStorage create() {
         return build().create(byteCapacity);
diff --git a/core/src/main/java/com/graphhopper/storage/GraphExtension.java b/core/src/main/java/com/graphhopper/storage/GraphExtension.java
index 08aacbf05..0883f407d 100644
--- a/core/src/main/java/com/graphhopper/storage/GraphExtension.java
+++ b/core/src/main/java/com/graphhopper/storage/GraphExtension.java
@@ -23,12 +23,12 @@ package com.graphhopper.storage;
  */
 public interface GraphExtension extends Storable<GraphExtension> {
     /**
-     * @return true, if and only if, if an additional field at the graphs node storage is required
+     * @return true, if and only if an additional field at the graphs node storage is required
      */
     boolean isRequireNodeField();
 
     /**
-     * @return true, if and only if, if an additional field at the graphs edge storage is required
+     * @return true, if and only if an additional field at the graphs edge storage is required
      */
     boolean isRequireEdgeField();
 
diff --git a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java
index 190005af5..9ac7866c9 100644
--- a/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java
+++ b/core/src/main/java/com/graphhopper/storage/GraphHopperStorage.java
@@ -47,7 +47,7 @@ public final class GraphHopperStorage implements GraphStorage, Graph {
     private final StorableProperties properties;
     private final BaseGraph baseGraph;
     // same flush order etc
-    private final Collection<CHGraphImpl> chGraphs = new ArrayList<CHGraphImpl>(5);
+    private final Collection<CHGraphImpl> chGraphs = new ArrayList<>(5);
 
     public GraphHopperStorage(Directory dir, EncodingManager encodingManager, boolean withElevation, GraphExtension extendedStorage) {
         this(Collections.<Weighting>emptyList(), dir, encodingManager, withElevation, extendedStorage);
@@ -100,7 +100,7 @@ public final class GraphHopperStorage implements GraphStorage, Graph {
         if (weighting == null)
             throw new IllegalStateException("Cannot find CHGraph with null weighting");
 
-        List<Weighting> existing = new ArrayList<Weighting>();
+        List<Weighting> existing = new ArrayList<>();
         for (CHGraphImpl cg : chGraphs) {
             if (cg.getWeighting() == weighting)
                 return (T) cg;
@@ -127,7 +127,7 @@ public final class GraphHopperStorage implements GraphStorage, Graph {
     }
 
     public List<Weighting> getCHWeightings() {
-        List<Weighting> list = new ArrayList<Weighting>(chGraphs.size());
+        List<Weighting> list = new ArrayList<>(chGraphs.size());
         for (CHGraphImpl cg : chGraphs) {
             list.add(cg.getWeighting());
         }
diff --git a/core/src/main/java/com/graphhopper/storage/SPTEntry.java b/core/src/main/java/com/graphhopper/storage/SPTEntry.java
index daaac4bcf..b97af7757 100644
--- a/core/src/main/java/com/graphhopper/storage/SPTEntry.java
+++ b/core/src/main/java/com/graphhopper/storage/SPTEntry.java
@@ -17,6 +17,8 @@
  */
 package com.graphhopper.storage;
 
+import com.graphhopper.util.EdgeIterator;
+
 /**
  * This class is used to create the shortest-path-tree from linked entities.
  * <p>
@@ -35,6 +37,10 @@ public class SPTEntry implements Cloneable, Comparable<SPTEntry> {
         this.weight = weight;
     }
 
+    public SPTEntry(int node, double weight) {
+        this(EdgeIterator.NO_EDGE, node, weight);
+    }
+
     /**
      * This method returns the weight to the origin e.g. to the start for the forward SPT and to the
      * destination for the backward SPT. Where the variable 'weight' is used to let heap select
diff --git a/core/src/main/java/com/graphhopper/util/GHUtility.java b/core/src/main/java/com/graphhopper/util/GHUtility.java
index a8c26cdaa..ff15a9bcb 100644
--- a/core/src/main/java/com/graphhopper/util/GHUtility.java
+++ b/core/src/main/java/com/graphhopper/util/GHUtility.java
@@ -26,6 +26,7 @@ import com.graphhopper.routing.util.AllEdgesIterator;
 import com.graphhopper.routing.util.EdgeFilter;
 import com.graphhopper.routing.util.FlagEncoder;
 import com.graphhopper.storage.*;
+import com.graphhopper.util.shapes.BBox;
 
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -114,20 +115,49 @@ public class GHUtility {
     }
 
     public static void printEdgeInfo(final Graph g, FlagEncoder encoder) {
-        System.out.println("-- Graph n:" + g.getNodes() + " e:" + g.getAllEdges().length() + " ---");
+        System.out.println("-- Graph nodes:" + g.getNodes() + " edges:" + g.getAllEdges().length() + " ---");
         AllEdgesIterator iter = g.getAllEdges();
         while (iter.next()) {
-            String sc = "";
-            if (iter instanceof AllCHEdgesIterator) {
-                AllCHEdgesIterator aeSkip = (AllCHEdgesIterator) iter;
-                sc = aeSkip.isShortcut() ? "sc" : "  ";
-            }
+            String prefix = (iter instanceof AllCHEdgesIterator && ((AllCHEdgesIterator) iter).isShortcut()) ? "sc" : "  ";
             String fwdStr = iter.isForward(encoder) ? "fwd" : "   ";
-            String bckStr = iter.isBackward(encoder) ? "bckwd" : "";
-            System.out.println(sc + " " + iter + " " + fwdStr + " " + bckStr);
+            String bwdStr = iter.isBackward(encoder) ? "bwd" : "   ";
+            System.out.println(prefix + " " + iter + " " + fwdStr + " " + bwdStr + " " + iter.getDistance());
         }
     }
 
+    public static void printGraphForUnitTest(Graph g, FlagEncoder encoder) {
+        printGraphForUnitTest(g, encoder, new BBox(
+                Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
+    }
+
+    public static void printGraphForUnitTest(Graph g, FlagEncoder encoder, BBox bBox) {
+        NodeAccess na = g.getNodeAccess();
+        for (int node = 0; node < g.getNodes(); ++node) {
+            if (bBox.contains(na.getLat(node), na.getLon(node))) {
+                System.out.printf(Locale.ROOT, "na.setNode(%d, %f, %f);\n", node, na.getLat(node), na.getLon(node));
+            }
+        }
+        AllEdgesIterator iter = g.getAllEdges();
+        while (iter.next()) {
+            if (bBox.contains(na.getLat(iter.getBaseNode()), na.getLon(iter.getBaseNode())) &&
+                    bBox.contains(na.getLat(iter.getAdjNode()), na.getLon(iter.getAdjNode()))) {
+                printUnitTestEdge(encoder, iter);
+            }
+        }
+    }
+
+    private static void printUnitTestEdge(FlagEncoder flagEncoder, EdgeIteratorState edge) {
+        boolean fwd = edge.isForward(flagEncoder);
+        boolean bwd = edge.isBackward(flagEncoder);
+        if (!fwd && !bwd) {
+            return;
+        }
+        int from = fwd ? edge.getBaseNode() : edge.getAdjNode();
+        int to = fwd ? edge.getAdjNode() : edge.getBaseNode();
+        System.out.printf(Locale.ROOT,
+                "graph.edge(%d, %d, %f, %s);\n", from, to, edge.getDistance(), fwd && bwd ? "true" : "false");
+    }
+
     public static void printInfo(final Graph g, int startNode, final int counts, final EdgeFilter filter) {
         new BreadthFirstSearch() {
             int counter = 0;
@@ -135,10 +165,7 @@ public class GHUtility {
             @Override
             protected boolean goFurther(int nodeId) {
                 System.out.println(getNodeInfo(g, nodeId, filter));
-                if (counter++ > counts) {
-                    return false;
-                }
-                return true;
+                return counter++ <= counts;
             }
         }.start(g.createEdgeExplorer(), startNode);
     }
@@ -307,8 +334,6 @@ public class GHUtility {
         };
     }
 
-    ;
-
     /**
      * @return the <b>first</b> edge containing the specified nodes base and adj. Returns null if
      * not found.
diff --git a/core/src/main/java/com/graphhopper/util/StopWatch.java b/core/src/main/java/com/graphhopper/util/StopWatch.java
index f32034478..de9d0c03a 100644
--- a/core/src/main/java/com/graphhopper/util/StopWatch.java
+++ b/core/src/main/java/com/graphhopper/util/StopWatch.java
@@ -58,7 +58,7 @@ public class StopWatch {
      * @return the time delta in milliseconds
      */
     public long getTime() {
-        return nanoTime / 1000000;
+        return nanoTime / 1_000_000;
     }
 
     public long getNanos() {
diff --git a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java
index 1e549e0b0..9e18aa3a1 100644
--- a/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java
+++ b/tools/src/main/java/com/graphhopper/ui/MiniGraphUI.java
@@ -268,7 +268,7 @@ public class MiniGraphUI {
                     g2.setColor(color);
                     boolean fwd = encoder.isForward(edge.getFlags());
                     boolean bwd = encoder.isBackward(edge.getFlags());
-                    float width = speed > 90? 1f : 0.8f;
+                    float width = speed > 90 ? 1f : 0.8f;
                     if (fwd && !bwd) {
                         mg.plotDirectedEdge(g2, lat, lon, lat2, lon2, width);
                     } else {


Test patch:
diff --git a/core/src/test/java/com/graphhopper/routing/AbstractRoutingAlgorithmTester.java b/core/src/test/java/com/graphhopper/routing/AbstractRoutingAlgorithmTester.java
index ccb057206..1484ce63f 100644
--- a/core/src/test/java/com/graphhopper/routing/AbstractRoutingAlgorithmTester.java
+++ b/core/src/test/java/com/graphhopper/routing/AbstractRoutingAlgorithmTester.java
@@ -407,11 +407,11 @@ public abstract class AbstractRoutingAlgorithmTester {
         assertFalse(p.isFound());
     }
 
-    // 1-2-3-4-5
+    // 0-1-2-3-4
     // |     / |
-    // |    9  |
+    // |    8  |
     // \   /   /
-    //  8-7-6-/
+    //  7-6-5-/
     @Test
     public void testBidirectional2() {
         GraphHopperStorage graph = createGHStorage(false);
diff --git a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmIT.java b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmIT.java
index 31375af0b..b77ee88d5 100644
--- a/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmIT.java
+++ b/core/src/test/java/com/graphhopper/routing/RoutingAlgorithmIT.java
@@ -166,7 +166,7 @@ public class RoutingAlgorithmIT {
             float perRun = sw.stop().getSeconds() / ((float) (N - noJvmWarming));
             System.out.println("# " + getClass().getSimpleName() + " " + entry
                     + ":" + sw.stop().getSeconds() + ", per run:" + perRun);
-            assertTrue("speed to low!? " + perRun + " per run", perRun < 0.08);
+            assertTrue("speed too low!? " + perRun + " per run", perRun < 0.08);
         }
     }
 }
diff --git a/core/src/test/java/com/graphhopper/routing/ch/NodeContractorTest.java b/core/src/test/java/com/graphhopper/routing/ch/NodeContractorTest.java
index c73b25eeb..e623ffe7b 100644
--- a/core/src/test/java/com/graphhopper/routing/ch/NodeContractorTest.java
+++ b/core/src/test/java/com/graphhopper/routing/ch/NodeContractorTest.java
@@ -85,7 +85,7 @@ public class NodeContractorTest {
 
         setMaxLevelOnAllNodes();
 
-        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes() + 1).setAvoidNode(3));
+        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes()).setAvoidNode(3));
         algo.setWeightLimit(100);
         int nodeEntry = algo.findEndNode(4, 2);
         assertTrue(algo.getWeight(nodeEntry) > normalDist);
@@ -105,7 +105,7 @@ public class NodeContractorTest {
 
         setMaxLevelOnAllNodes();
 
-        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes() + 1).setAvoidNode(3));
+        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes()).setAvoidNode(3));
         algo.setWeightLimit(10);
         int nodeEntry = algo.findEndNode(4, 2);
         assertEquals(4, algo.getWeight(nodeEntry), 1e-5);
@@ -121,7 +121,7 @@ public class NodeContractorTest {
 
         setMaxLevelOnAllNodes();
 
-        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes() + 1).setAvoidNode(0));
+        algo.setEdgeFilter(new NodeContractor.IgnoreNodeFilter(lg, graph.getNodes()).setAvoidNode(0));
         algo.setWeightLimit(2);
         int endNode = algo.findEndNode(4, 1);
         // did not reach endNode
@@ -333,7 +333,7 @@ public class NodeContractorTest {
     private void setMaxLevelOnAllNodes() {
         int nodes = lg.getNodes();
         for (int node = 0; node < nodes; node++) {
-            lg.setLevel(node, nodes + 1);
+            lg.setLevel(node, nodes);
         }
     }
 
diff --git a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
index 07bcfa25e..638ff061d 100644
--- a/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
+++ b/core/src/test/java/com/graphhopper/storage/GraphHopperStorageCHTest.java
@@ -296,7 +296,7 @@ public class GraphHopperStorageCHTest extends GraphHopperStorageTest {
         assertEquals(1, GHUtility.count(graph.createEdgeExplorer().setBaseNode(1)));
         assertEquals(1, GHUtility.count(chGraph.createEdgeExplorer().setBaseNode(1)));
 
-        // base graph does not see shortcut        
+        // base graph does not see shortcut
         assertEquals(0, GHUtility.count(graph.createEdgeExplorer().setBaseNode(2)));
         assertEquals(1, GHUtility.count(chGraph.createEdgeExplorer().setBaseNode(2)));
 
diff --git a/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMIT.java b/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMIT.java
index 1f53faf8c..62c72b43e 100644
--- a/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMIT.java
+++ b/reader-osm/src/test/java/com/graphhopper/routing/RoutingAlgorithmWithOSMIT.java
@@ -139,7 +139,7 @@ public class RoutingAlgorithmWithOSMIT {
     @Test
     public void testOneWayCircleBug() {
         // export from http://www.openstreetmap.org/export#map=19/51.37605/-0.53155
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // going the bit longer way out of the circle
         list.add(new OneRun(51.376197, -0.531576, 51.376509, -0.530863, 153, 18));
         // now exacle the opposite direction: going into the circle (shorter)
@@ -153,7 +153,7 @@ public class RoutingAlgorithmWithOSMIT {
     @Test
     public void testMoscow() {
         // extracted via ./graphhopper.sh extract "37.582641,55.805261,37.626929,55.824455"
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // choose perpendicular
         // http://localhost:8989/?point=55.818994%2C37.595354&point=55.819175%2C37.596931
         list.add(new OneRun(55.818994, 37.595354, 55.819175, 37.596931, 1052, 14));
@@ -170,7 +170,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testMoscowTurnCosts() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(55.813357, 37.5958585, 55.811042, 37.594689, 1043.99, 12));
         list.add(new OneRun(55.813159, 37.593884, 55.811278, 37.594217, 1048, 13));
         // TODO include CH
@@ -183,7 +183,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testSidewalkNo() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // roundabout contains sidewalk=no which should be avoided
         list.add(new OneRun(57.154888, -2.101822, 57.153445, -2.099869, 329, 31));
         // longer path should go through tertiary, see discussion in #476
@@ -227,7 +227,7 @@ public class RoutingAlgorithmWithOSMIT {
     }
 
     List<OneRun> createMonacoFoot() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(43.730729, 7.421288, 43.727697, 7.419199, 1566, 92));
         list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3438, 136));
         list.add(new OneRun(43.728677, 7.41016, 43.739213, 7.427806, 2085, 112));
@@ -269,7 +269,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testNorthBayreuthHikeFastestAnd3D() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // prefer hiking route 'Teufelsloch Unterwaiz' and 'Rotmain-Wanderweg'        
         list.add(new OneRun(49.974972, 11.515657, 49.991022, 11.512299, 2365, 66));
         // prefer hiking route 'Markgrafenweg Bayreuth Kulmbach' but avoid tertiary highway from Pechgraben
@@ -281,7 +281,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testMonacoBike3D_twoSpeedsPerEdge() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // 1. alternative: go over steps 'Rampe Major' => 1.7km vs. around 2.7km
         list.add(new OneRun(43.730864, 7.420771, 43.727687, 7.418737, 2710, 118));
         // 2.
@@ -319,7 +319,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testMonacoBike() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(43.730864, 7.420771, 43.727687, 7.418737, 1642, 87));
         list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3580, 168));
         list.add(new OneRun(43.728677, 7.41016, 43.739213, 7.427806, 2323, 121));
@@ -331,7 +331,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testMonacoMountainBike() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(43.730864, 7.420771, 43.727687, 7.418737, 2322, 110));
         list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3655, 176));
         list.add(new OneRun(43.728677, 7.41016, 43.739213, 7.427806, 2331, 121));
@@ -348,7 +348,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testMonacoRacingBike() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(43.730864, 7.420771, 43.727687, 7.418737, 2594, 111));
         list.add(new OneRun(43.727687, 7.418737, 43.74958, 7.436566, 3588, 170));
         list.add(new OneRun(43.728677, 7.41016, 43.739213, 7.427806, 2572, 135));
@@ -364,7 +364,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testKremsBikeRelation() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(48.409523, 15.602394, 48.375466, 15.72916, 12491, 159));
         // 3109m is better as cyclepath is used
         list.add(new OneRun(48.410061, 15.63951, 48.411386, 15.604899, 3112, 87));
@@ -381,7 +381,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testKremsMountainBikeRelation() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(48.409523, 15.602394, 48.375466, 15.72916, 12574, 169));
         list.add(new OneRun(48.410061, 15.63951, 48.411386, 15.604899, 3101, 94));
         list.add(new OneRun(48.412294, 15.62007, 48.398306, 15.609667, 3965, 95));
@@ -396,7 +396,7 @@ public class RoutingAlgorithmWithOSMIT {
     }
 
     List<OneRun> createAndorra() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(42.56819, 1.603231, 42.571034, 1.520662, 17708, 524));
         list.add(new OneRun(42.529176, 1.571302, 42.571034, 1.520662, 11408, 305));
         return list;
@@ -436,7 +436,7 @@ public class RoutingAlgorithmWithOSMIT {
         // bzcat campo-grande.osm.bz2 
         //   | ./bin/osmosis --read-xml enableDateParsing=no file=- --bounding-box top=-20.4 left=-54.6 bottom=-20.6 right=-54.5 --write-xml file=- 
         //   | bzip2 > campo-grande.extracted.osm.bz2
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(new OneRun(-20.4, -54.6, -20.6, -54.54, 25516, 271));
         list.add(new OneRun(-20.43, -54.54, -20.537, -54.674, 18009, 237));
         runAlgo(testCollector, DIR + "/campo-grande.osm.gz", "target/campo-grande-gh", list,
@@ -451,7 +451,7 @@ public class RoutingAlgorithmWithOSMIT {
         oneRun.add(43.727697, 7.419199, 2581, 110);
         oneRun.add(43.726387, 7.4, 3001, 90);
 
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         list.add(oneRun);
 
         runAlgo(testCollector, DIR + "/monaco.osm.gz", "target/monaco-gh",
@@ -461,7 +461,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testHarsdorf() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // TODO somehow the bigger road is take even if we make it less preferred (e.g. introduce AVOID AT ALL costs for lanes=2&&maxspeed>50)
         list.add(new OneRun(50.004333, 11.600254, 50.044449, 11.543434, 6952, 190));
 
@@ -474,7 +474,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testNeudrossenfeld() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         // choose cycleway (Dreschenauer Straße)
         list.add(new OneRun(49.987132, 11.510496, 50.018839, 11.505024, 3985, 106));
 
@@ -488,7 +488,7 @@ public class RoutingAlgorithmWithOSMIT {
 
     @Test
     public void testDisconnectedAreaAndMultiplePoints() {
-        List<OneRun> list = new ArrayList<OneRun>();
+        List<OneRun> list = new ArrayList<>();
         OneRun oneRun = new OneRun();
         oneRun.add(53.753177, 9.435968, 10, 10);
         oneRun.add(53.751299, 9.386959, 10, 10);