docs: public static Map<Point2D, Ruling[]> findIntersections(List<Ruling> horizontals, List<Ruling> verticals) {
          
          class SortObject {
              protected SOType type;
              protected float position;
              protected Ruling ruling;
              
              public SortObject(SOType type, float position, Ruling ruling) {
                  this.type = type;
                  this.position = position;
                  this.ruling = ruling;
              }
          }
          
          List<SortObject> sos = new ArrayList<>();
          
          TreeMap<Ruling, Boolean> tree = new TreeMap<>(new Comparator<Ruling>() {
              @Override
              public int compare(Ruling o1, Ruling o2) {
                  return java.lang.Double.compare(o1.getTop(), o2.getTop());
              }});
          
          TreeMap<Point2D, Ruling[]> rv = new TreeMap<>(new Comparator<Point2D>() {
              @Override
              public int compare(Point2D o1, Point2D o2) {
                  if (o1.getY() > o2.getY()) return  1;
                  if (o1.getY() < o2.getY()) return -1;
                  if (o1.getX() > o2.getX()) return  1;
                  if (o1.getX() < o2.getX()) return -1;
                  return 0;
              }
          });
          
          for (Ruling h : horizontals) {
              sos.add(new SortObject(SOType.HLEFT, h.getLeft() - PERPENDICULAR_PIXEL_EXPAND_AMOUNT, h));
              sos.add(new SortObject(SOType.HRIGHT, h.getRight() + PERPENDICULAR_PIXEL_EXPAND_AMOUNT, h));
          }
  
          for (Ruling v : verticals) {
              sos.add(new SortObject(SOType.VERTICAL, v.getLeft(), v));
          }
          
          Collections.sort(sos, new Comparator<SortObject>() {
              @Override
              public int compare(SortObject a, SortObject b) {
                  int rv;
                  if (Utils.feq(a.position, b.position)) {
                      if (a.type == SOType.VERTICAL && b.type == SOType.HLEFT) {
                         rv = 1;     
                      }
                      else if (a.type == SOType.VERTICAL && b.type == SOType.HRIGHT) {
                         rv = -1;
                      }
                      else if (a.type == SOType.HLEFT && b.type == SOType.VERTICAL) {
                         rv = -1;
                      }
                      else if (a.type == SOType.HRIGHT && b.type == SOType.VERTICAL) {
                         rv = 1;
                       }
                      else {
                         rv = java.lang.Double.compare(a.position, b.position);
                      }
                  }
                  else {
                      return java.lang.Double.compare(a.position, b.position);
                  }
                  return rv;
              }
          });
          
          for (SortObject so : sos) {
              switch(so.type) {
              case VERTICAL:
                  for (Map.Entry<Ruling, Boolean> h : tree.entrySet()) {
                      Point2D i = h.getKey().intersectionPoint(so.ruling);
                      if (i == null) {
                          continue;
                      }
                      rv.put(i, 
                             new Ruling[] { h.getKey().expand(PERPENDICULAR_PIXEL_EXPAND_AMOUNT), 
                                            so.ruling.expand(PERPENDICULAR_PIXEL_EXPAND_AMOUNT) });
                  }
                  break;
              case HRIGHT:
                  tree.remove(so.ruling);
                  break;
              case HLEFT:
                  tree.put(so.ruling, true);
                  break;
              }
          }
          
          return rv;
          
      }