package com.github.dakusui.scriptunit.drivers;

import com.github.dakusui.scriptunit.annotations.ReflectivelyReferenced;
import com.github.dakusui.scriptunit.annotations.Scriptable;
import com.github.dakusui.scriptunit.model.Func;
import com.github.dakusui.scriptunit.model.Stage;
import com.google.common.collect.Iterables;

import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;

public class Collections {
  @ReflectivelyReferenced
  @Scriptable
  public <T extends Stage, E> Func<T, Integer> size(Func<T, Iterable<? extends E>> iterable) {
    return input -> Iterables.size(requireNonNull(iterable.apply(input)));
  }

  @ReflectivelyReferenced
  @Scriptable
  public <T extends Stage, E> Func<T, Iterable<? super E>> filter(Func<T, Iterable<? extends E>> iterable, Func<T, Func<? super E, Boolean>> predicate) {
    return i -> {
      //noinspection unchecked
      return (Iterable<? super E>) stream(requireNonNull(iterable.apply(i)).<E>spliterator(), false).filter(input -> requireNonNull(requireNonNull(predicate.apply(i)).apply(input))).collect(toList());
    };
  }

  @ReflectivelyReferenced
  @Scriptable
  public <T extends Stage, E> Func<T, Func<E, Boolean>> containedBy(Func<T, Iterable<E>> iterable) {
    return input -> {
      Iterable<E> collection = requireNonNull(iterable.apply(input));
      return (Func<E, Boolean>) entry -> Iterables.contains(collection, entry);
    };
  }
}

@@ -315,24 +315,61 @@
 Iterables;%0A%0A
+import java.util.stream.Collectors;%0A%0A
 import stati
@@ -408,58 +408,8 @@
 ll;%0A
-import static java.util.stream.Collectors.toList;%0A
 impo
@@ -458,16 +458,40 @@
 tream;%0A%0A
+@ReflectivelyReferenced%0A
 public c
@@ -1042,16 +1042,27 @@
 pply(i))
+%0A          
 .%3CE%3Espli
@@ -1078,16 +1078,27 @@
 , false)
+%0A          
 .filter(
@@ -1174,17 +1174,42 @@
 t)))
-.collect(
+%0A          .collect(Collectors.%3CE%3E
 toLi

Make type parameter more explicit not to get error from compiler.