/** Introduces the necessary shortcuts for endNode v in the graph. */
  int addShortcuts(int v) {
    shortcuts.clear();
    findShortcuts(addScHandler.setNode(v));
    int tmpNewShortcuts = 0;
    for (Shortcut sc : shortcuts.keySet()) {
      boolean updatedInGraph = false;
      // check if we need to update some existing shortcut in the graph
      EdgeSkipIterator iter = vehicleOutExplorer.setBaseNode(sc.from);
      while (iter.next()) {
        if (iter.isShortcut()
            && iter.getAdjNode() == sc.to
            && prepareEncoder.canBeOverwritten(iter.getFlags(), sc.flags)
            && iter.getDistance() > sc.weight) {
          iter.setFlags(sc.flags);
          iter.setSkippedEdges(sc.skippedEdge1, sc.skippedEdge2);
          iter.setDistance(sc.weight);
          setOrigEdgeCount(iter.getEdge(), sc.originalEdges);
          updatedInGraph = true;
          break;
        }
      }

      if (!updatedInGraph) {
        EdgeSkipIterState edgeState = g.shortcut(sc.from, sc.to);
        edgeState.setDistance(sc.weight).setFlags(sc.flags);
        edgeState.setSkippedEdges(sc.skippedEdge1, sc.skippedEdge2);
        setOrigEdgeCount(edgeState.getEdge(), sc.originalEdges);
        tmpNewShortcuts++;
      }
    }
    return tmpNewShortcuts;
  }
  /**
   * Calculates the priority of endNode v without changing the graph. Warning: the calculated
   * priority must NOT depend on priority(v) and therefor findShortcuts should also not depend on
   * the priority(v). Otherwise updating the priority before contracting in contractNodes() could
   * lead to a slowishor even endless loop.
   */
  int calculatePriority(int v) {
    // set of shortcuts that would be added if endNode v would be contracted next.
    findShortcuts(calcScHandler.setNode(v));

    //        System.out.println(v + "\t " + tmpShortcuts);
    // # huge influence: the bigger the less shortcuts gets created and the faster is the
    // preparation
    //
    // every endNode has an 'original edge' number associated. initially it is r=1
    // when a new shortcut is introduced then r of the associated edges is summed up:
    // r(u,w)=r(u,v)+r(v,w) now we can define
    // originalEdgesCount = σ(v) := sum_{ (u,w) ∈ shortcuts(v) } of r(u, w)
    int originalEdgesCount = calcScHandler.originalEdgesCount;
    //        for (Shortcut sc : tmpShortcuts) {
    //            originalEdgesCount += sc.originalEdges;
    //        }

    // # lowest influence on preparation speed or shortcut creation count
    // (but according to paper should speed up queries)
    //
    // number of already contracted neighbors of v
    int contractedNeighbors = 0;
    int degree = 0;
    EdgeSkipIterator iter = calcPrioAllExplorer.setBaseNode(v);
    while (iter.next()) {
      degree++;
      if (iter.isShortcut()) contractedNeighbors++;
    }

    // from shortcuts we can compute the edgeDifference
    // # low influence: with it the shortcut creation is slightly faster
    //
    // |shortcuts(v)| − |{(u, v) | v uncontracted}| − |{(v, w) | v uncontracted}|
    // meanDegree is used instead of outDegree+inDegree as if one endNode is in both directions
    // only one bucket memory is used. Additionally one shortcut could also stand for two
    // directions.
    int edgeDifference = calcScHandler.shortcuts - degree;

    // according to the paper do a simple linear combination of the properties to get the priority.
    // this is the current optimum for unterfranken:
    return 10 * edgeDifference + originalEdgesCount + contractedNeighbors;
  }