text:
<?php

	class ArmyGreenMenu extends btThemeMenu {

		public function __construct($sqlConnection) {

			parent::__construct("armygreen", $sqlConnection);

		}

		public function displayMenuCategory($loc="top") {

			$menuCatInfo = $this->menuCatObj->get_info();
			if($loc == "top") {

				if($menuCatInfo['headertype'] == "image") {
					echo "";
				}
				else {

					$menuCatInfo['headercode'] = $this->replaceKeywords($menuCatInfo['headercode']);
					echo $menuCatInfo['headercode'];
				}

			}
			else {
				echo "
";
			}

		}

		public function displayLoggedOut() {
			echo "
			<form action='".MAIN_ROOT."login.php' method='post' style='padding: 0px; margin: 0px'>

					USERNAME:

					<input type='text' class='textBox' name='user'>

					PASSWORD:

					<input type='password' class='textBox' name='pass'>

					REMEMBER ME: <input type='checkbox' value='1' name='rememberme'>

					<input type='submit' name='submit' value='Log In' class='submitButton'>

			</form>

			";

		}

		public function displayLoggedIn() {

			echo "

					Rank:

					".$this->data['memberRank']."

					Member Options:

					· My Account

					· data['memberInfo']['member_id']."'>View Profile

					· ".$this->data['pmLink']."

					· Sign Out

data['memberInfo']['username']."'>".$this->data['memberInfo']['username']."

			";

			if($this->data['pmCount'] > 1) {
				$addS = "s";
				$addA = " ";
			}
			else {
				$addS = "";
				$addA = " a ";
			}

			if($this->data['pmAlert'] == 1) {
				echo "

";
			}
			else {
				echo "

";
			}

		}

	}

?>


text:
package org.scalameter

import collection._
import util.parsing.combinator._

object Main {

  def main(args: Array[String]) {
    // initialize
    val configuration = Configuration.fromCommandLineArgs(args)
    run(configuration)
  }

  def run(configuration: Configuration) {
    // prepare initial context
    // identify test objects
    dyn.currentContext.withValue(Context.topLevel ++ configuration.context) {
      import configuration._
      // schedule benchmarks
      val testResults = for (benchname <- benches) yield {
        val bench = Class.forName(benchname).newInstance.asInstanceOf[DSL[_]]
        bench.executeTests()
      }

      if (testResults.exists(_ == false)) sys.exit(1)
    }
  }

  case class Configuration(benches: Seq[String], context: Context)

  object Configuration extends JavaTokenParsers {

    import Key._

    def fromCommandLineArgs(args: Array[String]) = {
      def arguments: Parser[Configuration] = rep(arg) ^^ {
        case configs => configs.foldLeft(Configuration(Nil, Context.empty)) {
          case (acc, x) => Configuration(acc.benches ++ x.benches, acc.context ++ x.context)
        }
      }
      def arg: Parser[Configuration] = benches | intsetting | resdir | scopefilt | flag
      def listOf(flagname: String, shorthand: String): Parser[Seq[String]] = "-" ~ (flagname | shorthand) ~ classnames ^^ {
        case _ ~ _ ~ classnames => classnames
      }
      def classnames: Parser[Seq[String]] = repsep(classname, ":")
      def classname: Parser[String] = repsep(ident, ".") ^^ { _.mkString(".") }
      def benches: Parser[Configuration] = listOf("benches", "b") ^^ {
        case names => Configuration(names, Context.empty)
      }
      def intsetting: Parser[Configuration] = "-" ~ ident ~ (decimalNumber | "true" | "false") ^^ {
        case _ ~ "Cminwarmups" ~ num => Configuration(Nil, Context(exec.minWarmupRuns -> num.toInt))
        case _ ~ "Cmaxwarmups" ~ num => Configuration(Nil, Context(exec.maxWarmupRuns -> num.toInt))
        case _ ~ "Cruns" ~ num => Configuration(Nil, Context(exec.benchRuns -> num.toInt))
        case _ ~ "Ccolors" ~ flag => Configuration(Nil, Context(reports.colors -> flag.toBoolean))
      }
      def path: Parser[String] = opt("/") ~ repsep("""[\w\d-\.]+""".r, "/") ~ opt("/") ^^ {
        case lead ~ ps ~ trail => lead.getOrElse("") + ps.mkString("/") + trail.getOrElse("")
      }
      def resdir: Parser[Configuration] = "-" ~ "CresultDir" ~ path ^^ {
        case _ ~ _ ~ s => Configuration(Nil, Context(reports.resultDir -> s))
      }
      def stringLit = "['\"]".r ~ rep("[^'']".r) ~ "['\"]".r ^^ {
        case _ ~ cs ~ _ => cs.mkString
      }
      def scopefilt: Parser[Configuration] = "-" ~ "CscopeFilter" ~ (stringLit | failure("scopeFilter must be followed by a single or double quoted string.")) ^^ {
        case _ ~ _ ~ s => Configuration(Nil, Context(scopeFilter -> s))
      }
      def flag: Parser[Configuration] = "-" ~ ("silent" | "verbose" | "preJDK7") ^^ {
        case _ ~ "verbose" => Configuration(Nil, Context(Key.verbose -> true))
        case _ ~ "silent" => Configuration(Nil, Context(Key.verbose -> false))
        case _ ~ "preJDK7" => Configuration(Nil, Context(Key.preJDK7 -> true))
      }

      parseAll(arguments, args.mkString(" ")) match {
        case Success(result, _) => result
        case Failure(msg, _) => sys.error("failed to parse args: " + msg)
        case Error(msg, _) => sys.error("error while parsing args: " + msg)
      }
    }
  }

}

redpajama_set_name: RedPajamaGithub


text:
package io.fundrequest.core.request.fund.dto;

import io.fundrequest.common.infrastructure.mapping.BaseMapper;
import io.fundrequest.core.infrastructure.SecurityContextService;
import io.fundrequest.core.request.fund.domain.Fund;
import io.fundrequest.core.token.dto.TokenValueDto;
import io.fundrequest.core.token.mapper.TokenValueDtoMapper;
import io.fundrequest.platform.profile.profile.ProfileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

@Component
public class FundToFundWithUserDtoMapper implements BaseMapper<Fund, FundWithUserDto> {
    private static final String FND_TOKEN_SYMBOL = "FND";

    private final ProfileService profileService;
    private final TokenValueDtoMapper tokenValueDtoMapper;
    private final SecurityContextService securityContextService;

    public FundToFundWithUserDtoMapper(final ProfileService profileService,
                                       final TokenValueDtoMapper tokenValueDtoMapper,
                                       final SecurityContextService securityContextService) {
        this.profileService = profileService;
        this.tokenValueDtoMapper = tokenValueDtoMapper;
        this.securityContextService = securityContextService;
    }

    @Override
    public FundWithUserDto map(final Fund fund) {
        final TokenValueDto tokenValueDto = tokenValueDtoMapper.map(fund.getTokenValue());
        final String funderNameOrAddress = StringUtils.isNotBlank(fund.getFunderUserId())
                                           ? profileService.getUserProfile(fund::getFunderUserId).getName()
                                           : fund.getFunderAddress();
        final boolean isFundedByLoggedInUser = isFundedByLoggedInUser(fund.getFunderUserId(), fund.getFunderAddress());
        return tokenValueDto == null ? null : FundWithUserDto.builder()
                                                             .funder(funderNameOrAddress)
                                                             .funderAddress(fund.getFunderAddress())
                                                             .fndFunds(getFndFunds(tokenValueDto))
                                                             .otherFunds(getOtherFunds(tokenValueDto))
                                                             .isLoggedInUser(isFundedByLoggedInUser)
                                                             .timestamp(fund.getTimestamp())
                                                             .isRefund(false)
                                                             .build();
    }

    private boolean isFundedByLoggedInUser(final String funderUserId, final String funderAddress) {
        return securityContextService.getLoggedInUserProfile()
                                     .filter(loggedInUserProfile -> loggedInUserProfile.getId().equals(funderUserId))
                                     .filter(loggedInUserProfile -> loggedInUserProfile.userOwnsAddress(funderAddress))
                                     .isPresent();
    }

    private TokenValueDto getFndFunds(final TokenValueDto tokenValueDto) {
        return hasFNDTokenSymbol(tokenValueDto) ? tokenValueDto : null;
    }

    private TokenValueDto getOtherFunds(final TokenValueDto tokenValueDto) {
        return !hasFNDTokenSymbol(tokenValueDto) ? tokenValueDto : null;
    }

    private boolean hasFNDTokenSymbol(TokenValueDto tokenValueDto) {
        return FND_TOKEN_SYMBOL.equalsIgnoreCase(tokenValueDto.getTokenSymbol());
    }

}


text:
string(REGEX MATCH ".*[.]a$" LIBCLANG_ISSTATIC "${libclangBasic}")
# if gcc 4.9 or higher is used, static libstdc++ is a good option
if (CMAKE_COMPILER_IS_GNUCC AND LIBCLANG_ISSTATIC)
  execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
  if (GCC_VERSION VERSION_GREATER 4.9 OR GCC_VERSION VERSION_EQUAL 4.9)
    execute_process(COMMAND ${CMAKE_C_COMPILER} -print-libgcc-file-name OUTPUT_VARIABLE GCC_LIB)
    get_filename_component(GCC_DIR "${GCC_LIB}" DIRECTORY)
    find_library(GCC_LIBSTDCPP libstdc++.a PATHS "${GCC_DIR}" NO_DEFAULT_PATH)
    if (GCC_LIBSTDCPP)
      message(STATUS "Using static-libstdc++")
      set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++")
    endif()
  endif()
endif()


text:
package org.apache.commons.collections4;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.collection.PredicatedCollection;
import org.apache.commons.collections4.collection.SynchronizedCollection;
import org.apache.commons.collections4.collection.TransformedCollection;
import org.apache.commons.collections4.collection.UnmodifiableBoundedCollection;
import org.apache.commons.collections4.collection.UnmodifiableCollection;
import org.apache.commons.collections4.functors.TruePredicate;
import org.apache.commons.collections4.iterators.CollatingIterator;
import org.apache.commons.collections4.iterators.PermutationIterator;

/**
 * Provides utility methods and decorators for {@link Collection} instances.
 *

 * Various utility methods might put the input objects into a Set/Map/Bag. In case
 * the input objects override {@link Object#equals(Object)}, it is mandatory that
 * the general contract of the {@link Object#hashCode()} method is maintained.
 *

 * NOTE: From 4.0, method parameters will take {@link Iterable} objects when possible.
 *
 * @since 1.0
 * @version $Id$
 */
public class CollectionUtils {

    /**
     * Helper class to easily access cardinality properties of two collections.
     * @param <O>  the element type
     */
    private static class CardinalityHelper<O> {

        /** Contains the cardinality for each object in collection A. */
        final Map<O, Integer> cardinalityA;

        /** Contains the cardinality for each object in collection B. */
        final Map<O, Integer> cardinalityB;

        /**
         * Create a new CardinalityHelper for two collections.
         * @param a  the first collection
         * @param b  the second collection
         */
        public CardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) {
            cardinalityA = CollectionUtils.<O>getCardinalityMap(a);
            cardinalityB = CollectionUtils.<O>getCardinalityMap(b);
        }

        /**
         * Returns the maximum frequency of an object.
         * @param obj  the object
         * @return the maximum frequency of the object
         */
        public final int max(final Object obj) {
            return Math.max(freqA(obj), freqB(obj));
        }

        /**
         * Returns the minimum frequency of an object.
         * @param obj  the object
         * @return the minimum frequency of the object
         */
        public final int min(final Object obj) {
            return Math.min(freqA(obj), freqB(obj));
        }

        /**
         * Returns the frequency of this object in collection A.
         * @param obj  the object
         * @return the frequency of the object in collection A
         */
        public int freqA(final Object obj) {
            return getFreq(obj, cardinalityA);
        }

        /**
         * Returns the frequency of this object in collection B.
         * @param obj  the object
         * @return the frequency of the object in collection B
         */
        public int freqB(final Object obj) {
            return getFreq(obj, cardinalityB);
        }

        private final int getFreq(final Object obj, final Map<?, Integer> freqMap) {
            final Integer count = freqMap.get(obj);
            if (count != null) {
                return count.intValue();
            }
            return 0;
        }
    }

    /**
     * Helper class for set-related operations, e.g. union, subtract, intersection.
     * @param <O>  the element type
     */
    private static class SetOperationCardinalityHelper<O> extends CardinalityHelper<O> implements Iterable<O> {

        /** Contains the unique elements of the two collections. */
        private final Set<O> elements;

        /** Output collection. */
        private final List<O> newList;

        /**
         * Create a new set operation helper from the two collections.
         * @param a  the first collection
         * @param b  the second collection
         */
        public SetOperationCardinalityHelper(final Iterable<? extends O> a, final Iterable<? extends O> b) {
            super(a, b);
            elements = new HashSet<O>();
            addAll(elements, a);
            addAll(elements, b);
            // the resulting list must contain at least each unique element, but may grow
            newList = new ArrayList<O>(elements.size());
        }

        public Iterator<O> iterator() {
            return elements.iterator();
        }

        /**
         * Add the object {@code count} times to the result collection.
         * @param obj  the object to add
         * @param count  the count
         */
        public void setCardinality(final O obj, final int count) {
            for (int i = 0; i < count; i++) {
                newList.add(obj);
            }
        }

        /**
         * Returns the resulting collection.
         * @return the result
         */
        public Collection<O> list() {
            return newList;
        }

    }

    /**
     * An empty unmodifiable collection.
     * The JDK provides empty Set and List implementations which could be used for
     * this purpose. However they could be cast to Set or List which might be
     * undesirable. This implementation only implements Collection.
     */
    @SuppressWarnings("rawtypes") // we deliberately use the raw type here
    public static final Collection EMPTY_COLLECTION =
        UnmodifiableCollection.unmodifiableCollection(new ArrayList<Object>());

    /**
     * CollectionUtils should not normally be instantiated.
     */
    private CollectionUtils() {}

    /**
     * Returns the immutable EMPTY_COLLECTION with generic type safety.
     *
     * @see #EMPTY_COLLECTION
     * @since 4.0
     * @param <T> the element type
     * @return immutable empty collection
     */
    @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
    public static <T> Collection<T> emptyCollection() {
        return EMPTY_COLLECTION;
    }

    /**
     * Returns an immutable empty collection if the argument is null,
     * or the argument itself otherwise.
     *
     * @param <T> the element type
     * @param collection the collection, possibly null
     * @return an empty collection if the argument is null
     */
    @SuppressWarnings("unchecked") // OK, empty collection is compatible with any type
    public static <T> Collection<T> emptyIfNull(final Collection<T> collection) {
        return collection == null ? EMPTY_COLLECTION : collection;
    }

    /**
     * Returns a {@link Collection} containing the union of the given
     * {@link Iterable}s.
     *

     * The cardinality of each element in the returned {@link Collection} will
     * be equal to the maximum of the cardinality of that element in the two
     * given {@link Iterable}s.
     *
     * @param a the first collection, must not be null
     * @param b the second collection, must not be null
     * @param <O> the generic type that is able to represent the types contained
     *        in both input collections.
     * @return the union of the two collections
     * @see Collection#addAll
     */
    public static <O> Collection<O> union(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b);
        for (final O obj : helper) {
            helper.setCardinality(obj, helper.max(obj));
        }
        return helper.list();
    }

    /**
     * Returns a {@link Collection} containing the intersection of the given
     * {@link Iterable}s.
     *

     * The cardinality of each element in the returned {@link Collection} will
     * be equal to the minimum of the cardinality of that element in the two
     * given {@link Iterable}s.
     *
     * @param a the first collection, must not be null
     * @param b the second collection, must not be null
     * @param <O> the generic type that is able to represent the types contained
     *        in both input collections.
     * @return the intersection of the two collections
     * @see Collection#retainAll
     * @see #containsAny
     */
    public static <O> Collection<O> intersection(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b);
        for (final O obj : helper) {
            helper.setCardinality(obj, helper.min(obj));
        }
        return helper.list();
    }

    /**
     * Returns a {@link Collection} containing the exclusive disjunction
     * (symmetric difference) of the given {@link Iterable}s.
     *

     * The cardinality of each element e in the returned
     * {@link Collection} will be equal to
     * <tt>max(cardinality(e,a),cardinality(e,b)) - min(cardinality(e,a),
     * cardinality(e,b))</tt>.
     *

     * This is equivalent to
     * {@code {@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)})}
     * or
     * {@code {@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)})}.

     * @param a the first collection, must not be null
     * @param b the second collection, must not be null
     * @param <O> the generic type that is able to represent the types contained
     *        in both input collections.
     * @return the symmetric difference of the two collections
     */
    public static <O> Collection<O> disjunction(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        final SetOperationCardinalityHelper<O> helper = new SetOperationCardinalityHelper<O>(a, b);
        for (final O obj : helper) {
            helper.setCardinality(obj, helper.max(obj) - helper.min(obj));
        }
        return helper.list();
    }

    /**
     * Returns a new {@link Collection} containing {@code a - b}.
     * The cardinality of each element e in the returned {@link Collection}
     * will be the cardinality of e in a minus the cardinality
     * of e in b, or zero, whichever is greater.
     *
     * @param a  the collection to subtract from, must not be null
     * @param b  the collection to subtract, must not be null
     * @param <O> the generic type that is able to represent the types contained
     *        in both input collections.
     * @return a new collection with the results
     * @see Collection#removeAll
     */
    public static <O> Collection<O> subtract(final Iterable<? extends O> a, final Iterable<? extends O> b) {
        final Predicate<O> p = TruePredicate.truePredicate();
        return subtract(a, b, p);
    }

    /**
     * Returns a new {@link Collection} containing a minus a subset of
     * b.  Only the elements of b that satisfy the predicate
     * condition, p are subtracted from a.
     *
     *
The cardinality of each element e in the returned {@link Collection}
     * that satisfies the predicate condition will be the cardinality of e in a
     * minus the cardinality of e in b, or zero, whichever is greater.

     *
The cardinality of each element e in the returned {@link Collection} that does not
     * satisfy the predicate condition will be equal to the cardinality of e in a.

     *
     * @param a  the collection to subtract from, must not be null
     * @param b  the collection to subtract, must not be null
     * @param p  the condition used to determine which elements of b are
     *        subtracted.
     * @param <O> the generic type that is able to represent the types contained
     *        in both input collections.
     * @return a new collection with the results
     * @since 4.0
     * @see Collection#removeAll
     */
    public static <O> Collection<O> subtract(final Iterable<? extends O> a,
                                             final Iterable<? extends O> b,
                                             final Predicate<O> p) {
        final ArrayList<O> list = new ArrayList<O>();
        final HashBag<O> bag = new HashBag<O>();
        for (final O element : b) {
            if (p.evaluate(element)) {
                bag.add(element);
            }
        }
        for (final O element : a) {
            if (!bag.remove(element, 1)) {
                list.add(element);
            }
        }
        return list;
    }

    /**
     * Returns true iff all elements of {@code coll2} are also contained
     * in {@code coll1}. The cardinality of values in {@code coll2} is not taken into account,
     * which is the same behavior as {@link Collection#containsAll(Collection)}.
     *

     * In other words, this method returns true iff the
     * {@link #intersection} of coll1 and coll2 has the same cardinality as
     * the set of unique values from {@code coll2}. In case {@code coll2} is empty, {@code true}
     * will be returned.
     *

     * This method is intended as a replacement for {@link Collection#containsAll(Collection)}
     * with a guaranteed runtime complexity of {@code O(n + m)}. Depending on the type of
     * {@link Collection} provided, this method will be much faster than calling
     * {@link Collection#containsAll(Collection)} instead, though this will come at the
     * cost of an additional space complexity O(n).
     *
     * @param coll1  the first collection, must not be null
     * @param coll2  the second collection, must not be null
     * @return true iff the intersection of the collections has the same cardinality
     *   as the set of unique elements from the second collection
     * @since 4.0
     */
    public static boolean containsAll(final Collection<?> coll1, final Collection<?> coll2) {
        if (coll2.isEmpty()) {
            return true;
        } else {
            final Iterator<?> it = coll1.iterator();
            final Set<Object> elementsAlreadySeen = new HashSet<Object>();
            for (final Object nextElement : coll2) {
                if (elementsAlreadySeen.contains(nextElement)) {
                    continue;
                }

                boolean foundCurrentElement = false;
                while (it.hasNext()) {
                    final Object p = it.next();
                    elementsAlreadySeen.add(p);
                    if (nextElement == null ? p == null : nextElement.equals(p)) {
                        foundCurrentElement = true;
                        break;
                    }
                }

                if (foundCurrentElement) {
                    continue;
                } else {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * Returns true iff at least one element is in both collections.
     *

     * In other words, this method returns true iff the
     * {@link #intersection} of coll1 and coll2 is not empty.
     *
     * @param coll1  the first collection, must not be null
     * @param coll2  the second collection, must not be null
     * @return true iff the intersection of the collections is non-empty
     * @since 2.1
     * @see #intersection
     */
    public static boolean containsAny(final Collection<?> coll1, final Collection<?> coll2) {
        if (coll1.size() < coll2.size()) {
            for (final Object aColl1 : coll1) {
                if (coll2.contains(aColl1)) {
                    return true;
                }
            }
        } else {
            for (final Object aColl2 : coll2) {
                if (coll1.contains(aColl2)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Returns a {@link Map} mapping each unique element in the given
     * {@link Collection} to an {@link Integer} representing the number
     * of occurrences of that element in the {@link Collection}.
     *

     * Only those elements present in the collection will appear as
     * keys in the map.
     *
     * @param <O>  the type of object in the returned {@link Map}. This is a super type of .
     * @param coll  the collection to get the cardinality map for, must not be null
     * @return the populated cardinality map
     */
    public static <O> Map<O, Integer> getCardinalityMap(final Iterable<? extends O> coll) {
        final Map<O, Integer> count = new HashMap<O, Integer>();
        for (final O obj : coll) {
            final Integer c = count.get(obj);
            if (c == null) {
                count.put(obj, Integer.valueOf(1));
            } else {
                count.put(obj, Integer.valueOf(c.intValue() + 1));
            }
        }
        return count;
    }

    /**
     * Returns {@code true} iff a is a sub-collection of b,
     * that is, iff the cardinality of e in a is less than or
     * equal to the cardinality of e in b, for each element e
     * in a.
     *
     * @param a the first (sub?) collection, must not be null
     * @param b the second (super?) collection, must not be null
     * @return true iff a is a sub-collection of b
     * @see #isProperSubCollection
     * @see Collection#containsAll
     */
    public static boolean isSubCollection(final Collection<?> a, final Collection<?> b) {
        final CardinalityHelper<Object> helper = new CardinalityHelper<Object>(a, b);
        for (final Object obj : a) {
            if (helper.freqA(obj) > helper.freqB(obj)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns {@code true} iff a is a proper sub-collection of b,
     * that is, iff the cardinality of e in a is less
     * than or equal to the cardinality of e in b,
     * for each element e in a, and there is at least one
     * element f such that the cardinality of f in b
     * is strictly greater than the cardinality of f in a.
     *

     * The implementation assumes
     *

     *
a.size() and b.size() represent the
     *    total cardinality of a and b, resp.

     *
a.size() < Integer.MAXVALUE

     *

     *
     * @param a  the first (sub?) collection, must not be null
     * @param b  the second (super?) collection, must not be null
     * @return true iff a is a proper sub-collection of b
     * @see #isSubCollection
     * @see Collection#containsAll
     */
    public static boolean isProperSubCollection(final Collection<?> a, final Collection<?> b) {
        return a.size() < b.size() && CollectionUtils.isSubCollection(a, b);
    }

    /**
     * Returns {@code true} iff the given {@link Collection}s contain
     * exactly the same elements with exactly the same cardinalities.
     *

     * That is, iff the cardinality of e in a is
     * equal to the cardinality of e in b,
     * for each element e in a or b.
     *
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @return true iff the collections contain the same elements with the same cardinalities.
     */
    public static boolean isEqualCollection(final Collection<?> a, final Collection<?> b) {
        if(a.size() != b.size()) {
            return false;
        }
        final CardinalityHelper<Object> helper = new CardinalityHelper<Object>(a, b);
        if(helper.cardinalityA.size() != helper.cardinalityB.size()) {
            return false;
        }
        for( final Object obj : helper.cardinalityA.keySet()) {
            if(helper.freqA(obj) != helper.freqB(obj)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns {@code true} iff the given {@link Collection}s contain
     * exactly the same elements with exactly the same cardinalities.
     *

     * That is, iff the cardinality of e in a is
     * equal to the cardinality of e in b,
     * for each element e in a or b.
     *

     * Note: from version 4.1 onwards this method requires the input
     * collections and equator to be of compatible type (using bounded wildcards).
     * Providing incompatible arguments (e.g. by casting to their rawtypes)
     * will result in a {@code ClassCastException} thrown at runtime.
     *
     * @param <E>  the element type
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @param equator  the Equator used for testing equality
     * @return true iff the collections contain the same elements with the same cardinalities.
     * @throws IllegalArgumentException if the equator is null
     * @since 4.0
     */
    public static <E> boolean isEqualCollection(final Collection<? extends E> a,
                                                final Collection<? extends E> b,
                                                final Equator<? super E> equator) {
        if (equator == null) {
            throw new IllegalArgumentException("equator may not be null");
        }

        if(a.size() != b.size()) {
            return false;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        final Transformer<E, ?> transformer = new Transformer() {
            public EquatorWrapper<?> transform(final Object input) {
                return new EquatorWrapper(equator, input);
            }
        };

        return isEqualCollection(collect(a, transformer), collect(b, transformer));
    }

    /**
     * Wraps another object and uses the provided Equator to implement
     * {@link #equals(Object)} and {@link #hashCode()}.
     *

     * This class can be used to store objects into a Map.
     *
     * @param <O>  the element type
     * @since 4.0
     */
    private static class EquatorWrapper<O> {
        private final Equator<? super O> equator;
        private final O object;

        public EquatorWrapper(final Equator<? super O> equator, final O object) {
            this.equator = equator;
            this.object = object;
        }

        public O getObject() {
            return object;
        }

        @Override
        public boolean equals(final Object obj) {
            if (!(obj instanceof EquatorWrapper)) {
                return false;
            }
            @SuppressWarnings("unchecked")
            final EquatorWrapper<O> otherObj = (EquatorWrapper<O>) obj;
            return equator.equate(object, otherObj.getObject());
        }

        @Override
        public int hashCode() {
            return equator.hash(object);
        }
    }

    /**
     * Returns the number of occurrences of obj in coll.
     *
     * @param obj the object to find the cardinality of
     * @param coll the {@link Iterable} to search
     * @param <O> the type of object that the {@link Iterable} may contain.
     * @return the the number of occurrences of obj in coll
     */
    public static <O> int cardinality(final O obj, final Iterable<? super O> coll) {
        if (coll instanceof Set<?>) {
            return ((Set<? super O>) coll).contains(obj) ? 1 : 0;
        }
        if (coll instanceof Bag<?>) {
            return ((Bag<? super O>) coll).getCount(obj);
        }
        int count = 0;
        if (obj == null) {
            for (final Object element : coll) {
                if (element == null) {
                    count++;
                }
            }
        } else {
            for (final Object element : coll) {
                if (obj.equals(element)) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * Finds the first element in the given collection which matches the given predicate.
     *

     * If the input collection or predicate is null, or no element of the collection
     * matches the predicate, null is returned.
     *
     * @param <T>  the type of object the {@link Iterable} contains
     * @param collection  the collection to search, may be null
     * @param predicate  the predicate to use, may be null
     * @return the first element of the collection which matches the predicate or null if none could be found
     */
    public static <T> T find(final Iterable<T> collection, final Predicate<? super T> predicate) {
        if (collection != null && predicate != null) {
            for (final T item : collection) {
                if (predicate.evaluate(item)) {
                    return item;
                }
            }
        }
        return null;
    }

    /**
     * Executes the given closure on each element in the collection.
     *

     * If the input collection or closure is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Iterable} contains
     * @param <C>  the closure type
     * @param collection  the collection to get the input from, may be null
     * @param closure  the closure to perform, may be null
     * @return closure
     */
    public static <T, C extends Closure<? super T>> C forAllDo(final Iterable<T> collection, final C closure) {
        if (collection != null && closure != null) {
            for (final T element : collection) {
                closure.execute(element);
            }
        }
        return closure;
    }

    /**
     * Executes the given closure on each element in the collection.
     *

     * If the input collection or closure is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Iterator} contains
     * @param <C>  the closure type
     * @param iterator  the iterator to get the input from, may be null
     * @param closure  the closure to perform, may be null
     * @return closure
     * @since 4.0
     */
    public static <T, C extends Closure<? super T>> C forAllDo(final Iterator<T> iterator, final C closure) {
        if (iterator != null && closure != null) {
            while (iterator.hasNext()) {
                closure.execute(iterator.next());
            }
        }
        return closure;
    }

    /**
     * Executes the given closure on each but the last element in the collection.
     *

     * If the input collection or closure is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Iterable} contains
     * @param <C>  the closure type
     * @param collection  the collection to get the input from, may be null
     * @param closure  the closure to perform, may be null
     * @return the last element in the collection, or null if either collection or closure is null
     * @since 4.0
     */
    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterable<T> collection,
                                                                      final C closure) {
        return collection != null && closure != null ? forAllButLastDo(collection.iterator(), closure) : null;
    }

    /**
     * Executes the given closure on each but the last element in the collection.
     *

     * If the input collection or closure is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Collection} contains
     * @param <C>  the closure type
     * @param iterator  the iterator to get the input from, may be null
     * @param closure  the closure to perform, may be null
     * @return the last element in the collection, or null if either iterator or closure is null
     * @since 4.0
     */
    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterator<T> iterator, final C closure) {
        if (iterator != null && closure != null) {
            while (iterator.hasNext()) {
                final T element = iterator.next();
                if (iterator.hasNext()) {
                    closure.execute(element);
                } else {
                    return element;
                }
            }
        }
        return null;
    }

    /**
     * Filter the collection by applying a Predicate to each element. If the
     * predicate returns false, remove the element.
     *

     * If the input collection or predicate is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Iterable} contains
     * @param collection  the collection to get the input from, may be null
     * @param predicate  the predicate to use as a filter, may be null
     * @return true if the collection is modified by this call, false otherwise.
     */
    public static <T> boolean filter(final Iterable<T> collection, final Predicate<? super T> predicate) {
        boolean result = false;
        if (collection != null && predicate != null) {
            for (final Iterator<T> it = collection.iterator(); it.hasNext();) {
                if (!predicate.evaluate(it.next())) {
                    it.remove();
                    result = true;
                }
            }
        }
        return result;
    }

    /**
     * Filter the collection by applying a Predicate to each element. If the
     * predicate returns true, remove the element.
     *

     * This is equivalent to
filter(collection, PredicateUtils.notPredicate(predicate))

     * if predicate is != null.
     *

     * If the input collection or predicate is null, there is no change made.
     *
     * @param <T>  the type of object the {@link Iterable} contains
     * @param collection  the collection to get the input from, may be null
     * @param predicate  the predicate to use as a filter, may be null
     * @return true if the collection is modified by this call, false otherwise.
     */
    public static <T> boolean filterInverse(final Iterable<T> collection, final Predicate<? super T> predicate) {
        return filter(collection, predicate == null ? null : PredicateUtils.notPredicate(predicate));
    }

    /**
     * Transform the collection by applying a Transformer to each element.
     *

     * If the input collection or transformer is null, there is no change made.
     *

     * This routine is best for Lists, for which set() is used to do the
     * transformations "in place." For other Collections, clear() and addAll()
     * are used to replace elements.
     *

     * If the input collection controls its input, such as a Set, and the
     * Transformer creates duplicates (or are otherwise invalid), the collection
     * may reduce in size due to calling this method.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the {@link Collection} to get the input from, may be null
     * @param transformer  the transformer to perform, may be null
     */
    public static <C> void transform(final Collection<C> collection,
            final Transformer<? super C, ? extends C> transformer) {

        if (collection != null && transformer != null) {
            if (collection instanceof List<?>) {
                final List<C> list = (List<C>) collection;
                for (final ListIterator<C> it = list.listIterator(); it.hasNext();) {
                    it.set(transformer.transform(it.next()));
                }
            } else {
                final Collection<C> resultCollection = collect(collection, transformer);
                collection.clear();
                collection.addAll(resultCollection);
            }
        }
    }

    /**
     * Counts the number of elements in the input collection that match the
     * predicate.
     *

     * A null collection or predicate matches no elements.
     *
     * @param <C>  the type of object the {@link Iterable} contains
     * @param input  the {@link Iterable} to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @return the number of matches for the predicate in the collection
     */
    public static <C> int countMatches(final Iterable<C> input, final Predicate<? super C> predicate) {
        int count = 0;
        if (input != null && predicate != null) {
            for (final C o : input) {
                if (predicate.evaluate(o)) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * Answers true if a predicate is true for at least one element of a
     * collection.
     *

     * A null collection or predicate returns false.
     *
     * @param <C>  the type of object the {@link Iterable} contains
     * @param input  the {@link Iterable} to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @return true if at least one element of the collection matches the predicate
     */
    public static <C> boolean exists(final Iterable<C> input, final Predicate<? super C> predicate) {
        if (input != null && predicate != null) {
            for (final C o : input) {
                if (predicate.evaluate(o)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Answers true if a predicate is true for every element of a
     * collection.
     *

     * A null predicate returns false.

     * A null or empty collection returns true.
     *
     * @param <C>  the type of object the {@link Iterable} contains
     * @param input  the {@link Iterable} to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @return true if every element of the collection matches the predicate or if the
     * collection is empty, false otherwise
     * @since 4.0
     */
    public static <C> boolean matchesAll(final Iterable<C> input, final Predicate<? super C> predicate) {
        if (predicate == null) {
            return false;
        }

        if (input != null) {
            for (final C o : input) {
                if (!predicate.evaluate(o)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Selects all elements from input collection which match the given
     * predicate into an output collection.
     *

     * A null predicate matches no elements.
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param inputCollection  the collection to get the input from, may not be null
     * @param predicate  the predicate to use, may be null
     * @return the elements matching the predicate (new list)
     * @throws NullPointerException if the input collection is null
     */
    public static <O> Collection<O> select(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate) {
        final Collection<O> answer = inputCollection instanceof Collection<?> ?
                new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>();
        return select(inputCollection, predicate, answer);
    }

    /**
     * Selects all elements from input collection which match the given
     * predicate and adds them to outputCollection.
     *

     * If the input collection or predicate is null, there is no change to the
     * output collection.
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param <R>  the type of the output {@link Collection}
     * @param inputCollection  the collection to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @param outputCollection  the collection to output into, may not be null if the inputCollection
     *   and predicate or not null
     * @return the outputCollection
     */
    public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate, final R outputCollection) {

        if (inputCollection != null && predicate != null) {
            for (final O item : inputCollection) {
                if (predicate.evaluate(item)) {
                    outputCollection.add(item);
                }
            }
        }
        return outputCollection;
    }

    /**
     * Selects all elements from inputCollection which don't match the given
     * predicate into an output collection.
     *

     * If the input predicate is null, the result is an empty
     * list.
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param inputCollection  the collection to get the input from, may not be null
     * @param predicate  the predicate to use, may be null
     * @return the elements not matching the predicate (new list)
     * @throws NullPointerException if the input collection is null
     */
    public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate) {
        final Collection<O> answer = inputCollection instanceof Collection<?> ?
                new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>();
        return selectRejected(inputCollection, predicate, answer);
    }

    /**
     * Selects all elements from inputCollection which don't match the given
     * predicate and adds them to outputCollection.
     *

     * If the input predicate is null, no elements are added to
     * outputCollection.
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param <R>  the type of the output {@link Collection}
     * @param inputCollection  the collection to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @param outputCollection  the collection to output into, may not be null if the inputCollection
     *   and predicate or not null
     * @return outputCollection
     */
    public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate, final R outputCollection) {

        if (inputCollection != null && predicate != null) {
            for (final O item : inputCollection) {
                if (!predicate.evaluate(item)) {
                    outputCollection.add(item);
                }
            }
        }
        return outputCollection;
    }

    /**
     * Partitions all elements from inputCollection into separate output collections,
     * based on the evaluation of the given predicate.
     *

     * For each predicate, the result will contain a list holding all elements of the
     * input collection matching the predicate. The last list will hold all elements
     * which didn't match any predicate:
     *

     *  [C1, R] = partition(I, P1) with
     *  I = input collection
     *  P1 = first predicate
     *  C1 = collection of elements matching P1
     *  R = collection of elements rejected by all predicates
     *

     *

     * If the input collection is null, an empty list will be returned.
     * If the input predicate is null, all elements of the input collection
     * will be added to the rejected collection.
     *

     * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x < 3]
     * will result in the following output: [[1, 2], [3, 4, 5]].
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param inputCollection  the collection to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @return a list containing the output collections
     * @since 4.1
     */
    public static <O> List<List<O>> partition(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate) {

        @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
        final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
        @SuppressWarnings("unchecked") // safe
        final Predicate<? super O>[] predicates = new Predicate[] { predicate };
        return partition(inputCollection, factory, predicates);
    }

    /**
     * Partitions all elements from inputCollection into an output and rejected collection,
     * based on the evaluation of the given predicate.
     *

     * Elements matching the predicate are added to the outputCollection,
     * all other elements are added to the rejectedCollection.
     *

     * If the input predicate is null, no elements are added to
     * outputCollection or rejectedCollection.
     *

     * Note: calling the method is equivalent to the following code snippet:
     *

     *   select(inputCollection, predicate, outputCollection);
     *   selectRejected(inputCollection, predicate, rejectedCollection);
     *

     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param <R>  the type of the output {@link Collection}
     * @param inputCollection  the collection to get the input from, may be null
     * @param predicate  the predicate to use, may be null
     * @param outputCollection  the collection to output selected elements into, may not be null if the
     *   inputCollection and predicate are not null
     * @param rejectedCollection  the collection to output rejected elements into, may not be null if the
     *   inputCollection or predicate are not null
     * @since 4.1
     */
    public static <O, R extends Collection<? super O>> void partition(final Iterable<? extends O> inputCollection,
            final Predicate<? super O> predicate, R outputCollection, R rejectedCollection) {

        if (inputCollection != null && predicate != null) {
            for (final O element : inputCollection) {
                if (predicate.evaluate(element)) {
                    outputCollection.add(element);
                } else {
                    rejectedCollection.add(element);
                }
            }
        }
    }

    /**
     * Partitions all elements from inputCollection into separate output collections,
     * based on the evaluation of the given predicates.
     *

     * For each predicate, the result will contain a list holding all elements of the
     * input collection matching the predicate. The last list will hold all elements
     * which didn't match any predicate:
     *

     *  [C1, C2, R] = partition(I, P1, P2) with
     *  I = input collection
     *  P1 = first predicate
     *  P2 = second predicate
     *  C1 = collection of elements matching P1
     *  C2 = collection of elements matching P2
     *  R = collection of elements rejected by all predicates
     *

     *

     * Note: elements are only added to the output collection of the first matching
     * predicate, determined by the order of arguments.
     *

     * If the input collection is null, an empty list will be returned.
     * If the input predicate is null, all elements of the input collection
     * will be added to the rejected collection.
     *

     * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3]
     * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]].
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param inputCollection  the collection to get the input from, may be null
     * @param predicates  the predicates to use, may be null
     * @return a list containing the output collections
     * @since 4.1
     */
    public static <O> List<List<O>> partition(final Iterable<? extends O> inputCollection,
            final Predicate<? super O>... predicates) {

        @SuppressWarnings({ "unchecked", "rawtypes" }) // safe
        final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class);
        return partition(inputCollection, factory, predicates);
    }

    /**
     * Partitions all elements from inputCollection into separate output collections,
     * based on the evaluation of the given predicates.
     *

     * For each predicate, the returned list will contain a collection holding
     * all elements of the input collection matching the predicate. The last collection
     * contained in the list will hold all elements which didn't match any predicate:
     *

     *  [C1, C2, R] = partition(I, P1, P2) with
     *  I = input collection
     *  P1 = first predicate
     *  P2 = second predicate
     *  C1 = collection of elements matching P1
     *  C2 = collection of elements matching P2
     *  R = collection of elements rejected by all predicates
     *

     *

     * Note: elements are only added to the output collection of the first matching
     * predicate, determined by the order of arguments.
     *

     * If the input collection is null, an empty list will be returned.
     * If no predicates have been provided, all elements of the input collection
     * will be added to the rejected collection.
     *

     * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3]
     * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]].
     *
     * @param <O>  the type of object the {@link Iterable} contains
     * @param <R>  the type of the output {@link Collection}
     * @param inputCollection  the collection to get the input from, may be null
     * @param partitionFactory  the factory used to create the output collections
     * @param predicates  the predicates to use, may be empty
     * @return a list containing the output collections
     * @since 4.1
     */
    public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> inputCollection,
            final Factory<R> partitionFactory, final Predicate<? super O>... predicates) {

        if (inputCollection == null) {
            return Collections.emptyList();
        }

        if (predicates == null || predicates.length < 1) {
            // return the entire input collection as a single partition
            final R singlePartition = partitionFactory.create();
            select(inputCollection, PredicateUtils.truePredicate(), singlePartition);
            return Collections.singletonList(singlePartition);
        }

        // create the empty partitions
        final int numberOfPredicates = predicates.length;
        final int numberOfPartitions = numberOfPredicates + 1;
        final List<R> partitions = new ArrayList<R>(numberOfPartitions);
        for (int i = 0; i < numberOfPartitions; ++i) {
            partitions.add(partitionFactory.create());
        }

        // for each element in inputCollection:
        // find the first predicate that evaluates to true.
        // if there is a predicate, add the element to the corresponding partition.
        // if there is no predicate, add it to the last, catch-all partition.
        for (final O element : inputCollection) {
            boolean elementAssigned = false;
            for (int i = 0; i < numberOfPredicates; ++i) {
                if (predicates[i].evaluate(element)) {
                    partitions.get(i).add(element);
                    elementAssigned = true;
                    break;
                }
            }

            if (!elementAssigned) {
                // no predicates evaluated to true
                // add element to last partition
                partitions.get(numberOfPredicates).add(element);
            }
        }

        return partitions;
    }

    /**
     * Returns a new Collection consisting of the elements of inputCollection
     * transformed by the given transformer.
     *

     * If the input transformer is null, the result is an empty list.
     *
     * @param  the type of object in the input collection
     * @param <O> the type of object in the output collection
     * @param inputCollection  the collection to get the input from, may not be null
     * @param transformer  the transformer to use, may be null
     * @return the transformed result (new list)
     * @throws NullPointerException if the input collection is null
     */
    public static  Collection<O> collect(final Iterable inputCollection,
            final Transformer<? super I, ? extends O> transformer) {
        final Collection<O> answer = inputCollection instanceof Collection<?> ?
                new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>();
        return collect(inputCollection, transformer, answer);
    }

    /**
     * Transforms all elements from the inputIterator with the given transformer
     * and adds them to the outputCollection.
     *

     * If the input iterator or transformer is null, the result is an empty
     * list.
     *
     * @param inputIterator  the iterator to get the input from, may be null
     * @param transformer  the transformer to use, may be null
     * @param  the type of object in the input collection
     * @param <O> the type of object in the output collection
     * @return the transformed result (new list)
     */
    public static  Collection<O> collect(final Iterator inputIterator,
            final Transformer<? super I, ? extends O> transformer) {
        return collect(inputIterator, transformer, new ArrayList<O>());
    }

    /**
     * Transforms all elements from inputCollection with the given transformer
     * and adds them to the outputCollection.
     *

     * If the input collection or transformer is null, there is no change to the
     * output collection.
     *
     * @param  the type of object in the input collection
     * @param <O> the type of object in the output collection
     * @param <R> the output type of the transformer - this extends O.
     * @param inputCollection  the collection to get the input from, may be null
     * @param transformer  the transformer to use, may be null
     * @param outputCollection  the collection to output into, may not be null if the inputCollection
     *   and transformer are not null
     * @return the outputCollection with the transformed input added
     * @throws NullPointerException if the output collection is null and both, inputCollection and
     *   transformer are not null
     */
    public static <I, O, R extends Collection<? super O>> R collect(final Iterable<? extends I> inputCollection,
            final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
        if (inputCollection != null) {
            return collect(inputCollection.iterator(), transformer, outputCollection);
        }
        return outputCollection;
    }

    /**
     * Transforms all elements from the inputIterator with the given transformer
     * and adds them to the outputCollection.
     *

     * If the input iterator or transformer is null, there is no change to the
     * output collection.
     *
     * @param inputIterator  the iterator to get the input from, may be null
     * @param transformer  the transformer to use, may be null
     * @param outputCollection  the collection to output into, may not be null if the inputCollection
     *   and transformer are not null
     * @param  the type of object in the input collection
     * @param <O> the type of object in the output collection
     * @param <R> the output type of the transformer - this extends O.
     * @return the outputCollection with the transformed input added
     * @throws NullPointerException if the output collection is null and both, inputCollection and
     *   transformer are not null
     */
    public static <I, O, R extends Collection<? super O>> R collect(final Iterator<? extends I> inputIterator,
            final Transformer<? super I, ? extends O> transformer, final R outputCollection) {
        if (inputIterator != null && transformer != null) {
            while (inputIterator.hasNext()) {
                final I item = inputIterator.next();
                final O value = transformer.transform(item);
                outputCollection.add(value);
            }
        }
        return outputCollection;
    }

    //-----------------------------------------------------------------------
    /**
     * Adds an element to the collection unless the element is null.
     *
     * @param <T>  the type of object the {@link Collection} contains
     * @param collection  the collection to add to, must not be null
     * @param object  the object to add, if null it will not be added
     * @return true if the collection changed
     * @throws NullPointerException if the collection is null
     * @since 3.2
     */
    public static <T> boolean addIgnoreNull(final Collection<T> collection, final T object) {
        if (collection == null) {
            throw new NullPointerException("The collection must not be null");
        }
        return object != null && collection.add(object);
    }

    /**
     * Adds all elements in the {@link Iterable} to the given collection. If the
     * {@link Iterable} is a {@link Collection} then it is cast and will be
     * added using {@link Collection#addAll(Collection)} instead of iterating.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to add to, must not be null
     * @param iterable  the iterable of elements to add, must not be null
     * @return a boolean indicating whether the collection has changed or not.
     * @throws NullPointerException if the collection or iterator is null
     */
    public static <C> boolean addAll(final Collection<C> collection, final Iterable<? extends C> iterable) {
        if (iterable instanceof Collection<?>) {
            return collection.addAll((Collection<? extends C>) iterable);
        }
        return addAll(collection, iterable.iterator());
    }

    /**
     * Adds all elements in the iteration to the given collection.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to add to, must not be null
     * @param iterator  the iterator of elements to add, must not be null
     * @return a boolean indicating whether the collection has changed or not.
     * @throws NullPointerException if the collection or iterator is null
     */
    public static <C> boolean addAll(final Collection<C> collection, final Iterator<? extends C> iterator) {
        boolean changed = false;
        while (iterator.hasNext()) {
            changed |= collection.add(iterator.next());
        }
        return changed;
    }

    /**
     * Adds all elements in the enumeration to the given collection.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to add to, must not be null
     * @param enumeration  the enumeration of elements to add, must not be null
     * @return {@code true} if the collections was changed, {@code false} otherwise
     * @throws NullPointerException if the collection or enumeration is null
     */
    public static <C> boolean addAll(final Collection<C> collection, final Enumeration<? extends C> enumeration) {
        boolean changed = false;
        while (enumeration.hasMoreElements()) {
            changed |= collection.add(enumeration.nextElement());
        }
        return changed;
    }

    /**
     * Adds all elements in the array to the given collection.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to add to, must not be null
     * @param elements  the array of elements to add, must not be null
     * @return {@code true} if the collection was changed, {@code false} otherwise
     * @throws NullPointerException if the collection or array is null
     */
    public static <C> boolean addAll(final Collection<C> collection, final C[] elements) {
        boolean changed = false;
        for (final C element : elements) {
            changed |= collection.add(element);
        }
        return changed;
    }

    /**
     * Returns the index-th value in {@link Iterator}, throwing
     * IndexOutOfBoundsException if there is no such element.
     *

     * The Iterator is advanced to index (or to the end, if
     * index exceeds the number of entries) as a side effect of this method.
     *
     * @param iterator  the iterator to get a value from
     * @param index  the index to get
     * @param <T> the type of object in the {@link Iterator}
     * @return the object at the specified index
     * @throws IndexOutOfBoundsException if the index is invalid
     * @throws IllegalArgumentException if the object type is invalid
     */
    public static <T> T get(final Iterator<T> iterator, final int index) {
        int i = index;
        checkIndexBounds(i);
        while (iterator.hasNext()) {
            i--;
            if (i == -1) {
                return iterator.next();
            }
            iterator.next();
        }
        throw new IndexOutOfBoundsException("Entry does not exist: " + i);
    }

    /**
     * Returns the index-th value in the {@link Enumeration}, throwing
     * IndexOutOfBoundsException if there is no such element.
     *

     * The Enumeration is advanced to index (or to the end, if
     * index exceeds the number of entries) as a side effect of this method.
     *
     * @param e  the enumeration to get a value from
     * @param index  the index to get
     * @param <T> the type of object in the {@link Enumeration}
     * @return the object at the specified index
     * @throws IndexOutOfBoundsException if the index is invalid
     * @throws IllegalArgumentException if the object type is invalid
     * @since 4.1
     */
    public static <T> T get(final Enumeration<T> e, final int index) {
        int i = index;
        checkIndexBounds(i);
        while (e.hasMoreElements()) {
            i--;
            if (i == -1) {
                return e.nextElement();
            } else {
                e.nextElement();
            }
        }
        throw new IndexOutOfBoundsException("Entry does not exist: " + i);
    }

    /**
     * Ensures an index is not negative.
     * @param index the index to check.
     * @throws IndexOutOfBoundsException if the index is negative.
     */
    private static void checkIndexBounds(final int index) {
        if (index < 0) {
            throw new IndexOutOfBoundsException("Index cannot be negative: " + index);
        }
    }

    /**
     * Returns the index-th value in the iterable's {@link Iterator}, throwing
     * IndexOutOfBoundsException if there is no such element.
     *

     * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}.
     *
     * @param iterable  the {@link Iterable} to get a value from
     * @param index  the index to get
     * @param <T> the type of object in the {@link Iterable}.
     * @return the object at the specified index
     * @throws IndexOutOfBoundsException if the index is invalid
     */
    public static <T> T get(final Iterable<T> iterable, final int index) {
        checkIndexBounds(index);
        if (iterable instanceof List<?>) {
            return ((List<T>) iterable).get(index);
        }
        return get(iterable.iterator(), index);
    }

    /**
     * Returns the index-th value in object, throwing
     * IndexOutOfBoundsException if there is no such element or
     * IllegalArgumentException if object is not an
     * instance of one of the supported types.
     *

     * The supported types, and associated semantics are:
     *

     *
 Map -- the value returned is the Map.Entry in position
     *      index in the map's entrySet iterator,
     *      if there is such an entry.

     *
 List -- this method is equivalent to the list's get method.

     *
 Array -- the index-th array entry is returned,
     *      if there is such an entry; otherwise an IndexOutOfBoundsException
     *      is thrown.

     *
 Collection -- the value returned is the index-th object
     *      returned by the collection's default iterator, if there is such an element.

     *
 Iterator or Enumeration -- the value returned is the
     *      index-th object in the Iterator/Enumeration, if there
     *      is such an element.  The Iterator/Enumeration is advanced to
     *      index (or to the end, if index exceeds the
     *      number of entries) as a side effect of this method.

     *

     *
     * @param object  the object to get a value from
     * @param index  the index to get
     * @return the object at the specified index
     * @throws IndexOutOfBoundsException if the index is invalid
     * @throws IllegalArgumentException if the object type is invalid
     */
    public static Object get(final Object object, final int index) {
        int i = index;
        if (i < 0) {
            throw new IndexOutOfBoundsException("Index cannot be negative: " + i);
        }
        if (object instanceof Map<?,?>) {
            final Map<?, ?> map = (Map<?, ?>) object;
            final Iterator<?> iterator = map.entrySet().iterator();
            return get(iterator, i);
        } else if (object instanceof Object[]) {
            return ((Object[]) object)[i];
        } else if (object instanceof Iterator<?>) {
            final Iterator<?> it = (Iterator<?>) object;
            return get(it, i);
        } else if (object instanceof Collection<?>) {
            final Iterator<?> iterator = ((Collection<?>) object).iterator();
            return get(iterator, i);
        } else if (object instanceof Enumeration<?>) {
            final Enumeration<?> it = (Enumeration<?>) object;
            return get(it, i);
        } else if (object == null) {
            throw new IllegalArgumentException("Unsupported object type: null");
        } else {
            try {
                return Array.get(object, i);
            } catch (final IllegalArgumentException ex) {
                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
            }
        }
    }

    /**
     * Returns the index-th Map.Entry in the map's entrySet,
     * throwing IndexOutOfBoundsException if there is no such element.
     *
     * @param <K>  the key type in the {@link Map}
     * @param <V>  the key type in the {@link Map}
     * @param map  the object to get a value from
     * @param index  the index to get
     * @return the object at the specified index
     * @throws IndexOutOfBoundsException if the index is invalid
     */
    public static <K,V> Map.Entry<K, V> get(final Map<K,V> map, final int index) {
        checkIndexBounds(index);
        return get(map.entrySet(), index);
    }

    /**
     * Gets the size of the collection/iterator specified.
     *

     * This method can handles objects as follows
     *

     *
Collection - the collection size
     *
Map - the map size
     *
Array - the array size
     *
Iterator - the number of elements remaining in the iterator
     *
Enumeration - the number of elements remaining in the enumeration
     *

     *
     * @param object  the object to get the size of, may be null
     * @return the size of the specified collection or 0 if the object was null
     * @throws IllegalArgumentException thrown if object is not recognised
     * @since 3.1
     */
    public static int size(final Object object) {
        if (object == null) {
            return 0;
        }
        int total = 0;
        if (object instanceof Map<?,?>) {
            total = ((Map<?, ?>) object).size();
        } else if (object instanceof Collection<?>) {
            total = ((Collection<?>) object).size();
        } else if (object instanceof Object[]) {
            total = ((Object[]) object).length;
        } else if (object instanceof Iterator<?>) {
            final Iterator<?> it = (Iterator<?>) object;
            while (it.hasNext()) {
                total++;
                it.next();
            }
        } else if (object instanceof Enumeration<?>) {
            final Enumeration<?> it = (Enumeration<?>) object;
            while (it.hasMoreElements()) {
                total++;
                it.nextElement();
            }
        } else {
            try {
                total = Array.getLength(object);
            } catch (final IllegalArgumentException ex) {
                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
            }
        }
        return total;
    }

    /**
     * Checks if the specified collection/array/iterator is empty.
     *

     * This method can handles objects as follows
     *

     *
Collection - via collection isEmpty
     *
Map - via map isEmpty
     *
Array - using array size
     *
Iterator - via hasNext
     *
Enumeration - via hasMoreElements
     *

     *

     * Note: This method is named to avoid clashing with
     * {@link #isEmpty(Collection)}.
     *
     * @param object  the object to get the size of, may be null
     * @return true if empty or null
     * @throws IllegalArgumentException thrown if object is not recognised
     * @since 3.2
     */
    public static boolean sizeIsEmpty(final Object object) {
        if (object == null) {
            return true;
        } else if (object instanceof Collection<?>) {
            return ((Collection<?>) object).isEmpty();
        } else if (object instanceof Map<?, ?>) {
            return ((Map<?, ?>) object).isEmpty();
        } else if (object instanceof Object[]) {
            return ((Object[]) object).length == 0;
        } else if (object instanceof Iterator<?>) {
            return ((Iterator<?>) object).hasNext() == false;
        } else if (object instanceof Enumeration<?>) {
            return ((Enumeration<?>) object).hasMoreElements() == false;
        } else {
            try {
                return Array.getLength(object) == 0;
            } catch (final IllegalArgumentException ex) {
                throw new IllegalArgumentException("Unsupported object type: " + object.getClass().getName());
            }
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Null-safe check if the specified collection is empty.
     *

     * Null returns true.
     *
     * @param coll  the collection to check, may be null
     * @return true if empty or null
     * @since 3.2
     */
    public static boolean isEmpty(final Collection<?> coll) {
        return coll == null || coll.isEmpty();
    }

    /**
     * Null-safe check if the specified collection is not empty.
     *

     * Null returns false.
     *
     * @param coll  the collection to check, may be null
     * @return true if non-null and non-empty
     * @since 3.2
     */
    public static boolean isNotEmpty(final Collection<?> coll) {
        return !isEmpty(coll);
    }

    //-----------------------------------------------------------------------
    /**
     * Reverses the order of the given array.
     *
     * @param array  the array to reverse
     */
    public static void reverseArray(final Object[] array) {
        int i = 0;
        int j = array.length - 1;
        Object tmp;

        while (j > i) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
            j--;
            i++;
        }
    }

    /**
     * Returns true if no more elements can be added to the Collection.
     *

     * This method uses the {@link BoundedCollection} interface to determine the
     * full status. If the collection does not implement this interface then
     * false is returned.
     *

     * The collection does not have to implement this interface directly.
     * If the collection has been decorated using the decorators subpackage
     * then these will be removed to access the BoundedCollection.
     *
     * @param coll  the collection to check
     * @return true if the BoundedCollection is full
     * @throws NullPointerException if the collection is null
     */
    public static boolean isFull(final Collection<? extends Object> coll) {
        if (coll == null) {
            throw new NullPointerException("The collection must not be null");
        }
        if (coll instanceof BoundedCollection) {
            return ((BoundedCollection<?>) coll).isFull();
        }
        try {
            final BoundedCollection<?> bcoll =
                    UnmodifiableBoundedCollection.unmodifiableBoundedCollection(coll);
            return bcoll.isFull();
        } catch (final IllegalArgumentException ex) {
            return false;
        }
    }

    /**
     * Get the maximum number of elements that the Collection can contain.
     *

     * This method uses the {@link BoundedCollection} interface to determine the
     * maximum size. If the collection does not implement this interface then
     * -1 is returned.
     *

     * The collection does not have to implement this interface directly.
     * If the collection has been decorated using the decorators subpackage
     * then these will be removed to access the BoundedCollection.
     *
     * @param coll  the collection to check
     * @return the maximum size of the BoundedCollection, -1 if no maximum size
     * @throws NullPointerException if the collection is null
     */
    public static int maxSize(final Collection<? extends Object> coll) {
        if (coll == null) {
            throw new NullPointerException("The collection must not be null");
        }
        if (coll instanceof BoundedCollection) {
            return ((BoundedCollection<?>) coll).maxSize();
        }
        try {
            final BoundedCollection<?> bcoll =
                    UnmodifiableBoundedCollection.unmodifiableBoundedCollection(coll);
            return bcoll.maxSize();
        } catch (final IllegalArgumentException ex) {
            return -1;
        }
    }

    //-----------------------------------------------------------------------
    /**
     * Merges two sorted Collections, a and b, into a single, sorted List
     * such that the natural ordering of the elements is retained.
     *

     * Uses the standard O(n) merge algorithm for combining two sorted lists.
     *
     * @param <O>  the element type
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @return a new sorted List, containing the elements of Collection a and b
     * @throws IllegalArgumentException if either collection is null
     * @since 4.0
     */
    public static <O extends Comparable<? super O>> List<O> collate(Iterable<? extends O> a,
                                                                    Iterable<? extends O> b) {
        return collate(a, b, ComparatorUtils.<O>naturalComparator(), true);
    }

    /**
     * Merges two sorted Collections, a and b, into a single, sorted List
     * such that the natural ordering of the elements is retained.
     *

     * Uses the standard O(n) merge algorithm for combining two sorted lists.
     *
     * @param <O>  the element type
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @param includeDuplicates  if {@code true} duplicate elements will be retained, otherwise
     *   they will be removed in the output collection
     * @return a new sorted List, containing the elements of Collection a and b
     * @throws IllegalArgumentException if either collection is null
     * @since 4.0
     */
    public static <O extends Comparable<? super O>> List<O> collate(final Iterable<? extends O> a,
                                                                    final Iterable<? extends O> b,
                                                                    final boolean includeDuplicates) {
        return collate(a, b, ComparatorUtils.<O>naturalComparator(), includeDuplicates);
    }

    /**
     * Merges two sorted Collections, a and b, into a single, sorted List
     * such that the ordering of the elements according to Comparator c is retained.
     *

     * Uses the standard O(n) merge algorithm for combining two sorted lists.
     *
     * @param <O>  the element type
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @param c  the comparator to use for the merge.
     * @return a new sorted List, containing the elements of Collection a and b
     * @throws IllegalArgumentException if either collection or the comparator is null
     * @since 4.0
     */
    public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b,
                                      final Comparator<? super O> c) {
        return collate(a, b, c, true);
    }

    /**
     * Merges two sorted Collections, a and b, into a single, sorted List
     * such that the ordering of the elements according to Comparator c is retained.
     *

     * Uses the standard O(n) merge algorithm for combining two sorted lists.
     *
     * @param <O>  the element type
     * @param a  the first collection, must not be null
     * @param b  the second collection, must not be null
     * @param c  the comparator to use for the merge.
     * @param includeDuplicates  if {@code true} duplicate elements will be retained, otherwise
     *   they will be removed in the output collection
     * @return a new sorted List, containing the elements of Collection a and b
     * @throws IllegalArgumentException if either collection or the comparator is null
     * @since 4.0
     */
    public static <O> List<O> collate(final Iterable<? extends O> a, final Iterable<? extends O> b,
                                      final Comparator<? super O> c, final boolean includeDuplicates) {

        if (a == null || b == null) {
            throw new IllegalArgumentException("The collections must not be null");
        }
        if (c == null) {
            throw new IllegalArgumentException("The comparator must not be null");
        }

        // if both Iterables are a Collection, we can estimate the size
        final int totalSize = a instanceof Collection<?> && b instanceof Collection<?> ?
                Math.max(1, ((Collection<?>) a).size() + ((Collection<?>) b).size()) : 10;

        final Iterator<O> iterator = new CollatingIterator<O>(c, a.iterator(), b.iterator());
        if (includeDuplicates) {
            return IteratorUtils.toList(iterator, totalSize);
        } else {
            final ArrayList<O> mergedList = new ArrayList<O>(totalSize);

            O lastItem = null;
            while (iterator.hasNext()) {
                final O item = iterator.next();
                if (lastItem == null || !lastItem.equals(item)) {
                    mergedList.add(item);
                }
                lastItem = item;
            }

            mergedList.trimToSize();
            return mergedList;
        }
    }

    //-----------------------------------------------------------------------

    /**
     * Returns a {@link Collection} of all the permutations of the input collection.
     *

     * NOTE: the number of permutations of a given collection is equal to n!, where
     * n is the size of the collection. Thus, the resulting collection will become
     * very large for collections > 10 (e.g. 10! = 3628800, 15! = 1307674368000).
     *

     * For larger collections it is advised to use a {@link PermutationIterator} to
     * iterate over all permutations.
     *
     * @see PermutationIterator
     *
     * @param <E>  the element type
     * @param collection  the collection to create permutations for, may not be null
     * @return an unordered collection of all permutations of the input collection
     * @throws NullPointerException if collection is null
     * @since 4.0
     */
    public static <E> Collection<List<E>> permutations(final Collection<E> collection) {
        final PermutationIterator<E> it = new PermutationIterator<E>(collection);
        final Collection<List<E>> result = new LinkedList<List<E>>();
        while (it.hasNext()) {
            result.add(it.next());
        }
        return result;
    }

    //-----------------------------------------------------------------------
    /**
     * Returns a collection containing all the elements in collection
     * that are also in retain. The cardinality of an element e
     * in the returned collection is the same as the cardinality of e
     * in collection unless retain does not contain e, in which
     * case the cardinality is zero. This method is useful if you do not wish to modify
     * the collection c and thus cannot call c.retainAll(retain);.
     *

     * This implementation iterates over collection, checking each element in
     * turn to see if it's contained in retain. If it's contained, it's added
     * to the returned list. As a consequence, it is advised to use a collection type for
     * retain that provides a fast (e.g. O(1)) implementation of
     * {@link Collection#contains(Object)}.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection whose contents are the target of the #retailAll operation
     * @param retain  the collection containing the elements to be retained in the returned collection
     * @return a Collection containing all the elements of collection
     * that occur at least once in retain.
     * @throws NullPointerException if either parameter is null
     * @since 3.2
     */
    public static <C> Collection<C> retainAll(final Collection<C> collection, final Collection<?> retain) {
        return ListUtils.retainAll(collection, retain);
    }

    /**
     * Returns a collection containing all the elements in
     * collection that are also in retain. The
     * cardinality of an element e in the returned collection is
     * the same as the cardinality of e in collection
     * unless retain does not contain e, in which case
     * the cardinality is zero. This method is useful if you do not wish to
     * modify the collection c and thus cannot call
     * c.retainAll(retain);.
     *

     * Moreover this method uses an {@link Equator} instead of
     * {@link Object#equals(Object)} to determine the equality of the elements
     * in collection and retain. Hence this method is
     * useful in cases where the equals behavior of an object needs to be
     * modified without changing the object itself.
     *
     * @param <E> the type of object the {@link Collection} contains
     * @param collection the collection whose contents are the target of the {@code retainAll} operation
     * @param retain the collection containing the elements to be retained in the returned collection
     * @param equator the Equator used for testing equality
     * @return a Collection containing all the elements of collection
     * that occur at least once in retain according to the equator
     * @throws NullPointerException if any of the parameters is null
     * @since 4.1
     */
    public static <E> Collection<E> retainAll(final Iterable<E> collection,
                                              final Iterable<? extends E> retain,
                                              final Equator<? super E> equator) {

        final Transformer<E, EquatorWrapper<E>> transformer = new Transformer<E, EquatorWrapper<E>>() {
            public EquatorWrapper<E> transform(E input) {
                return new EquatorWrapper<E>(equator, input);
            }
        };

        final Set<EquatorWrapper<E>> retainSet =
                collect(retain, transformer, new HashSet<EquatorWrapper<E>>());

        final List<E> list = new ArrayList<E>();
        for (final E element : collection) {
            if (retainSet.contains(new EquatorWrapper<E>(equator, element))) {
                list.add(element);
            }
        }
        return list;
    }

    /**
     * Removes the elements in remove from collection. That is, this
     * method returns a collection containing all the elements in c
     * that are not in remove. The cardinality of an element e
     * in the returned collection is the same as the cardinality of e
     * in collection unless remove contains e, in which
     * case the cardinality is zero. This method is useful if you do not wish to modify
     * the collection c and thus cannot call collection.removeAll(remove);.
     *

     * This implementation iterates over collection, checking each element in
     * turn to see if it's contained in remove. If it's not contained, it's added
     * to the returned list. As a consequence, it is advised to use a collection type for
     * remove that provides a fast (e.g. O(1)) implementation of
     * {@link Collection#contains(Object)}.
     *
     * @param <E>  the type of object the {@link Collection} contains
     * @param collection  the collection from which items are removed (in the returned collection)
     * @param remove  the items to be removed from the returned collection
     * @return a Collection containing all the elements of collection except
     * any elements that also occur in remove.
     * @throws NullPointerException if either parameter is null
     * @since 4.0 (method existed in 3.2 but was completely broken)
     */
    public static <E> Collection<E> removeAll(final Collection<E> collection, final Collection<?> remove) {
        return ListUtils.removeAll(collection, remove);
  }

    /**
     * Removes all elements in remove from collection.
     * That is, this method returns a collection containing all the elements in
     * collection that are not in remove. The
     * cardinality of an element e in the returned collection is
     * the same as the cardinality of e in collection
     * unless remove contains e, in which case the
     * cardinality is zero. This method is useful if you do not wish to modify
     * the collection c and thus cannot call
     * collection.removeAll(remove).
     *

     * Moreover this method uses an {@link Equator} instead of
     * {@link Object#equals(Object)} to determine the equality of the elements
     * in collection and remove. Hence this method is
     * useful in cases where the equals behavior of an object needs to be
     * modified without changing the object itself.
     *
     * @param <E> the type of object the {@link Collection} contains
     * @param collection the collection from which items are removed (in the returned collection)
     * @param remove the items to be removed from the returned collection
     * @param equator the Equator used for testing equality
     * @return a Collection containing all the elements of collection
     * except any element that if equal according to the equator
     * @throws NullPointerException if any of the parameters is null
     * @since 4.1
     */
    public static <E> Collection<E> removeAll(final Iterable<E> collection,
                                              final Iterable<? extends E> remove,
                                              final Equator<? super E> equator) {

        final Transformer<E, EquatorWrapper<E>> transformer = new Transformer<E, EquatorWrapper<E>>() {
            public EquatorWrapper<E> transform(E input) {
                return new EquatorWrapper<E>(equator, input);
            }
        };

        final Set<EquatorWrapper<E>> removeSet =
                collect(remove, transformer, new HashSet<EquatorWrapper<E>>());

        final List<E> list = new ArrayList<E>();
        for (final E element : collection) {
            if (!removeSet.contains(new EquatorWrapper<E>(equator, element))) {
                list.add(element);
            }
        }
        return list;
    }

    /**
     * This method checks, if any of the elements in collection is
     * equal to object. Object equality is tested with an
     * equator unlike collection.contains(object)
     * which uses {@link Object#equals(Object)}.
     *
     * @param <E> the type of object the {@link Collection} contains
     * @param collection the collection from which items are compared
     * @param object the object to compare with the collection's entries
     * @param equator the equator to use to check, if the item if equal to any
     *        of the collection's entries.
     * @return true if object is in collection
     *         according to equator
     * @throws NullPointerException if any parameter is null
     * @since 4.1
     */
    public static <E> boolean contains(final Collection<? extends E> collection, final E object,
            final Equator<? super E> equator) {
        for (final E obj : collection) {
            if (equator.equate(obj, object)) {
                return true;
            }
        }
        return false;
    }

    //-----------------------------------------------------------------------
    /**
     * Returns a synchronized collection backed by the given collection.
     *

     * You must manually synchronize on the returned buffer's iterator to
     * avoid non-deterministic behavior:
     *
     *

     * Collection c = CollectionUtils.synchronizedCollection(myCollection);
     * synchronized (c) {
     *     Iterator i = c.iterator();
     *     while (i.hasNext()) {
     *         process (i.next());
     *     }
     * }
     *

     *
     * This method uses the implementation in the decorators subpackage.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to synchronize, must not be null
     * @return a synchronized collection backed by the given collection
     * @throws IllegalArgumentException  if the collection is null
     */
    public static <C> Collection<C> synchronizedCollection(final Collection<C> collection) {
        return SynchronizedCollection.synchronizedCollection(collection);
    }

    /**
     * Returns an unmodifiable collection backed by the given collection.
     *

     * This method uses the implementation in the decorators subpackage.
     *
     * @param <C>  the type of object the {@link Collection} contains
     * @param collection  the collection to make unmodifiable, must not be null
     * @return an unmodifiable collection backed by the given collection
     * @throws IllegalArgumentException  if the collection is null
     */
    public static <C> Collection<C> unmodifiableCollection(final Collection<? extends C> collection) {
        return UnmodifiableCollection.unmodifiableCollection(collection);
    }

    /**
     * Returns a predicated (validating) collection backed by the given collection.
     *

     * Only objects that pass the test in the given predicate can be added to the collection.
     * Trying to add an invalid object results in an IllegalArgumentException.
     * It is important not to use the original collection after invoking this method,
     * as it is a backdoor for adding invalid objects.
     *
     * @param collection  the collection to predicate, must not be null
     * @param predicate  the predicate for the collection, must not be null
     * @param <C> the type of objects in the Collection.
     * @return a predicated collection backed by the given collection
     * @throws IllegalArgumentException  if the Collection is null
     */
    public static <C> Collection<C> predicatedCollection(final Collection<C> collection,
                                                         final Predicate<? super C> predicate) {
        return PredicatedCollection.predicatedCollection(collection, predicate);
    }

    /**
     * Returns a transformed bag backed by the given collection.
     *

     * Each object is passed through the transformer as it is added to the
     * Collection. It is important not to use the original collection after invoking this
     * method, as it is a backdoor for adding untransformed objects.
     *

     * Existing entries in the specified collection will not be transformed.
     * If you want that behaviour, see {@link TransformedCollection#transformedCollection}.
     *
     * @param <E>  the type of object the {@link Collection} contains
     * @param collection  the collection to predicate, must not be null
     * @param transformer  the transformer for the collection, must not be null
     * @return a transformed collection backed by the given collection
     * @throws IllegalArgumentException  if the Collection or Transformer is null
     */
    public static <E> Collection<E> transformingCollection(final Collection<E> collection,
            final Transformer<? super E, ? extends E> transformer) {
        return TransformedCollection.transformingCollection(collection, transformer);
    }

    /**
     * Extract the lone element of the specified Collection.
     * @param <E> collection type
     * @param collection to read
     * @return sole member of collection
     * @throws IllegalArgumentException if collection is null/empty or contains more than one element
     * @since 4.0
     */
    public static <E> E extractSingleton(final Collection<E> collection) {
        if (collection == null || collection.size() != 1) {
            throw new IllegalArgumentException("Can extract singleton only when collection size == 1");
        }
        return collection.iterator().next();
    }
}