private Seq<PolygonwithHoles> buildMultipolygons(
     Hashtable<Long, Point2D> nodes,
     Hashtable<Long, List<Long>> multipolygonWays,
     List<List<Tuple2<WayRole, Long>>> multipolygonWayRefs) {
   return Seq.seq(multipolygonWayRefs)
       .map(
           waysOfPoly -> {
             try {
               // I know this not how should assemble them, but parsing OSM wasn't our objective.
               List<Polygon> holes = new ArrayList<>();
               Polygon outer = null;
               for (Tuple2<WayRole, Long> way : waysOfPoly) {
                 WayRole role = way.v1;
                 long wayRef = way.v2;
                 List<Long> nodeRefs = multipolygonWays.get(wayRef);
                 Polygon p = buildPolygonFromWayRefs(nodeRefs, nodes);
                 if (role == WayRole.OUTER && outer == null && p.GetPointsNumber() > 0) {
                   outer = p;
                 } else if (role == WayRole.INNER && p.GetPointsNumber() > 0) {
                   holes.add(p);
                 } else {
                   LOG.warn("Could not process a way");
                 }
               }
               return new PolygonwithHoles(outer, holes);
             } catch (Exception ex) {
               // System.out.println("Failed to build a certain multipolygon");
             }
             return null;
           })
       .filter(p -> p != null);
 }
  /**
   * Requires vn to point to a way element. From there it iterates over all matches of the ap. Puts
   * a dummy point into nodes for every node it finds.
   */
  private List<Long> extractNodeRefs(VTDNav vn, Hashtable<Long, Point2D> nodes)
      throws NavException, XPathEvalException {
    vn.push();

    List<Long> refs = new ArrayList<>();
    for (int j = NODE_REF_PATH.evalXPath(); j != -1; j = NODE_REF_PATH.evalXPath()) {
      long ref = Long.parseLong(vn.toString(j + 1));
      refs.add(ref);
      nodes.put(ref, new Point2D(0, 0));
    }
    NODE_REF_PATH.resetXPath();

    vn.pop();

    return refs;
  }