class CollectionFunctions {

    public static <T, R> boolean containsAll(Collection<T> containing, Collection<R> contained, BiFunction<T, R, Boolean> equalsFunction){
        if (containing == null && contained != null) {
            return false;
        } else if (contained == null) {
            return true;
        }
        boolean notContained =
                contained.stream().anyMatch(containedItem ->
                        containing.stream().noneMatch(containingItem -> equalsFunction.apply(containingItem, containedItem))
        );
        return !notContained;
    }

    private  CollectionFunctions();

}