/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ode.utils.stl;

import java.util.*;

/**
 * Useful extensions to the java.util.Collections class.
 */
public class CollectionsX {

    public static UnaryFunction<Map.Entry, Object> ufnMapEntry_getKey = new UnaryFunction<Map.Entry, Object>() {
        public Object apply(Map.Entry x) {
            return x.getKey();
        }
    };

    public static UnaryFunction<Map.Entry, Object> ufnMapEntry_getValue = new UnaryFunction<Map.Entry, Object>() {
        public Object apply(Map.Entry x) {
            return x.getValue();
        }
    };

    public static <T> void apply(Collection<T> coll, UnaryFunction<T, ?> f) {
        apply(coll.iterator(), f);
    }

    public static <T> void apply(Iterator<T> i, UnaryFunction<T, ?> f) {
        while (i.hasNext()) {
            f.apply(i.next());
        }
    }

    public static <T> void apply(Collection<T> coll, UnaryFunctionEx<T, ?> f) throws Exception {
        apply(coll.iterator(), f);
    }

    public static <T> void apply(Iterator<T> i, UnaryFunctionEx<T, ?> f) throws Exception {
        while (i.hasNext()) {
            f.apply(i.next());
        }
    }

    /**
     * Find an element in a colletion satisfying a condition. The condition is
     * given in the form of a unary function which returns a non-<code>false</code>
     * value when the condition is satisfied. The first object in the collection
     * matching the condition is returned.
     *
     * @param coll
     *            the collection to search through
     * @param f
     *            the test to apply to the collection elements
     *
     * @return the first object in the collection (coll) which, satisfies the
     *         condition (f)
     */
    public static <T> T find_if(Collection<T> coll, MemberOfFunction<? super T> f) {
        return find_if(coll.iterator(), f);
    }

    /**
     * Find an element in a collection satisfying a condition.
     *
     * @param i
     *            the iterator to iterate with
     * @param f
     *            the test to apply to the elements
     *
     * @return the first object enumerated by the iterator (i) which satisfies
     *         the condition (f)
     *
     * @see #find_if(java.util.Collection,
     *      org.apache.ode.utils.stl.MemberOfFunction)
     */
    public static <T> T find_if(Iterator<T> i, MemberOfFunction<? super T> f) {
        while (i.hasNext()) {
            T x = i.next();

            if (f.isMember(x)) {
                return x;
            }
        }

        return null;
    }

    public static <T> Collection<T> insert(Collection<T> coll, Enumeration<? extends T> e) {
        while (e.hasMoreElements()) {
            coll.add(e.nextElement());
        }
        return coll;
    }

    public static <T> Collection<T> insert(Collection<T> coll, Iterator<? extends T> i) {
        while (i.hasNext()) {
            coll.add(i.next());
        }
        return coll;
    }

    public static <T> Collection<T> insert(Collection<T> coll, Collection<? extends T> src) {
        return insert(coll, src.iterator());
    }

    /**
     * Remove elements from collection based on the results of specified unary
     * function. An element will be deleted if <code>f.isMember(element)
     * </code>
     * returns <code>true</code>. So: <em>coll' = { x : x el-of coll
     * AND f(x) == false }</em>
     *
     * @param coll
     *            the collection from which to remove elements
     * @param f
     *            the function to apply
     *
     * @return coll, for convenience
     */
    public static <T> Collection<T> remove_if(Collection<T> coll, MemberOfFunction<T> f) {
        Iterator<T> i = coll.iterator();

        while (i.hasNext()) {
            if (f.isMember(i.next())) {
                i.remove();
            }
        }

        return coll;
    }

    /**
     * Transform a collection with a unary function. Roughly speaking dest = {
     * f(a) : a el-of src }
     *
     * @param dest
     *            the empty (mutable) collection to transform into
     * @param src
     *            the collection to transform from
     * @param f
     *            the unary function to apply
     *
     * @return dest, for convenience
     */
    public static <C extends Collection<T>, T, V extends T, E> C transform(C dest, Collection<E> src,
            UnaryFunction<E, V> f) {
        Iterator<E> i = src.iterator();

        while (i.hasNext()) {
            dest.add(f.apply(i.next()));
        }

        return dest;
    }

    public static <C extends Collection<T>, T, V extends T, E> C transformEx(C dest, Collection<E> src,
            UnaryFunctionEx<E, V> f) throws Exception {
        Iterator<E> i = src.iterator();

        while (i.hasNext()) {
            dest.add(f.apply(i.next()));
        }

        return dest;
    }

    public static <C extends Collection<T>, T, V extends T, E> C transform(C dest, Enumeration<E> i,
            UnaryFunction<E, V> f) {
        while (i.hasMoreElements()) {
            dest.add(f.apply(i.nextElement()));
        }
        return dest;
    }

    public static <C extends Collection<T>, T, S extends T> C filter(C dest, Collection<S> source,
            MemberOfFunction<S> function) {
        return filter(dest, source.iterator(), function);
    }

    public static <C extends Collection<T>, T, S extends T> C filter(C dest, Iterator<S> source,
            MemberOfFunction<S> function) {
        while (source.hasNext()) {
            S next = source.next();
            if (function.isMember(next)) {
                dest.add(next);
            }
        }
        return dest;
    }

    public static <C extends Collection<T>, S, T extends S> C filter(C dest, Collection<S> src, Class<T> t) {
        return filter(dest, src.iterator(), t);
    }

    public static <C extends Collection<T>, S, T extends S> C filter(C newList, Iterator<S> iterator, Class<T> t) {
        while (iterator.hasNext()) {
            S next = iterator.next();
            if (t.isAssignableFrom(next.getClass())) {
                newList.add((T) next);
            }
        }
        return newList;
    }

    /**
     * Filter a collection by member class.
     *
     * @param src
     *            source collection
     * @param aClass
     *            requested class
     * @return collection consisting of the members of the input that are
     *         assignable to the given class
     */
    @SuppressWarnings("unchecked")
    public static <T> Collection<T> filter(Collection src, final Class<T> aClass) {
        return filter(new ArrayList<T>(src.size()), src.iterator(), aClass);
    }

}

@@ -7375,32 +7375,48 @@
 %7B%0A        return
+ (Collection%3CT%3E)
  filter(new Arra

Make java8 happy.