public static <T, G> ItemGroup<T, G> create(final Iterable<T> items,
            @Nullable final Function<T, G> groupMapper,
            @Nullable final Function<G, G> groupGroupMapper,
            @Nullable final Comparator<Object> itemOrder,
            @Nullable final Predicate<ItemGroup<T, G>> pruner) {

        if (items == null) {
            return new ItemGroup<>(null);
        }

        //create base map
        final Map<G, ItemGroup<T, G>> groupMap = createBaseInfoMap(items, groupMapper, groupGroupMapper);
        for (Map.Entry<G, ItemGroup<T, G>> entry : groupMap.entrySet()) {
            entry.getValue().recalculateItemsAndGroups(itemOrder);
        }
        final ItemGroup<T, G> root = groupMap.get(null); // this will never be null

        //prune
        if (pruner != null) {
            pruneTree(root, itemOrder, pruner);
        }

        //level
        calculateLevel(root, 0);

        return root;
    }
Creates a new tree of grouped items and returns it

@param items items to group
@param groupMapper function to map an item to a group
@param groupGroupMapper function to map groups to other groups (thus creating a tree)
@param itemOrder function to order groups and items within each other
@param pruner checker for created groups if the group should be pruned from the tree
@return root of grouped tree
main/src/main/java/cgeo/geocaching/utils/ItemGroup.java