Repository: graphhopper/graphhopper
Pull request #2027 (2020-05-08 16:45:55)

better estimate factor to store landmark weights more precise
In production this improves visited nodes by at least 10% for a few examples. In our benchmarks this is ~3% faster, but could be also be noise. At least it should improve the warning logs for smaller graphs.


Patch:
diff --git a/api/src/main/java/com/graphhopper/GHResponse.java b/api/src/main/java/com/graphhopper/GHResponse.java
index 6fe8f8c0e..407b0222f 100644
--- a/api/src/main/java/com/graphhopper/GHResponse.java
+++ b/api/src/main/java/com/graphhopper/GHResponse.java
@@ -31,38 +31,38 @@ import java.util.List;
 public class GHResponse {
     private final List<Throwable> errors = new ArrayList<>(4);
     private final PMap hintsMap = new PMap();
-    private final List<PathWrapper> pathWrappers = new ArrayList<>(5);
+    private final List<ResponsePath> responsePaths = new ArrayList<>(5);
     private String debugInfo = "";
 
     public GHResponse() {
     }
 
-    public void add(PathWrapper altResponse) {
-        pathWrappers.add(altResponse);
+    public void add(ResponsePath responsePath) {
+        responsePaths.add(responsePath);
     }
 
     /**
      * Returns the best path.
      */
-    public PathWrapper getBest() {
-        if (pathWrappers.isEmpty())
+    public ResponsePath getBest() {
+        if (responsePaths.isEmpty())
             throw new RuntimeException("Cannot fetch best response if list is empty");
 
-        return pathWrappers.get(0);
+        return responsePaths.get(0);
     }
 
     /**
      * This method returns the best path as well as all alternatives.
      */
-    public List<PathWrapper> getAll() {
-        return pathWrappers;
+    public List<ResponsePath> getAll() {
+        return responsePaths;
     }
 
     /**
      * This method returns true if there are alternative paths available besides the best.
      */
     public boolean hasAlternatives() {
-        return pathWrappers.size() > 1;
+        return responsePaths.size() > 1;
     }
 
     public void addDebugInfo(String debugInfo) {
@@ -77,11 +77,11 @@ public class GHResponse {
 
     public String getDebugInfo() {
         String str = debugInfo;
-        for (PathWrapper ar : pathWrappers) {
+        for (ResponsePath p : responsePaths) {
             if (!str.isEmpty())
                 str += "; ";
 
-            str += ar.getDebugInfo();
+            str += p.getDebugInfo();
         }
         return str;
     }
@@ -94,8 +94,8 @@ public class GHResponse {
         if (!errors.isEmpty())
             return true;
 
-        for (PathWrapper ar : pathWrappers) {
-            if (ar.hasErrors())
+        for (ResponsePath p : responsePaths) {
+            if (p.hasErrors())
                 return true;
         }
 
@@ -108,8 +108,8 @@ public class GHResponse {
     public List<Throwable> getErrors() {
         List<Throwable> list = new ArrayList<>();
         list.addAll(errors);
-        for (PathWrapper ar : pathWrappers) {
-            list.addAll(ar.getErrors());
+        for (ResponsePath p : responsePaths) {
+            list.addAll(p.getErrors());
         }
         return list;
     }
@@ -127,11 +127,11 @@ public class GHResponse {
     @Override
     public String toString() {
         String str = "";
-        for (PathWrapper a : pathWrappers) {
+        for (ResponsePath a : responsePaths) {
             str += "; " + a.toString();
         }
 
-        if (pathWrappers.isEmpty())
+        if (responsePaths.isEmpty())
             str = "no paths";
 
         if (!errors.isEmpty())
diff --git a/api/src/main/java/com/graphhopper/PathWrapper.java b/api/src/main/java/com/graphhopper/ResponsePath.java
similarity index 93%
rename from api/src/main/java/com/graphhopper/PathWrapper.java
rename to api/src/main/java/com/graphhopper/ResponsePath.java
index 4b148a647..676b536fd 100644
--- a/api/src/main/java/com/graphhopper/PathWrapper.java
+++ b/api/src/main/java/com/graphhopper/ResponsePath.java
@@ -31,7 +31,7 @@ import java.util.*;
  *
  * @author Peter Karich
  */
-public class PathWrapper {
+public class ResponsePath {
     private final List<Throwable> errors = new ArrayList<>(4);
     private List<String> description;
     private double distance;
@@ -60,12 +60,12 @@ public class PathWrapper {
         return description;
     }
 
-    public PathWrapper setDescription(List<String> names) {
+    public ResponsePath setDescription(List<String> names) {
         this.description = names;
         return this;
     }
 
-    public PathWrapper addDebugInfo(String debugInfo) {
+    public ResponsePath addDebugInfo(String debugInfo) {
         if (debugInfo == null)
             throw new IllegalStateException("Debug information has to be none null");
 
@@ -80,7 +80,7 @@ public class PathWrapper {
         return debugInfo;
     }
 
-    public PathWrapper setPointsOrder(List<Integer> list) {
+    public ResponsePath setPointsOrder(List<Integer> list) {
         pointsOrder.clear();
         pointsOrder.addAll(list);
         return this;
@@ -100,7 +100,7 @@ public class PathWrapper {
         return pointList;
     }
 
-    public PathWrapper setPoints(PointList points) {
+    public ResponsePath setPoints(PointList points) {
         if (pointList != PointList.EMPTY)
             throw new IllegalStateException("Cannot call setPoint twice");
 
@@ -138,7 +138,7 @@ public class PathWrapper {
         return distance;
     }
 
-    public PathWrapper setDistance(double distance) {
+    public ResponsePath setDistance(double distance) {
         this.distance = distance;
         return this;
     }
@@ -153,7 +153,7 @@ public class PathWrapper {
         return ascend;
     }
 
-    public PathWrapper setAscend(double ascend) {
+    public ResponsePath setAscend(double ascend) {
         if (ascend < 0 || Double.isNaN(ascend))
             throw new IllegalStateException("ascend has to be positive but was " + ascend);
 
@@ -171,7 +171,7 @@ public class PathWrapper {
         return descend;
     }
 
-    public PathWrapper setDescend(double descend) {
+    public ResponsePath setDescend(double descend) {
         if (descend < 0 || Double.isNaN(descend))
             throw new IllegalStateException("descend has to be positive but was " + descend);
 
@@ -187,7 +187,7 @@ public class PathWrapper {
         return time;
     }
 
-    public PathWrapper setTime(long timeInMillis) {
+    public ResponsePath setTime(long timeInMillis) {
         this.time = timeInMillis;
         return this;
     }
@@ -202,7 +202,7 @@ public class PathWrapper {
         return routeWeight;
     }
 
-    public PathWrapper setRouteWeight(double weight) {
+    public ResponsePath setRouteWeight(double weight) {
         this.routeWeight = weight;
         return this;
     }
@@ -307,12 +307,12 @@ public class PathWrapper {
         return errors;
     }
 
-    public PathWrapper addError(Throwable error) {
+    public ResponsePath addError(Throwable error) {
         errors.add(error);
         return this;
     }
 
-    public PathWrapper addErrors(List<Throwable> errors) {
+    public ResponsePath addErrors(List<Throwable> errors) {
         this.errors.addAll(errors);
         return this;
     }
diff --git a/client-hc/src/main/java/com/graphhopper/api/GraphHopperWeb.java b/client-hc/src/main/java/com/graphhopper/api/GraphHopperWeb.java
index dce0d73e3..03628934b 100644
--- a/client-hc/src/main/java/com/graphhopper/api/GraphHopperWeb.java
+++ b/client-hc/src/main/java/com/graphhopper/api/GraphHopperWeb.java
@@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
 import com.graphhopper.GraphHopperAPI;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.http.WebHelper;
 import com.graphhopper.jackson.Jackson;
 import com.graphhopper.jackson.PathWrapperDeserializer;
@@ -210,7 +210,7 @@ public class GraphHopperWeb implements GraphHopperAPI {
             JsonNode paths = json.get("paths");
 
             for (JsonNode path : paths) {
-                PathWrapper altRsp = PathWrapperDeserializer.createPathWrapper(objectMapper, path, tmpElevation, tmpTurnDescription);
+                ResponsePath altRsp = PathWrapperDeserializer.createPathWrapper(objectMapper, path, tmpElevation, tmpTurnDescription);
                 res.add(altRsp);
             }
 
diff --git a/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java b/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java
index 1f5866fae..e8de0cb66 100644
--- a/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java
+++ b/core/src/main/java/com/graphhopper/routing/lm/LandmarkStorage.java
@@ -36,7 +36,6 @@ import com.graphhopper.routing.weighting.Weighting;
 import com.graphhopper.storage.*;
 import com.graphhopper.util.*;
 import com.graphhopper.util.exceptions.ConnectionNotFoundException;
-import com.graphhopper.util.shapes.BBox;
 import com.graphhopper.util.shapes.GHPoint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -227,28 +226,6 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
             landmarkWeightDA.setShort(pointer, (short) SHORT_INFINITY);
         }
 
-        String additionalInfo = "";
-        // guess the factor
-        if (factor <= 0) {
-            // A 'factor' is necessary to store the weight in just a short value but without loosing too much precision.
-            // This factor is rather delicate to pick, we estimate it through the graph boundaries its maximum distance.
-            // For small areas we use max_bounds_dist*X and otherwise we use a big fixed value for this distance.
-            // If we would pick the distance too big for small areas this could lead to (slightly) suboptimal routes as there
-            // will be too big rounding errors. But picking it too small is dangerous regarding performance
-            // e.g. for Germany at least 1500km is very important otherwise speed is at least twice as slow e.g. for just 1000km
-            BBox bounds = graph.getBounds();
-            double distanceInMeter = Helper.DIST_EARTH.calcDist(bounds.maxLat, bounds.maxLon, bounds.minLat, bounds.minLon) * 7;
-            if (distanceInMeter > 50_000 * 7 || /* for tests and convenience we do for now: */ !bounds.isValid())
-                distanceInMeter = 30_000_000;
-
-            double maxWeight = weighting.getMinWeight(distanceInMeter);
-            setMaximumWeight(maxWeight);
-            additionalInfo = ", maxWeight:" + maxWeight + ", from max distance:" + distanceInMeter / 1000f + "km";
-        }
-
-        if (logDetails)
-            LOGGER.info("init landmarks for subnetworks with node count greater than " + minimumNodes + " with factor:" + factor + additionalInfo);
-
         int[] empty = new int[landmarks];
         Arrays.fill(empty, UNSET_SUBNETWORK);
         landmarkIDs.add(empty);
@@ -277,12 +254,30 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
             LOGGER.info("Calculated " + graphComponents.size() + " subnetworks via tarjan in " + sw.stop().getSeconds() + "s, " + Helper.getMemInfo());
 
         EdgeExplorer tmpExplorer = graph.createEdgeExplorer(new RequireBothDirectionsEdgeFilter(encoder));
+        String additionalInfo = "";
+        // guess the factor
+        if (factor <= 0) {
+            // A 'factor' is necessary to store the weight in just a short value but without loosing too much precision.
+            // This factor is rather delicate to pick, we estimate it from an exploration with some "test landmarks",
+            // see estimateMaxWeight. If we pick the distance too big for small areas this could lead to (slightly)
+            // suboptimal routes as there will be too big rounding errors. But picking it too small is bad for performance
+            // e.g. for Germany at least 1500km is very important otherwise speed is at least twice as slow e.g. for 1000km
+            double maxWeight = estimateMaxWeight(tmpExplorer, graphComponents, blockedEdges);
+            setMaximumWeight(maxWeight);
+            additionalInfo = ", maxWeight:" + maxWeight + " from quick estimation";
+        }
+
+        if (logDetails)
+            LOGGER.info("init landmarks for subnetworks with node count greater than " + minimumNodes + " with factor:" + factor + additionalInfo);
 
         int nodes = 0;
         for (IntArrayList subnetworkIds : graphComponents) {
             nodes += subnetworkIds.size();
             if (subnetworkIds.size() < minimumNodes)
                 continue;
+            if (factor <= 0)
+                throw new IllegalStateException("factor wasn't initialized " + factor + ", subnetworks:"
+                        + graphComponents.size() + ", minimumNodes:" + minimumNodes + ", current size:" + subnetworkIds.size());
 
             int index = subnetworkIds.size() - 1;
             // ensure start node is reachable from both sides and no subnetwork is associated
@@ -335,6 +330,51 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
         initialized = true;
     }
 
+    /**
+     * This method returns the maximum weight for the graph starting from the landmarks
+     */
+    private double estimateMaxWeight(EdgeExplorer requireBothDirExplorer, List<IntArrayList> graphComponents, IntHashSet blockedEdges) {
+        double maxWeight = 0;
+        int searchedSubnetworks = 0;
+        // the maximum weight can only be an approximation so there is only a tiny improvement when we would do this for
+        // all landmarks. See #2027 (1st commit) where only 1 landmark was sufficient when multiplied with 1.01 at the end
+        // TODO instead of calculating the landmarks again here we could store them in landmarkIDs and do this for all here
+        int[] tmpLandmarkNodeIds = new int[3];
+        for (IntArrayList subnetworkIds : graphComponents) {
+            if (subnetworkIds.size() < minimumNodes)
+                continue;
+
+            searchedSubnetworks++;
+            int index = subnetworkIds.size() - 1;
+            for (; index >= 0; index--) {
+                int nextStartNode = subnetworkIds.get(index);
+                if (GHUtility.count(requireBothDirExplorer.setBaseNode(nextStartNode)) > 0) {
+                    LandmarkExplorer explorer = findLandmarks(tmpLandmarkNodeIds, nextStartNode, blockedEdges);
+                    if (explorer.getFromCount() < minimumNodes)
+                        continue;
+
+                    // starting
+                    for (int lmIdx = 0; lmIdx < tmpLandmarkNodeIds.length; lmIdx++) {
+                        int lmNodeId = tmpLandmarkNodeIds[lmIdx];
+                        explorer = new LandmarkExplorer(graph, this, weighting, traversalMode, true);
+                        explorer.setStartNode(lmNodeId);
+                        explorer.setFilter(blockedEdges, true, true);
+                        explorer.runAlgo();
+                        maxWeight = Math.max(maxWeight, explorer.getLastEntry().weight);
+                    }
+                    break;
+                }
+            }
+        }
+
+        if (maxWeight <= 0 && searchedSubnetworks > 0)
+            throw new IllegalStateException("max weight wasn't set although " + searchedSubnetworks + " subnetworks were searched (total " + graphComponents.size() + "), minimumNodes:" + minimumNodes);
+
+        // we have to increase maxWeight slightly as it is only an approximation towards the maximum weight,
+        // especially when external landmarks are provided, but also because we do not traverse all landmarks
+        return maxWeight * 1.008;
+    }
+
     /**
      * This method creates landmarks for the specified subnetwork (integer list)
      *
@@ -343,7 +383,7 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
     private boolean createLandmarksForSubnetwork(final int startNode, final byte[] subnetworks, IntHashSet blockedEdges) {
         final int subnetworkId = landmarkIDs.size();
         int[] tmpLandmarkNodeIds = new int[landmarks];
-        int logOffset = Math.max(1, tmpLandmarkNodeIds.length / 2);
+        int logOffset = Math.max(1, landmarks / 2);
         boolean pickedPrecalculatedLandmarks = false;
 
         if (!landmarkSuggestions.isEmpty()) {
@@ -370,40 +410,14 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
         }
 
         if (pickedPrecalculatedLandmarks) {
-            LOGGER.info("Picked " + tmpLandmarkNodeIds.length + " landmark suggestions, skipped expensive landmark determination");
+            LOGGER.info("Picked " + tmpLandmarkNodeIds.length + " landmark suggestions, skip finding landmarks");
         } else {
-            // 1a) pick landmarks via special weighting for a better geographical spreading
-            Weighting initWeighting = lmSelectionWeighting;
-            LandmarkExplorer explorer = new LandmarkExplorer(graph, this, initWeighting, traversalMode, true);
-            explorer.setStartNode(startNode);
-            explorer.setFilter(blockedEdges, true, true);
-            explorer.runAlgo();
-
+            LandmarkExplorer explorer = findLandmarks(tmpLandmarkNodeIds, startNode, blockedEdges);
             if (explorer.getFromCount() < minimumNodes) {
                 // too small subnetworks are initialized with special id==0
                 explorer.setSubnetworks(subnetworks, UNCLEAR_SUBNETWORK);
                 return false;
             }
-
-            // 1b) we have one landmark, now determine the other landmarks
-            tmpLandmarkNodeIds[0] = explorer.getLastNode();
-            for (int lmIdx = 0; lmIdx < tmpLandmarkNodeIds.length - 1; lmIdx++) {
-                if (Thread.currentThread().isInterrupted()) {
-                    throw new RuntimeException("Thread was interrupted");
-                }
-                explorer = new LandmarkExplorer(graph, this, initWeighting, traversalMode, true);
-                explorer.setFilter(blockedEdges, true, true);
-                // set all current landmarks as start so that the next getLastNode is hopefully a "far away" node
-                for (int j = 0; j < lmIdx + 1; j++) {
-                    explorer.setStartNode(tmpLandmarkNodeIds[j]);
-                }
-                explorer.runAlgo();
-                tmpLandmarkNodeIds[lmIdx + 1] = explorer.getLastNode();
-                if (logDetails && lmIdx % logOffset == 0)
-                    LOGGER.info("Finding landmarks [" + lmConfig + "] in network [" + explorer.getVisitedNodes() + "]. "
-                            + "Progress " + (int) (100.0 * lmIdx / tmpLandmarkNodeIds.length) + "%, " + Helper.getMemInfo());
-            }
-
             if (logDetails)
                 LOGGER.info("Finished searching landmarks for subnetwork " + subnetworkId + " of size " + explorer.getVisitedNodes());
         }
@@ -411,7 +425,7 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
         // 2) calculate weights for all landmarks -> 'from' and 'to' weight
         for (int lmIdx = 0; lmIdx < tmpLandmarkNodeIds.length; lmIdx++) {
             if (Thread.currentThread().isInterrupted()) {
-                throw new RuntimeException("Thread was interrupted");
+                throw new RuntimeException("Thread was interrupted for landmark " + lmIdx);
             }
             int lmNodeId = tmpLandmarkNodeIds[lmIdx];
             LandmarkExplorer explorer = new LandmarkExplorer(graph, this, weighting, traversalMode, true);
@@ -521,7 +535,7 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
     final boolean setWeight(long pointer, double value) {
         double tmpVal = value / factor;
         if (tmpVal > Integer.MAX_VALUE)
-            throw new UnsupportedOperationException("Cannot store infinity explicitely, pointer=" + pointer + ", value: " + value);
+            throw new UnsupportedOperationException("Cannot store infinity explicitly, pointer=" + pointer + ", value=" + value + ", factor=" + factor);
 
         if (tmpVal >= SHORT_MAX) {
             landmarkWeightDA.setShort(pointer, (short) SHORT_MAX);
@@ -551,7 +565,8 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
         if (subnetworkFrom <= UNCLEAR_SUBNETWORK || subnetworkTo <= UNCLEAR_SUBNETWORK)
             return false;
         if (subnetworkFrom != subnetworkTo) {
-            throw new ConnectionNotFoundException("Connection between locations not found. Different subnetworks " + subnetworkFrom + " vs. " + subnetworkTo, new HashMap<String, Object>());
+            throw new ConnectionNotFoundException("Connection between locations not found. Different subnetworks " + subnetworkFrom
+                    + " vs. " + subnetworkTo, new HashMap<String, Object>());
         }
 
         int[] tmpIDs = landmarkIDs.get(subnetworkFrom);
@@ -714,15 +729,44 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
         return graph.getNodes();
     }
 
+    private LandmarkExplorer findLandmarks(int[] landmarkNodeIdsToReturn, int startNode, IntHashSet blockedEdges) {
+        int logOffset = Math.max(1, landmarkNodeIdsToReturn.length / 2);
+        // 1a) pick landmarks via special weighting for a better geographical spreading
+        Weighting initWeighting = lmSelectionWeighting;
+        LandmarkExplorer explorer = new LandmarkExplorer(graph, this, initWeighting, traversalMode, true);
+        explorer.setStartNode(startNode);
+        explorer.setFilter(blockedEdges, true, true);
+        explorer.runAlgo();
+
+        if (explorer.getFromCount() >= minimumNodes) {
+            // 1b) we have one landmark, now determine the other landmarks
+            landmarkNodeIdsToReturn[0] = explorer.getLastEntry().adjNode;
+            for (int lmIdx = 0; lmIdx < landmarkNodeIdsToReturn.length - 1; lmIdx++) {
+                explorer = new LandmarkExplorer(graph, this, initWeighting, traversalMode, true);
+                explorer.setFilter(blockedEdges, true, true);
+                // set all current landmarks as start so that the next getLastNode is hopefully a "far away" node
+                for (int j = 0; j < lmIdx + 1; j++) {
+                    explorer.setStartNode(landmarkNodeIdsToReturn[j]);
+                }
+                explorer.runAlgo();
+                landmarkNodeIdsToReturn[lmIdx + 1] = explorer.getLastEntry().adjNode;
+                if (logDetails && lmIdx % logOffset == 0)
+                    LOGGER.info("Finding landmarks [" + lmConfig + "] in network [" + explorer.getVisitedNodes() + "]. "
+                            + "Progress " + (int) (100.0 * lmIdx / landmarkNodeIdsToReturn.length) + "%, " + Helper.getMemInfo());
+            }
+        }
+        return explorer;
+    }
+
     /**
      * This class is used to calculate landmark location (equally distributed).
      * It derives from DijkstraBidirectionRef, but is only used as forward or backward search.
      */
     private static class LandmarkExplorer extends DijkstraBidirectionRef {
-        private int lastNode;
         // todo: rename 'from' to 'reverse' (and flip it) ? 'from' is used in many places for node ids and 'reverse' is mostly used for the direction
         private boolean from;
         private final LandmarkStorage lms;
+        private SPTEntry lastEntry;
 
         public LandmarkExplorer(Graph g, LandmarkStorage lms, Weighting weighting, TraversalMode tMode, boolean from) {
             super(g, weighting, tMode);
@@ -754,25 +798,23 @@ public class LandmarkStorage implements Storable<LandmarkStorage> {
             return bestWeightMapFrom.size();
         }
 
-        int getToCount() {
-            return bestWeightMapTo.size();
-        }
-
-        public int getLastNode() {
-            return lastNode;
-        }
-
         public void runAlgo() {
             super.runAlgo();
         }
 
+        SPTEntry getLastEntry() {
+            if (!finished())
+                throw new IllegalStateException("Cannot get max weight if not yet finished");
+            return lastEntry;
+        }
+
         @Override
         public boolean finished() {
             if (from) {
-                lastNode = currFrom.adjNode;
+                lastEntry = currFrom;
                 return finishedFrom;
             } else {
-                lastNode = currTo.adjNode;
+                lastEntry = currTo;
                 return finishedTo;
             }
         }
diff --git a/core/src/main/java/com/graphhopper/routing/template/AlternativeRoutingTemplate.java b/core/src/main/java/com/graphhopper/routing/template/AlternativeRoutingTemplate.java
index a743888f1..6a97fdb0d 100644
--- a/core/src/main/java/com/graphhopper/routing/template/AlternativeRoutingTemplate.java
+++ b/core/src/main/java/com/graphhopper/routing/template/AlternativeRoutingTemplate.java
@@ -19,7 +19,7 @@ package com.graphhopper.routing.template;
 
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.routing.AlgorithmOptions;
 import com.graphhopper.routing.Path;
 import com.graphhopper.routing.RoutingAlgorithmFactory;
@@ -74,14 +74,14 @@ final public class AlternativeRoutingTemplate extends ViaRoutingTemplate {
 
         // if alternative route calculation was done then create the responses from single paths        
         PointList wpList = getWaypoints();
-        pathWrapper.setWaypoints(wpList);
-        ghResponse.add(pathWrapper);
-        pathMerger.doWork(pathWrapper, Collections.singletonList(pathList.get(0)), lookup, tr);
+        responsePath.setWaypoints(wpList);
+        ghResponse.add(responsePath);
+        pathMerger.doWork(responsePath, Collections.singletonList(pathList.get(0)), lookup, tr);
         for (int index = 1; index < pathList.size(); index++) {
-            PathWrapper tmpAltRsp = new PathWrapper();
-            tmpAltRsp.setWaypoints(wpList);
-            ghResponse.add(tmpAltRsp);
-            pathMerger.doWork(tmpAltRsp, Collections.singletonList(pathList.get(index)), lookup, tr);
+            ResponsePath p = new ResponsePath();
+            p.setWaypoints(wpList);
+            ghResponse.add(p);
+            pathMerger.doWork(p, Collections.singletonList(pathList.get(index)), lookup, tr);
         }
     }
 }
diff --git a/core/src/main/java/com/graphhopper/routing/template/RoundTripRoutingTemplate.java b/core/src/main/java/com/graphhopper/routing/template/RoundTripRoutingTemplate.java
index ec07b2006..9a3d4c6cb 100644
--- a/core/src/main/java/com/graphhopper/routing/template/RoundTripRoutingTemplate.java
+++ b/core/src/main/java/com/graphhopper/routing/template/RoundTripRoutingTemplate.java
@@ -19,7 +19,7 @@ package com.graphhopper.routing.template;
 
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.routing.AlgorithmOptions;
 import com.graphhopper.routing.Path;
 import com.graphhopper.routing.RoutingAlgorithm;
@@ -150,10 +150,10 @@ public class RoundTripRoutingTemplate extends AbstractRoutingTemplate implements
 
     @Override
     public void finish(PathMerger pathMerger, Translation tr) {
-        PathWrapper altResponse = new PathWrapper();
-        altResponse.setWaypoints(getWaypoints());
-        ghResponse.add(altResponse);
-        pathMerger.doWork(altResponse, pathList, lookup, tr);
+        ResponsePath responsePath = new ResponsePath();
+        responsePath.setWaypoints(getWaypoints());
+        ghResponse.add(responsePath);
+        pathMerger.doWork(responsePath, pathList, lookup, tr);
     }
 
     private QueryResult generateValidPoint(GHPoint from, double distanceInMeters, double heading,
diff --git a/core/src/main/java/com/graphhopper/routing/template/RoutingTemplate.java b/core/src/main/java/com/graphhopper/routing/template/RoutingTemplate.java
index c9ce92c87..9f0d89c81 100644
--- a/core/src/main/java/com/graphhopper/routing/template/RoutingTemplate.java
+++ b/core/src/main/java/com/graphhopper/routing/template/RoutingTemplate.java
@@ -48,7 +48,7 @@ public interface RoutingTemplate {
 
     /**
      * This method merges the returned paths appropriately e.g. all paths from the list into one
-     * PathWrapper of GHResponse or multiple (via / round trip).
+     * ResponsePath of GHResponse or multiple (via / round trip).
      */
     void finish(PathMerger pathMerger, Translation tr);
 
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 76c7ac56e..d73c4831b 100644
--- a/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java
+++ b/core/src/main/java/com/graphhopper/routing/template/ViaRoutingTemplate.java
@@ -19,7 +19,7 @@ package com.graphhopper.routing.template;
 
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.routing.*;
 import com.graphhopper.routing.ev.EncodedValueLookup;
 import com.graphhopper.routing.ev.EnumEncodedValue;
@@ -56,7 +56,7 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
     protected final GHResponse ghResponse;
     // result from route
     protected List<Path> pathList;
-    protected final PathWrapper pathWrapper = new PathWrapper();
+    protected final ResponsePath responsePath = new ResponsePath();
     private final EnumEncodedValue<RoadClass> roadClassEnc;
     private final EnumEncodedValue<RoadEnvironment> roadEnvEnc;
 
@@ -194,7 +194,7 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
                 debug += ", " + path.getDebugInfo();
             }
 
-            pathWrapper.addDebugInfo(debug);
+            responsePath.addDebugInfo(debug);
 
             // reset all direction enforcements in queryGraph to avoid influencing next path
             queryGraph.clearUnfavoredStatus();
@@ -203,7 +203,7 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
                 throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
 
             visitedNodesSum += algo.getVisitedNodes();
-            pathWrapper.addDebugInfo("visited nodes sum: " + visitedNodesSum);
+            responsePath.addDebugInfo("visited nodes sum: " + visitedNodesSum);
             fromQResult = toQResult;
         }
 
@@ -233,9 +233,9 @@ public class ViaRoutingTemplate extends AbstractRoutingTemplate implements Routi
         if (ghRequest.getPoints().size() - 1 != pathList.size())
             throw new RuntimeException("There should be exactly one more points than paths. points:" + ghRequest.getPoints().size() + ", paths:" + pathList.size());
 
-        pathWrapper.setWaypoints(getWaypoints());
-        ghResponse.add(pathWrapper);
-        pathMerger.doWork(pathWrapper, pathList, lookup, tr);
+        responsePath.setWaypoints(getWaypoints());
+        ghResponse.add(responsePath);
+        pathMerger.doWork(responsePath, pathList, lookup, tr);
     }
 
 }
diff --git a/core/src/main/java/com/graphhopper/util/PathMerger.java b/core/src/main/java/com/graphhopper/util/PathMerger.java
index 7552c4271..0d88aa2af 100644
--- a/core/src/main/java/com/graphhopper/util/PathMerger.java
+++ b/core/src/main/java/com/graphhopper/util/PathMerger.java
@@ -17,7 +17,7 @@
  */
 package com.graphhopper.util;
 
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.routing.InstructionsFromEdges;
 import com.graphhopper.routing.Path;
 import com.graphhopper.routing.ev.EncodedValueLookup;
@@ -33,7 +33,7 @@ import java.util.List;
 
 /**
  * This class merges multiple {@link Path} objects into one continuous object that
- * can be used in the {@link PathWrapper}. There will be a Path between every waypoint.
+ * can be used in the {@link ResponsePath}. There will be a Path between every waypoint.
  * So for two waypoints there will be only one Path object. For three waypoints there will be
  * two Path objects.
  * <p>
@@ -88,7 +88,7 @@ public class PathMerger {
         return this;
     }
 
-    public void doWork(PathWrapper altRsp, List<Path> paths, EncodedValueLookup evLookup, Translation tr) {
+    public void doWork(ResponsePath responsePath, List<Path> paths, EncodedValueLookup evLookup, Translation tr) {
         int origPoints = 0;
         long fullTimeInMillis = 0;
         double fullWeight = 0;
@@ -134,7 +134,7 @@ public class PathMerger {
                 }
 
                 fullPoints.add(tmpPoints);
-                altRsp.addPathDetails(PathDetailsFromEdges.calcDetails(path, evLookup, weighting, requestedPathDetails, pathBuilderFactory, origPoints));
+                responsePath.addPathDetails(PathDetailsFromEdges.calcDetails(path, evLookup, weighting, requestedPathDetails, pathBuilderFactory, origPoints));
                 origPoints = fullPoints.size();
             }
 
@@ -142,29 +142,29 @@ public class PathMerger {
         }
 
         if (!fullPoints.isEmpty()) {
-            String debug = altRsp.getDebugInfo() + ", simplify (" + origPoints + "->" + fullPoints.getSize() + ")";
-            altRsp.addDebugInfo(debug);
+            String debug = responsePath.getDebugInfo() + ", simplify (" + origPoints + "->" + fullPoints.getSize() + ")";
+            responsePath.addDebugInfo(debug);
             if (fullPoints.is3D)
-                calcAscendDescend(altRsp, fullPoints);
+                calcAscendDescend(responsePath, fullPoints);
         }
 
         if (enableInstructions) {
             fullInstructions = updateInstructionsWithContext(fullInstructions);
-            altRsp.setInstructions(fullInstructions);
+            responsePath.setInstructions(fullInstructions);
         }
 
         if (!allFound) {
-            altRsp.addError(new ConnectionNotFoundException("Connection between locations not found", Collections.<String, Object>emptyMap()));
+            responsePath.addError(new ConnectionNotFoundException("Connection between locations not found", Collections.<String, Object>emptyMap()));
         }
 
-        altRsp.setDescription(description).
+        responsePath.setDescription(description).
                 setPoints(fullPoints).
                 setRouteWeight(fullWeight).
                 setDistance(fullDistance).
                 setTime(fullTimeInMillis);
 
         if (allFound && simplifyResponse && (calcPoints || enableInstructions)) {
-            PathSimplification.simplify(altRsp, douglasPeucker, enableInstructions);
+            PathSimplification.simplify(responsePath, douglasPeucker, enableInstructions);
         }
     }
 
@@ -213,7 +213,7 @@ public class PathMerger {
         return instructions;
     }
 
-    private void calcAscendDescend(final PathWrapper rsp, final PointList pointList) {
+    private void calcAscendDescend(final ResponsePath responsePath, final PointList pointList) {
         double ascendMeters = 0;
         double descendMeters = 0;
         double lastEle = pointList.getElevation(0);
@@ -229,8 +229,8 @@ public class PathMerger {
             lastEle = ele;
 
         }
-        rsp.setAscend(ascendMeters);
-        rsp.setDescend(descendMeters);
+        responsePath.setAscend(ascendMeters);
+        responsePath.setDescend(descendMeters);
     }
 
     public void setFavoredHeading(double favoredHeading) {
diff --git a/core/src/main/java/com/graphhopper/util/PathSimplification.java b/core/src/main/java/com/graphhopper/util/PathSimplification.java
index 31e84a4b4..393e4e91c 100644
--- a/core/src/main/java/com/graphhopper/util/PathSimplification.java
+++ b/core/src/main/java/com/graphhopper/util/PathSimplification.java
@@ -17,7 +17,7 @@
  */
 package com.graphhopper.util;
 
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.util.details.PathDetail;
 
 import java.util.ArrayList;
@@ -64,12 +64,12 @@ public class PathSimplification {
     /**
      * Convenience method used to obtain the partitions from a calculated path with details and instructions
      */
-    public static PointList simplify(PathWrapper pathWrapper, DouglasPeucker douglasPeucker, boolean enableInstructions) {
-        final PointList pointList = pathWrapper.getPoints();
+    public static PointList simplify(ResponsePath responsePath, DouglasPeucker douglasPeucker, boolean enableInstructions) {
+        final PointList pointList = responsePath.getPoints();
         List<Partition> partitions = new ArrayList<>();
         // todo: maybe this code can be simplified if path details and instructions would be merged, see #1121
         if (enableInstructions) {
-            final InstructionList instructions = pathWrapper.getInstructions();
+            final InstructionList instructions = responsePath.getInstructions();
             partitions.add(new Partition() {
                 @Override
                 public int size() {
@@ -97,7 +97,7 @@ public class PathSimplification {
             });
         }
 
-        for (final Map.Entry<String, List<PathDetail>> entry : pathWrapper.getPathDetails().entrySet()) {
+        for (final Map.Entry<String, List<PathDetail>> entry : responsePath.getPathDetails().entrySet()) {
             // If the pointList only contains one point, PathDetails have to be empty because 1 point => 0 edges
             final List<PathDetail> detail = entry.getValue();
             if (detail.isEmpty() && pointList.size() > 1)
@@ -123,10 +123,10 @@ public class PathSimplification {
             });
         }
 
-        simplify(pathWrapper.getPoints(), partitions, douglasPeucker);
-        assertConsistencyOfPathDetails(pathWrapper.getPathDetails());
+        simplify(responsePath.getPoints(), partitions, douglasPeucker);
+        assertConsistencyOfPathDetails(responsePath.getPathDetails());
         if (enableInstructions)
-            assertConsistencyOfInstructions(pathWrapper.getInstructions(), pathWrapper.getPoints().size());
+            assertConsistencyOfInstructions(responsePath.getInstructions(), responsePath.getPoints().size());
         return pointList;
     }
 
diff --git a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/PtRouteResource.java b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/PtRouteResource.java
index 30824bca3..2a61c1bdd 100644
--- a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/PtRouteResource.java
+++ b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/PtRouteResource.java
@@ -22,7 +22,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.transit.realtime.GtfsRealtime;
 import com.graphhopper.GHResponse;
 import com.graphhopper.GraphHopper;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.Trip;
 import com.graphhopper.http.WebHelper;
 import com.graphhopper.routing.querygraph.QueryGraph;
@@ -91,7 +91,7 @@ public final class PtRouteResource {
                             @QueryParam("pt.ignore_transfers") Boolean ignoreTransfers,
                             @QueryParam("pt.profile") Boolean profileQuery,
                             @QueryParam("pt.limit_solutions") Integer limitSolutions,
-                            @QueryParam("pt.limit_street_time") Integer limitStreetTime) {
+                            @QueryParam("pt.limit_street_time") DurationParam limitStreetTime) {
         StopWatch stopWatch = new StopWatch().start();
         List<GHLocation> points = requestPoints.stream().map(AbstractParam::get).collect(toList());
         Instant departureTime = departureTimeParam.get();
@@ -103,7 +103,7 @@ public final class PtRouteResource {
         Optional.ofNullable(ignoreTransfers).ifPresent(request::setIgnoreTransfers);
         Optional.ofNullable(localeStr).ifPresent(s -> request.setLocale(Helper.getLocale(s)));
         Optional.ofNullable(limitSolutions).ifPresent(request::setLimitSolutions);
-        Optional.ofNullable(limitStreetTime).ifPresent(request::setLimitStreetTime);
+        Optional.ofNullable(limitStreetTime.get()).ifPresent(request::setLimitStreetTime);
 
         GHResponse route = new RequestHandler(request).route();
         return WebHelper.jsonObject(route, true, true, false, false, stopWatch.stop().getMillis());
@@ -177,7 +177,7 @@ public final class PtRouteResource {
             translation = translationMap.getWithFallBack(request.getLocale());
             enter = request.getPoints().get(0);
             exit = request.getPoints().get(1);
-            limitStreetTime = request.getLimitStreetTime() != null ? request.getLimitStreetTime() * 60 * 1_000 : Long.MAX_VALUE;
+            limitStreetTime = request.getLimitStreetTime() != null ? request.getLimitStreetTime().toMillis() : Long.MAX_VALUE;
         }
 
         GHResponse route() {
@@ -243,13 +243,13 @@ public final class PtRouteResource {
         private void parseSolutionsAndAddToResponse(List<List<Label.Transition>> solutions, PointList waypoints) {
             for (List<Label.Transition> solution : solutions) {
                 final List<Trip.Leg> legs = tripFromLabel.getTrip(translation, queryGraph, accessEgressWeighting, solution);
-                final PathWrapper pathWrapper = tripFromLabel.createPathWrapper(translation, waypoints, legs);
-                pathWrapper.setImpossible(solution.stream().anyMatch(t -> t.label.impossible));
-                pathWrapper.setTime((solution.get(solution.size() - 1).label.currentTime - solution.get(0).label.currentTime));
-                response.add(pathWrapper);
+                final ResponsePath responsePath = tripFromLabel.createPathWrapper(translation, waypoints, legs);
+                responsePath.setImpossible(solution.stream().anyMatch(t -> t.label.impossible));
+                responsePath.setTime((solution.get(solution.size() - 1).label.currentTime - solution.get(0).label.currentTime));
+                response.add(responsePath);
             }
-            Comparator<PathWrapper> c = Comparator.comparingInt(p -> (p.isImpossible() ? 1 : 0));
-            Comparator<PathWrapper> d = Comparator.comparingDouble(PathWrapper::getTime);
+            Comparator<ResponsePath> c = Comparator.comparingInt(p -> (p.isImpossible() ? 1 : 0));
+            Comparator<ResponsePath> d = Comparator.comparingDouble(ResponsePath::getTime);
             response.getAll().sort(c.thenComparing(d));
         }
 
diff --git a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/Request.java b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/Request.java
index 52d42ee9c..90f5cb854 100644
--- a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/Request.java
+++ b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/Request.java
@@ -40,7 +40,7 @@ public class Request {
     private double walkSpeedKmH = 5.0;
     private int blockedRouteTypes;
     private Locale locale = Helper.getLocale("en");
-    private Integer limitStreetTime;
+    private Duration limitStreetTime;
     private Duration maxProfileDuration = Duration.ofHours(1);
 
     public Request(List<GHLocation> points, Instant departureTime) {
@@ -144,11 +144,11 @@ public class Request {
         return points;
     }
 
-    public Integer getLimitStreetTime() {
+    public Duration getLimitStreetTime() {
         return this.limitStreetTime;
     }
 
-    public void setLimitStreetTime(Integer streetTime) {
+    public void setLimitStreetTime(Duration streetTime) {
         this.limitStreetTime = streetTime;
     }
 
diff --git a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/TripFromLabel.java b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/TripFromLabel.java
index 1702e700b..de787791f 100644
--- a/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/TripFromLabel.java
+++ b/reader-gtfs/src/main/java/com/graphhopper/reader/gtfs/TripFromLabel.java
@@ -23,7 +23,7 @@ import com.conveyal.gtfs.model.Stop;
 import com.conveyal.gtfs.model.StopTime;
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.transit.realtime.GtfsRealtime;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.Trip;
 import com.graphhopper.gtfs.fare.Fares;
 import com.graphhopper.routing.InstructionsFromEdges;
@@ -59,7 +59,7 @@ class TripFromLabel {
         this.realtimeFeed = realtimeFeed;
     }
 
-    PathWrapper createPathWrapper(Translation tr, PointList waypoints, List<Trip.Leg> legs) {
+    ResponsePath createPathWrapper(Translation tr, PointList waypoints, List<Trip.Leg> legs) {
         if (legs.size() > 1 && legs.get(0) instanceof Trip.WalkLeg) {
             final Trip.WalkLeg accessLeg = (Trip.WalkLeg) legs.get(0);
             legs.set(0, new Trip.WalkLeg(accessLeg.departureLocation, new Date(legs.get(1).getDepartureTime().getTime() - (accessLeg.getArrivalTime().getTime() - accessLeg.getDepartureTime().getTime())),
@@ -72,7 +72,7 @@ class TripFromLabel {
                     new Date(legs.get(legs.size() - 2).getArrivalTime().getTime() + (egressLeg.getArrivalTime().getTime() - egressLeg.getDepartureTime().getTime()))));
         }
 
-        PathWrapper path = new PathWrapper();
+        ResponsePath path = new ResponsePath();
         path.setWaypoints(waypoints);
 
         path.getLegs().addAll(legs);
diff --git a/tools/src/main/java/com/graphhopper/tools/Measurement.java b/tools/src/main/java/com/graphhopper/tools/Measurement.java
index 2248fdf64..fd6e39ef1 100644
--- a/tools/src/main/java/com/graphhopper/tools/Measurement.java
+++ b/tools/src/main/java/com/graphhopper/tools/Measurement.java
@@ -739,7 +739,7 @@ public class Measurement {
                     return 0;
                 }
 
-                PathWrapper arsp = rsp.getBest();
+                ResponsePath responsePath = rsp.getBest();
                 if (!warmup) {
                     long visitedNodes = rsp.getHints().getLong("visited_nodes.sum", 0);
                     visitedNodesSum.addAndGet(visitedNodes);
@@ -747,7 +747,7 @@ public class Measurement {
                         maxVisitedNodes.set(visitedNodes);
                     }
 
-                    long dist = (long) arsp.getDistance();
+                    long dist = (long) responsePath.getDistance();
                     distSum.addAndGet(dist);
 
                     airDistSum.addAndGet((long) distCalc.calcDist(fromLat, fromLon, toLat, toLon));
@@ -762,7 +762,7 @@ public class Measurement {
                         altCount.addAndGet(rsp.getAll().size());
                 }
 
-                return arsp.getPoints().getSize();
+                return responsePath.getPoints().getSize();
             }
         }.setIterations(querySettings.count).start();
 
diff --git a/web-api/src/main/java/com/graphhopper/http/WebHelper.java b/web-api/src/main/java/com/graphhopper/http/WebHelper.java
index 1b691ea50..97b5f4aa0 100644
--- a/web-api/src/main/java/com/graphhopper/http/WebHelper.java
+++ b/web-api/src/main/java/com/graphhopper/http/WebHelper.java
@@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.util.Helper;
 import com.graphhopper.util.PointList;
 
@@ -162,32 +162,32 @@ public class WebHelper {
         json.putPOJO("hints", ghRsp.getHints().toMap());
         jsonResponsePutInfo(json, took);
         ArrayNode jsonPathList = json.putArray("paths");
-        for (PathWrapper ar : ghRsp.getAll()) {
+        for (ResponsePath p : ghRsp.getAll()) {
             ObjectNode jsonPath = jsonPathList.addObject();
-            jsonPath.put("distance", Helper.round(ar.getDistance(), 3));
-            jsonPath.put("weight", Helper.round6(ar.getRouteWeight()));
-            jsonPath.put("time", ar.getTime());
-            jsonPath.put("transfers", ar.getNumChanges());
-            if (!ar.getDescription().isEmpty()) {
-                jsonPath.putPOJO("description", ar.getDescription());
+            jsonPath.put("distance", Helper.round(p.getDistance(), 3));
+            jsonPath.put("weight", Helper.round6(p.getRouteWeight()));
+            jsonPath.put("time", p.getTime());
+            jsonPath.put("transfers", p.getNumChanges());
+            if (!p.getDescription().isEmpty()) {
+                jsonPath.putPOJO("description", p.getDescription());
             }
             if (calcPoints) {
                 jsonPath.put("points_encoded", pointsEncoded);
-                if (ar.getPoints().getSize() >= 2) {
-                    jsonPath.putPOJO("bbox", ar.calcBBox2D());
+                if (p.getPoints().getSize() >= 2) {
+                    jsonPath.putPOJO("bbox", p.calcBBox2D());
                 }
-                jsonPath.putPOJO("points", pointsEncoded ? encodePolyline(ar.getPoints(), enableElevation) : ar.getPoints().toLineString(enableElevation));
+                jsonPath.putPOJO("points", pointsEncoded ? encodePolyline(p.getPoints(), enableElevation) : p.getPoints().toLineString(enableElevation));
                 if (enableInstructions) {
-                    jsonPath.putPOJO("instructions", ar.getInstructions());
+                    jsonPath.putPOJO("instructions", p.getInstructions());
                 }
-                jsonPath.putPOJO("legs", ar.getLegs());
-                jsonPath.putPOJO("details", ar.getPathDetails());
-                jsonPath.put("ascend", ar.getAscend());
-                jsonPath.put("descend", ar.getDescend());
+                jsonPath.putPOJO("legs", p.getLegs());
+                jsonPath.putPOJO("details", p.getPathDetails());
+                jsonPath.put("ascend", p.getAscend());
+                jsonPath.put("descend", p.getDescend());
             }
-            jsonPath.putPOJO("snapped_waypoints", pointsEncoded ? encodePolyline(ar.getWaypoints(), enableElevation) : ar.getWaypoints().toLineString(enableElevation));
-            if (ar.getFare() != null) {
-                jsonPath.put("fare", NumberFormat.getCurrencyInstance(Locale.ROOT).format(ar.getFare()));
+            jsonPath.putPOJO("snapped_waypoints", pointsEncoded ? encodePolyline(p.getWaypoints(), enableElevation) : p.getWaypoints().toLineString(enableElevation));
+            if (p.getFare() != null) {
+                jsonPath.put("fare", NumberFormat.getCurrencyInstance(Locale.ROOT).format(p.getFare()));
             }
         }
         return json;
diff --git a/web-api/src/main/java/com/graphhopper/jackson/GHResponseDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/GHResponseDeserializer.java
index eaaed4cff..0488500fe 100644
--- a/web-api/src/main/java/com/graphhopper/jackson/GHResponseDeserializer.java
+++ b/web-api/src/main/java/com/graphhopper/jackson/GHResponseDeserializer.java
@@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.JsonDeserializer;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 
 import java.io.IOException;
 
@@ -33,8 +33,8 @@ public class GHResponseDeserializer extends JsonDeserializer<GHResponse> {
         GHResponse ghResponse = new GHResponse();
         JsonNode treeNode = p.readValueAsTree();
         for (JsonNode path : treeNode.get("paths")) {
-            PathWrapper pathWrapper = ((ObjectMapper) p.getCodec()).convertValue(path, PathWrapper.class);
-            ghResponse.add(pathWrapper);
+            ResponsePath responsePath = ((ObjectMapper) p.getCodec()).convertValue(path, ResponsePath.class);
+            ghResponse.add(responsePath);
         }
         return ghResponse;
     }
diff --git a/web-api/src/main/java/com/graphhopper/jackson/GraphHopperModule.java b/web-api/src/main/java/com/graphhopper/jackson/GraphHopperModule.java
index c3991daa1..ceca2d8bf 100644
--- a/web-api/src/main/java/com/graphhopper/jackson/GraphHopperModule.java
+++ b/web-api/src/main/java/com/graphhopper/jackson/GraphHopperModule.java
@@ -34,7 +34,7 @@ public class GraphHopperModule extends SimpleModule {
         setMixInAnnotation(LMProfile.class, LMProfileMixIn.class);
         setMixInAnnotation(GraphHopperConfig.class, GraphHopperConfigMixIn.class);
         addDeserializer(GHResponse.class, new GHResponseDeserializer());
-        addDeserializer(PathWrapper.class, new PathWrapperDeserializer());
+        addDeserializer(ResponsePath.class, new PathWrapperDeserializer());
         addDeserializer(BBox.class, new BBoxDeserializer());
         addSerializer(BBox.class, new BBoxSerializer());
         addDeserializer(GHPoint.class, new GHPointDeserializer());
diff --git a/web-api/src/main/java/com/graphhopper/jackson/PathWrapperDeserializer.java b/web-api/src/main/java/com/graphhopper/jackson/PathWrapperDeserializer.java
index 7eb3b84f8..7e1618bcd 100644
--- a/web-api/src/main/java/com/graphhopper/jackson/PathWrapperDeserializer.java
+++ b/web-api/src/main/java/com/graphhopper/jackson/PathWrapperDeserializer.java
@@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.DeserializationContext;
 import com.fasterxml.jackson.databind.JsonDeserializer;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.http.WebHelper;
 import com.graphhopper.util.*;
 import com.graphhopper.util.details.PathDetail;
@@ -33,32 +33,32 @@ import org.locationtech.jts.geom.LineString;
 import java.io.IOException;
 import java.util.*;
 
-public class PathWrapperDeserializer extends JsonDeserializer<PathWrapper> {
+public class PathWrapperDeserializer extends JsonDeserializer<ResponsePath> {
     @Override
-    public PathWrapper deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
+    public ResponsePath deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
         return createPathWrapper((ObjectMapper) p.getCodec(), p.readValueAsTree(), false, true);
     }
 
-    public static PathWrapper createPathWrapper(ObjectMapper objectMapper, JsonNode path, boolean hasElevation, boolean turnDescription) {
-        PathWrapper pathWrapper = new PathWrapper();
-        pathWrapper.addErrors(readErrors(objectMapper, path));
-        if (pathWrapper.hasErrors())
-            return pathWrapper;
+    public static ResponsePath createPathWrapper(ObjectMapper objectMapper, JsonNode path, boolean hasElevation, boolean turnDescription) {
+        ResponsePath responsePath = new ResponsePath();
+        responsePath.addErrors(readErrors(objectMapper, path));
+        if (responsePath.hasErrors())
+            return responsePath;
 
         if (path.has("snapped_waypoints")) {
             JsonNode snappedWaypoints = path.get("snapped_waypoints");
             PointList snappedPoints = deserializePointList(objectMapper, snappedWaypoints, hasElevation);
-            pathWrapper.setWaypoints(snappedPoints);
+            responsePath.setWaypoints(snappedPoints);
         }
 
         if (path.has("ascend")) {
-            pathWrapper.setAscend(path.get("ascend").asDouble());
+            responsePath.setAscend(path.get("ascend").asDouble());
         }
         if (path.has("descend")) {
-            pathWrapper.setDescend(path.get("descend").asDouble());
+            responsePath.setDescend(path.get("descend").asDouble());
         }
         if (path.has("weight")) {
-            pathWrapper.setRouteWeight(path.get("weight").asDouble());
+            responsePath.setRouteWeight(path.get("weight").asDouble());
         }
         if (path.has("description")) {
             JsonNode descriptionNode = path.get("description");
@@ -67,7 +67,7 @@ public class PathWrapperDeserializer extends JsonDeserializer<PathWrapper> {
                 for (JsonNode descNode : descriptionNode) {
                     description.add(descNode.asText());
                 }
-                pathWrapper.setDescription(description);
+                responsePath.setDescription(description);
             } else {
                 throw new IllegalStateException("Description has to be an array");
             }
@@ -75,7 +75,7 @@ public class PathWrapperDeserializer extends JsonDeserializer<PathWrapper> {
 
         if (path.has("points")) {
             final PointList pointList = deserializePointList(objectMapper, path.get("points"), hasElevation);
-            pathWrapper.setPoints(pointList);
+            responsePath.setPoints(pointList);
 
             if (path.has("instructions")) {
                 JsonNode instrArr = path.get("instructions");
@@ -147,7 +147,7 @@ public class PathWrapperDeserializer extends JsonDeserializer<PathWrapper> {
                     instr.setDistance(instDist).setTime(instTime);
                     il.add(instr);
                 }
-                pathWrapper.setInstructions(il);
+                responsePath.setInstructions(il);
             }
 
             if (path.has("details")) {
@@ -163,24 +163,24 @@ public class PathWrapperDeserializer extends JsonDeserializer<PathWrapper> {
                     }
                     pathDetails.put(detailEntry.getKey(), pathDetailList);
                 }
-                pathWrapper.addPathDetails(pathDetails);
+                responsePath.addPathDetails(pathDetails);
             }
         }
 
         if (path.has("points_order")) {
-            pathWrapper.setPointsOrder((List<Integer>) objectMapper.convertValue(path.get("points_order"), List.class));
+            responsePath.setPointsOrder((List<Integer>) objectMapper.convertValue(path.get("points_order"), List.class));
         } else {
-            List<Integer> list = new ArrayList<>(pathWrapper.getWaypoints().size());
-            for (int i = 0; i < pathWrapper.getWaypoints().size(); i++) {
+            List<Integer> list = new ArrayList<>(responsePath.getWaypoints().size());
+            for (int i = 0; i < responsePath.getWaypoints().size(); i++) {
                 list.add(i);
             }
-            pathWrapper.setPointsOrder(list);
+            responsePath.setPointsOrder(list);
         }
 
         double distance = path.get("distance").asDouble();
         long time = path.get("time").asLong();
-        pathWrapper.setDistance(distance).setTime(time);
-        return pathWrapper;
+        responsePath.setDistance(distance).setTime(time);
+        return responsePath;
     }
 
     private static PointList deserializePointList(ObjectMapper objectMapper, JsonNode jsonNode, boolean hasElevation) {


Test patch:
diff --git a/api/src/test/java/com/graphhopper/util/GHResponseTest.java b/api/src/test/java/com/graphhopper/util/GHResponseTest.java
index b9b19108d..72561be41 100644
--- a/api/src/test/java/com/graphhopper/util/GHResponseTest.java
+++ b/api/src/test/java/com/graphhopper/util/GHResponseTest.java
@@ -18,11 +18,10 @@
 package com.graphhopper.util;
 
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import org.junit.Assert;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
 public class GHResponseTest {
@@ -35,7 +34,7 @@ public class GHResponseTest {
     public void testHasNoErrorIfEmpty() throws Exception {
         assertFalse(new GHResponse().hasErrors());
         GHResponse rsp = new GHResponse();
-        rsp.add(new PathWrapper());
+        rsp.add(new ResponsePath());
         assertFalse(rsp.hasErrors());
     }
 }
diff --git a/api/src/test/java/com/graphhopper/util/shapes/BBoxTest.java b/api/src/test/java/com/graphhopper/util/shapes/BBoxTest.java
index 24cf2beef..e6705d364 100644
--- a/api/src/test/java/com/graphhopper/util/shapes/BBoxTest.java
+++ b/api/src/test/java/com/graphhopper/util/shapes/BBoxTest.java
@@ -33,7 +33,7 @@ public class BBoxTest {
         DistanceCalc c = new DistanceCalcEarth();
         BBox b = c.createBBox(52, 10, 100000);
 
-        // The calclulated bounding box has no negative values (also for southern hemisphere and negative meridians)
+        // The calculated bounding box has no negative values (also for southern hemisphere and negative meridians)
         // and the ordering is always the same (top to bottom and left to right)
         assertEquals(52.8993, b.maxLat, 1e-4);
         assertEquals(8.5393, b.minLon, 1e-4);
diff --git a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java
index 60665819f..bc6ee8b06 100644
--- a/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java
+++ b/client-hc/src/test/java/com/graphhopper/api/GraphHopperWebTest.java
@@ -4,15 +4,13 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.graphhopper.GHRequest;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.jackson.Jackson;
 import com.graphhopper.jackson.PathWrapperDeserializer;
 import com.graphhopper.util.shapes.GHPoint;
 import org.junit.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.io.IOException;
 
@@ -51,9 +49,9 @@ public class GraphHopperWebTest {
         // Modified the sign though
         ObjectMapper objectMapper = Jackson.newObjectMapper();
         JsonNode json = objectMapper.readTree("{\"instructions\":[{\"distance\":1.073,\"sign\":741,\"interval\":[0,1],\"text\":\"Continue onto A 81\",\"time\":32,\"street_name\":\"A 81\"},{\"distance\":0,\"sign\":4,\"interval\":[1,1],\"text\":\"Finish!\",\"time\":0,\"street_name\":\"\"}],\"descend\":0,\"ascend\":0,\"distance\":1.073,\"bbox\":[8.676286,48.354446,8.676297,48.354453],\"weight\":0.032179,\"time\":32,\"points_encoded\":true,\"points\":\"gfcfHwq}s@}c~AAA?\",\"snapped_waypoints\":\"gfcfHwq}s@}c~AAA?\"}");
-        PathWrapper wrapper = PathWrapperDeserializer.createPathWrapper(objectMapper, json, true, true);
+        ResponsePath responsePath = PathWrapperDeserializer.createPathWrapper(objectMapper, json, true, true);
 
-        assertEquals(741, wrapper.getInstructions().get(0).getSign());
-        assertEquals("Continue onto A 81", wrapper.getInstructions().get(0).getName());
+        assertEquals(741, responsePath.getInstructions().get(0).getSign());
+        assertEquals("Continue onto A 81", responsePath.getInstructions().get(0).getName());
     }
 }
\ No newline at end of file
diff --git a/core/src/main/java/com/graphhopper/routing/util/TestAlgoCollector.java b/core/src/main/java/com/graphhopper/routing/util/TestAlgoCollector.java
index 55ba4f11d..eab76b598 100644
--- a/core/src/main/java/com/graphhopper/routing/util/TestAlgoCollector.java
+++ b/core/src/main/java/com/graphhopper/routing/util/TestAlgoCollector.java
@@ -17,7 +17,7 @@
  */
 package com.graphhopper.routing.util;
 
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.routing.*;
 import com.graphhopper.routing.querygraph.QueryGraph;
 import com.graphhopper.storage.CHGraph;
@@ -65,34 +65,34 @@ public class TestAlgoCollector {
                 setCalcPoints(true).
                 setSimplifyResponse(false).
                 setEnableInstructions(true);
-        PathWrapper rsp = new PathWrapper();
-        pathMerger.doWork(rsp, altPaths, encodingManager, trMap.getWithFallBack(Locale.US));
+        ResponsePath responsePath = new ResponsePath();
+        pathMerger.doWork(responsePath, altPaths, encodingManager, trMap.getWithFallBack(Locale.US));
 
-        if (rsp.hasErrors()) {
+        if (responsePath.hasErrors()) {
             errors.add("response for " + algoEntry + " contains errors. Expected distance: " + oneRun.getDistance()
-                    + ", expected points: " + oneRun + ". " + queryList + ", errors:" + rsp.getErrors());
+                    + ", expected points: " + oneRun + ". " + queryList + ", errors:" + responsePath.getErrors());
             return this;
         }
 
-        PointList pointList = rsp.getPoints();
+        PointList pointList = responsePath.getPoints();
         double tmpDist = pointList.calcDistance(distCalc);
-        if (Math.abs(rsp.getDistance() - tmpDist) > 2) {
-            errors.add(algoEntry + " path.getDistance was  " + rsp.getDistance()
+        if (Math.abs(responsePath.getDistance() - tmpDist) > 2) {
+            errors.add(algoEntry + " path.getDistance was  " + responsePath.getDistance()
                     + "\t pointList.calcDistance was " + tmpDist + "\t (expected points " + oneRun.getLocs()
                     + ", expected distance " + oneRun.getDistance() + ") " + queryList);
         }
 
-        if (Math.abs(rsp.getDistance() - oneRun.getDistance()) > 2) {
+        if (Math.abs(responsePath.getDistance() - oneRun.getDistance()) > 2) {
             errors.add(algoEntry + " returns path not matching the expected distance of " + oneRun.getDistance()
-                    + "\t Returned was " + rsp.getDistance() + "\t (expected points " + oneRun.getLocs()
-                    + ", was " + pointList.getSize() + ") " + "\t (weight " + rsp.getRouteWeight() + ") " + queryList);
+                    + "\t Returned was " + responsePath.getDistance() + "\t (expected points " + oneRun.getLocs()
+                    + ", was " + pointList.getSize() + ") " + "\t (weight " + responsePath.getRouteWeight() + ") " + queryList);
         }
 
         // There are real world instances where A-B-C is identical to A-C (in meter precision).
         if (Math.abs(pointList.getSize() - oneRun.getLocs()) > 1) {
             errors.add(algoEntry + " returns path not matching the expected points of " + oneRun.getLocs()
                     + "\t Returned was " + pointList.getSize() + "\t (expected distance " + oneRun.getDistance()
-                    + ", was " + rsp.getDistance() + ") " + queryList);
+                    + ", was " + responsePath.getDistance() + ") " + queryList);
         }
         return this;
     }
diff --git a/core/src/test/java/com/graphhopper/GraphHopperAPITest.java b/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
index db8a1c9ad..581eed444 100644
--- a/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
+++ b/core/src/test/java/com/graphhopper/GraphHopperAPITest.java
@@ -68,10 +68,10 @@ public class GraphHopperAPITest {
         // 3 -> 0
         GHResponse rsp = instance.route(new GHRequest(42, 10.4, 42, 10).setProfile(profile));
         assertFalse(rsp.hasErrors());
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(80, arsp.getDistance(), 1e-6);
+        ResponsePath responsePath = rsp.getBest();
+        assertEquals(80, responsePath.getDistance(), 1e-6);
 
-        PointList points = arsp.getPoints();
+        PointList points = responsePath.getPoints();
         assertEquals(42, points.getLatitude(0), 1e-5);
         assertEquals(10.4, points.getLongitude(0), 1e-5);
         assertEquals(41.9, points.getLatitude(1), 1e-5);
diff --git a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java
index d7f8c0cd5..2485e55fd 100644
--- a/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java
+++ b/core/src/test/java/com/graphhopper/routing/lm/PrepareLandmarksTest.java
@@ -157,7 +157,7 @@ public class PrepareLandmarksTest {
 
         assertEquals(expectedPath.getWeight(), path.getWeight(), .1);
         assertEquals(expectedPath.calcNodes(), path.calcNodes());
-        assertEquals(expectedAlgo.getVisitedNodes() - 133, oneDirAlgoWithLandmarks.getVisitedNodes());
+        assertEquals(expectedAlgo.getVisitedNodes() - 135, oneDirAlgoWithLandmarks.getVisitedNodes());
 
         // landmarks with bidir A*
         RoutingAlgorithm biDirAlgoWithLandmarks = prepare.getRoutingAlgorithmFactory().createAlgo(graph,
@@ -180,7 +180,7 @@ public class PrepareLandmarksTest {
         expectedPath = expectedAlgo.calcPath(fromQR.getClosestNode(), toQR.getClosestNode());
         assertEquals(expectedPath.getWeight(), path.getWeight(), .1);
         assertEquals(expectedPath.calcNodes(), path.calcNodes());
-        assertEquals(expectedAlgo.getVisitedNodes() - 133, qGraphOneDirAlgo.getVisitedNodes());
+        assertEquals(expectedAlgo.getVisitedNodes() - 135, qGraphOneDirAlgo.getVisitedNodes());
     }
 
     @Test
@@ -202,7 +202,7 @@ public class PrepareLandmarksTest {
         assertEquals(Arrays.toString(new int[]{
                 2, 0
         }), Arrays.toString(plm.getLandmarkStorage().getLandmarks(1)));
-        assertEquals(4791, Math.round(plm.getLandmarkStorage().getFromWeight(0, 1) * expectedFactor));
+        assertEquals(4800, Math.round(plm.getLandmarkStorage().getFromWeight(0, 1) * expectedFactor));
 
         dir = new RAMDirectory(fileStr, true);
         plm = new PrepareLandmarks(dir, graph, lmConfig, 2);
@@ -211,7 +211,7 @@ public class PrepareLandmarksTest {
         assertEquals(Arrays.toString(new int[]{
                 2, 0
         }), Arrays.toString(plm.getLandmarkStorage().getLandmarks(1)));
-        assertEquals(4791, Math.round(plm.getLandmarkStorage().getFromWeight(0, 1) * expectedFactor));
+        assertEquals(4800, Math.round(plm.getLandmarkStorage().getFromWeight(0, 1) * expectedFactor));
 
         Helper.removeDir(new File(fileStr));
     }
diff --git a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java
index 84107dfb5..5ec3f1745 100644
--- a/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java
+++ b/core/src/test/java/com/graphhopper/util/PathSimplificationTest.java
@@ -17,7 +17,7 @@
  */
 package com.graphhopper.util;
 
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.reader.ReaderWay;
 import com.graphhopper.routing.Dijkstra;
 import com.graphhopper.routing.InstructionsFromEdges;
@@ -143,10 +143,10 @@ public class PathSimplificationTest {
         Map<String, List<PathDetail>> details = PathDetailsFromEdges.calcDetails(p, carManager, weighting,
                 Arrays.asList(AVERAGE_SPEED), new PathDetailsBuilderFactory(), 0);
 
-        PathWrapper pathWrapper = new PathWrapper();
-        pathWrapper.setInstructions(wayList);
-        pathWrapper.addPathDetails(details);
-        pathWrapper.setPoints(p.calcPoints());
+        ResponsePath responsePath = new ResponsePath();
+        responsePath.setInstructions(wayList);
+        responsePath.addPathDetails(details);
+        responsePath.setPoints(p.calcPoints());
 
         int numberOfPoints = p.calcPoints().size();
 
@@ -154,19 +154,19 @@ public class PathSimplificationTest {
         // Do not simplify anything
         douglasPeucker.setMaxDistance(0);
 
-        PathSimplification.simplify(pathWrapper, douglasPeucker, true);
+        PathSimplification.simplify(responsePath, douglasPeucker, true);
 
-        assertEquals(numberOfPoints, pathWrapper.getPoints().size());
+        assertEquals(numberOfPoints, responsePath.getPoints().size());
 
-        pathWrapper = new PathWrapper();
-        pathWrapper.setInstructions(wayList);
-        pathWrapper.addPathDetails(details);
-        pathWrapper.setPoints(p.calcPoints());
+        responsePath = new ResponsePath();
+        responsePath.setInstructions(wayList);
+        responsePath.addPathDetails(details);
+        responsePath.setPoints(p.calcPoints());
 
         douglasPeucker.setMaxDistance(100000000);
-        PathSimplification.simplify(pathWrapper, douglasPeucker, true);
+        PathSimplification.simplify(responsePath, douglasPeucker, true);
 
-        assertTrue(numberOfPoints > pathWrapper.getPoints().size());
+        assertTrue(numberOfPoints > responsePath.getPoints().size());
     }
 
     @Test
diff --git a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java
index 64b16f73e..27bf45bf0 100644
--- a/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java
+++ b/reader-gtfs/src/test/java/com/graphhopper/AnotherAgencyIT.java
@@ -37,7 +37,8 @@ import java.util.Arrays;
 import java.util.Collections;
 
 import static com.graphhopper.reader.gtfs.GtfsHelper.time;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 
 public class AnotherAgencyIT {
 
@@ -81,7 +82,7 @@ public class AnotherAgencyIT {
 
         assertFalse(route.hasErrors());
         assertEquals(1, route.getAll().size());
-        PathWrapper transitSolution = route.getBest();
+        ResponsePath transitSolution = route.getBest();
         assertEquals("Expected total travel time == scheduled travel time + wait time", time(1, 30), transitSolution.getTime());
     }
 
@@ -100,7 +101,7 @@ public class AnotherAgencyIT {
 
         assertFalse(route.hasErrors());
         assertEquals(1, route.getAll().size());
-        PathWrapper transitSolution = route.getBest();
+        ResponsePath transitSolution = route.getBest();
         assertEquals(2, transitSolution.getLegs().size());
         Trip.PtLeg ptLeg1 = (Trip.PtLeg) transitSolution.getLegs().get(0);
         assertEquals("COURT2MUSEUM", ptLeg1.route_id);
diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java
index bf82ff94b..b4a57c1a8 100644
--- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java
+++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperGtfsIT.java
@@ -392,7 +392,7 @@ public class GraphHopperGtfsIT {
         );
         ghRequest.setEarliestDepartureTime(LocalDateTime.of(2007, 1, 1, 18, 0).atZone(zoneId).toInstant());
         GHResponse response = ptRouteResource.route(ghRequest);
-        PathWrapper mondayTrip = response.getBest();
+        ResponsePath mondayTrip = response.getBest();
         assertEquals("Monday trip has no transfers", 0, mondayTrip.getNumChanges());
         assertEquals("Monday trip has 3 legs", 3, mondayTrip.getLegs().size());
         assertEquals("FUNNY_BLOCK_AB1", (((Trip.PtLeg) mondayTrip.getLegs().get(0)).trip_id));
@@ -401,7 +401,7 @@ public class GraphHopperGtfsIT {
 
         ghRequest.setEarliestDepartureTime(LocalDateTime.of(2007, 1, 7, 18, 0).atZone(zoneId).toInstant());
         response = ptRouteResource.route(ghRequest);
-        PathWrapper sundayTrip = response.getBest();
+        ResponsePath sundayTrip = response.getBest();
         assertEquals("Sunday trip has no transfers", 0, sundayTrip.getNumChanges());
         assertEquals("Sunday trip has 2 legs", 2, sundayTrip.getLegs().size());
         assertEquals("FUNNY_BLOCK_AB1", (((Trip.PtLeg) sundayTrip.getLegs().get(0)).trip_id));
@@ -502,8 +502,8 @@ public class GraphHopperGtfsIT {
 
         GHResponse response = ptRouteResource.route(ghRequest);
 
-        PathWrapper solutionWithTransfer = response.getAll().get(0);
-        PathWrapper solutionWithoutTransfer = response.getAll().get(1);
+        ResponsePath solutionWithTransfer = response.getAll().get(0);
+        ResponsePath solutionWithoutTransfer = response.getAll().get(1);
 
         Assume.assumeTrue("First solution has one transfer", solutionWithTransfer.getNumChanges() == 1);
         Assume.assumeTrue("Second solution has no transfers", solutionWithoutTransfer.getNumChanges() == 0);
diff --git a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java
index ad5e7e476..8c17db932 100644
--- a/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java
+++ b/reader-gtfs/src/test/java/com/graphhopper/GraphHopperMultimodalIT.java
@@ -77,7 +77,7 @@ public class GraphHopperMultimodalIT {
         GHResponse response = graphHopper.route(ghRequest);
         assertThat(response.getHints().getInt("visited_nodes.sum", Integer.MAX_VALUE)).isLessThanOrEqualTo(243);
 
-        PathWrapper firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); // There can be a walk-only trip.
+        ResponsePath firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); // There can be a walk-only trip.
         assertThat(firstTransitSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:41:04.833"));
         assertThat(firstTransitSolution.getLegs().get(0).getArrivalTime().toInstant())
@@ -98,7 +98,7 @@ public class GraphHopperMultimodalIT {
         GHResponse response = graphHopper.route(ghRequest);
         assertThat(response.getHints().getInt("visited_nodes.sum", Integer.MAX_VALUE)).isLessThanOrEqualTo(129);
 
-        PathWrapper firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); // There can be a walk-only trip.
+        ResponsePath firstTransitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get(); // There can be a walk-only trip.
         assertThat(firstTransitSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:41:04.833"));
         assertThat(firstTransitSolution.getLegs().get(0).getArrivalTime().toInstant())
@@ -106,7 +106,7 @@ public class GraphHopperMultimodalIT {
         assertThat(firstTransitSolution.getLegs().get(2).getArrivalTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:52:02.729"));
 
-        PathWrapper walkSolution = response.getAll().stream().filter(p -> p.getLegs().size() == 1).findFirst().get();
+        ResponsePath walkSolution = response.getAll().stream().filter(p -> p.getLegs().size() == 1).findFirst().get();
         assertThat(walkSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:40"));
         // In principle, this would dominate the transit solution, since it's faster, but
@@ -148,7 +148,7 @@ public class GraphHopperMultimodalIT {
 
         GHResponse response = graphHopper.route(ghRequest);
 
-        PathWrapper walkSolution = response.getAll().stream().filter(p -> p.getLegs().size() == 1).findFirst().get();
+        ResponsePath walkSolution = response.getAll().stream().filter(p -> p.getLegs().size() == 1).findFirst().get();
         assertThat(walkSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:40"));
         assertThat(walkSolution.getLegs().get(0).getArrivalTime().toInstant().atZone(zoneId).toLocalTime())
@@ -169,7 +169,7 @@ public class GraphHopperMultimodalIT {
 
         GHResponse response = graphHopper.route(ghRequest);
 
-        PathWrapper walkSolution = response.getAll().get(0);
+        ResponsePath walkSolution = response.getAll().get(0);
         assertThat(walkSolution.getLegs().get(0).getDepartureTime().toInstant().atZone(zoneId).toLocalTime())
                 .isEqualTo(LocalTime.parse("06:40"));
         assertThat(walkSolution.getLegs().get(0).getArrivalTime().toInstant().atZone(zoneId).toLocalTime())
@@ -215,7 +215,7 @@ public class GraphHopperMultimodalIT {
 
         GHResponse response = graphHopper.route(ghRequest);
 
-        PathWrapper transitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get();
+        ResponsePath transitSolution = response.getAll().stream().filter(p -> p.getLegs().size() > 1).findFirst().get();
         assertThat(transitSolution.getLegs().size()).isEqualTo(3);
     }
 }
diff --git a/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java b/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java
index 4aacd1486..8c5b6524c 100644
--- a/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java
+++ b/reader-gtfs/src/test/java/com/graphhopper/RealtimeIT.java
@@ -95,11 +95,11 @@ public class RealtimeIT {
 
         GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest);
 
-        PathWrapper possibleAlternative = response.getAll().stream().filter(a -> !a.isImpossible()).findFirst().get();
+        ResponsePath possibleAlternative = response.getAll().stream().filter(a -> !a.isImpossible()).findFirst().get();
         assertFalse(((Trip.PtLeg) possibleAlternative.getLegs().get(0)).stops.get(0).departureCancelled);
         assertEquals("I have to wait half an hour for the next one (and ride 5 minutes)", time(0, 35), possibleAlternative.getTime(), 0.1);
 
-        PathWrapper impossibleAlternative = response.getAll().stream().filter(a -> a.isImpossible()).findFirst().get();
+        ResponsePath impossibleAlternative = response.getAll().stream().filter(a -> a.isImpossible()).findFirst().get();
         assertTrue(impossibleAlternative.isImpossible());
         assertTrue(((Trip.PtLeg) impossibleAlternative.getLegs().get(0)).stops.get(0).departureCancelled);
     }
@@ -133,12 +133,12 @@ public class RealtimeIT {
         GHResponse response = graphHopperFactory.createWith(feedMessageBuilder.build()).route(ghRequest);
         assertEquals(2, response.getAll().size());
 
-        PathWrapper best = response.getBest();
+        ResponsePath best = response.getBest();
         Trip.PtLeg bestPtLeg = (Trip.PtLeg) best.getLegs().get(0);
         assertEquals("It's better to wait half an hour for the next one (and ride 5 minutes).", LocalDateTime.parse("2007-01-01T07:19:00").atZone(zoneId).toInstant(), bestPtLeg.stops.get(bestPtLeg.stops.size()-1).plannedArrivalTime.toInstant());
         assertEquals("There is no predicted arrival time.", null, bestPtLeg.stops.get(bestPtLeg.stops.size()-1).predictedArrivalTime);
 
-        PathWrapper impossibleAlternative = response.getAll().get(1);
+        ResponsePath impossibleAlternative = response.getAll().get(1);
         assertTrue(impossibleAlternative.isImpossible());
         Trip.PtLeg impossiblePtLeg = (Trip.PtLeg) impossibleAlternative.getLegs().get(0);
         assertEquals("The impossible alternative is my planned 5-minute-trip", LocalDateTime.parse("2007-01-01T06:49:00").atZone(zoneId).toInstant(), impossiblePtLeg.stops.get(impossiblePtLeg.stops.size()-1).plannedArrivalTime.toInstant());
@@ -206,7 +206,7 @@ public class RealtimeIT {
 
         assertEquals("I have to continue to STAGECOACH and then go back one stop with the 07:00 bus.", time(0, 21), response.getBest().getTime(), 0.1);
 
-        PathWrapper impossibleAlternative = response.getAll().get(2);
+        ResponsePath impossibleAlternative = response.getAll().get(2);
         assertTrue(impossibleAlternative.isImpossible());
         assertTrue(((Trip.PtLeg) impossibleAlternative.getLegs().get(0)).stops.get(1).arrivalCancelled);
     }
@@ -241,7 +241,7 @@ public class RealtimeIT {
 
         assertEquals("The 6:44 bus will not call at STAGECOACH, so I will be 30 min late at the airport.", time(1, 6), response.getBest().getTime(), 0.1);
 
-        PathWrapper impossibleAlternative = response.getAll().get(1);
+        ResponsePath impossibleAlternative = response.getAll().get(1);
         assertTrue(impossibleAlternative.isImpossible());
         assertTrue(((Trip.PtLeg) impossibleAlternative.getLegs().get(0)).stops.get(2).departureCancelled);
     }
@@ -300,7 +300,7 @@ public class RealtimeIT {
 
         assertEquals("Luckily, there is an extra service directly from my stop to the airport, at 6:45, taking 30 minutes", time(0, 31), response.getBest().getTime(), 0.1);
 
-        PathWrapper solution = response.getAll().get(0);
+        ResponsePath solution = response.getAll().get(0);
         Trip.PtLeg ptLeg = ((Trip.PtLeg) solution.getLegs().stream().filter(leg -> leg instanceof Trip.PtLeg).findFirst().get());
         assertEquals("EXTRA0", ptLeg.trip_id);
     }
@@ -547,7 +547,7 @@ public class RealtimeIT {
 
         assertEquals("The 6:44 bus will be late at STAGECOACH, so I will be 30 min late at the airport.", time(1, 6), response.getBest().getTime(), 0.1);
 
-        PathWrapper impossibleAlternative = response.getAll().get(1);
+        ResponsePath impossibleAlternative = response.getAll().get(1);
         assertTrue(impossibleAlternative.isImpossible());
         Trip.Stop delayedStop = ((Trip.PtLeg) impossibleAlternative.getLegs().get(0)).stops.get(2);
         assertEquals("Five minutes late", 300, Duration.between(delayedStop.plannedArrivalTime.toInstant(), delayedStop.predictedArrivalTime.toInstant()).getSeconds());
@@ -680,7 +680,7 @@ public class RealtimeIT {
 
         assertEquals("The 7:44 bus will not call at STAGECOACH, so I will be 30 min late at the airport.", time(1, 6), response.getBest().getTime(), 0.1);
 
-        PathWrapper impossibleAlternative = response.getAll().get(1);
+        ResponsePath impossibleAlternative = response.getAll().get(1);
         assertTrue(impossibleAlternative.isImpossible());
         Trip.Stop delayedStop = ((Trip.PtLeg) impossibleAlternative.getLegs().get(0)).stops.get(2);
         assertEquals("Five minutes late", 300, Duration.between(delayedStop.plannedArrivalTime.toInstant(), delayedStop.predictedArrivalTime.toInstant()).getSeconds());
diff --git a/reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java b/reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java
index 6cbadc4e4..4ed0bdee6 100644
--- a/reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java
+++ b/reader-osm/src/test/java/com/graphhopper/GraphHopperIT.java
@@ -109,7 +109,7 @@ public class GraphHopperIT {
         assertFalse(rsp.getErrors().toString(), rsp.hasErrors());
         assertEquals(expectedVisitedNodes, rsp.getHints().getLong("visited_nodes.sum", 0));
 
-        PathWrapper res = rsp.getBest();
+        ResponsePath res = rsp.getBest();
         assertEquals(3587.9, res.getDistance(), .1);
         assertEquals(277173, res.getTime(), 10);
         assertEquals(91, res.getPoints().getSize());
@@ -135,14 +135,14 @@ public class GraphHopperIT {
         // identify the number of counts to compare with CH foot route
         assertEquals(699, rsp.getHints().getLong("visited_nodes.sum", 0));
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(3437.6, arsp.getDistance(), .1);
-        assertEquals(85, arsp.getPoints().getSize());
+        ResponsePath res = rsp.getBest();
+        assertEquals(3437.6, res.getDistance(), .1);
+        assertEquals(85, res.getPoints().getSize());
 
-        assertEquals(43.7276852, arsp.getWaypoints().getLat(0), 1e-7);
-        assertEquals(43.7495432, arsp.getWaypoints().getLat(1), 1e-7);
+        assertEquals(43.7276852, res.getWaypoints().getLat(0), 1e-7);
+        assertEquals(43.7495432, res.getWaypoints().getLat(1), 1e-7);
 
-        InstructionList il = arsp.getInstructions();
+        InstructionList il = res.getInstructions();
         assertEquals(16, il.size());
 
         // TODO roundabout fine tuning -> enter + leave roundabout (+ two roundabouts -> is it necessary if we do not leave the street?)
@@ -167,7 +167,7 @@ public class GraphHopperIT {
         assertEquals(7, il.get(4).getTime() / 1000);
         assertEquals(30, il.get(5).getTime() / 1000);
 
-        assertEquals(85, arsp.getPoints().size());
+        assertEquals(85, res.getPoints().size());
     }
 
     @Test
@@ -216,8 +216,8 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(request);
 
         assertFalse(rsp.hasErrors());
-        PathWrapper arsp = rsp.getBest();
-        InstructionList il = arsp.getInstructions();
+        ResponsePath res = rsp.getBest();
+        InstructionList il = res.getInstructions();
         assertEquals(3, il.size());
 
         // Initial U-turn
@@ -272,7 +272,7 @@ public class GraphHopperIT {
             req.putHint(Landmark.DISABLE, true);
             GHResponse rsp = hopper.route(req);
 
-            PathWrapper bestPath = rsp.getBest();
+            ResponsePath bestPath = rsp.getBest();
             long sum = rsp.getHints().getLong("visited_nodes.sum", 0);
             assertNotEquals(sum, 0);
             assertTrue("Too many nodes visited " + sum, sum < 120);
@@ -288,7 +288,7 @@ public class GraphHopperIT {
             req.putHint(Landmark.DISABLE, false);
             GHResponse rsp = hopper.route(req);
 
-            PathWrapper bestPath = rsp.getBest();
+            ResponsePath bestPath = rsp.getBest();
             long sum = rsp.getHints().getLong("visited_nodes.sum", 0);
             assertNotEquals(sum, 0);
             assertTrue("Too many nodes visited " + sum, sum < 120);
@@ -303,7 +303,7 @@ public class GraphHopperIT {
         req.putHint(Landmark.DISABLE, true);
         GHResponse rsp = hopper.route(req);
 
-        PathWrapper bestPath = rsp.getBest();
+        ResponsePath bestPath = rsp.getBest();
         long sum = rsp.getHints().getLong("visited_nodes.sum", 0);
         assertNotEquals(sum, 0);
         assertTrue("Too few nodes visited " + sum, sum > 120);
@@ -591,11 +591,11 @@ public class GraphHopperIT {
                 addPoint(new GHPoint(43.727687, 7.418737)).
                 setAlgorithm(ASTAR).setProfile(profile));
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(6875.2, arsp.getDistance(), .1);
-        assertEquals(170, arsp.getPoints().getSize());
+        ResponsePath res = rsp.getBest();
+        assertEquals(6875.2, res.getDistance(), .1);
+        assertEquals(170, res.getPoints().getSize());
 
-        InstructionList il = arsp.getInstructions();
+        InstructionList il = res.getInstructions();
         assertEquals(30, il.size());
         assertEquals("continue onto Avenue des Guelfes", il.get(0).getTurnDescription(tr));
         assertEquals("turn slight left onto Avenue des Papalins", il.get(1).getTurnDescription(tr));
@@ -633,13 +633,13 @@ public class GraphHopperIT {
                 addPoint(new GHPoint(43.727687, 7.418737)).
                 setAlgorithm(ASTAR).setProfile(profile));
 
-        arsp = rsp.getBest();
-        assertEquals(0, arsp.getDistance(), .1);
-        assertEquals(0, arsp.getRouteWeight(), .1);
-        assertEquals(1, arsp.getPoints().getSize());
-        assertEquals(1, arsp.getInstructions().size());
-        assertEquals("arrive at destination", arsp.getInstructions().get(0).getTurnDescription(tr));
-        assertEquals(Instruction.FINISH, arsp.getInstructions().get(0).getSign());
+        res = rsp.getBest();
+        assertEquals(0, res.getDistance(), .1);
+        assertEquals(0, res.getRouteWeight(), .1);
+        assertEquals(1, res.getPoints().getSize());
+        assertEquals(1, res.getInstructions().size());
+        assertEquals("arrive at destination", res.getInstructions().get(0).getTurnDescription(tr));
+        assertEquals(Instruction.FINISH, res.getInstructions().get(0).getSign());
 
         rsp = hopper.route(new GHRequest().
                 setPoints(Arrays.asList(
@@ -649,13 +649,13 @@ public class GraphHopperIT {
                 )).
                 setAlgorithm(ASTAR).setProfile(profile));
 
-        arsp = rsp.getBest();
-        assertEquals(0, arsp.getDistance(), .1);
-        assertEquals(0, arsp.getRouteWeight(), .1);
-        assertEquals(1, arsp.getPoints().getSize());
-        assertEquals(2, arsp.getInstructions().size());
-        assertEquals(Instruction.REACHED_VIA, arsp.getInstructions().get(0).getSign());
-        assertEquals(Instruction.FINISH, arsp.getInstructions().get(1).getSign());
+        res = rsp.getBest();
+        assertEquals(0, res.getDistance(), .1);
+        assertEquals(0, res.getRouteWeight(), .1);
+        assertEquals(1, res.getPoints().getSize());
+        assertEquals(2, res.getInstructions().size());
+        assertEquals(Instruction.REACHED_VIA, res.getInstructions().get(0).getSign());
+        assertEquals(Instruction.FINISH, res.getInstructions().get(1).getSign());
     }
 
     @Test
@@ -678,15 +678,15 @@ public class GraphHopperIT {
 
         GHResponse rsp = hopper.route(request);
 
-        PathWrapper arsp = rsp.getBest();
-        Map<String, List<PathDetail>> details = arsp.getPathDetails();
+        ResponsePath res = rsp.getBest();
+        Map<String, List<PathDetail>> details = res.getPathDetails();
         assertEquals(1, details.size());
         List<PathDetail> detailList = details.get(Parameters.Details.AVERAGE_SPEED);
         assertEquals(9, detailList.size());
         assertEquals(5.0, detailList.get(0).getValue());
         assertEquals(0, detailList.get(0).getFirst());
         assertEquals(3.0, detailList.get(1).getValue());
-        assertEquals(arsp.getPoints().size() - 1, detailList.get(8).getLast());
+        assertEquals(res.getPoints().size() - 1, detailList.get(8).getLast());
     }
 
     @Test
@@ -708,9 +708,9 @@ public class GraphHopperIT {
         req.putHint(Routing.HEADING_PENALTY, "300");
         GHResponse rsp = hopper.route(req);
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(839., arsp.getDistance(), 10.);
-        assertEquals(26, arsp.getPoints().getSize());
+        ResponsePath res = rsp.getBest();
+        assertEquals(839., res.getDistance(), 10.);
+        assertEquals(26, res.getPoints().getSize());
 
         // headings must be in [0, 360)
         req = new GHRequest().
@@ -850,9 +850,9 @@ public class GraphHopperIT {
         rq.putHint(Routing.PASS_THROUGH, true);
         GHResponse rsp = hopper.route(rq);
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(297, arsp.getDistance(), 5.);
-        assertEquals(23, arsp.getPoints().getSize());
+        ResponsePath res = rsp.getBest();
+        assertEquals(297, res.getDistance(), 5.);
+        assertEquals(23, res.getPoints().getSize());
 
         // test if start and first point are identical leading to an empty path, #788
         rq = new GHRequest().
@@ -882,16 +882,16 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.730729, 7.421288, 43.727697, 7.419199).
                 setAlgorithm(ASTAR).setProfile(profile));
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(1625.4, arsp.getDistance(), .1);
-        assertEquals(55, arsp.getPoints().getSize());
-        assertTrue(arsp.getPoints().is3D());
+        ResponsePath res = rsp.getBest();
+        assertEquals(1625.4, res.getDistance(), .1);
+        assertEquals(55, res.getPoints().getSize());
+        assertTrue(res.getPoints().is3D());
 
-        InstructionList il = arsp.getInstructions();
+        InstructionList il = res.getInstructions();
         assertEquals(12, il.size());
         assertTrue(il.get(0).getPoints().is3D());
 
-        String str = arsp.getPoints().toString();
+        String str = res.getPoints().toString();
 
         assertEquals("(43.73068455771767,7.421283689825812,62.0), (43.73067957305937,7.421382123709815,66.0), " +
                         "(43.73109792316924,7.421546222751131,45.0), (43.73129908884985,7.421589994913116,45.0), " +
@@ -906,16 +906,16 @@ public class GraphHopperIT {
         assertEquals("(43.727778875703635,7.418772930326453,11.0), (43.72768239068275,7.419007064826944,11.0), (43.727679637988224,7.419198521975086,11.0)",
                 str.substring(str.length() - 132));
 
-        assertEquals(84, arsp.getAscend(), 1e-1);
-        assertEquals(135, arsp.getDescend(), 1e-1);
+        assertEquals(84, res.getAscend(), 1e-1);
+        assertEquals(135, res.getDescend(), 1e-1);
 
-        assertEquals(55, arsp.getPoints().size());
-        assertEquals(new GHPoint3D(43.73068455771767, 7.421283689825812, 62.0), arsp.getPoints().get(0));
-        assertEquals(new GHPoint3D(43.727679637988224, 7.419198521975086, 11.0), arsp.getPoints().get(arsp.getPoints().size() - 1));
+        assertEquals(55, res.getPoints().size());
+        assertEquals(new GHPoint3D(43.73068455771767, 7.421283689825812, 62.0), res.getPoints().get(0));
+        assertEquals(new GHPoint3D(43.727679637988224, 7.419198521975086, 11.0), res.getPoints().get(res.getPoints().size() - 1));
 
-        assertEquals(62, arsp.getPoints().get(0).getElevation(), 1e-2);
-        assertEquals(66, arsp.getPoints().get(1).getElevation(), 1e-2);
-        assertEquals(52, arsp.getPoints().get(10).getElevation(), 1e-2);
+        assertEquals(62, res.getPoints().get(0).getElevation(), 1e-2);
+        assertEquals(66, res.getPoints().get(1).getElevation(), 1e-2);
+        assertEquals(52, res.getPoints().get(10).getElevation(), 1e-2);
     }
 
     @Test
@@ -943,9 +943,9 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.74056471749763, 7.4299266210693755,
                 43.73790260334179, 7.427984089259056).setAlgorithm(ASTAR)
                 .setProfile(profile));
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(356.5, arsp.getDistance(), .1);
-        PointList pointList = arsp.getPoints();
+        ResponsePath res = rsp.getBest();
+        assertEquals(356.5, res.getDistance(), .1);
+        PointList pointList = res.getPoints();
         assertEquals(6, pointList.getSize());
         assertTrue(pointList.is3D());
 
@@ -974,10 +974,10 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.74056471749763, 7.4299266210693755,
                 43.73790260334179, 7.427984089259056).setAlgorithm(ASTAR)
                 .setProfile(profile));
-        PathWrapper arsp = rsp.getBest();
+        ResponsePath res = rsp.getBest();
         // Without interpolation: 356.5
-        assertEquals(351, arsp.getDistance(), .1);
-        PointList pointList = arsp.getPoints();
+        assertEquals(351, res.getDistance(), .1);
+        PointList pointList = res.getPoints();
         assertEquals(6, pointList.getSize());
         assertTrue(pointList.is3D());
 
@@ -1008,13 +1008,13 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.730729, 7.421288, 43.727697, 7.419199)
                 .setProfile(profile));
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(1601.6, arsp.getDistance(), .1);
-        assertEquals(55, arsp.getPoints().getSize());
-        assertTrue(arsp.getPoints().is3D());
-        assertEquals(69, arsp.getAscend(), 1e-1);
-        assertEquals(121, arsp.getDescend(), 1e-1);
-        assertEquals(64.5, arsp.getPoints().get(0).getElevation(), 1e-2);
+        ResponsePath res = rsp.getBest();
+        assertEquals(1601.6, res.getDistance(), .1);
+        assertEquals(55, res.getPoints().getSize());
+        assertTrue(res.getPoints().is3D());
+        assertEquals(69, res.getAscend(), 1e-1);
+        assertEquals(121, res.getDescend(), 1e-1);
+        assertEquals(64.5, res.getPoints().get(0).getElevation(), 1e-2);
     }
 
     @Test
@@ -1037,11 +1037,11 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(48.410987, 15.599492, 48.383419, 15.659294).
                 setProfile(profile2));
         assertFalse(rsp.hasErrors());
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(6932.2, arsp.getDistance(), .1);
-        assertEquals(104, arsp.getPoints().getSize());
+        ResponsePath res = rsp.getBest();
+        assertEquals(6932.2, res.getDistance(), .1);
+        assertEquals(104, res.getPoints().getSize());
 
-        InstructionList il = arsp.getInstructions();
+        InstructionList il = res.getInstructions();
         assertEquals(21, il.size());
 
         assertEquals("continue onto Obere Landstraße", il.get(0).getTurnDescription(tr));
@@ -1097,23 +1097,23 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.745084, 7.430513, 43.745247, 7.430347)
                 .setProfile(profile1));
 
-        PathWrapper arsp = rsp.getBest();
-        assertEquals(2, ((RoundaboutInstruction) arsp.getInstructions().get(1)).getExitNumber());
+        ResponsePath res = rsp.getBest();
+        assertEquals(2, ((RoundaboutInstruction) res.getInstructions().get(1)).getExitNumber());
 
         rsp = hopper.route(new GHRequest(43.745968, 7.42907, 43.745832, 7.428614)
                 .setProfile(profile1));
-        arsp = rsp.getBest();
-        assertEquals(2, ((RoundaboutInstruction) arsp.getInstructions().get(1)).getExitNumber());
+        res = rsp.getBest();
+        assertEquals(2, ((RoundaboutInstruction) res.getInstructions().get(1)).getExitNumber());
 
         rsp = hopper.route(new GHRequest(43.745948, 7.42914, 43.746173, 7.428834)
                 .setProfile(profile1));
-        arsp = rsp.getBest();
-        assertEquals(1, ((RoundaboutInstruction) arsp.getInstructions().get(1)).getExitNumber());
+        res = rsp.getBest();
+        assertEquals(1, ((RoundaboutInstruction) res.getInstructions().get(1)).getExitNumber());
 
         rsp = hopper.route(new GHRequest(43.735817, 7.417096, 43.735666, 7.416587)
                 .setProfile(profile1));
-        arsp = rsp.getBest();
-        assertEquals(2, ((RoundaboutInstruction) arsp.getInstructions().get(1)).getExitNumber());
+        res = rsp.getBest();
+        assertEquals(2, ((RoundaboutInstruction) res.getInstructions().get(1)).getExitNumber());
     }
 
     @Test
@@ -1169,17 +1169,17 @@ public class GraphHopperIT {
         String str = hopper.getEncodingManager().toString();
         GHResponse rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826)
                 .setProfile("profile2"));
-        PathWrapper arsp = rsp.getBest();
+        ResponsePath res = rsp.getBest();
         assertFalse("car routing for " + str + " should not have errors:" + rsp.getErrors(), rsp.hasErrors());
-        assertEquals(207, arsp.getTime() / 1000f, 1);
-        assertEquals(2838, arsp.getDistance(), 1);
+        assertEquals(207, res.getTime() / 1000f, 1);
+        assertEquals(2838, res.getDistance(), 1);
 
         rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826)
                 .setProfile("profile1"));
-        arsp = rsp.getBest();
+        res = rsp.getBest();
         assertFalse("bike routing for " + str + " should not have errors:" + rsp.getErrors(), rsp.hasErrors());
-        assertEquals(494, arsp.getTime() / 1000f, 1);
-        assertEquals(2192, arsp.getDistance(), 1);
+        assertEquals(494, res.getTime() / 1000f, 1);
+        assertEquals(2192, res.getDistance(), 1);
 
         rsp = hopper.route(new GHRequest(43.73005, 7.415707, 43.741522, 7.42826)
                 .setProfile("profile3"));
@@ -1220,7 +1220,7 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(new GHRequest(43.727687, 7.418737, 43.74958, 7.436566).
                 setProfile(profile));
 
-        PathWrapper bestPath = rsp.getBest();
+        ResponsePath bestPath = rsp.getBest();
         // identify the number of counts to compare with none-CH foot route which had nearly 700 counts
         long sum = rsp.getHints().getLong("visited_nodes.sum", 0);
         assertNotEquals(sum, 0);
@@ -1262,10 +1262,10 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(rq);
 
         assertEquals(1, rsp.getAll().size());
-        PathWrapper pw = rsp.getBest();
+        ResponsePath res = rsp.getBest();
         assertEquals(1.49, rsp.getBest().getDistance() / 1000f, .01);
         assertEquals(19, rsp.getBest().getTime() / 1000f / 60, 1);
-        assertEquals(67, pw.getPoints().size());
+        assertEquals(67, res.getPoints().size());
     }
 
     @Test
@@ -1343,7 +1343,7 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(req);
         long chSum = rsp.getHints().getLong("visited_nodes.sum", 0);
         assertTrue("Too many visited nodes for ch mode " + chSum, chSum < 60);
-        PathWrapper bestPath = rsp.getBest();
+        ResponsePath bestPath = rsp.getBest();
         assertEquals(3587, bestPath.getDistance(), 1);
         assertEquals(91, bestPath.getPoints().getSize());
 
@@ -1408,13 +1408,13 @@ public class GraphHopperIT {
         testCrossQueryAssert(profile3, hopper, 815.4, 146, true);
 
         // LM (should be the same as flex, but with less visited nodes!)
-        testCrossQueryAssert(profile1, hopper, 528.3, 106, false);
-        testCrossQueryAssert(profile2, hopper, 636.0, 78, false);
+        testCrossQueryAssert(profile1, hopper, 528.3, 74, false);
+        testCrossQueryAssert(profile2, hopper, 636.0, 84, false);
         // this is actually interesting: the number of visited nodes *increases* once again (while it strictly decreases
         // with rising distance factor for flex): cross-querying 'works', but performs *worse*, because the landmarks
         // were not customized for the weighting in use. Creating a separate LM preparation for profile3 yields 74
         // instead of 124 visited nodes (not shown here)
-        testCrossQueryAssert(profile3, hopper, 815.4, 124, false);
+        testCrossQueryAssert(profile3, hopper, 815.4, 128, false);
     }
 
     private void testCrossQueryAssert(String profile, GraphHopper hopper, double expectedWeight, int expectedVisitedNodes, boolean disableLM) {
@@ -1551,11 +1551,11 @@ public class GraphHopperIT {
             GHRequest req = new GHRequest(lat1, lon1, lat2, lon2);
             req.setProfile(profile);
             req.getHints().putObject(CH.DISABLE, false).putObject(Landmark.DISABLE, true);
-            PathWrapper pathCH = hopper.route(req).getBest();
+            ResponsePath pathCH = hopper.route(req).getBest();
             req.getHints().putObject(CH.DISABLE, true).putObject(Landmark.DISABLE, false);
-            PathWrapper pathLM = hopper.route(req).getBest();
+            ResponsePath pathLM = hopper.route(req).getBest();
             req.getHints().putObject(CH.DISABLE, true).putObject(Landmark.DISABLE, true);
-            PathWrapper path = hopper.route(req).getBest();
+            ResponsePath path = hopper.route(req).getBest();
 
             String failMessage = "seed: " + seed + ", i=" + i;
             assertEquals(path.hasErrors(), pathCH.hasErrors(), failMessage);
@@ -1589,11 +1589,11 @@ public class GraphHopperIT {
         GHRequest req = new GHRequest(55.815670, 37.604613, 55.806151, 37.617823);
         req.setProfile("car");
         req.getHints().putObject(CH.DISABLE, false).putObject(Landmark.DISABLE, true);
-        PathWrapper pathCH = hopper.route(req).getBest();
+        ResponsePath pathCH = hopper.route(req).getBest();
         req.getHints().putObject(CH.DISABLE, true).putObject(Landmark.DISABLE, false);
-        PathWrapper pathLM = hopper.route(req).getBest();
+        ResponsePath pathLM = hopper.route(req).getBest();
         req.getHints().putObject(CH.DISABLE, true).putObject(Landmark.DISABLE, true);
-        PathWrapper path = hopper.route(req).getBest();
+        ResponsePath path = hopper.route(req).getBest();
 
         assertEquals(1995.38, pathCH.getDistance(), 0.1);
         assertEquals(1995.38, pathLM.getDistance(), 0.1);
@@ -1832,7 +1832,7 @@ public class GraphHopperIT {
     private void assertCurbsidesPath(GraphHopper hopper, GHPoint source, GHPoint target, List<String> curbsides, int expectedDistance, List<String> expectedStreets, boolean force) {
         GHResponse rsp = calcCurbsidePath(hopper, source, target, curbsides, force);
         assertFalse(rsp.getErrors().toString(), rsp.hasErrors());
-        PathWrapper path = rsp.getBest();
+        ResponsePath path = rsp.getBest();
         List<String> streets = new ArrayList<>(path.getInstructions().size());
         for (Instruction instruction : path.getInstructions()) {
             if (!Helper.isEmpty(instruction.getName())) {
@@ -1912,7 +1912,7 @@ public class GraphHopperIT {
         GHResponse rsp = hopper.route(req);
         assertFalse(rsp.getErrors().toString(), rsp.hasErrors());
 
-        PathWrapper path = rsp.getBest();
+        ResponsePath path = rsp.getBest();
 
         // check path was simplified (without it would be more like 58)
         assertEquals(41, path.getPoints().size());
diff --git a/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java b/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
index cf5ae9ddb..415b1c657 100644
--- a/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
+++ b/reader-osm/src/test/java/com/graphhopper/reader/osm/GraphHopperOSMTest.java
@@ -389,7 +389,7 @@ public class GraphHopperOSMTest {
                 setGraphHopperLocation(ghLoc).
                 setDataReaderFile(testOsm);
         instance.importOrLoad();
-        PathWrapper rsp = instance.route(new GHRequest(51.2492152, 9.4317166, 51.2, 9.4).
+        ResponsePath rsp = instance.route(new GHRequest(51.2492152, 9.4317166, 51.2, 9.4).
                 setProfile(profile).
                 setAlgorithm(DIJKSTRA_BI)).getBest();
         assertFalse(rsp.hasErrors());
@@ -435,7 +435,7 @@ public class GraphHopperOSMTest {
         // A to D
         GHResponse grsp = instance.route(new GHRequest(11.1, 50, 11.3, 51).setProfile(profile1));
         assertFalse(grsp.hasErrors());
-        PathWrapper rsp = grsp.getBest();
+        ResponsePath rsp = grsp.getBest();
         assertEquals(3, rsp.getPoints().getSize());
         // => found A and D
         assertEquals(50, rsp.getPoints().getLongitude(0), 1e-3);
@@ -705,7 +705,7 @@ public class GraphHopperOSMTest {
         // A to E only for foot
         GHResponse grsp = instance.route(new GHRequest(11.1, 50, 11.19, 52).setProfile(profile));
         assertFalse(grsp.hasErrors());
-        PathWrapper rsp = grsp.getBest();
+        ResponsePath rsp = grsp.getBest();
         // the last points snaps to the edge
         assertEquals(Helper.createPointList(11.1, 50, 10, 51, 11.194015, 51.995013), rsp.getPoints());
     }
@@ -739,7 +739,7 @@ public class GraphHopperOSMTest {
 
         GHResponse grsp = instance.route(new GHRequest(Arrays.asList(first, second, third)).setProfile(profile));
         assertFalse("should find 1->2->3", grsp.hasErrors());
-        PathWrapper rsp = grsp.getBest();
+        ResponsePath rsp = grsp.getBest();
         assertEquals(rsp12.getBest().getDistance() + rsp23.getBest().getDistance(), rsp.getDistance(), 1e-6);
         assertEquals(4, rsp.getPoints().getSize());
         assertEquals(5, rsp.getInstructions().size());
diff --git a/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java b/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
index e0810ee51..8c2ecb6b2 100644
--- a/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
+++ b/web/src/test/java/com/graphhopper/http/resources/GpxTravelTimeConsistencyTest.java
@@ -20,7 +20,7 @@ package com.graphhopper.http.resources;
 
 import com.graphhopper.GHRequest;
 import com.graphhopper.GraphHopper;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.config.Profile;
 import com.graphhopper.reader.osm.GraphHopperOSM;
 import com.graphhopper.routing.util.EncodingManager;
@@ -62,13 +62,13 @@ public class GpxTravelTimeConsistencyTest {
         GHPoint routeEnd = new GHPoint(43.74958, 7.436566);
         GHRequest request = new GHRequest(routeStart, routeEnd);
         request.setProfile("profile");
-        PathWrapper path = hopper.route(request).getBest();
+        ResponsePath path = hopper.route(request).getBest();
         List<GPXEntry> gpxList = GpxFromInstructions.createGPXList(path.getInstructions());
         for (GPXEntry entry : gpxList) {
             if (entry.getTime() != null) {
                 GHRequest requestForWaypoint = new GHRequest(routeStart, entry.getPoint());
                 requestForWaypoint.setProfile("profile");
-                PathWrapper partialPath = hopper.route(requestForWaypoint).getBest();
+                ResponsePath partialPath = hopper.route(requestForWaypoint).getBest();
                 assertEquals(partialPath.getTime(), entry.getTime().longValue(), "GPXListEntry timeStamp is expected to be the same as route duration.");
             }
         }
diff --git a/web/src/test/java/com/graphhopper/http/resources/RouteResourceClientHCTest.java b/web/src/test/java/com/graphhopper/http/resources/RouteResourceClientHCTest.java
index 146c8b0ca..c63e2b725 100644
--- a/web/src/test/java/com/graphhopper/http/resources/RouteResourceClientHCTest.java
+++ b/web/src/test/java/com/graphhopper/http/resources/RouteResourceClientHCTest.java
@@ -19,7 +19,7 @@ package com.graphhopper.http.resources;
 
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.api.GraphHopperWeb;
 import com.graphhopper.config.CHProfile;
 import com.graphhopper.config.Profile;
@@ -113,23 +113,23 @@ public class RouteResourceClientHCTest {
                 putHint("elevation", false).
                 putHint("instructions", true).
                 putHint("calc_points", true);
-        GHResponse res = gh.route(req);
-        assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
-        PathWrapper alt = res.getBest();
-        isBetween(60, 70, alt.getPoints().size());
-        isBetween(2900, 3000, alt.getDistance());
-        isBetween(110, 120, alt.getAscend());
-        isBetween(70, 80, alt.getDescend());
-        isBetween(190, 200, alt.getRouteWeight());
+        GHResponse rsp = gh.route(req);
+        assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString());
+        ResponsePath res = rsp.getBest();
+        isBetween(60, 70, res.getPoints().size());
+        isBetween(2900, 3000, res.getDistance());
+        isBetween(110, 120, res.getAscend());
+        isBetween(70, 80, res.getDescend());
+        isBetween(190, 200, res.getRouteWeight());
 
         // change vehicle
-        res = gh.route(new GHRequest(42.5093, 1.5274, 42.5126, 1.5410).
+        rsp = gh.route(new GHRequest(42.5093, 1.5274, 42.5126, 1.5410).
                 putHint("vehicle", "bike"));
-        alt = res.getBest();
-        assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
-        isBetween(2500, 2600, alt.getDistance());
+        res = rsp.getBest();
+        assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString());
+        isBetween(2500, 2600, res.getDistance());
 
-        assertEquals("[0, 1]", alt.getPointsOrder().toString());
+        assertEquals("[0, 1]", res.getPointsOrder().toString());
     }
 
     @ParameterizedTest
@@ -146,10 +146,10 @@ public class RouteResourceClientHCTest {
                 putHint("ch.disable", true);
         GHResponse res = gh.route(req);
         assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
-        List<PathWrapper> paths = res.getAll();
+        List<ResponsePath> paths = res.getAll();
         assertEquals(2, paths.size());
 
-        PathWrapper path = paths.get(0);
+        ResponsePath path = paths.get(0);
         isBetween(31, 37, path.getPoints().size());
         isBetween(1670, 1710, path.getDistance());
         assertTrue("Avinguda Carlemany".contains(path.getDescription().get(0)), "expected: " + path.getDescription().get(0));
@@ -171,11 +171,11 @@ public class RouteResourceClientHCTest {
 
         req.putHint("instructions", false);
         req.putHint("calc_points", false);
-        GHResponse res = gh.route(req);
-        assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
-        PathWrapper alt = res.getBest();
-        assertEquals(0, alt.getPoints().size());
-        isBetween(1750, 1800, alt.getDistance());
+        GHResponse rsp = gh.route(req);
+        assertFalse(rsp.hasErrors(), "errors:" + rsp.getErrors().toString());
+        ResponsePath res = rsp.getBest();
+        assertEquals(0, res.getPoints().size());
+        isBetween(1750, 1800, res.getDistance());
     }
 
     @ParameterizedTest
@@ -222,7 +222,7 @@ public class RouteResourceClientHCTest {
         assertEquals(Arrays.asList("Carrer de l'Aigüeta", "Carrer Pere d'Urg", "Carrer Bonaventura Armengol", "Avinguda Consell d'Europa", ""), given);
     }
 
-    private List<String> extractInstructionNames(PathWrapper path, int count) {
+    private List<String> extractInstructionNames(ResponsePath path, int count) {
         List<String> result = new ArrayList<>();
         for (Instruction instruction : path.getInstructions()) {
             result.add(instruction.getName());
@@ -307,7 +307,7 @@ public class RouteResourceClientHCTest {
         req.getPathDetails().add("average_speed");
         GHResponse res = gh.route(req);
         assertFalse(res.hasErrors(), "errors:" + res.getErrors().toString());
-        PathWrapper alt = res.getBest();
+        ResponsePath alt = res.getBest();
         assertEquals(1, alt.getPathDetails().size());
         List<PathDetail> details = alt.getPathDetails().get("average_speed");
         assertFalse(details.isEmpty());
diff --git a/web/src/test/java/com/graphhopper/http/resources/RouteResourceTest.java b/web/src/test/java/com/graphhopper/http/resources/RouteResourceTest.java
index f6aec128f..c08edc6bc 100644
--- a/web/src/test/java/com/graphhopper/http/resources/RouteResourceTest.java
+++ b/web/src/test/java/com/graphhopper/http/resources/RouteResourceTest.java
@@ -21,7 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.graphhopper.GHRequest;
 import com.graphhopper.GHResponse;
 import com.graphhopper.GraphHopperAPI;
-import com.graphhopper.PathWrapper;
+import com.graphhopper.ResponsePath;
 import com.graphhopper.api.GraphHopperWeb;
 import com.graphhopper.config.CHProfile;
 import com.graphhopper.config.Profile;
@@ -209,9 +209,9 @@ public class RouteResourceTest {
         assertFalse(rsp.hasErrors(), rsp.getErrors().toString());
         assertTrue(rsp.getErrors().isEmpty(), rsp.getErrors().toString());
 
-        PathWrapper arsp = rsp.getBest();
-        assertTrue(arsp.getDistance() > 9000, "distance wasn't correct:" + arsp.getDistance());
-        assertTrue(arsp.getDistance() < 9500, "distance wasn't correct:" + arsp.getDistance());
+        ResponsePath res = rsp.getBest();
+        assertTrue(res.getDistance() > 9000, "distance wasn't correct:" + res.getDistance());
+        assertTrue(res.getDistance() < 9500, "distance wasn't correct:" + res.getDistance());
 
         rsp = hopper.route(new GHRequest().
                 setProfile("my_car").
@@ -219,11 +219,11 @@ public class RouteResourceTest {
                 addPoint(new GHPoint(42.531896, 1.553278)).
                 addPoint(new GHPoint(42.510071, 1.548128)));
         assertTrue(rsp.getErrors().isEmpty(), rsp.getErrors().toString());
-        arsp = rsp.getBest();
-        assertTrue(arsp.getDistance() > 20000, "distance wasn't correct:" + arsp.getDistance());
-        assertTrue(arsp.getDistance() < 21000, "distance wasn't correct:" + arsp.getDistance());
+        res = rsp.getBest();
+        assertTrue(res.getDistance() > 20000, "distance wasn't correct:" + res.getDistance());
+        assertTrue(res.getDistance() < 21000, "distance wasn't correct:" + res.getDistance());
 
-        InstructionList instructions = arsp.getInstructions();
+        InstructionList instructions = res.getInstructions();
         assertEquals(24, instructions.size());
         assertEquals("Continue onto la Callisa", instructions.get(0).getTurnDescription(null));
         assertEquals("At roundabout, take exit 2", instructions.get(4).getTurnDescription(null));