public static Result calcPaths(List<Snap> snaps, FlexiblePathCalculator pathCalculator) {
        RoundTripCalculator roundTripCalculator = new RoundTripCalculator(pathCalculator);
        Result result = new Result(snaps.size() - 1);
        Snap start = snaps.get(0);
        for (int snapIndex = 1; snapIndex < snaps.size(); snapIndex++) {
            // instead getClosestNode (which might be a virtual one and introducing unnecessary tails of the route)
            // use next tower node -> getBaseNode or getAdjNode
            // Later: remove potential route tail, maybe we can just enforce the heading at the start and when coming
            // back, and for tower nodes it does not matter anyway
            Snap startSnap = snaps.get(snapIndex - 1);
            int startNode = (startSnap == start) ? startSnap.getClosestNode() : startSnap.getClosestEdge().getBaseNode();
            Snap endSnap = snaps.get(snapIndex);
            int endNode = (endSnap == start) ? endSnap.getClosestNode() : endSnap.getClosestEdge().getBaseNode();

            Path path = roundTripCalculator.calcPath(startNode, endNode);
            if (snapIndex == 1) {
                result.wayPoints = new PointList(snaps.size(), path.graph.getNodeAccess().is3D());
                result.wayPoints.add(path.graph.getNodeAccess(), startNode);
            }
            result.wayPoints.add(path.graph.getNodeAccess(), endNode);
            result.visitedNodes += pathCalculator.getVisitedNodes();
            result.paths.add(path);
        }

        return result;
    }
@Test
    public void testCalcRoundTrip() {
        BaseGraph g = createTestGraph();

        LocationIndex locationIndex = new LocationIndexTree(g, new RAMDirectory()).prepareIndex();
        Snap snap4 = locationIndex.findClosest(0.05, 0.25, EdgeFilter.ALL_EDGES);
        assertEquals(4, snap4.getClosestNode());
        Snap snap5 = locationIndex.findClosest(0.00, 0.05, EdgeFilter.ALL_EDGES);
        assertEquals(5, snap5.getClosestNode());
        Snap snap6 = locationIndex.findClosest(0.00, 0.10, EdgeFilter.ALL_EDGES);
        assertEquals(6, snap6.getClosestNode());

        QueryGraph qGraph = QueryGraph.create(g, Arrays.asList(snap4, snap5));

        FlexiblePathCalculator pathCalculator = new FlexiblePathCalculator(
                qGraph, new RoutingAlgorithmFactorySimple(), weighting, new AlgorithmOptions().setAlgorithm(DIJKSTRA_BI).setTraversalMode(tMode));
        List<Path> paths = RoundTripRouting.calcPaths(Arrays.asList(snap5, snap4, snap5), pathCalculator).paths;
        assertEquals(2, paths.size());
        assertEquals(IntArrayList.from(5, 6, 3), paths.get(0).calcNodes());
        assertEquals(IntArrayList.from(3, 2, 9, 1, 5), paths.get(1).calcNodes());

        qGraph = QueryGraph.create(g, Arrays.asList(snap4, snap6));
        pathCalculator = new FlexiblePathCalculator(
                qGraph, new RoutingAlgorithmFactorySimple(), weighting, new AlgorithmOptions().setAlgorithm(DIJKSTRA_BI).setTraversalMode(tMode));
        paths = RoundTripRouting.calcPaths(Arrays.asList(snap6, snap4, snap6), pathCalculator).paths;
        assertEquals(2, paths.size());
        assertEquals(IntArrayList.from(6, 3), paths.get(0).calcNodes());
        assertEquals(IntArrayList.from(3, 4, 8, 7, 6), paths.get(1).calcNodes());
    }