@Override
  public int compare(@NotNull GraphElement o1, @NotNull GraphElement o2) {
    if (o1 instanceof GraphEdge edge1 && o2 instanceof GraphEdge edge2) {
      NormalEdge normalEdge1 = asNormalEdge(edge1);
      NormalEdge normalEdge2 = asNormalEdge(edge2);
      if (normalEdge1 == null) return -compare2(edge2, new GraphNode(getNotNullNodeIndex(edge1)));
      if (normalEdge2 == null) return compare2(edge1, new GraphNode(getNotNullNodeIndex(edge2)));

      if (normalEdge1.up == normalEdge2.up) {
        if (normalEdge1.down < normalEdge2.down) {
          return -compare2(edge2, new GraphNode(normalEdge1.down));
        }
        else {
          return compare2(edge1, new GraphNode(normalEdge2.down));
        }
      }

      if (normalEdge1.up < normalEdge2.up) {
        return compare2(edge1, new GraphNode(normalEdge2.up));
      }
      else {
        return -compare2(edge2, new GraphNode(normalEdge1.up));
      }
    }

    if (o1 instanceof GraphEdge && o2 instanceof GraphNode) return compare2((GraphEdge)o1, (GraphNode)o2);

    if (o1 instanceof GraphNode && o2 instanceof GraphEdge) return -compare2((GraphEdge)o2, (GraphNode)o1);

    assert false; // both GraphNode
    return 0;
  }
@Override
  public int compare(@NotNull GraphElement o1, @NotNull GraphElement o2)