/**
   * Processes a treeNode (add it to the TreeGrid)
   *
   * @param treeNode The treeNode to process
   * @param nodeRoot The root node to which the treeNode has te be added
   * @param tree The tree to which the node has to be added
   * @param mapModel map model
   * @param refresh True if the tree is refreshed (causing it to keep its expanded state)
   */
  private void processNode(
      final ClientLayerTreeNodeInfo treeNode,
      final TreeNode nodeRoot,
      final Tree tree,
      final MapModel mapModel,
      final boolean refresh) {
    if (null != treeNode) {
      String treeNodeLabel = treeNode.getLabel();
      final TreeNode node = new TreeNode(treeNodeLabel);

      tree.add(node, nodeRoot);

      // (final leafs)
      for (ClientLayerInfo info : treeNode.getLayers()) {
        Layer<?> layer = mapModel.getLayer(info.getId());
        tree.add(new LayerTreeTreeNode(this.tree, layer), node);
      }

      // treeNodes
      List<ClientLayerTreeNodeInfo> children = treeNode.getTreeNodes();
      for (ClientLayerTreeNodeInfo newNode : children) {
        processNode(newNode, node, tree, mapModel, refresh);
      }

      // expand tree nodes
      // when not refreshing expand them like configured
      // when refreshing expand them as before the refresh
      boolean isTreeNodeExpanded = treeNode.isExpanded();
      if (!refresh) {
        if (isTreeNodeExpanded) {
          tree.openFolder(node);
        }
      } else {
        // TODO close previously opened tree nodes, close others
      }
    }
  }
  /**
   * Builds up the tree showing the layers
   *
   * @param mapModel The mapModel containing the layerTree
   */
  private void buildTree(MapModel mapModel) {
    treeGrid.setWidth100();
    treeGrid.setHeight100();
    treeGrid.setShowHeader(false);
    tree = new RefreshableTree();
    final TreeNode nodeRoot = new TreeNode("ROOT");
    tree.setRoot(nodeRoot); // invisible ROOT node (ROOT node is required)

    ClientLayerTreeInfo layerTreeInfo = mapModel.getMapInfo().getLayerTree();
    if (layerTreeInfo != null) {
      ClientLayerTreeNodeInfo treeNode = layerTreeInfo.getTreeNode();
      processNode(treeNode, nodeRoot, tree, mapModel, false);
    }

    treeGrid.setData(tree);
    treeGrid.addLeafClickHandler(this);
    treeGrid.addFolderClickHandler(this);

    // -- add event listeners to layers
    for (Layer<?> layer : mapModel.getLayers()) {
      registrations.add(
          layer.addLayerChangedHandler(
              new LayerChangedHandler() {
                public void onLabelChange(LayerLabeledEvent event) {}

                public void onVisibleChange(LayerShownEvent event) {
                  for (TreeNode node : tree.getAllNodes()) {
                    if (node.getName().equals(event.getLayer().getLabel())) {
                      if (node instanceof LayerTreeTreeNode) {
                        ((LayerTreeTreeNode) node).updateIcon();
                      }
                    }
                  }
                }
              }));
    }
  }