docs: private int expandVertically(Rectangular gp, Rectangular limit, AreaImpl template, boolean down, boolean sep)
      {
          //System.out.println("exp: " + gp + (down?" _":" ^") + " " + sep);
          int na = down ? gp.getY2() : gp.getY1(); //what to return when it's not possible to expand
          int targety = down ? (gp.getY2() + 1) : (gp.getY1() - 1); 
          //find candidate boxes
          Vector<AreaImpl> cands = new Vector<AreaImpl>();
          int x = gp.getX1();
          while (x <= gp.getX2()) //scan everything at the target position
          {
              AreaImpl cand = (AreaImpl) getTopology().findAreaAt(x, targety);
              //ignore candidates that intersect with our area (could leat to an infinite loop)
              if (cand == null || cand.getGridPosition().intersects(gp))
                  x++;
              else
              {
                  cands.add(cand);
                  x = cand.getGridPosition().getX2() + 1;
              }
          }
          //everything below/above empty, can safely expand
          if (cands.size() == 0)
              return targety;
          //try to align the candidate boxes
          for (Iterator<AreaImpl> it = cands.iterator(); it.hasNext(); )
          {
              AreaImpl cand = it.next();
              if (sep && 
                      ((down && separatorUp(cand.getGridPosition())) ||
                       (!down && separatorDown(cand.getGridPosition()))))
                  return na; //separated, cannot expand
              else if ((matchstyles && !cand.hasSameStyle(template)) || cand.getLevel() > maxlevel)
                  return na; //not the same style or level
              else
              {
                  Rectangular cgp = new Rectangular(cand.getGridPosition());
                  if (cgp.getX1() == gp.getX1() && cgp.getX2() == gp.getX2())
                      return targety; //simple match
                  else if (cgp.getX1() < gp.getX1() || cgp.getX2() > gp.getX2())
                      return na; //area overflows, cannot expand
                  else //candidate is smaller, try to expand align to our width
                  {
                      if (down)
                      {
                          Rectangular newlimit = new Rectangular(gp.getX1(), targety, gp.getX2(), limit.getY2());
                          expandToLimit(cand, cgp, newlimit, template, true, false, DIR_RIGHT, REQ_HORIZONTAL);
                          if (cgp.getX1() == gp.getX1() && cgp.getX2() == gp.getX2())
                              return cgp.getY2(); //successfully aligned
                      }
                      else
                      {
                          Rectangular newlimit = new Rectangular(gp.getX1(), limit.getY1(), gp.getX2(), targety);
                          expandToLimit(cand, cgp, newlimit, template, true, false, DIR_RIGHT, REQ_HORIZONTAL);
                          if (cgp.getX1() == gp.getX1() && cgp.getX2() == gp.getX2())
                              return cgp.getY1(); //successfully aligned
                      }
                  }
              }
          }
          return na; //some candidates but none usable
      }