docs: void processWay(ReaderWay way) {
          if (way.getNodes().size() < 2)
              return;
  
          // ignore multipolygon geometry
          if (!way.hasTags())
              return;
  
          long wayOsmId = way.getId();
  
          EncodingManager.AcceptWay acceptWay = new EncodingManager.AcceptWay();
          if (!encodingManager.acceptWay(way, acceptWay))
              return;
  
          long relationFlags = getRelFlagsMap().get(way.getId());
  
          // TODO move this after we have created the edge and know the coordinates => encodingManager.applyWayTags
          LongArrayList osmNodeIds = way.getNodes();
          // Estimate length of ways containing a route tag e.g. for ferry speed calculation
          if (osmNodeIds.size() > 1) {
              int first = getNodeMap().get(osmNodeIds.get(0));
              int last = getNodeMap().get(osmNodeIds.get(osmNodeIds.size() - 1));
              double firstLat = getTmpLatitude(first), firstLon = getTmpLongitude(first);
              double lastLat = getTmpLatitude(last), lastLon = getTmpLongitude(last);
              if (!Double.isNaN(firstLat) && !Double.isNaN(firstLon) && !Double.isNaN(lastLat) && !Double.isNaN(lastLon)) {
                  double estimatedDist = distCalc.calcDist(firstLat, firstLon, lastLat, lastLon);
                  // Add artificial tag for the estimated distance and center
                  way.setTag("estimated_distance", estimatedDist);
                  way.setTag("estimated_center", new GHPoint((firstLat + lastLat) / 2, (firstLon + lastLon) / 2));
              }
          }
  
          if (way.getTag("duration") != null) {
              try {
                  long dur = OSMReaderUtility.parseDuration(way.getTag("duration"));
                  // Provide the duration value in seconds in an artificial graphhopper specific tag:
                  way.setTag("duration:seconds", Long.toString(dur));
              } catch (Exception ex) {
                  LOGGER.warn("Parsing error in way with OSMID=" + way.getId() + " : " + ex.getMessage());
              }
          }
  
          IntsRef edgeFlags = encodingManager.handleWayTags(way, acceptWay, relationFlags);
          if (edgeFlags.isEmpty())
              return;
  
          List<EdgeIteratorState> createdEdges = new ArrayList<>();
          // look for barriers along the way
          final int size = osmNodeIds.size();
          int lastBarrier = -1;
          for (int i = 0; i < size; i++) {
              long nodeId = osmNodeIds.get(i);
              long nodeFlags = getNodeFlagsMap().get(nodeId);
              // barrier was spotted and the way is passable for that mode of travel
              if (nodeFlags > 0) {
                  if (isOnePassable(encodingManager.getAccessEncFromNodeFlags(nodeFlags), edgeFlags)) {
                      // remove barrier to avoid duplicates
                      getNodeFlagsMap().put(nodeId, 0);
  
                      // create shadow node copy for zero length edge
                      long newNodeId = addBarrierNode(nodeId);
                      if (i > 0) {
                          // start at beginning of array if there was no previous barrier
                          if (lastBarrier < 0)
                              lastBarrier = 0;
  
                          // add way up to barrier shadow node                        
                          int length = i - lastBarrier + 1;
                          LongArrayList partNodeIds = new LongArrayList();
                          partNodeIds.add(osmNodeIds.buffer, lastBarrier, length);
                          partNodeIds.set(length - 1, newNodeId);
                          createdEdges.addAll(addOSMWay(partNodeIds, edgeFlags, wayOsmId));
  
                          // create zero length edge for barrier
                          createdEdges.addAll(addBarrierEdge(newNodeId, nodeId, edgeFlags, nodeFlags, wayOsmId));
                      } else {
                          // run edge from real first node to shadow node
                          createdEdges.addAll(addBarrierEdge(nodeId, newNodeId, edgeFlags, nodeFlags, wayOsmId));
  
                          // exchange first node for created barrier node
                          osmNodeIds.set(0, newNodeId);
                      }
                      // remember barrier for processing the way behind it
                      lastBarrier = i;
                  }
              }
          }
  
          // just add remainder of way to graph if barrier was not the last node
          if (lastBarrier >= 0) {
              if (lastBarrier < size - 1) {
                  LongArrayList partNodeIds = new LongArrayList();
                  partNodeIds.add(osmNodeIds.buffer, lastBarrier, size - lastBarrier);
                  createdEdges.addAll(addOSMWay(partNodeIds, edgeFlags, wayOsmId));
              }
          } else {
              // no barriers - simply add the whole way
              createdEdges.addAll(addOSMWay(way.getNodes(), edgeFlags, wayOsmId));
          }
  
          for (EdgeIteratorState edge : createdEdges) {
              encodingManager.applyWayTags(way, edge);
          }
      }