@SuppressWarnings("rawtypes")
  public void layout(IFigure parent) {
    Rectangle relativeArea = parent.getClientArea();
    constrainedData.area = transposer.t(relativeArea);

    // parent may not be set yet
    if (relativeArea.width == 0) return;

    Iterator iterator = parent.getChildren().iterator();
    int dx;

    initVariables(parent);
    initRow();
    int i = 0;
    while (iterator.hasNext()) {
      IFigure f = (IFigure) iterator.next();

      Rectangle bounds = getConstraint(f);

      // -- There is a constraint, process width and height
      int widthHint = bounds.width;
      int heightHint = bounds.height;
      if (widthHint == -1 || heightHint == -1) {
        Dimension _preferredSize = f.getPreferredSize(widthHint, heightHint);
        bounds = bounds.getCopy();
        if (widthHint == -1) bounds.width = _preferredSize.width;
        if (heightHint == -1) bounds.height = _preferredSize.height;
      }
      Dimension min = f.getMinimumSize(widthHint, heightHint);
      Dimension max = f.getMaximumSize();

      if (min.width > bounds.width) bounds.width = min.width;
      else if (max.width < bounds.width) bounds.width = max.width;

      if (min.height > bounds.height) bounds.height = min.height;
      else if (max.height < bounds.height) bounds.height = max.height;

      Rectangle r = new Rectangle(0, 0, bounds.width, bounds.height);

      if (constrainedData.rowCount > 0) {
        if (constrainedData.rowWidth + bounds.width > constrainedData.maxWidth) layoutRow(parent);
      }
      r.x = constrainedData.rowX;
      r.y = constrainedData.rowY;
      dx = r.width + getMinorSpacing();
      constrainedData.rowX += dx;
      constrainedData.rowWidth += dx;
      constrainedData.rowHeight = Math.max(constrainedData.rowHeight, r.height);
      constrainedData.row[constrainedData.rowCount] = f;
      constrainedData.bounds[constrainedData.rowCount] = r;
      constrainedData.rowCount++;
      i++;
    }
    if (constrainedData.rowCount != 0) layoutRow(parent);
    totalHeight = constrainedData.rowY;
    constrainedData.rowY = 0;
  }
  protected void layoutRow(IFigure parent) {
    int majorAdjustment = 0;
    int minorAdjustment = 0;
    int correctMajorAlignment = majorAlignment;
    int correctMinorAlignment = minorAlignment;

    majorAdjustment = constrainedData.area.width - constrainedData.rowWidth + getMinorSpacing();

    switch (correctMajorAlignment) {
      case ALIGN_LEFTTOP:
        majorAdjustment = 0;
        break;
      case ALIGN_CENTER:
        majorAdjustment /= 2;
        break;
      case ALIGN_RIGHTBOTTOM:
        break;
    }

    for (int j = 0; j < constrainedData.rowCount; j++) {
      if (fill) {
        constrainedData.bounds[j].height = constrainedData.rowHeight;
      } else {
        minorAdjustment = constrainedData.rowHeight - constrainedData.bounds[j].height;
        switch (correctMinorAlignment) {
          case ALIGN_LEFTTOP:
            minorAdjustment = 0;
            break;
          case ALIGN_CENTER:
            minorAdjustment /= 2;
            break;
          case ALIGN_RIGHTBOTTOM:
            break;
        }
        constrainedData.bounds[j].y += minorAdjustment;
      }
      constrainedData.bounds[j].x += majorAdjustment;

      setBoundsOfChild(parent, constrainedData.row[j], transposer.t(constrainedData.bounds[j]));
    }
    constrainedData.rowY += getMajorSpacing() + constrainedData.rowHeight;
    initRow();
  }
 protected void initRow() {
   constrainedData.rowX = 0;
   constrainedData.rowHeight = 0;
   constrainedData.rowWidth = 0;
   constrainedData.rowCount = 0;
 }
 protected void initVariables(IFigure parent) {
   constrainedData.row = new IFigure[parent.getChildren().size()];
   constrainedData.bounds = new Rectangle[constrainedData.row.length];
   constrainedData.maxWidth = constrainedData.area.width;
 }