class DefaultModelGraphMapper implements ModelGraphMapper {

  @Override
  public Graph<String, ModelEdge> translateModel(Collection<Point> points,
                                                 Collection<Path> paths,
                                                 Vehicle vehicle) {
    requireNonNull(points, "points");
    requireNonNull(paths, "paths");
    requireNonNull(vehicle, "vehicle");

    Graph<String, ModelEdge> graph = new DirectedWeightedMultigraph<>(ModelEdge.class);

    for (Point point : points) {
      graph.addVertex(point.getName());
    }

    boolean allowNegativeEdgeWeights = configuration.algorithm().isHandlingNegativeCosts();

    for (Path path : paths) {

      if (shouldAddForwardEdge(path, vehicle)) {
        ModelEdge edge = new ModelEdge(path, false);
        double weight = edgeEvaluator.computeWeight(edge, vehicle);

        if (weight < 0 && !allowNegativeEdgeWeights) {
          LOG.warn("Edge {} with weight {} ignored. Algorithm {} cannot handle negative weights.",
                   edge,
                   weight,
                   configuration.algorithm().name());
        }
        else {
          graph.addEdge(path.getSourcePoint().getName(),
                        path.getDestinationPoint().getName(),
                        edge);
          graph.setEdgeWeight(edge, weight);
        }
      }

      if (shouldAddReverseEdge(path, vehicle)) {
        ModelEdge edge = new ModelEdge(path, true);
        double weight = edgeEvaluator.computeWeight(edge, vehicle);

        if (weight < 0 && !allowNegativeEdgeWeights) {
          LOG.warn("Edge {} with weight {} ignored. Algorithm {} cannot handle negative weights.",
                   edge,
                   weight,
                   configuration.algorithm().name());
        }
        else {
          graph.addEdge(path.getDestinationPoint().getName(),
                        path.getSourcePoint().getName(),
                        edge);
          graph.setEdgeWeight(edge, weight);
        }
      }

    }

    return graph;
  }

  @Inject public  DefaultModelGraphMapper(@Nonnull EdgeEvaluator edgeEvaluator,
                                 @Nonnull ShortestPathConfiguration configuration);

}