/**
   * @param nodeSelection The node that should be selected recursively
   * @param select true: select the node and its children; false: deselect the node and its children
   */
  private void selectRec(MultipleSelectionElement nodeSelection, boolean select) {
    SelectNodeObject userObject = (SelectNodeObject) nodeSelection.getUserObject();
    String id = userObject.getId();
    if (nodeSelection.isMultiselect()) {
      nodeSelection.select(id, select);
    }

    for (MultipleSelectionElement childSelection : userObject.getChildren()) {
      selectRec(childSelection, select);
    }
  }
 @Override
 protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
   if (nodeSelections.contains(source)) {
     MultipleSelectionElement nodeSelection = (MultipleSelectionElement) source;
     if (nodeSelection.isMultiselect()) {
       selectRec(nodeSelection, nodeSelection.isSelected(0));
     }
   } else if (source == selectAll) {
     for (MultipleSelectionElement nodeSelection : nodeSelections) {
       if (nodeSelection.isMultiselect() && !nodeSelection.isSelected(0)) {
         SelectNodeObject treeNode = (SelectNodeObject) nodeSelection.getUserObject();
         String id = treeNode.getId();
         nodeSelection.select(id, true);
       }
     }
   } else if (source == deselectAll) {
     for (MultipleSelectionElement nodeSelection : nodeSelections) {
       if (nodeSelection.isMultiselect() && nodeSelection.isSelected(0)) {
         SelectNodeObject treeNode = (SelectNodeObject) nodeSelection.getUserObject();
         String id = treeNode.getId();
         nodeSelection.select(id, false);
       }
     }
   } else if (source == asChild) {
     position = -1;
     ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
     create(rootSelection, course, selectedNode.getCourseNode());
     fireEvent(ureq, Event.CHANGED_EVENT);
   } else if (source == sameLevel) {
     ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
     CourseEditorTreeNode parentNode = (CourseEditorTreeNode) selectedNode.getParent();
     position = 0;
     for (position = parentNode.getChildCount(); position-- > 0; ) {
       if (selectedNode.getIdent().equals(parentNode.getChildAt(position).getIdent())) {
         position++;
         break;
       }
     }
     create(rootSelection, course, parentNode.getCourseNode());
     fireEvent(ureq, Event.CHANGED_EVENT);
   } else {
     super.formInnerEvent(ureq, source, event);
   }
 }
  private MultipleSelectionElement initTreeRec(
      int level, VFSItem item, FormLayoutContainer layoutcont) {
    SelectNodeObject node = new SelectNodeObject(item, UUID.randomUUID().toString(), level);

    String[] singleKey = new String[] {node.getId()};
    String[] singleValue = new String[] {node.getName()};
    String[] css = new String[] {"b_with_small_icon_left " + node.getIconCssClass()};
    MultipleSelectionElement nodeSelection =
        uifactory.addCheckboxesVertical(
            "print.node.list." + nodeSelections.size(), layoutcont, singleKey, singleValue, css, 1);
    nodeSelection.setLabel("multi.sps.file", null);

    nodeSelection.setUserObject(node);
    nodeSelection.addActionListener(this, FormEvent.ONCLICK);
    nodeSelections.add(nodeSelection);
    identToSelectionMap.put(node.getId(), nodeSelection);
    layoutcont.add(nodeSelection.getComponent().getComponentName(), nodeSelection);

    if (item instanceof VFSContainer) {
      VFSContainer container = (VFSContainer) item;
      for (VFSItem subItem : container.getItems(new MultiSPVFSItemFilter())) {
        MultipleSelectionElement sel = initTreeRec(level + 1, subItem, layoutcont);
        node.getChildren().add(sel);
      }
    }

    return nodeSelection;
  }
  private void create(MultipleSelectionElement selection, ICourse course, CourseNode parentNode) {
    SelectNodeObject node = (SelectNodeObject) selection.getUserObject();
    if (selection.isMultiselect() && selection.isSelected(0)) {
      VFSItem item = node.getItem();

      CourseNode newNode = null;
      if (item instanceof VFSLeaf) {
        // create node
        newNode = createCourseNode(item, "sp");
        ModuleConfiguration moduleConfig = newNode.getModuleConfiguration();
        String path = getRelativePath(item);
        moduleConfig.set(SPEditController.CONFIG_KEY_FILE, path);
        moduleConfig.setBooleanEntry(SPEditController.CONFIG_KEY_ALLOW_RELATIVE_LINKS, true);
      } else if (item instanceof VFSContainer) {
        // add structure
        newNode = createCourseNode(item, "st");
      }

      int pos = -1;
      if (position >= 0 && selectedNode.getCourseNode().getIdent().equals(parentNode.getIdent())) {
        pos = position++;
      }

      if (pos < 0 || pos >= parentNode.getChildCount()) {
        course.getEditorTreeModel().addCourseNode(newNode, parentNode);
      } else {
        course.getEditorTreeModel().insertCourseNodeAt(newNode, parentNode, pos);
      }

      if (item instanceof VFSContainer) {
        parentNode = newNode;
      }
    }

    // recurse
    for (MultipleSelectionElement childElement : node.getChildren()) {
      create(childElement, course, parentNode);
    }
  }