@Override
  public GHResponse route(GHRequest request) {
    try {
      String places = "";
      for (GHPoint p : request.getPoints()) {
        places += "point=" + p.lat + "," + p.lon + "&";
      }

      boolean tmpInstructions = request.getHints().getBool("instructions", instructions);
      boolean tmpCalcPoints = request.getHints().getBool("calc_points", calcPoints);

      if (tmpInstructions && !tmpCalcPoints)
        throw new IllegalStateException(
            "Cannot calculate instructions without points (only points without instructions). "
                + "Use calc_points=false and instructions=false to disable point and instruction calculation");

      boolean tmpElevation = request.getHints().getBool("elevation", elevation);

      String url =
          routeServiceUrl
              + "?"
              + places
              + "&type=json"
              + "&instructions="
              + tmpInstructions
              + "&points_encoded=true"
              + "&calc_points="
              + tmpCalcPoints
              + "&algorithm="
              + request.getAlgorithm()
              + "&locale="
              + request.getLocale().toString()
              + "&elevation="
              + tmpElevation;

      if (!request.getVehicle().isEmpty()) url += "&vehicle=" + request.getVehicle();

      if (!key.isEmpty()) url += "&key=" + key;

      for (Entry<String, String> entry : request.getHints().toMap().entrySet()) {
        String urlKey = entry.getKey();
        String urlValue = entry.getValue();

        // use lower case conversion for check only!
        if (ignoreSet.contains(urlKey.toLowerCase())) continue;

        if (urlValue != null && !urlValue.isEmpty())
          url += "&" + WebHelper.encodeURL(urlKey) + "=" + WebHelper.encodeURL(urlValue);
      }

      String str = downloader.downloadAsString(url, true);
      JSONObject json = new JSONObject(str);

      GHResponse res = new GHResponse();
      res.addErrors(readErrors(json));
      if (res.hasErrors()) return res;

      JSONArray paths = json.getJSONArray("paths");
      for (int index = 0; index < paths.length(); index++) {
        JSONObject path = paths.getJSONObject(index);
        PathWrapper altRsp = createPathWrapper(path, tmpCalcPoints, tmpInstructions, tmpElevation);
        res.add(altRsp);
      }

      return res;

    } catch (Exception ex) {
      throw new RuntimeException(
          "Problem while fetching path " + request.getPoints() + ": " + ex.getMessage(), ex);
    }
  }