/** Adds the header to the TreeTable. */
  protected void addHeader() {
    // create the view for side columns
    SideColumnsView sideColumns = new SideColumnsView("sideColumns", null);
    add(sideColumns);
    if (columns != null) {
      for (int i = 0; i < columns.length; i++) {
        IColumn column = columns[i];
        if ((column.getLocation().getAlignment() == Alignment.LEFT)
            || (column.getLocation().getAlignment() == Alignment.RIGHT)) {
          TreeTableItem component = new TreeTableItem(i);
          Component cell = column.newHeader(sideColumns, TreeTableItem.ID);
          component.add(cell);
          sideColumns.addColumn(column, component, null);
        }
      }
    }

    // create the view for middle columns
    MiddleColumnsView middleColumns = new MiddleColumnsView("middleColumns", null, hasLeftColumn());
    add(middleColumns);
    if (columns != null) {
      for (int i = 0; i < columns.length; i++) {
        IColumn column = columns[i];
        if (column.getLocation().getAlignment() == Alignment.MIDDLE) {
          TreeTableItem component = new TreeTableItem(i);
          Component cell = column.newHeader(middleColumns, TreeTableItem.ID);
          component.add(cell);
          middleColumns.addColumn(column, component, null);
        }
      }
    }
  }
  /**
   * Populates one row of the tree.
   *
   * @param item the tree node component
   * @param level the current level
   */
  @Override
  protected void populateTreeItem(final WebMarkupContainer item, final int level) {
    final TreeNode node = (TreeNode) item.getDefaultModelObject();

    // add side columns
    SideColumnsView sideColumns = new SideColumnsView("sideColumns", node);
    item.add(sideColumns);
    if (columns != null) {
      for (int i = 0; i < columns.length; i++) {
        IColumn column = columns[i];
        if ((column.getLocation().getAlignment() == Alignment.LEFT)
            || (column.getLocation().getAlignment() == Alignment.RIGHT)) {
          TreeTableItem component;
          // first try to create a renderable
          IRenderable renderable = column.newCell(node, level);

          if (renderable == null) {
            // if renderable failed, try to create a regular component.
            component = new TreeTableItem(i);
            Component cell = column.newCell(sideColumns, TreeTableItem.ID, node, level);
            component.add(cell);
          } else {
            component = null;
          }

          sideColumns.addColumn(column, component, renderable);
        }
      }
    }

    // add middle columns
    MiddleColumnsView middleColumns = new MiddleColumnsView("middleColumns", node, hasLeftColumn());
    if (columns != null) {
      for (int i = 0; i < columns.length; i++) {
        IColumn column = columns[i];
        if (column.getLocation().getAlignment() == Alignment.MIDDLE) {
          TreeTableItem component;
          // first try to create a renderable
          IRenderable renderable = column.newCell(node, level);

          if (renderable == null) {
            // if renderable failed, try to create a regular component
            component = new TreeTableItem(i);
            Component cell = column.newCell(middleColumns, TreeTableItem.ID, node, level);
            component.add(cell);
          } else {
            component = null;
          }

          middleColumns.addColumn(column, component, renderable);
        }
      }
    }
    item.add(middleColumns);

    // do distinguish between selected and unselected rows we add an
    // behavior that modifies row css class.
    item.add(
        new Behavior() {
          private static final long serialVersionUID = 1L;

          @Override
          public void onComponentTag(final Component component, final ComponentTag tag) {
            super.onComponentTag(component, tag);
            if (getTreeState().isNodeSelected(node)) {
              tag.put("class", "row-selected");
            } else {
              tag.put("class", "row");
            }
          }
        });
  }