/** @param grids */
  private void writeGeometry(SuperGrid<BPMNElement> grids) {
    // write cells
    double x = 0;
    double y = 0;
    int row = 0;
    int column = 0;
    for (Row<BPMNElement> r : grids) {
      column = 0;
      double cellHeight = heightOfRow[row];
      for (Cell<BPMNElement> c : r) {
        double cellWidth = widthOfColumn[column];
        if (c.isFilled()) {
          BPMNElement elem = c.getValue();
          LayoutingBounds geom = elem.getGeometry();
          double newX =
              x + (cellWidth / 2.0) - (geom.getWidth() / 2.0) + maxLaneDepth * LANE_HEAD_WIDTH;
          double newY = y + (cellHeight / 2.0) - (geom.getHeight() / 2.0);

          elem.setGeometry(new LayoutingBoundsImpl(newX, newY, geom.getWidth(), geom.getHeight()));
          elem.updateDataModel();
        }
        x += cellWidth;
        column++;
      }
      x = 0;
      y += cellHeight;
      row++;
    }
  }
  /**
   * @param lane
   * @param absY
   * @param level
   */
  private void correctLaneElements(BPMNElement lane, double absY, int level) {
    List<BPMNElement> childs = lane2LaneChilds.get(lane);
    double height = 0;
    for (BPMNElement child : childs) {
      correctLaneElements(child, absY + height, level + 1);
      height += child.getGeometry().getHeight();
    }

    int xTrans = level * -LANE_HEAD_WIDTH;
    for (LayoutingElement content : diagram.getChildElementsOf(lane)) {
      if (!BPMNType.isASwimlane(content.getType())) {
        LayoutingBounds geom = content.getGeometry();
        content.setGeometry(
            new LayoutingBoundsImpl(
                geom.getX() + xTrans, geom.getY() - absY, geom.getWidth(), geom.getHeight()));
        ((BPMNElement) content).updateDataModel();
      }
    }
  }
  /** @param grids */
  private void calcGeometry(SuperGrid<BPMNElement> grids) {
    grids.pack();
    heightOfRow = new double[grids.getHeight()];
    widthOfColumn = new double[grids.getWidth()];
    // initialize with standard values
    Arrays.fill(heightOfRow, CELL_HEIGHT);
    Arrays.fill(widthOfColumn, CELL_WIDTH);
    // find biggest
    int row = 0;
    int column = 0;
    for (Row<BPMNElement> r : grids) {
      column = 0;
      for (Cell<BPMNElement> c : r) {
        if (c.isFilled()) {
          BPMNElement elem = c.getValue();
          LayoutingBounds geom = elem.getGeometry();
          widthOfColumn[column] = Math.max(widthOfColumn[column], geom.getWidth() + CELL_MARGIN);
          heightOfRow[row] = Math.max(heightOfRow[row], geom.getHeight() + CELL_MARGIN);
        }
        column++;
      }
      row++;
    }

    // calc width / height
    widthOfSuperGrid = 0;
    for (double columnWidth : widthOfColumn) {
      widthOfSuperGrid += columnWidth;
    }
    heightOfSuperGrid = 0;
    for (double rowHeight : heightOfRow) {
      heightOfSuperGrid += rowHeight;
    }

    poolWidth = maxLaneDepth * LANE_HEAD_WIDTH;
    poolWidth += widthOfSuperGrid;
  }