class Pipe {

	public List<T> process(T elem) {
		Pipe<T> p = head;
		List<T> elems = new ArrayList<T>();
		p.fun.eval(elem, p.collector);
		while (p.getNext() != null) {
			// logger.info("pipe {}",p.fun.getClass());
			Iterator<T> iter = p.getOutput();
			if (iter == null) {
				logger.warn("iter is null");
			}
			elems.clear();
			while (iter.hasNext()) {
				T obj = iter.next();
				if (obj == null) {
					// FIXME understand why sometimes this is null, concurrency?
					logger.warn("iter returned null object");
				}
				if (obj != null) {
					elems.add(obj);
				}
			}
			// logger.info("output -> {}",elems);
			p.clearOutput();

			p = p.getNext();
			for (T t : elems) {
				p.fun.eval(t, p.collector);

			}
		}
		// logger.info("pipe {}",p.fun.getClass());
		// logger.info("f output -> {}",output);

		return getResults();
	}

	public  Pipe(Function<T> fun);
	public  Pipe(Pipe<T> previous, Function<T> fun);

}