private void addNodeToRest(DirectedNode node) {
   if (this.nodesSortedByDegree.containsKey(node.getOutDegree())) {
     this.nodesSortedByDegree.get(node.getOutDegree()).add(node);
   } else {
     LinkedList<Node> temp = new LinkedList<Node>();
     temp.add(node);
     this.nodesSortedByDegree.put(node.getOutDegree(), temp);
   }
 }
  private boolean directedCompute() {

    SortedSet<Integer> degrees = new TreeSet<Integer>();
    for (IElement iE : g.getNodes()) {
      DirectedNode n = (DirectedNode) iE;
      int degree = n.getOutDegree();

      degrees.add(degree);
      if (nodesSortedByDegree.containsKey(degree)) {
        this.nodesSortedByDegree.get(degree).add(n);
      } else {
        LinkedList<Node> temp = new LinkedList<>();
        temp.add(n);
        this.nodesSortedByDegree.put(degree, temp);
      }
    }

    HashSet<Node> currentRichClub = new HashSet<Node>();
    int currentRichClubSize = 0;
    int size = degrees.size();
    for (int i = 0; i < size; i++) {
      int currentDegree = degrees.last();
      degrees.remove(currentDegree);
      LinkedList<Node> current = this.nodesSortedByDegree.get(currentDegree);
      currentRichClubSize += current.size();
      this.nodesSortedByDegree.remove(currentDegree);

      if (currentRichClubSize >= this.richClubSize) {
        int seperateAT = current.size() - (currentRichClubSize - this.richClubSize);
        LinkedList<Node> temp = new LinkedList<>();
        temp.addAll(current.subList(0, seperateAT));
        this.richClub.put(currentDegree, temp);
        currentRichClub.addAll(temp);
        LinkedList<Node> temp2 = new LinkedList<>();
        temp2.addAll(current.subList(seperateAT, current.size()));
        if (!temp2.isEmpty()) this.nodesSortedByDegree.put(currentDegree, (LinkedList<Node>) temp2);
        break;
      } else {
        richClub.put(currentDegree, current);
        currentRichClub.addAll(current);
      }
    }

    for (Node n : currentRichClub) {
      DirectedNode ne = (DirectedNode) n;
      for (IElement iE : ne.getOutgoingEdges()) {
        DirectedEdge e = (DirectedEdge) iE;
        if (currentRichClub.contains(e.getDst())) {
          edgesBetweenRichClub++;
        }
      }
    }
    return true;
  }
  private boolean directedAdd(DirectedWeightedEdge e, DirectedNode s) {
    HashMap<Node, Node> parent = parents.get(s);
    HashMap<Node, Integer> height = heights.get(s);
    IntWeight eWeight = (IntWeight) e.getWeight();

    DirectedNode src = e.getSrc();
    DirectedNode dst = e.getDst();
    if (height.get(src) + (int) eWeight.getWeight() >= height.get(dst)
        || height.get(src) + (int) eWeight.getWeight() < 0) {
      return true;
    }
    if (height.get(dst) != Integer.MAX_VALUE) apsp.decr(height.get(dst));
    height.put(dst, height.get(src) + (int) eWeight.getWeight());
    apsp.incr(height.get(src) + (int) eWeight.getWeight());
    parent.put(dst, src);
    PriorityQueue<QueueElement<DirectedNode>> q = new PriorityQueue<QueueElement<DirectedNode>>();
    QueueElement<DirectedNode> queueElement = new QueueElement<DirectedNode>(dst, height.get(dst));
    q.add(queueElement);
    while (!q.isEmpty()) {
      QueueElement<DirectedNode> c = q.poll();
      DirectedNode current = c.e;

      if (height.get(current) == Integer.MAX_VALUE) {
        break;
      }

      for (IElement iEdge : current.getOutgoingEdges()) {
        DirectedWeightedEdge d = (DirectedWeightedEdge) iEdge;
        DirectedNode neighbor = d.getDst();
        IntWeight dWeight = (IntWeight) d.getWeight();

        int alt = height.get(current) + (int) dWeight.getWeight();

        if (alt < height.get(neighbor)) {
          if (height.get(neighbor) != Integer.MAX_VALUE) apsp.decr(height.get(neighbor));
          apsp.incr(alt);
          height.put(neighbor, alt);
          parent.put(neighbor, current);
          QueueElement<DirectedNode> temp =
              new QueueElement<DirectedNode>(neighbor, height.get(neighbor));
          if (q.contains(temp)) {
            q.remove(temp);
          }
          q.add(temp);
        }
      }
    }
    return true;
  }
 private void removeFromRichclub(DirectedNode node) {
   int degree = node.getOutDegree() - 1;
   this.richClub.get(degree).remove(node);
   if (this.richClub.get(degree).isEmpty()) {
     this.richClub.remove(degree);
   }
 }
 private void addToRichClub(DirectedNode node) {
   int degree = node.getOutDegree();
   if (this.richClub.containsKey(degree)) {
     this.richClub.get(degree).add(node);
   } else {
     LinkedList<Node> temp = new LinkedList<Node>();
     temp.add(node);
     this.richClub.put(degree, temp);
   }
 }
 private boolean applyAfterUpdateDirected(Update u) {
   if (u instanceof EdgeRemoval) {
     DirectedEdge e = (DirectedEdge) ((EdgeRemoval) u).getEdge();
     DirectedNode a = e.getSrc();
     DirectedNode b = e.getDst();
     if (a.hasEdge(new DirectedEdge(b, a))) {
       // remove triangles
       for (IElement cUncasted : a.getNeighbors()) {
         DirectedNode c = (DirectedNode) cUncasted;
         if (b.hasNeighbor(c)) {
           this.removeTriangle(a);
           this.removeTriangle(b);
           this.removeTriangle(c);
         }
       }
       // remove potentials
       this.removePotentials(a, a.getNeighborCount());
       this.removePotentials(b, b.getNeighborCount());
     }
   }
   return true;
 }
  protected void compute(Node n) {
    boolean[] seen = new boolean[this.g.getMaxNodeIndex() + 1];
    int[] dist = new int[this.g.getMaxNodeIndex() + 1];
    LinkedList<Node> queue = new LinkedList<Node>();
    queue.add(n);
    seen[n.getIndex()] = true;
    dist[n.getIndex()] = 0;

    while (!queue.isEmpty()) {
      Node current = queue.pop();

      if (current instanceof DirectedNode) {
        DirectedNode curr = (DirectedNode) current;
        for (IElement out_ : curr.getOutgoingEdges()) {
          DirectedNode out = ((DirectedEdge) out_).getDst();
          if (!seen[out.getIndex()]) {
            queue.addLast(out);
            seen[out.getIndex()] = true;
            dist[out.getIndex()] = dist[curr.getIndex()] + 1;
            this.apsp.incr(dist[out.getIndex()]);
          }
        }
      } else if (current instanceof UndirectedNode) {
        UndirectedNode curr = (UndirectedNode) current;
        for (IElement out_ : curr.getEdges()) {
          UndirectedNode out = (UndirectedNode) ((UndirectedEdge) out_).getDifferingNode(curr);
          if (!seen[out.getIndex()]) {
            queue.addLast(out);
            seen[out.getIndex()] = true;
            dist[out.getIndex()] = dist[curr.getIndex()] + 1;
            this.apsp.incr(dist[out.getIndex()]);
          }
        }
      }
    }
  }
  private boolean applyBeforeUpdateDirected(Update u) {
    if (u instanceof NodeAddition) {
      Node n = (Node) ((NodeAddition) u).getNode();
      this.localCC.setValue(n.getIndex(), 0);
      this.nodePotentialCount =
          ArrayUtils.set(this.nodePotentialCount, n.getIndex(), 0, Long.MIN_VALUE);
      this.nodeTriangleCount =
          ArrayUtils.set(this.nodeTriangleCount, n.getIndex(), 0, Long.MIN_VALUE);
      this.averageCC = ArrayUtils.avgIgnoreNaN(this.localCC.getValues());
    } else if (u instanceof NodeRemoval) {

      DirectedNode n = (DirectedNode) ((NodeRemoval) u).getNode();

      DirectedNode[] neighbors = new DirectedNode[n.getNeighborCount()];
      int index = 0;
      for (IElement neighbor : n.getNeighbors()) {
        neighbors[index++] = (DirectedNode) neighbor;
      }

      for (int i = 0; i < neighbors.length; i++) {
        for (int j = i + 1; j < neighbors.length; j++) {
          if (neighbors[i].hasEdge(new DirectedEdge(neighbors[i], neighbors[j]))
              && neighbors[i].hasEdge(new DirectedEdge(neighbors[j], neighbors[i]))) {
            this.removeTriangle(n);
            this.removeTriangle(neighbors[i]);
            this.removeTriangle(neighbors[j]);
          }
        }
        this.removePotentials(neighbors[i], neighbors[i].getNeighborCount() - 1);
      }

      this.removePotentials(n, n.getNeighborCount() * (n.getNeighborCount() - 1) / 2);

      this.localCC.setValue(n.getIndex(), NodeValueList.emptyValue);
      this.nodePotentialCount[n.getIndex()] = Long.MIN_VALUE;
      this.nodeTriangleCount[n.getIndex()] = Long.MIN_VALUE;
      this.localCC.truncate();
      this.nodePotentialCount = ArrayUtils.truncate(this.nodePotentialCount, Long.MIN_VALUE);
      this.nodeTriangleCount = ArrayUtils.truncate(this.nodeTriangleCount, Long.MIN_VALUE);

      this.averageCC = ArrayUtils.avgIgnoreNaN(this.localCC.getValues());

    } else if (u instanceof EdgeAddition) {
      DirectedEdge e = (DirectedEdge) ((EdgeAddition) u).getEdge();
      DirectedNode a = e.getSrc();
      DirectedNode b = e.getDst();
      if (a.hasEdge(new DirectedEdge(b, a))) {
        // new triangles
        for (IElement cUncasted : a.getNeighbors()) {
          DirectedNode c = (DirectedNode) cUncasted;
          if (b.hasNeighbor(c)) {
            this.addTriangle(a);
            this.addTriangle(b);
            this.addTriangle(c);
          }
        }
        // new potentials
        this.addPotentials(a, a.getNeighborCount());
        this.addPotentials(b, b.getNeighborCount());
      }
    }
    return true;
  }
  private boolean applyAfterDirectedEdgeAddition(Update u) {
    DirectedEdge e = (DirectedEdge) ((EdgeUpdate) u).getEdge();
    DirectedNode src = e.getSrc();
    DirectedNode dst = e.getDst();
    int srcDegree = src.getOutDegree();
    int dstDegree = dst.getOutDegree();

    if (richClub.containsKey(srcDegree - 1) && richClub.get(srcDegree - 1).contains(src)) {

      if (richClub.containsKey(dstDegree) && richClub.get(dstDegree).contains(dst)) {
        this.edgesBetweenRichClub++;
      }
      removeFromRichclub(src);
      addToRichClub(src);
    } else if (this.richClub.containsKey(srcDegree - 1)
        && this.nodesSortedByDegree.containsKey(srcDegree - 1)
        && this.nodesSortedByDegree.get(srcDegree - 1).contains(src)) {

      // changes for lastNode of Richclub
      DirectedNode lastNode = (DirectedNode) this.richClub.get(srcDegree - 1).removeLast();
      if (this.richClub.get(lastNode.getOutDegree()).isEmpty()) {
        this.richClub.remove(lastNode.getOutDegree());
      }
      addNodeToRest(lastNode);

      // Changes for src node for richclub
      this.nodesSortedByDegree.get(srcDegree - 1).remove(src);
      if (this.nodesSortedByDegree.get(src.getOutDegree() - 1).isEmpty()) {
        this.nodesSortedByDegree.remove(src.getOutDegree() - 1);
      }
      addToRichClub(src);

      // calculate changes for richclub connectivity
      for (IElement ie : src.getEdges()) {
        DirectedEdge edge = (DirectedEdge) ie;
        DirectedNode node = (DirectedNode) edge.getDifferingNode(src);
        if (this.richClub.containsKey(node.getOutDegree())
            && this.richClub.get(node.getOutDegree()).contains(node)) {
          this.edgesBetweenRichClub++;
        }
      }

      for (IElement ie : lastNode.getEdges()) {
        DirectedEdge edge = (DirectedEdge) ie;
        DirectedNode node = (DirectedNode) edge.getDifferingNode(lastNode);
        if (this.richClub.containsKey(node.getOutDegree())
            && this.richClub.get(node.getOutDegree()).contains(node)) {
          this.edgesBetweenRichClub--;
        }
      }

    } else {
      this.nodesSortedByDegree.get(src.getOutDegree() - 1).remove(src);
      if (this.nodesSortedByDegree.get(src.getOutDegree() - 1).isEmpty()) {
        this.nodesSortedByDegree.remove(src.getOutDegree() - 1);
      }
      addNodeToRest(src);
    }
    return true;
  }
  private boolean applyAfterDirectedNodeRemoval(Update u) {
    DirectedNode node = (DirectedNode) ((NodeRemoval) u).getNode();
    int min = Integer.MAX_VALUE;
    int max = 0;
    HashMap<Integer, LinkedList<DirectedNode>> order = new HashMap<>();
    for (IElement ie : node.getIncomingEdges()) {
      DirectedEdge e = (DirectedEdge) ie;
      DirectedNode n = e.getSrc();

      if (richClub.containsKey(n.getOutDegree() + 1)
          && richClub.get(n.getOutDegree() + 1).contains(n)) {
        this.edgesBetweenRichClub--;
        min = Math.min(min, n.getOutDegree());
        max = Math.max(max, n.getOutDegree());
        richClub.get(n.getOutDegree() + 1).remove(n);
        if (richClub.get(n.getOutDegree() + 1).isEmpty()) {
          richClub.remove(n.getOutDegree() + 1);
        }
        if (richClub.containsKey(n.getOutDegree())) {
          richClub.get(n.getOutDegree()).add(n);
        } else {
          richClub.put(n.getOutDegree(), new LinkedList<Node>());
          richClub.get(n.getOutDegree()).add(n);
        }
        if (order.containsKey(n.getOutDegree())) {
          order.get(n.getOutDegree()).add(n);
        } else {
          order.put(n.getOutDegree(), new LinkedList<DirectedNode>());
          order.get(n.getOutDegree()).add(n);
        }
      } else if (nodesSortedByDegree.containsKey(n.getOutDegree() + 1)
          && nodesSortedByDegree.get(n.getOutDegree() + 1).contains(n)) {
        nodesSortedByDegree.get(n.getOutDegree() + 1).remove(n);
        if (nodesSortedByDegree.get(n.getOutDegree() + 1).isEmpty()) {
          nodesSortedByDegree.remove(n.getOutDegree() + 1);
        }
        if (nodesSortedByDegree.containsKey(n.getOutDegree())) {
          nodesSortedByDegree.get(n.getOutDegree()).add(n);
        } else {
          nodesSortedByDegree.put(n.getOutDegree(), new LinkedList<Node>());
          nodesSortedByDegree.get(n.getOutDegree()).add(n);
        }
      } else {
        System.out.println("f**k");
      }
    }

    for (int i = min; i <= max; i++) {
      boolean f = false;
      if (f) {
        break;
      }
      if (!order.containsKey(i)) {
        continue;
      }
      for (DirectedNode n1 : order.get(i)) {
        int big = getBiggest();
        if (i >= big) {
          f = true;
          break;
        }

        // changes for firstNode of Rest
        DirectedNode firstNode = (DirectedNode) this.nodesSortedByDegree.get(big).removeFirst();
        if (this.nodesSortedByDegree.get(firstNode.getOutDegree()).isEmpty()) {
          this.nodesSortedByDegree.remove(firstNode.getOutDegree());
        }
        addToRichClub(firstNode);

        // Changes for src node for richclub
        this.richClub.get(i).remove(n1);
        if (this.richClub.get(i).isEmpty()) {
          this.richClub.remove(i);
        }
        addNodeToRest(n1);

        // calculate changes for richclub connectivity
        for (IElement ie : n1.getEdges()) {
          DirectedEdge edge = (DirectedEdge) ie;
          DirectedNode n2 = (DirectedNode) edge.getDifferingNode(n1);
          if (this.richClub.containsKey(n2.getOutDegree())
              && this.richClub.get(n2.getOutDegree()).contains(n2)) {
            this.edgesBetweenRichClub--;
          }
        }

        for (IElement ie : firstNode.getEdges()) {
          DirectedEdge edge = (DirectedEdge) ie;
          DirectedNode n2 = (DirectedNode) edge.getDifferingNode(firstNode);
          if (this.richClub.containsKey(n2.getOutDegree())
              && this.richClub.get(n2.getOutDegree()).contains(n2)) {
            this.edgesBetweenRichClub++;
          }
        }
      }
    }
    if (this.richClub.containsKey(node.getOutDegree())
        && this.richClub.get(node.getOutDegree()).contains(node)) {
      int degree = ((DirectedNode) node).getOutDegree();

      // changes for firstNode of Rest
      DirectedNode firstNode =
          (DirectedNode) this.nodesSortedByDegree.get(getBiggest()).removeFirst();
      if (this.nodesSortedByDegree.get(firstNode.getOutDegree()).isEmpty()) {
        this.nodesSortedByDegree.remove(firstNode.getOutDegree());
      }
      addToRichClub(firstNode);

      // Changes for src node for richclub
      this.richClub.get(degree).remove(node);
      if (this.richClub.get(degree).isEmpty()) {
        this.richClub.remove(degree);
      }

      // calculate changes for richclub connectivity
      for (IElement ie : node.getOutgoingEdges()) {
        DirectedEdge edge = (DirectedEdge) ie;
        DirectedNode n2 = (DirectedNode) edge.getDifferingNode(node);
        if (this.richClub.containsKey(n2.getOutDegree())
            && this.richClub.get(n2.getOutDegree()).contains(n2)) {
          this.edgesBetweenRichClub--;
        }
      }

      for (IElement ie : firstNode.getEdges()) {
        DirectedEdge edge = (DirectedEdge) ie;
        DirectedNode n2 = (DirectedNode) edge.getDifferingNode(firstNode);
        if (this.richClub.containsKey(n2.getOutDegree())
            && this.richClub.get(n2.getOutDegree()).contains(n2)) {
          this.edgesBetweenRichClub++;
        }
      }

    } else {
      int degree = ((DirectedNode) node).getOutDegree();

      this.nodesSortedByDegree.get(degree).remove(node);
      if (this.nodesSortedByDegree.get(degree).isEmpty()) {
        this.nodesSortedByDegree.remove(degree);
      }
    }

    return true;
  }
  @Override
  public boolean compute() {

    for (IElement ie : g.getNodes()) {
      Node s = (Node) ie;

      HashMap<Node, Node> parent = new HashMap<Node, Node>();
      HashMap<Node, Integer> height = new HashMap<Node, Integer>();

      for (IElement iNode : g.getNodes()) {
        Node t = (Node) iNode;
        if (t.equals(s)) {
          height.put(s, 0);
        } else {
          height.put(t, Integer.MAX_VALUE);
        }
      }
      if (DirectedNode.class.isAssignableFrom(this.g.getGraphDatastructures().getNodeType())) {
        PriorityQueue<QueueElement<DirectedNode>> q =
            new PriorityQueue<QueueElement<DirectedNode>>();
        q.add(new QueueElement((DirectedNode) s, height.get(s)));
        while (!q.isEmpty()) {
          QueueElement<DirectedNode> c = q.poll();
          DirectedNode current = c.e;
          if (height.get(current) == Integer.MAX_VALUE) {
            break;
          }

          for (IElement iEdge : current.getOutgoingEdges()) {
            DirectedWeightedEdge d = (DirectedWeightedEdge) iEdge;
            IntWeight dWeight = (IntWeight) d.getWeight();

            DirectedNode neighbor = d.getDst();

            int alt = height.get(current) + (int) dWeight.getWeight();
            if (alt < 0) {
              continue;
            }
            if (alt < height.get(neighbor)) {
              height.put(neighbor, alt);
              parent.put(neighbor, current);
              QueueElement<DirectedNode> temp =
                  new QueueElement<DirectedNode>(neighbor, height.get(neighbor));
              if (q.contains(temp)) {
                q.remove(temp);
              }
              q.add(temp);
            }
          }
        }
      } else {
        PriorityQueue<QueueElement<Node>> q = new PriorityQueue<QueueElement<Node>>();
        q.add(new QueueElement((Node) s, height.get(s)));
        while (!q.isEmpty()) {
          QueueElement<Node> c = q.poll();
          Node current = c.e;

          if (height.get(current) == Integer.MAX_VALUE) {
            break;
          }

          for (IElement iEdge : current.getEdges()) {
            UndirectedWeightedEdge d = (UndirectedWeightedEdge) iEdge;
            IntWeight dWeight = (IntWeight) d.getWeight();

            Node neighbor = d.getDifferingNode(current);

            int alt = height.get(current) + (int) dWeight.getWeight();
            if (alt < 0) {
              continue;
            }
            if (alt < height.get(neighbor)) {
              height.put(neighbor, alt);
              parent.put(neighbor, current);
              QueueElement<Node> temp = new QueueElement<Node>(neighbor, height.get(neighbor));
              if (q.contains(temp)) {
                q.remove(temp);
              }
              q.add(temp);
            }
          }
        }
      }
      for (int i : height.values()) {
        if (i != Integer.MAX_VALUE && i != 0) {
          apsp.incr(i);
        }
      }
      apsp.truncate();
      parents.put(s, parent);
      heights.put(s, height);
    }

    return true;
  }
  private void directedDelete(DirectedNode r, DirectedEdge e) {
    HashMap<Node, Node> parent = this.parents.get(r);
    HashMap<Node, Integer> height = this.heights.get(r);
    DirectedNode src = e.getSrc();
    DirectedNode dst = e.getDst();

    // if the source or dst or edge is not in tree do nothing
    if (height.get(src) == Integer.MAX_VALUE
        || height.get(dst) == Integer.MAX_VALUE
        || dst.equals(r)
        || !parent.get(dst).equals(src)) {
      return;
    }

    // Queues and data structure for tree change
    HashSet<DirectedNode> uncertain = new HashSet<DirectedNode>();
    HashSet<DirectedNode> changed = new HashSet<DirectedNode>();

    PriorityQueue<QueueElement<DirectedNode>> q = new PriorityQueue<QueueElement<DirectedNode>>();

    q.add(new QueueElement<DirectedNode>(dst, height.get(dst)));

    uncertain.add(dst);
    parent.remove(dst);

    while (!q.isEmpty()) {
      QueueElement<DirectedNode> qE = q.poll();
      DirectedNode w = qE.e;

      int key = qE.distance;

      // find the new shortest path
      int dist = Integer.MAX_VALUE;

      ArrayList<DirectedNode> minSettled = new ArrayList<DirectedNode>();
      ArrayList<DirectedNode> min = new ArrayList<DirectedNode>();
      for (IElement iEgde : w.getIncomingEdges()) {
        DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
        IntWeight eWeight = (IntWeight) edge.getWeight();
        DirectedNode z = edge.getSrc();

        if (changed.contains(z) || height.get(z) == Integer.MAX_VALUE) {
          continue;
        }
        if (height.get(z) + (int) eWeight.getWeight() < dist) {
          min.clear();
          minSettled.clear();
          min.add(z);
          if (!uncertain.contains(z)) minSettled.add(z);
          dist = height.get(z) + (int) eWeight.getWeight();
          continue;
        }
        if (height.get(z) + (int) eWeight.getWeight() == dist) {
          min.add(z);
          if (!uncertain.contains(z)) minSettled.add(z);
          continue;
        }
      }

      boolean noPossibleNeighbour =
          (key >= breakLoop && dist > breakLoop)
              || (min.isEmpty() && (!uncertain.contains(w) || (key == dist)));

      // no neighbour found
      if (noPossibleNeighbour) {
        if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
        height.put(w, Integer.MAX_VALUE);
        parent.remove(w);
        continue;
      }
      if (uncertain.contains(w)) {
        if (key == dist) {
          if (minSettled.isEmpty()) {
            parent.put(w, min.get(0));
          } else {
            parent.put(w, minSettled.get(0));
          }
          if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
          apsp.incr(dist);
          height.put(w, dist);
          for (IElement iEgde : w.getOutgoingEdges()) {
            DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
            IntWeight iEdgeWeight = (IntWeight) edge.getWeight();

            DirectedNode z = edge.getDst();

            if (height.get(z) > dist + (int) iEdgeWeight.getWeight()) {
              q.remove(new QueueElement<DirectedNode>(z, dist + (int) iEdgeWeight.getWeight()));
              q.add(new QueueElement<DirectedNode>(z, dist + (int) iEdgeWeight.getWeight()));
            }
          }
        } else {
          changed.add(w);

          q.add(new QueueElement<DirectedNode>(w, dist));
          uncertain.remove(w);
          for (IElement iEgde : w.getOutgoingEdges()) {
            DirectedEdge edge = (DirectedEdge) iEgde;

            DirectedNode z = edge.getDst();

            if (parent.get(z) == w) {
              parent.remove(z);
              uncertain.add(z);
              q.add(new QueueElement<DirectedNode>(z, height.get(z)));
            }
          }
        }
        continue;
      }
      if (dist > key) {
        q.add(new QueueElement<DirectedNode>(w, dist));

        continue;
      }
      if (minSettled.isEmpty()) {
        parent.put(w, min.get(0));
      } else {
        parent.put(w, minSettled.get(0));
      }

      changed.remove(w);
      if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
      apsp.incr(dist);
      height.put(w, dist);
      for (IElement iEgde : w.getOutgoingEdges()) {
        DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
        IntWeight eWeight = (IntWeight) edge.getWeight();

        DirectedNode z = edge.getDst();

        if (height.get(z) > dist + (int) eWeight.getWeight()) {
          q.remove(new QueueElement<DirectedNode>(z, dist + (int) eWeight.getWeight()));
          q.add(new QueueElement<DirectedNode>(z, dist + (int) eWeight.getWeight()));
        }
      }
    }
  }