public static Map<String, Set<Double>> edgeAnglesByType(final Node<?> node) {
   final Map<String, Set<Double>> anglesByType = new HashMap<>();
   for (final Edge<?> edge : node.getInEdges()) {
     final String typePath = edge.getTypeName();
     final double toAngle = edge.getToAngle();
     final Set<Double> angles = getAnglesForType(anglesByType, typePath);
     angles.add(toAngle);
   }
   for (final Edge<?> edge : node.getOutEdges()) {
     final String typePath = edge.getTypeName();
     final double fromAngle = edge.getFromAngle();
     final Set<Double> angles = getAnglesForType(anglesByType, typePath);
     angles.add(fromAngle);
   }
   return anglesByType;
 }
 public static Set<String> edgeTypeNames(final Node<?> node) {
   final Set<String> typePaths = new HashSet<>();
   for (final Edge<?> edge : node.getEdges()) {
     final String typePath = edge.getTypeName();
     typePaths.add(typePath);
   }
   return typePaths;
 }
 public static <T> Map<String, List<Edge<T>>> edgesByType(final Node<T> node) {
   final Map<String, List<Edge<T>>> edgesByType = new HashMap<>();
   for (final Edge<T> edge : node.getEdges()) {
     final String typePath = edge.getTypeName();
     List<Edge<T>> typeEdges = edgesByType.get(typePath);
     if (typeEdges == null) {
       typeEdges = new ArrayList<>();
       edgesByType.put(typePath, typeEdges);
     }
     typeEdges.add(edge);
   }
   return edgesByType;
 }
 public static <T> Map<LineString, Map<String, Set<Edge<T>>>> edgesByLineAndTypeName(
     final Node<T> node) {
   final List<Edge<T>> edges = node.getEdges();
   final Map<LineString, Map<String, Set<Edge<T>>>> lineEdgeMap = new HashMap<>();
   for (final Edge<T> edge : new HashSet<>(edges)) {
     LineString line = edge.getLine();
     Map<String, Set<Edge<T>>> edgesByType = edgesByTypeForLine(lineEdgeMap, line);
     if (edgesByType == null) {
       edgesByType = new HashMap<>();
       if (edge.getEnd(node).isTo()) {
         line = line.reverse();
       }
       lineEdgeMap.put(line, edgesByType);
     }
     Set<Edge<T>> typeEdges = edgesByType.get(edge.getTypeName());
     if (typeEdges == null) {
       typeEdges = new HashSet<>();
       final String typePath = edge.getTypeName();
       edgesByType.put(typePath, typeEdges);
     }
     typeEdges.add(edge);
   }
   return lineEdgeMap;
 }
    public static <T> Map<String, Map<LineString, Set<Edge<T>>>> edgesByTypeNameAndLine(
        final Node<T> node) {
      final List<Edge<T>> edges = node.getEdges();
      final Map<String, Map<LineString, Set<Edge<T>>>> typeLineEdgeMap = new HashMap<>();
      for (final Edge<T> edge : new HashSet<>(edges)) {
        final String typePath = edge.getTypeName();
        Map<LineString, Set<Edge<T>>> lineEdgeMap = typeLineEdgeMap.get(typePath);
        if (lineEdgeMap == null) {
          lineEdgeMap = new HashMap<>();
          typeLineEdgeMap.put(typePath, lineEdgeMap);
        }

        Edge.addEdgeToEdgesByLine(node, lineEdgeMap, edge);
      }
      return typeLineEdgeMap;
    }