private BxBounds parseElementContainingVertexes(Element el) {
   ArrayList<Element> vs = getChildren("Vertex", el);
   if (vs.isEmpty()) {
     return null;
   }
   ArrayList<ComparablePair<Integer, Integer>> list =
       new ArrayList<ComparablePair<Integer, Integer>>();
   int minx = Integer.MAX_VALUE;
   int maxx = Integer.MIN_VALUE;
   int miny = Integer.MAX_VALUE;
   int maxy = Integer.MIN_VALUE;
   for (Element v : vs) {
     int x = Integer.parseInt(v.getAttribute("x"));
     if (x < minx) minx = x;
     if (x > maxx) maxx = x;
     int y = Integer.parseInt(v.getAttribute("y"));
     if (y < miny) miny = y;
     if (y > maxy) maxy = y;
     list.add(new ComparablePair<Integer, Integer>(x, y));
   }
   Collections.sort(list);
   ComparablePair<Integer, Integer> mine = list.get(0);
   ComparablePair<Integer, Integer> maxe = list.get(list.size() - 1);
   BxBounds ret = new BxBounds(minx, miny, maxx - minx, maxy - miny);
   if (ret.getHeight() == 0 || ret.getWidth() == 0) {
     log.warn("problems with height or width points are:");
     for (ComparablePair<Integer, Integer> pa : list) {
       log.warn("\t" + pa.o1 + " , " + pa.o2);
     }
   }
   return ret;
 }
  private BxPage parsePageNode(Element elem) {
    BxPage page = new BxPage();

    double minX = 0, minY = 0, maxX = 0, maxY = 0;
    boolean started = false;

    List<Element> e = getChildren("Zone", elem);
    for (Element zo : e) {
      BxZone zon = parseZoneNode(zo);
      page.addZone(zon);

      BxBounds zoneBounds = zon.getBounds();
      if (!started) {
        minX = zoneBounds.getX();
        minY = zoneBounds.getY();
        maxX = zoneBounds.getX() + zoneBounds.getWidth();
        maxY = zoneBounds.getY() + zoneBounds.getHeight();
        started = true;
      }

      if (zoneBounds.getX() < minX) {
        minX = zoneBounds.getX();
      }
      if (zoneBounds.getX() + zoneBounds.getWidth() > maxX) {
        maxX = zoneBounds.getX() + zoneBounds.getWidth();
      }
      if (zoneBounds.getY() < minY) {
        minY = zoneBounds.getY();
      }
      if (zoneBounds.getY() + zoneBounds.getHeight() > maxY) {
        maxY = zoneBounds.getY() + zoneBounds.getHeight();
      }
    }

    Collections.sort(
        page.getZones(),
        new Comparator() {

          @Override
          public int compare(Object t, Object t1) {
            BxZone z1 = (BxZone) t;
            BxZone z2 = (BxZone) t1;
            int ret = Double.compare(z1.getBounds().getY(), z2.getBounds().getY());
            if (ret == 0) {
              ret = Double.compare(z1.getBounds().getX(), z2.getBounds().getX());
            }
            return ret;
          }
        });
    return page.setBounds(new BxBounds(minX, minY, maxX - minX, maxY - minY));
  }
 private double getFontIndex(BxLine line) {
   List<String> fonts =
       Lists.newArrayList(line.getParent().getParent().getParent().getFontNames());
   Collections.sort(fonts);
   return fonts.indexOf(line.getMostPopularFontName());
 }