package org.ovirt.engine.core.utils.linq;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class LinqUtils {

    /**
     * Replaces firstOrDefault() LINQ
     *
     * Returns first object from the collection that matches the predicate, or null if no such object was found
     */
    public static <T> T firstOrNull(Collection<T> collection, Predicate<T> predicate) {
        for (T t : collection) {
            if (predicate.eval(t))
                return t;
        }

        return null;
    }

    /**
     * Replaces first() LINQ
     *
     * Returns first object of collection or null if empty
     */
    public static <T> T first(Collection<T> collection) {
        Iterator<T> iterator = collection.iterator();
        if (iterator.hasNext())
            return iterator.next();
        else
            return null;
    }

    /**
     * Replaces LINQ's select()
     *
     * Returns a new list which contains all the objects from original collection with function applied to them.
     */
    public static <IN, OUT> List<OUT> transformToList(final Collection<IN> collection, final Function<IN, OUT> f) {
        LinkedList<OUT> list = new LinkedList<OUT>();
        for (IN in : collection) {
            list.add(f.eval(in));
        }
        return list;
    }

    /**
     * Returns a new set which contains transformed objects from the original collection
     */
    public static <IN, OUT> Set<OUT> transformToSet(final Collection<IN> collection, final Function<IN, OUT> f) {
        return new HashSet<OUT>() {
            {
                addAll(transformToList(collection, f));
            }
        };
    }

    /**
     * Replaces LINQ WHERE
     *
     * Returns list containing all objects from original collection that matches the predicate
     */
    public static <T> List<T> filter(Collection<T> collection, Predicate<T> predicate) {
        LinkedList<T> results = new LinkedList<T>();
        for (T t : collection) {
            if (predicate.eval(t))
                results.add(t);
        }

        return results;
    }

    /**
     * Replaces LINQ ToDictionary()
     *
     * Transforms given collection into map using mapper
     * <p>
     *
     * See DefaultMapper if you want to map keys only (similar to single parameter toDictionary())
     */
    public static <IN, KEY, VALUE> Map<KEY, VALUE> toMap(Collection<IN> collection, Mapper<IN, KEY, VALUE> mapper) {
        Map<KEY, VALUE> map = new LinkedHashMap<KEY, VALUE>();
        for (IN in : collection) {
            map.put(mapper.createKey(in), mapper.createValue(in));
        }

        return map;
    }

    public static <VALUE> VALUE aggregate(Collection<VALUE> values, Aggregator<VALUE> aggregator) {
        boolean first = true;
        VALUE aggregate = null;

        for (VALUE value : values) {
            if (first) {
                aggregate = value;
                first = false;
            } else {
                aggregate = aggregator.process(aggregate, value);
            }
        }
        return aggregate;
    }
}

@@ -69,34 +69,8 @@
 on;%0A
-import java.util.HashSet;%0A
 impo
@@ -201,30 +201,8 @@
 Map;
-%0Aimport java.util.Set;
 %0A%0Apu
@@ -1404,365 +1404,8 @@
  %7D%0A%0A
-    /**%0A     * Returns a new set which contains transformed objects from the original collection%0A     */%0A    public static %3CIN, OUT%3E Set%3COUT%3E transformToSet(final Collection%3CIN%3E collection, final Function%3CIN, OUT%3E f) %7B%0A        return new HashSet%3COUT%3E() %7B%0A            %7B%0A                addAll(transformToList(collection, f));%0A            %7D%0A        %7D;%0A    %7D%0A%0A
     

Remove unused LinqUtils.transformToSet