All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.phloc.commons.collections.ContainerHelper Maven / Gradle / Ivy

There is a newer version: 5.0.0
Show newest version
/**
 * Copyright (C) 2006-2015 phloc systems
 * http://www.phloc.com
 * office[at]phloc[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.phloc.commons.collections;//NOPMD

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import com.phloc.commons.ValueEnforcer;
import com.phloc.commons.annotations.ReturnsImmutableObject;
import com.phloc.commons.annotations.ReturnsMutableCopy;
import com.phloc.commons.annotations.ReturnsMutableObject;
import com.phloc.commons.collections.iterate.CombinedEnumeration;
import com.phloc.commons.collections.iterate.CombinedIterator;
import com.phloc.commons.collections.iterate.EmptyEnumeration;
import com.phloc.commons.collections.iterate.EmptyIterator;
import com.phloc.commons.collections.iterate.EnumerationFromIterator;
import com.phloc.commons.collections.iterate.IIterableIterator;
import com.phloc.commons.collections.iterate.IterableIteratorFromEnumeration;
import com.phloc.commons.collections.iterate.ReverseListIterator;
import com.phloc.commons.collections.multimap.IMultiMap;
import com.phloc.commons.collections.multimap.IMultiMapSetBased;
import com.phloc.commons.collections.multimap.MultiHashMapHashSetBased;
import com.phloc.commons.compare.ComparatorComparableNullAware;
import com.phloc.commons.compare.ComparatorUtils;
import com.phloc.commons.compare.ESortOrder;
import com.phloc.commons.id.IHasID;
import com.phloc.commons.name.IHasName;
import com.phloc.commons.state.EChange;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * Provides various helper methods to handle collections like {@link List},
 * {@link Set} and {@link Map}.
 * 
 * @author Philip Helger
 * @author Boris Gregorcic
 */
@Immutable
public final class ContainerHelper
{
  private ContainerHelper ()
  {
    // private
  }

  @Nonnull
  public static  List  getNotNull (final List  aList)
  {
    return aList == null ? ContainerHelper. newList () : aList;
  }

  @Nonnull
  public static  Set  getNotNull (final Set  aSet)
  {
    return aSet == null ? ContainerHelper. newSet () : aSet;
  }

  @Nonnull
  public static > SortedSet  getNotNull (final SortedSet  aSortedSet)
  {
    return aSortedSet == null ? ContainerHelper. newSortedSet () : aSortedSet;
  }

  @Nonnull
  public static  Map  getNotNull (final Map  aMap)
  {
    return aMap == null ? ContainerHelper. newMap () : aMap;
  }

  @Nonnull
  public static , VALUETYPE> SortedMap  getNotNull (final SortedMap  aSortedMap)
  {
    return aSortedMap == null ? ContainerHelper. newSortedMap () : aSortedMap;
  }

  @Nullable
  @ReturnsImmutableObject
  public static  Collection  makeUnmodifiable (@Nullable final Collection  aCollection)
  {
    return aCollection == null ? null : Collections.unmodifiableCollection (aCollection);
  }

  @Nullable
  @ReturnsImmutableObject
  public static  List  makeUnmodifiable (@Nullable final List  aList)
  {
    return aList == null ? null : Collections.unmodifiableList (aList);
  }

  @Nullable
  @ReturnsImmutableObject
  public static  Set  makeUnmodifiable (@Nullable final Set  aSet)
  {
    return aSet == null ? null : Collections.unmodifiableSet (aSet);
  }

  @Nullable
  @ReturnsImmutableObject
  public static  Map  makeUnmodifiable (@Nullable final Map  aMap)
  {
    return aMap == null ? null : Collections.unmodifiableMap (aMap);
  }

  @Nullable
  @ReturnsImmutableObject
  public static > SortedSet  makeUnmodifiable (@Nullable final SortedSet  aSortedSet)
  {
    return aSortedSet == null ? null : Collections.unmodifiableSortedSet (aSortedSet);
  }

  @Nullable
  @ReturnsImmutableObject
  public static  SortedMap  makeUnmodifiable (@Nullable final SortedMap  aSortedMap)
  {
    return aSortedMap == null ? null : Collections.unmodifiableSortedMap (aSortedMap);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Collection  makeUnmodifiableNotNull (@Nullable final Collection  aCollection)
  {
    return aCollection == null ? ContainerHelper. newUnmodifiableList ()
                               : Collections.unmodifiableCollection (aCollection);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  makeUnmodifiableNotNull (@Nullable final List  aList)
  {
    return aList == null ? ContainerHelper. newUnmodifiableList () : Collections.unmodifiableList (aList);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  makeUnmodifiableNotNull (@Nullable final Set  aSet)
  {
    return aSet == null ? ContainerHelper. newUnmodifiableSet () : Collections.unmodifiableSet (aSet);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  makeUnmodifiableNotNull (@Nullable final Map  aMap)
  {
    return aMap == null ? ContainerHelper. newUnmodifiableMap ()
                        : Collections.unmodifiableMap (aMap);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  makeUnmodifiableNotNull (@Nullable final SortedSet  aSortedSet)
  {
    return aSortedSet == null ? ContainerHelper. newUnmodifiableSortedSet ()
                              : Collections.unmodifiableSortedSet (aSortedSet);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  makeUnmodifiableNotNull (@Nullable final SortedMap  aSortedMap)
  {
    return Collections.unmodifiableSortedMap (aSortedMap == null ? ContainerHelper. newSortedMap ()
                                                                 : aSortedMap);
  }

  /**
   * Get all elements that are only contained in the first contained, and not in
   * the second. This method implements aCont1 - aCont2.
   * 
   * @param 
   *        The element type
   * @param aCollection1
   *        The first container. May be null or empty.
   * @param aCollection2
   *        The second container. May be null or empty.
   * @return The difference and never null. Returns an empty set,
   *         if the first container is empty. Returns a copy of the first
   *         container, if the second container is empty. Returns
   *         aCont1 - aCont2 if both containers are non-empty.
   */
  @Nullable
  @ReturnsMutableCopy
  public static  Set  getDifference (@Nullable final Collection  aCollection1,
                                                               @Nullable final Collection  aCollection2)
  {
    if (isEmpty (aCollection1))
      return newSet ();
    if (isEmpty (aCollection2))
      return newSet (aCollection1);

    final Set  ret = newSet (aCollection1);
    ret.removeAll (aCollection2);
    return ret;
  }

  /**
   * Get all elements that are only contained in the first contained, and not in
   * the second. This method implements aCont1 - aCont2.
   * 
   * @param 
   *        The element type
   * @param aList1
   *        The first container. May be null or empty.
   * @param aList2
   *        The second container. May be null or empty.
   * @return The difference and never null. Returns an empty List,
   *         if the first container is empty. Returns a copy of the first
   *         container, if the second container is empty. Returns
   *         aCont1 - aCont2 if both containers are non-empty.
   */
  @Nullable
  @ReturnsMutableCopy
  public static  List  getDifference (@Nullable final List  aList1,
                                                                @Nullable final List  aList2)
  {
    if (ContainerHelper.isEmpty (aList1))
      return ContainerHelper.newList ();
    if (ContainerHelper.isEmpty (aList2))
      return ContainerHelper.newList (aList1);

    final List  ret = ContainerHelper.newList (aList1);
    ret.removeAll (aList2);
    return ret;
  }

  /**
   * Get all elements that are contained in the first AND in the second
   * container.
   * 
   * @param 
   *        The element type
   * @param aCollection1
   *        The first container. May be null or empty.
   * @param aCollection2
   *        The second container. May be null or empty.
   * @return An empty set, if either the first or the second container are
   *         empty. Returns a set of elements that are contained in both
   *         containers, if both containers are non-empty. The return value is
   *         never null.
   */
  @Nullable
  @ReturnsMutableCopy
  public static  Set  getIntersected (@Nullable final Collection  aCollection1,
                                                                @Nullable final Collection  aCollection2)
  {
    if (isEmpty (aCollection1))
      return newSet ();
    if (isEmpty (aCollection2))
      return newSet ();

    final Set  ret = newSet (aCollection1);
    ret.retainAll (aCollection2);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap ()
  {
    return new HashMap  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final KEYTYPE aKey,
                                                                      @Nullable final VALUETYPE aValue)
  {
    final Map  ret = new HashMap  (1);
    ret.put (aKey, aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final ELEMENTTYPE... aValues)
  {
    if (ArrayHelper.isEmpty (aValues))
      return new HashMap  (0);

    if ((aValues.length % 2) != 0)
      throw new IllegalArgumentException ("The passed array needs an even number of elements!"); //$NON-NLS-1$

    final Map  ret = new HashMap  (aValues.length / 2);
    for (int i = 0; i < aValues.length; i += 2)
      ret.put (aValues[i], aValues[i + 1]);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final KEYTYPE [] aKeys,
                                                                      @Nullable final VALUETYPE [] aValues)
  {
    // Are both empty?
    if (ArrayHelper.isEmpty (aKeys) && ArrayHelper.isEmpty (aValues))
      return new HashMap  (0);

    // keys OR values may be null here
    if (ArrayHelper.getSize (aKeys) != ArrayHelper.getSize (aValues))
      throw new IllegalArgumentException ("The passed arrays have different length!"); //$NON-NLS-1$

    final Map  ret = new HashMap  (aKeys.length);
    for (int i = 0; i < aKeys.length; ++i)
      ret.put (aKeys[i], aValues[i]);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final Collection  aKeys,
                                                                      @Nullable final Collection  aValues)
  {
    // Are both empty?
    if (isEmpty (aKeys) && isEmpty (aValues))
      return new HashMap  (0);

    // keys OR values may be null here
    if (getSize (aKeys) != getSize (aValues))
      throw new IllegalArgumentException ("Number of keys is different from number of values"); //$NON-NLS-1$

    final Map  ret = new HashMap  (aKeys.size ());
    final Iterator  itk = aKeys.iterator ();
    final Iterator  itv = aValues.iterator ();
    while (itk.hasNext ())
      ret.put (itk.next (), itv.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final Map  aMap)
  {
    if (isEmpty (aMap))
      return new HashMap  (0);

    return new HashMap  (aMap);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final Map  [] aMaps)
  {
    if (aMaps == null || aMaps.length == 0)
      return new HashMap  (0);

    final Map  ret = new HashMap  ();
    for (final Map  aMap : aMaps)
      ret.putAll (aMap);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newMap (@Nullable final Collection > aCollection)
  {
    if (isEmpty (aCollection))
      return new HashMap  (0);

    final Map  ret = new HashMap  (aCollection.size ());
    for (final Map.Entry  aEntry : aCollection)
      ret.put (aEntry.getKey (), aEntry.getValue ());
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap ()
  {
    return Collections. emptyMap ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final KEYTYPE aKey,
                                                                                  @Nullable final VALUETYPE aValue)
  {
    return Collections.singletonMap (aKey, aValue);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newMap (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final KEYTYPE [] aKeys,
                                                                                  @Nullable final VALUETYPE [] aValues)
  {
    return makeUnmodifiable (newMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final Collection  aKeys,
                                                                                  @Nullable final Collection  aValues)
  {
    return makeUnmodifiable (newMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final Map  aMap)
  {
    return makeUnmodifiable (aMap);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final Map  [] aMaps)
  {
    return makeUnmodifiable (newMap (aMaps));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableMap (@Nullable final Collection > aCollection)
  {
    return makeUnmodifiable (newMap (aCollection));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap ()
  {
    return new LinkedHashMap  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final KEYTYPE aKey,
                                                                             @Nullable final VALUETYPE aValue)
  {
    final Map  ret = new LinkedHashMap  (1);
    ret.put (aKey, aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final ELEMENTTYPE... aValues)
  {
    if (ArrayHelper.isEmpty (aValues))
      return new LinkedHashMap  (0);

    if ((aValues.length % 2) != 0)
      throw new IllegalArgumentException ("The passed array needs an even number of elements!"); //$NON-NLS-1$

    final Map  ret = new LinkedHashMap  (aValues.length / 2);
    for (int i = 0; i < aValues.length; i += 2)
      ret.put (aValues[i], aValues[i + 1]);
    return ret;
  }

  /**
   * Retrieve a map that is ordered in the way the parameter arrays are passed
   * in. Note that key and value arrays need to have the same length.
   * 
   * @param 
   *        The key type.
   * @param 
   *        The value type.
   * @param aKeys
   *        The key array to use. May not be null.
   * @param aValues
   *        The value array to use. May not be null.
   * @return A {@link java.util.LinkedHashMap} containing the passed key-value
   *         entries. Never null.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final KEYTYPE [] aKeys,
                                                                             @Nullable final VALUETYPE [] aValues)
  {
    // Are both empty?
    if (ArrayHelper.isEmpty (aKeys) && ArrayHelper.isEmpty (aValues))
      return new LinkedHashMap  (0);

    // keys OR values may be null here
    if (ArrayHelper.getSize (aKeys) != ArrayHelper.getSize (aValues))
      throw new IllegalArgumentException ("The passed arrays have different length!"); //$NON-NLS-1$

    final Map  ret = new LinkedHashMap  (aKeys.length);
    for (int i = 0; i < aKeys.length; ++i)
      ret.put (aKeys[i], aValues[i]);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final Collection  aKeys,
                                                                             @Nullable final Collection  aValues)
  {
    // Are both empty?
    if (isEmpty (aKeys) && isEmpty (aValues))
      return new LinkedHashMap  (0);

    // keys OR values may be null here
    if (getSize (aKeys) != getSize (aValues))
      throw new IllegalArgumentException ("Number of keys is different from number of values"); //$NON-NLS-1$

    final Map  ret = new LinkedHashMap  (aKeys.size ());
    final Iterator  itk = aKeys.iterator ();
    final Iterator  itv = aValues.iterator ();
    while (itk.hasNext ())
      ret.put (itk.next (), itv.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final Map  aMap)
  {
    if (isEmpty (aMap))
      return new LinkedHashMap  (0);

    return new LinkedHashMap  (aMap);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final Map  [] aMaps)
  {
    if (aMaps == null || aMaps.length == 0)
      return new LinkedHashMap  (0);

    final Map  ret = new LinkedHashMap  ();
    for (final Map  aMap : aMaps)
      ret.putAll (aMap);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Map  newOrderedMap (@Nullable final Collection > aCollection)
  {
    if (isEmpty (aCollection))
      return new LinkedHashMap  (0);

    final Map  ret = new LinkedHashMap  (aCollection.size ());
    for (final Map.Entry  aEntry : aCollection)
      ret.put (aEntry.getKey (), aEntry.getValue ());
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap ()
  {
    return Collections. emptyMap ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final KEYTYPE aKey,
                                                                                         @Nullable final VALUETYPE aValue)
  {
    return Collections.singletonMap (aKey, aValue);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newOrderedMap (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final KEYTYPE [] aKeys,
                                                                                         @Nullable final VALUETYPE [] aValues)
  {
    return makeUnmodifiable (newOrderedMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final Collection  aKeys,
                                                                                         @Nullable final Collection  aValues)
  {
    return makeUnmodifiable (newOrderedMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final Map  aOrderedMap)
  {
    return makeUnmodifiable (aOrderedMap);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final Map  [] aOrderedMaps)
  {
    return makeUnmodifiable (newOrderedMap (aOrderedMaps));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Map  newUnmodifiableOrderedMap (@Nullable final Collection > aCollection)
  {
    return makeUnmodifiable (newOrderedMap (aCollection));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap ()
  {
    return new TreeMap  (new ComparatorComparableNullAware  ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final KEYTYPE aKey,
                                                                                                                     @Nullable final VALUETYPE aValue)
  {
    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    ret.put (aKey, aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeMap  newSortedMap (@Nullable final ELEMENTTYPE... aValues)
  {
    if (ArrayHelper.isEmpty (aValues))
      return new TreeMap  (new ComparatorComparableNullAware  ());

    if ((aValues.length % 2) != 0)
      throw new IllegalArgumentException ("The passed array needs an even number of elements!"); //$NON-NLS-1$

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    for (int i = 0; i < aValues.length; i += 2)
      ret.put (aValues[i], aValues[i + 1]);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final KEYTYPE [] aKeys,
                                                                                                                     @Nullable final VALUETYPE [] aValues)
  {
    // Are both empty?
    if (ArrayHelper.isEmpty (aKeys) && ArrayHelper.isEmpty (aValues))
      return new TreeMap  (new ComparatorComparableNullAware  ());

    // keys OR values may be null here
    if (ArrayHelper.getSize (aKeys) != ArrayHelper.getSize (aValues))
      throw new IllegalArgumentException ("The passed arrays have different length!"); //$NON-NLS-1$

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    for (int i = 0; i < aKeys.length; ++i)
      ret.put (aKeys[i], aValues[i]);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final Collection  aKeys,
                                                                                                                     @Nullable final Collection  aValues)
  {
    // Are both empty?
    if (isEmpty (aKeys) && isEmpty (aValues))
      return new TreeMap  (new ComparatorComparableNullAware  ());

    // keys OR values may be null here
    if (getSize (aKeys) != getSize (aValues))
      throw new IllegalArgumentException ("Number of keys is different from number of values"); //$NON-NLS-1$

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    final Iterator  itk = aKeys.iterator ();
    final Iterator  itv = aValues.iterator ();
    while (itk.hasNext ())
      ret.put (itk.next (), itv.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final Map  aMap)
  {
    if (isEmpty (aMap))
      return new TreeMap  (new ComparatorComparableNullAware  ());

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    ret.putAll (aMap);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final Map  [] aMaps)
  {
    if (aMaps == null || aMaps.length == 0)
      return new TreeMap  (new ComparatorComparableNullAware  ());

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    for (final Map  aMap : aMaps)
      ret.putAll (aMap);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static , VALUETYPE> TreeMap  newSortedMap (@Nullable final Collection > aCollection)
  {
    if (isEmpty (aCollection))
      return new TreeMap  (new ComparatorComparableNullAware  ());

    final TreeMap  ret = new TreeMap  (new ComparatorComparableNullAware  ());
    for (final Map.Entry  aEntry : aCollection)
      ret.put (aEntry.getKey (), aEntry.getValue ());
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap ()
  {
    return makeUnmodifiable (ContainerHelper. newSortedMap ());
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final KEYTYPE aKey,
                                                                                                                                   @Nullable final VALUETYPE aValue)
  {
    return makeUnmodifiable (newSortedMap (aKey, aValue));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedMap  newUnmodifiableSortedMap (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newSortedMap (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final KEYTYPE [] aKeys,
                                                                                                                                   @Nullable final VALUETYPE [] aValues)
  {
    return makeUnmodifiable (newSortedMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final Collection  aKeys,
                                                                                                                                   @Nullable final Collection  aValues)
  {
    return makeUnmodifiable (newSortedMap (aKeys, aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final SortedMap  aMap)
  {
    return makeUnmodifiable (aMap);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final Map  [] aMaps)
  {
    return makeUnmodifiable (newSortedMap (aMaps));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static , VALUETYPE> SortedMap  newUnmodifiableSortedMap (@Nullable final Collection > aCollection)
  {
    return makeUnmodifiable (newSortedMap (aCollection));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet ()
  {
    return new HashSet  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final ELEMENTTYPE aValue)
  {
    final Set  ret = new HashSet  (1);
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final ELEMENTTYPE... aValues)
  {
    if (ArrayHelper.isEmpty (aValues))
      return new HashSet  (0);

    final Set  ret = new HashSet  (aValues.length);
    Collections.addAll (ret, aValues);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final Iterable  aCont)
  {
    final Set  ret = new HashSet  ();
    if (aCont != null)
      for (final ELEMENTTYPE aValue : aCont)
        ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final Collection  aCont)
  {
    if (isEmpty (aCont))
      return new HashSet  (0);

    return new HashSet  (aCont);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final Iterator  aIter)
  {
    final Set  ret = new HashSet  ();
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new HashSet  (0);
    return newSet (aIter.iterator ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newSet (@Nullable final Enumeration  aEnum)
  {
    final Set  ret = new HashSet  ();
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > EnumSet  newEnumSet (@Nonnull final Class  aEnumClass,
                                                                                           @Nullable final ELEMENTTYPE... aValues)
  {
    final EnumSet  ret = EnumSet.noneOf (aEnumClass);
    if (aValues != null)
      for (final ELEMENTTYPE aValue : aValues)
        ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > EnumSet  newEnumSet (@Nonnull final Class  aEnumClass,
                                                                                           @Nullable final Collection  aValues)
  {
    if (isEmpty (aValues))
      return EnumSet.noneOf (aEnumClass);
    return EnumSet.copyOf (aValues);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > EnumSet  newEnumSet (@Nonnull final Class  aEnumClass,
                                                                                           @Nullable final EnumSet  aValues)
  {
    if (aValues == null)
      return EnumSet.noneOf (aEnumClass);
    return EnumSet.copyOf (aValues);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newBooleanSet (@Nullable final boolean... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final boolean aValue : aValues)
        ret.add (Boolean.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newByteSet (@Nullable final byte... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final byte aValue : aValues)
        ret.add (Byte.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newCharSet (@Nullable final char... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final char aValue : aValues)
        ret.add (Character.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newDoubleSet (@Nullable final double... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final double aValue : aValues)
        ret.add (Double.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newFloatSet (@Nullable final float... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final float aValue : aValues)
        ret.add (Float.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newIntSet (@Nullable final int... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final int aValue : aValues)
        ret.add (Integer.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newLongSet (@Nullable final long... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final long aValue : aValues)
        ret.add (Long.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newShortSet (@Nullable final short... aValues)
  {
    final Set  ret = new HashSet  ();
    if (aValues != null)
      for (final short aValue : aValues)
        ret.add (Short.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet ()
  {
    return Collections. emptySet ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final ELEMENTTYPE aValue)
  {
    return Collections.singleton (aValue);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final Iterable  aCont)
  {
    return makeUnmodifiable (newSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final Collection  aCont)
  {
    return makeUnmodifiable (newSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final Iterator  aIter)
  {
    return makeUnmodifiable (newSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final IIterableIterator  aIter)
  {
    return makeUnmodifiable (newSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableSet (@Nullable final Enumeration  aEnum)
  {
    return makeUnmodifiable (newSet (aEnum));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableBooleanSet (@Nullable final boolean... aValues)
  {
    return makeUnmodifiable (newBooleanSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableByteSet (@Nullable final byte... aValues)
  {
    return makeUnmodifiable (newByteSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableCharSet (@Nullable final char... aValues)
  {
    return makeUnmodifiable (newCharSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableDoubleSet (@Nullable final double... aValues)
  {
    return makeUnmodifiable (newDoubleSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableFloatSet (@Nullable final float... aValues)
  {
    return makeUnmodifiable (newFloatSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableIntSet (@Nullable final int... aValues)
  {
    return makeUnmodifiable (newIntSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableLongSet (@Nullable final long... aValues)
  {
    return makeUnmodifiable (newLongSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableShortSet (@Nullable final short... aValues)
  {
    return makeUnmodifiable (newShortSet (aValues));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet ()
  {
    return new TreeSet  (new ComparatorComparableNullAware  ());
  }

  @Nonnull
  @ReturnsMutableCopy
  @SuppressFBWarnings (value = { "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE" },
                       justification = "When using the constructor with the Comparator it works with null values!")
  public static > TreeSet  newSortedSet (@Nullable final ELEMENTTYPE aValue)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final ELEMENTTYPE... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (ArrayHelper.isNotEmpty (aValues))
      Collections.addAll (ret, aValues);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final Iterable  aCont)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aCont != null)
      for (final ELEMENTTYPE aValue : aCont)
        ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final Collection  aCont)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (isNotEmpty (aCont))
      ret.addAll (aCont);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final Iterator  aIter)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new TreeSet  (new ComparatorComparableNullAware  ());
    return newSortedSet (aIter.iterator ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static > TreeSet  newSortedSet (@Nullable final Enumeration  aEnum)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newBooleanSortedSet (@Nullable final boolean... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final boolean aValue : aValues)
        ret.add (Boolean.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newByteSortedSet (@Nullable final byte... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final byte aValue : aValues)
        ret.add (Byte.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newCharSortedSet (@Nullable final char... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final char aValue : aValues)
        ret.add (Character.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newDoubleSortedSet (@Nullable final double... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final double aValue : aValues)
        ret.add (Double.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newFloatSortedSet (@Nullable final float... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final float aValue : aValues)
        ret.add (Float.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newIntSortedSet (@Nullable final int... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final int aValue : aValues)
        ret.add (Integer.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newLongSortedSet (@Nullable final long... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final long aValue : aValues)
        ret.add (Long.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static TreeSet  newShortSortedSet (@Nullable final short... aValues)
  {
    final TreeSet  ret = new TreeSet  (new ComparatorComparableNullAware  ());
    if (aValues != null)
      for (final short aValue : aValues)
        ret.add (Short.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  SortedSet  newUnmodifiableSortedSet ()
  {
    return EmptySortedSet. getInstance ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final ELEMENTTYPE aValue)
  {
    return makeUnmodifiable (newSortedSet (aValue));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final Iterable  aCont)
  {
    return makeUnmodifiable (newSortedSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final Collection  aCont)
  {
    return makeUnmodifiable (newSortedSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final Iterator  aIter)
  {
    return makeUnmodifiable (newSortedSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final IIterableIterator  aIter)
  {
    return makeUnmodifiable (newSortedSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static > SortedSet  newUnmodifiableSortedSet (@Nullable final Enumeration  aEnum)
  {
    return makeUnmodifiable (newSortedSet (aEnum));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableBooleanSortedSet (@Nullable final boolean... aValues)
  {
    return makeUnmodifiable (newBooleanSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableByteSortedSet (@Nullable final byte... aValues)
  {
    return makeUnmodifiable (newByteSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableCharSortedSet (@Nullable final char... aValues)
  {
    return makeUnmodifiable (newCharSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableDoubleSortedSet (@Nullable final double... aValues)
  {
    return makeUnmodifiable (newDoubleSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableFloatSortedSet (@Nullable final float... aValues)
  {
    return makeUnmodifiable (newFloatSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableIntSortedSet (@Nullable final int... aValues)
  {
    return makeUnmodifiable (newIntSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableLongSortedSet (@Nullable final long... aValues)
  {
    return makeUnmodifiable (newLongSortedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static SortedSet  newUnmodifiableShortSortedSet (@Nullable final short... aValues)
  {
    return makeUnmodifiable (newShortSortedSet (aValues));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet ()
  {
    return new LinkedHashSet  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final ELEMENTTYPE aValue)
  {
    final Set  ret = new LinkedHashSet  (1);
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final ELEMENTTYPE... aValues)
  {
    if (ArrayHelper.isEmpty (aValues))
      return new LinkedHashSet  (0);

    final Set  ret = new LinkedHashSet  (aValues.length);
    Collections.addAll (ret, aValues);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final Iterable  aCont)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aCont != null)
      for (final ELEMENTTYPE aValue : aCont)
        ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final Collection  aCont)
  {
    if (isEmpty (aCont))
      return new LinkedHashSet  (0);

    return new LinkedHashSet  (aCont);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nonnull final Iterator  aIter)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new LinkedHashSet  (0);
    return newOrderedSet (aIter.iterator ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  newOrderedSet (@Nullable final Enumeration  aEnum)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newBooleanOrderedSet (@Nullable final boolean... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final boolean aValue : aValues)
        ret.add (Boolean.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newByteOrderedSet (@Nullable final byte... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final byte aValue : aValues)
        ret.add (Byte.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newCharOrderedSet (@Nullable final char... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final char aValue : aValues)
        ret.add (Character.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newDoubleOrderedSet (@Nullable final double... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final double aValue : aValues)
        ret.add (Double.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newFloatOrderedSet (@Nullable final float... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final float aValue : aValues)
        ret.add (Float.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newIntOrderedSet (@Nullable final int... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final int aValue : aValues)
        ret.add (Integer.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newLongOrderedSet (@Nullable final long... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final long aValue : aValues)
        ret.add (Long.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Set  newShortOrderedSet (@Nullable final short... aValues)
  {
    final Set  ret = new LinkedHashSet  ();
    if (aValues != null)
      for (final short aValue : aValues)
        ret.add (Short.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet ()
  {
    return Collections. emptySet ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nullable final ELEMENTTYPE aValue)
  {
    return Collections.singleton (aValue);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nonnull final Iterable  aCont)
  {
    return makeUnmodifiable (newOrderedSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nonnull final Collection  aCont)
  {
    return makeUnmodifiable (newOrderedSet (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nonnull final Iterator  aIter)
  {
    return makeUnmodifiable (newOrderedSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nonnull final IIterableIterator  aIter)
  {
    return makeUnmodifiable (newOrderedSet (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  Set  newUnmodifiableOrderedSet (@Nullable final Enumeration  aEnum)
  {
    return makeUnmodifiable (newOrderedSet (aEnum));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableBooleanOrderedSet (@Nullable final boolean... aValues)
  {
    return makeUnmodifiable (newBooleanOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableByteOrderedSet (@Nullable final byte... aValues)
  {
    return makeUnmodifiable (newByteOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableCharOrderedSet (@Nullable final char... aValues)
  {
    return makeUnmodifiable (newCharOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableDoubleOrderedSet (@Nullable final double... aValues)
  {
    return makeUnmodifiable (newDoubleOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableFloatOrderedSet (@Nullable final float... aValues)
  {
    return makeUnmodifiable (newFloatOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableIntOrderedSet (@Nullable final int... aValues)
  {
    return makeUnmodifiable (newIntOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableLongOrderedSet (@Nullable final long... aValues)
  {
    return makeUnmodifiable (newLongOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static Set  newUnmodifiableShortOrderedSet (@Nullable final short... aValues)
  {
    return makeUnmodifiable (newShortOrderedSet (aValues));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newListPrefilled (@Nullable final ELEMENTTYPE aValue,
                                                                   @Nonnegative final int nElements)
  {
    ValueEnforcer.isGE0 (nElements, "Elements"); //$NON-NLS-1$

    final List  ret = new ArrayList  (nElements);
    for (int i = 0; i < nElements; ++i)
      ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList ()
  {
    return new ArrayList  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final ELEMENTTYPE aValue)
  {
    final List  ret = new ArrayList  (1);
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final ELEMENTTYPE... aValues)
  {
    // Don't user Arrays.asList since aIter returns an unmodifiable list!
    if (ArrayHelper.isEmpty (aValues))
      return new ArrayList  (0);

    final List  ret = new ArrayList  (aValues.length);
    Collections.addAll (ret, aValues);
    return ret;
  }

  /**
   * Compared to {@link Collections#list(Enumeration)} this method is more
   * flexible in Generics parameter.
   * 
   * @param 
   *        Type of the elements
   * @param aEnum
   *        The enumeration to be converted
   * @return The non-null created {@link ArrayList}.
   * @see Collections#list(Enumeration)
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final Enumeration  aEnum)
  {
    final List  ret = new ArrayList  ();
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final Iterator  aIter)
  {
    final List  ret = new ArrayList  ();
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final Iterable  aIter)
  {
    final List  ret = new ArrayList  ();
    if (aIter != null)
      for (final ELEMENTTYPE aObj : aIter)
        ret.add (aObj);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final Collection  aCont)
  {
    if (isEmpty (aCont))
      return new ArrayList  (0);

    return new ArrayList  (aCont);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  List  newList (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new ArrayList  (0);
    return newList (aIter.iterator ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVectorPrefilled (@Nullable final ELEMENTTYPE aValue,
                                                                       @Nonnegative final int nElements)
  {
    ValueEnforcer.isGE0 (nElements, "Elements"); //$NON-NLS-1$

    final Vector  ret = new Vector  (nElements);
    for (int i = 0; i < nElements; ++i)
      ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector ()
  {
    return new Vector  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final ELEMENTTYPE aValue)
  {
    final Vector  ret = new Vector  (1);
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final ELEMENTTYPE... aValues)
  {
    // Don't user Arrays.asVector since aIter returns an unmodifiable list!
    if (ArrayHelper.isEmpty (aValues))
      return new Vector  (0);

    final Vector  ret = new Vector  (aValues.length);
    Collections.addAll (ret, aValues);
    return ret;
  }

  /**
   * Compared to {@link Collections#list(Enumeration)} this method is more
   * flexible in Generics parameter.
   * 
   * @param 
   *        Type of the elements
   * @param aEnum
   *        The enumeration to be converted
   * @return The non-null created {@link Vector}.
   * @see Collections#list(Enumeration)
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final Enumeration  aEnum)
  {
    final Vector  ret = new Vector  ();
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final Iterator  aIter)
  {
    final Vector  ret = new Vector  ();
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final Iterable  aIter)
  {
    final Vector  ret = new Vector  ();
    if (aIter != null)
      for (final ELEMENTTYPE aObj : aIter)
        ret.add (aObj);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final Collection  aCont)
  {
    if (isEmpty (aCont))
      return new Vector  (0);

    return new Vector  (aCont);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Vector  newVector (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new Vector  (0);
    return newVector (aIter.iterator ());
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newBooleanList (@Nullable final boolean... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final boolean aValue : aValues)
        ret.add (Boolean.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newByteList (@Nullable final byte... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final byte aValue : aValues)
        ret.add (Byte.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newCharList (@Nullable final char... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final char aValue : aValues)
        ret.add (Character.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newDoubleList (@Nullable final double... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final double aValue : aValues)
        ret.add (Double.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newFloatList (@Nullable final float... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final float aValue : aValues)
        ret.add (Float.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newIntList (@Nullable final int... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final int aValue : aValues)
        ret.add (Integer.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newLongList (@Nullable final long... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final long aValue : aValues)
        ret.add (Long.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static List  newShortList (@Nullable final short... aValues)
  {
    final List  ret = new ArrayList  ();
    if (aValues != null)
      for (final short aValue : aValues)
        ret.add (Short.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newBooleanVector (@Nullable final boolean... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final boolean aValue : aValues)
        ret.add (Boolean.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newByteVector (@Nullable final byte... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final byte aValue : aValues)
        ret.add (Byte.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newCharVector (@Nullable final char... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final char aValue : aValues)
        ret.add (Character.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newDoubleVector (@Nullable final double... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final double aValue : aValues)
        ret.add (Double.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newFloatVector (@Nullable final float... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final float aValue : aValues)
        ret.add (Float.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newIntVector (@Nullable final int... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final int aValue : aValues)
        ret.add (Integer.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newLongVector (@Nullable final long... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final long aValue : aValues)
        ret.add (Long.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static Vector  newShortVector (@Nullable final short... aValues)
  {
    final Vector  ret = new Vector  ();
    if (aValues != null)
      for (final short aValue : aValues)
        ret.add (Short.valueOf (aValue));
    return ret;
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList ()
  {
    return Collections. emptyList ();
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final ELEMENTTYPE aValue)
  {
    return Collections.singletonList (aValue);
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final ELEMENTTYPE... aValues)
  {
    return makeUnmodifiable (newList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final Enumeration  aIter)
  {
    return makeUnmodifiable (newList (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final Iterator  aIter)
  {
    return makeUnmodifiable (newList (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final Iterable  aCont)
  {
    return makeUnmodifiable (newList (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final Collection  aCont)
  {
    return makeUnmodifiable (newList (aCont));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static  List  newUnmodifiableList (@Nullable final IIterableIterator  aIter)
  {
    return makeUnmodifiable (newList (aIter));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableBooleanList (@Nullable final boolean... aValues)
  {
    return makeUnmodifiable (newBooleanList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableByteList (@Nullable final byte... aValues)
  {
    return makeUnmodifiable (newByteList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableCharList (@Nullable final char... aValues)
  {
    return makeUnmodifiable (newCharList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableDoubleList (@Nullable final double... aValues)
  {
    return makeUnmodifiable (newDoubleList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableFloatList (@Nullable final float... aValues)
  {
    return makeUnmodifiable (newFloatList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableIntList (@Nullable final int... aValues)
  {
    return makeUnmodifiable (newIntList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableLongList (@Nullable final long... aValues)
  {
    return makeUnmodifiable (newLongList (aValues));
  }

  @Nonnull
  @ReturnsImmutableObject
  public static List  newUnmodifiableShortList (@Nullable final short... aValues)
  {
    return makeUnmodifiable (newShortList (aValues));
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  NonBlockingStack  newStack ()
  {
    return new NonBlockingStack  ();
  }

  /**
   * Create a new stack with a single element.
   * 
   * @param 
   *        The type of elements contained in the stack.
   * @param aValue
   *        The value to push. Maybe null.
   * @return A non-null stack.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  NonBlockingStack  newStack (@Nullable final ELEMENTTYPE aValue)
  {
    final NonBlockingStack  ret = new NonBlockingStack  ();
    ret.push (aValue);
    return ret;
  }

  /**
   * Create a new stack from the given array.
   * 
   * @param 
   *        The type of elements contained in the stack.
   * @param aValues
   *        The values that are to be pushed on the stack. The last element will
   *        be the top element on the stack. May not be null .
   * @return A non-null stack object.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  NonBlockingStack  newStack (@Nullable final ELEMENTTYPE... aValues)
  {
    return new NonBlockingStack  (aValues);
  }

  /**
   * Create a new stack from the given collection.
   * 
   * @param 
   *        The type of elements contained in the stack.
   * @param aValues
   *        The values that are to be pushed on the stack. The last element will
   *        be the top element on the stack. May not be null .
   * @return A non-null stack object.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  NonBlockingStack  newStack (@Nullable final Collection  aValues)
  {
    return new NonBlockingStack  (aValues);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue ()
  {
    return new PriorityQueue  (0);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nonnull final ELEMENTTYPE aValue)
  {
    final Queue  ret = new PriorityQueue  (1);
    ret.add (aValue);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final ELEMENTTYPE... aValues)
  {
    // Don't user Arrays.asQueue since aIter returns an unmodifiable list!
    if (ArrayHelper.isEmpty (aValues))
      return new PriorityQueue  (0);

    final Queue  ret = new PriorityQueue  (aValues.length);
    Collections.addAll (ret, aValues);
    return ret;
  }

  /**
   * Compared to {@link Collections#list(Enumeration)} this method is more
   * flexible in Generics parameter.
   * 
   * @param 
   *        Type of the elements
   * @param aEnum
   *        The enumeration to be converted
   * @return The non-null created {@link PriorityQueue}.
   * @see Collections#list(Enumeration)
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final Enumeration  aEnum)
  {
    final Queue  ret = new PriorityQueue  ();
    if (aEnum != null)
      while (aEnum.hasMoreElements ())
        ret.add (aEnum.nextElement ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final Iterator  aIter)
  {
    final Queue  ret = new PriorityQueue  ();
    if (aIter != null)
      while (aIter.hasNext ())
        ret.add (aIter.next ());
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final Iterable  aIter)
  {
    final Queue  ret = new PriorityQueue  ();
    if (aIter != null)
      for (final ELEMENTTYPE aObj : aIter)
        ret.add (aObj);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final Collection  aCont)
  {
    if (isEmpty (aCont))
      return new PriorityQueue  (0);

    return new PriorityQueue  (aCont);
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Queue  newQueue (@Nullable final IIterableIterator  aIter)
  {
    if (aIter == null)
      return new PriorityQueue  (0);
    return newQueue (aIter.iterator ());
  }

  /**
   * Convert the given iterator to a sorted list.
   * 
   * @param 
   *        The type of elements to iterate. May not be null.
   * @param aIter
   *        Input iterator. May be null.
   * @return a non-null {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final IIterableIterator  aIter)
  {
    return getSortedInline (newList (aIter));
  }

  /**
   * Convert the given iterator to a sorted list.
   * 
   * @param 
   *        The type of elements to iterate. May not be null.
   * @param aIter
   *        Input iterator. May be null.
   * @param aComparator
   *        The comparator to use. May not be null.
   * @return a non-null {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final IIterableIterator  aIter,
                                                                                                     @Nonnull final Comparator  aComparator)
  {
    return getSortedInline (newList (aIter), aComparator);
  }

  /**
   * Convert the given iterator to a sorted list.
   * 
   * @param 
   *        The type of elements to iterate. May not be null.
   * @param aIter
   *        Input iterator. May not be null.
   * @return a non-null {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final Iterator  aIter)
  {
    return getSortedInline (newList (aIter));
  }

  /**
   * Convert the given iterator to a sorted list.
   * 
   * @param 
   *        The type of elements to iterate.
   * @param aIter
   *        Input iterator. May be null.
   * @param aComparator
   *        The comparator to use. May not be null.
   * @return a non-null {@link ArrayList} based on the results of
   *         {@link Collections#sort(List, Comparator)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  getSorted (@Nullable final Iterator  aIter,
                                                            @Nonnull final Comparator  aComparator)
  {
    return getSortedInline (newList (aIter), aComparator);
  }

  /**
   * Convert the given iterable object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Iterable input object. May be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final Iterable  aCont)
  {
    return getSortedInline (newList (aCont));
  }

  /**
   * Convert the given iterable object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Iterable input object. May be null.
   * @param aComparator
   *        The comparator to use. May not be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List, Comparator)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  getSorted (@Nullable final Iterable  aCont,
                                                            @Nonnull final Comparator  aComparator)
  {
    return getSortedInline (newList (aCont), aComparator);
  }

  /**
   * Convert the given collection object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Collection input object. May be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final Collection  aCont)
  {
    return getSortedInline (newList (aCont));
  }

  /**
   * Convert the given collection object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Collection input object. May be null.
   * @param aComparator
   *        The comparator to use. May not be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List, Comparator)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  getSorted (@Nullable final Collection  aCont,
                                                            @Nonnull final Comparator  aComparator)
  {
    return getSortedInline (newList (aCont), aComparator);
  }

  /**
   * Convert the given iterable object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Array input object. May be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static > List  getSorted (@Nullable final ELEMENTTYPE... aCont)
  {
    return getSortedInline (newList (aCont));
  }

  /**
   * Convert the given iterable object to a sorted list.
   * 
   * @param 
   *        The type of element to iterate.
   * @param aCont
   *        Iterable input object. May be null.
   * @param aComparator
   *        The comparator to use. May not be null.
   * @return A {@link ArrayList} based on the results of
   *         {@link Collections#sort(List, Comparator)}.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  getSorted (@Nullable final ELEMENTTYPE [] aCont,
                                                            @Nonnull final Comparator  aComparator)
  {
    return getSortedInline (newList (aCont), aComparator);
  }

  @Nullable
  @ReturnsMutableObject (reason = "design")
  public static > List  getSortedInline (@Nullable final List  aList)
  {
    if (isNotEmpty (aList))
      Collections.sort (aList);
    return aList;
  }

  @Nullable
  @ReturnsMutableObject (reason = "design")
  public static  List  getSortedInline (@Nullable final List  aList,
                                                                  @Nonnull final Comparator  aComparator)
  {
    ValueEnforcer.notNull (aComparator, "Comparator"); //$NON-NLS-1$

    if (isNotEmpty (aList))
      Collections.sort (aList, aComparator);
    return aList;
  }

  /**
   * Get a map sorted by aIter's keys. Because no comparator is defined, the key
   * type needs to implement the {@link java.lang.Comparable} interface.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        the map to sort
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static , VALUETYPE> Map  getSortedByKey (@Nullable final Map  aMap)
  {
    return getSortedByKey (aMap, ESortOrder.DEFAULT);
  }

  /**
   * Get a map sorted by its keys. Because no comparator is defined, the key
   * type needs to implement the {@link java.lang.Comparable} interface.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        the map to sort
   * @param eSortOrder
   *        The sort oder to use for sorting. May not be null.
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static , VALUETYPE> Map  getSortedByKey (@Nullable final Map  aMap,
                                                                                                                   @Nonnull final ESortOrder eSortOrder)
  {
    if (isEmpty (aMap))
      return aMap;

    // get sorted entry list
    final List > aList = newList (aMap.entrySet ());
    Collections.sort (aList, ComparatorUtils. getComparatorMapEntryKey (eSortOrder));
    return newOrderedMap (aList);
  }

  /**
   * Get a map sorted by its keys. The comparison order is defined by the passed
   * comparator object.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map to sort. May not be null.
   * @param aKeyComparator
   *        The comparator to be used. May not be null.
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static  Map  getSortedByKey (@Nullable final Map  aMap,
                                                                              @Nonnull final Comparator  aKeyComparator)
  {
    ValueEnforcer.notNull (aKeyComparator, "KeyComparator"); //$NON-NLS-1$

    if (isEmpty (aMap))
      return aMap;

    // get sorted Map.Entry list by Entry.getValue ()
    final List > aList = newList (aMap.entrySet ());
    Collections.sort (aList, ComparatorUtils. getComparatorMapEntryKey (aKeyComparator));
    return newOrderedMap (aList);
  }

  /**
   * Get a map sorted by its values. Because no comparator is defined, the value
   * type needs to implement the {@link java.lang.Comparable} interface.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map to sort. May not be null.
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static > Map  getSortedByValue (@Nullable final Map  aMap)
  {
    return getSortedByValue (aMap, ESortOrder.DEFAULT);
  }

  /**
   * Get a map sorted by its values. Because no comparator is defined, the value
   * type needs to implement the {@link java.lang.Comparable} interface.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map to sort. May not be null.
   * @param eSortOrder
   *        The sort order to be applied. May not be null.
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static > Map  getSortedByValue (@Nullable final Map  aMap,
                                                                                                                       @Nonnull final ESortOrder eSortOrder)
  {
    if (isEmpty (aMap))
      return aMap;

    // get sorted entry list
    final List > aList = newList (aMap.entrySet ());
    Collections.sort (aList, ComparatorUtils. getComparatorMapEntryValue (eSortOrder));
    return newOrderedMap (aList);
  }

  /**
   * Get a map sorted by aIter's values. The comparison order is defined by the
   * passed comparator object.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map to sort. May not be null.
   * @param aValueComparator
   *        The comparator to be used. May not be null.
   * @return the sorted map or the original map, if it was empty
   */
  @Nullable
  public static  Map  getSortedByValue (@Nullable final Map  aMap,
                                                                                @Nonnull final Comparator  aValueComparator)
  {
    ValueEnforcer.notNull (aValueComparator, "ValueComparator"); //$NON-NLS-1$

    if (isEmpty (aMap))
      return aMap;

    // get sorted Map.Entry list by Entry.getValue ()
    final List > aList = newList (aMap.entrySet ());
    Collections.sort (aList, ComparatorUtils. getComparatorMapEntryValue (aValueComparator));
    return newOrderedMap (aList);
  }

  @Nullable
  @ReturnsMutableCopy
  public static  List  getReverseList (@Nullable final Collection  aCollection)
  {
    if (isEmpty (aCollection))
      return new ArrayList  (0);

    final List  ret = new ArrayList  (aCollection);
    Collections.reverse (ret);
    return ret;
  }

  @Nullable
  @ReturnsMutableObject (reason = "semantics of this method")
  public static  List  getReverseInlineList (@Nullable final List  aList)
  {
    if (aList == null)
      return null;

    Collections.reverse (aList);
    return aList;
  }

  @Nonnull
  public static  IIterableIterator  getIterator (@Nullable final Enumeration  aEnum)
  {
    return new IterableIteratorFromEnumeration  (aEnum);
  }

  @Nonnull
  public static  Iterator  getIterator (@Nullable final Iterable  aCont)
  {
    return aCont == null ? EmptyIterator. getInstance () : getIterator (aCont.iterator ());
  }

  @Nonnull
  public static  Iterator  getIterator (@Nullable final Iterator  aIter)
  {
    return aIter == null ? EmptyIterator. getInstance () : aIter;
  }

  @Nonnull
  public static  Iterator  getIterator (@Nullable final ELEMENTTYPE... aArray)
  {
    return ArrayHelper.isEmpty (aArray) ? EmptyIterator. getInstance ()
                                        : getIterator (newList (aArray).iterator ());
  }

  @Nonnull
  public static  Iterator  getReverseIterator (@Nullable final List  aCont)
  {
    if (isEmpty (aCont))
      return EmptyIterator. getInstance ();

    /**
     * Performance note: this implementation is much faster than building a
     * temporary list in reverse order and returning a forward iterator!
     */
    return ReverseListIterator.create (aCont);
  }

  /**
   * Create an empty iterator.
   * 
   * @param 
   *        The type the iterator's elements.
   * @return A non-null object.
   */
  @Nonnull
  public static  Iterator  getEmptyIterator ()
  {
    return EmptyIterator. getInstance ();
  }

  /**
   * Get a merged iterator of both iterators. The first iterator is iterated
   * first, the second one afterwards.
   * 
   * @param 
   *        The type of elements to be enumerated.
   * @param aIter1
   *        First iterator. May be null.
   * @param aIter2
   *        Second iterator. May be null.
   * @return The merged iterator. Never null.
   */
  @Nonnull
  public static  Iterator  getCombinedIterator (@Nullable final Iterator  aIter1,
                                                                          @Nullable final Iterator  aIter2)
  {
    return new CombinedIterator  (aIter1, aIter2);
  }

  /**
   * Get an {@link Enumeration} object based on a {@link Collection} object.
   * 
   * @param 
   *        the type of the elements in the container
   * @param aCont
   *        The container to enumerate.
   * @return an Enumeration object
   */
  @Nonnull
  public static  Enumeration  getEnumeration (@Nullable final Iterable  aCont)
  {
    return isEmpty (aCont) ? EmptyEnumeration. getInstance () : getEnumeration (aCont.iterator ());
  }

  /**
   * Get an {@link Enumeration} object based on the passed array.
   * 
   * @param 
   *        the type of the elements in the container
   * @param aArray
   *        The array to enumerate.
   * @return an Enumeration object
   */
  @Nonnull
  public static  Enumeration  getEnumeration (@Nullable final ELEMENTTYPE... aArray)
  {
    return getEnumeration (getIterator (aArray));
  }

  /**
   * Get an Enumeration object based on an Iterator object.
   * 
   * @param 
   *        the type of the elements in the container
   * @param aIter
   *        iterator object to use
   * @return an Enumeration object
   */
  @Nonnull
  public static  Enumeration  getEnumeration (@Nullable final Iterator  aIter)
  {
    if (aIter == null)
      return EmptyEnumeration. getInstance ();

    return new EnumerationFromIterator  (aIter);
  }

  /**
   * Get an Enumeration object based on a Map object.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        map object to use
   * @return an Enumeration object
   */
  @Nonnull
  public static  Enumeration > getEnumeration (@Nullable final Map  aMap)
  {
    if (aMap == null)
      return EmptyEnumeration.> getInstance ();
    return getEnumeration (aMap.entrySet ());
  }

  /**
   * Get a merged enumeration of both enumeration. The first enumeration is
   * enumerated first, the second one afterwards.
   * 
   * @param 
   *        The type of elements to be enumerated.
   * @param aEnum1
   *        First enumeration. May be null.
   * @param aEnum2
   *        Second enumeration. May be null.
   * @return The merged enumeration. Never null.
   */
  @Nonnull
  public static  Enumeration  getCombinedEnumeration (@Nullable final Enumeration  aEnum1,
                                                                                @Nullable final Enumeration  aEnum2)
  {
    return new CombinedEnumeration  (aEnum1, aEnum2);
  }

  /**
   * Create an empty enumeration.
   * 
   * @param 
   *        The type the enumeration's elements.
   * @return A non-null object.
   */
  @Nonnull
  public static  Enumeration  getEmptyEnumeration ()
  {
    return EmptyEnumeration. getInstance ();
  }

  @Nullable
  @ReturnsMutableCopy
  public static  NonBlockingStack  getStackCopyWithoutTop (@Nullable final NonBlockingStack  aStack)
  {
    if (isEmpty (aStack))
      return null;

    final NonBlockingStack  ret = new NonBlockingStack  (aStack);
    ret.pop ();
    return ret;
  }

  /**
   * Get a map consisting only of a set of specified keys. If an element from
   * the key set is not contained in the original map, the key is ignored.
   * 
   * @param 
   *        Source map key type.
   * @param 
   *        Source map value type.
   * @param aValues
   *        Source map to filter. May not be null.
   * @param aKeys
   *        The filter set to filter the entries from. May not be
   *        null.
   * @return A non-null map containing only the elements from the
   *         specified key set.
   */
  @Nullable
  @ReturnsMutableCopy
  public static  Map  getFilteredMap (@Nullable final Map  aValues,
                                                              @Nullable final Collection  aKeys)
  {
    if (isEmpty (aValues) || isEmpty (aKeys))
      return null;

    final Map  ret = new HashMap  ();
    for (final KEY aKey : aKeys)
      if (aValues.containsKey (aKey))
        ret.put (aKey, aValues.get (aKey));
    return ret;
  }

  /**
   * Get the first element of the passed list.
   * 
   * @param 
   *        The element type
   * @param aList
   *        The list. May be null.
   * @return null if the list is null or empty, the
   *         first element otherwise.
   */
  @Nullable
  public static  ELEMENTTYPE getFirstElement (@Nullable final List  aList)
  {
    return isEmpty (aList) ? null : aList.get (0);
  }

  /**
   * Get the first element of the passed sorted set.
   * 
   * @param 
   *        The element type
   * @param aSortedSet
   *        The sorted set. May be null.
   * @return null if the list is null or empty, the
   *         first element otherwise.
   */
  @Nullable
  public static  ELEMENTTYPE getFirstElement (@Nullable final SortedSet  aSortedSet)
  {
    return isEmpty (aSortedSet) ? null : aSortedSet.first ();
  }

  /**
   * Get the first element of the passed collection.
   * 
   * @param 
   *        The element type
   * @param aCollection
   *        The collection. May be null.
   * @return null if the collection is null or empty,
   *         the first element otherwise.
   */
  @Nullable
  public static  ELEMENTTYPE getFirstElement (@Nullable final Collection  aCollection)
  {
    return isEmpty (aCollection) ? null : aCollection.iterator ().next ();
  }

  /**
   * Get the first element of the passed iterable.
   * 
   * @param 
   *        The element type
   * @param aIterable
   *        The iterable. May be null.
   * @return null if the iterable is null or empty,
   *         the first element otherwise.
   */
  @Nullable
  public static  ELEMENTTYPE getFirstElement (@Nullable final Iterable  aIterable)
  {
    if (aIterable == null)
      return null;
    final Iterator  it = aIterable.iterator ();
    return it.hasNext () ? it.next () : null;
  }

  /**
   * Get the first element of the passed map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map. May be null.
   * @return null if the map is null or empty, the
   *         first element otherwise.
   */
  @Nullable
  public static  Map.Entry  getFirstElement (@Nullable final Map  aMap)
  {
    return isEmpty (aMap) ? null : aMap.entrySet ().iterator ().next ();
  }

  /**
   * Get the first key of the passed map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map. May be null.
   * @return null if the map is null or empty, the
   *         first key otherwise.
   */
  @Nullable
  public static  KEYTYPE getFirstKey (@Nullable final Map  aMap)
  {
    return isEmpty (aMap) ? null : aMap.keySet ().iterator ().next ();
  }

  /**
   * Get the first key of the passed sorted map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aSortedMap
   *        The sorted map. May be null.
   * @return null if the map is null or empty, the
   *         first key otherwise.
   */
  @Nullable
  public static  KEYTYPE getFirstKey (@Nullable final SortedMap  aSortedMap)
  {
    return isEmpty (aSortedMap) ? null : aSortedMap.firstKey ();
  }

  /**
   * Get the first value of the passed map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aMap
   *        The map. May be null.
   * @return null if the map is null or empty, the
   *         first value otherwise.
   */
  @Nullable
  public static  VALUETYPE getFirstValue (@Nullable final Map  aMap)
  {
    return isEmpty (aMap) ? null : aMap.values ().iterator ().next ();
  }

  /**
   * Get the first value of the passed map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aSortedMap
   *        The map. May be null.
   * @return null if the map is null or empty, the
   *         first value otherwise.
   */
  @Nullable
  public static  VALUETYPE getFirstValue (@Nullable final SortedMap  aSortedMap)
  {
    final KEYTYPE aKey = getFirstKey (aSortedMap);
    return aKey == null ? null : aSortedMap.get (aKey);
  }

  @Nullable
  public static  ELEMENTTYPE removeFirstElement (@Nullable final List  aList)
  {
    return isEmpty (aList) ? null : aList.remove (0);
  }

  @Nullable
  public static  ELEMENTTYPE getLastElement (@Nullable final List  aList)
  {
    final int nSize = getSize (aList);
    return nSize == 0 ? null : aList.get (nSize - 1);
  }

  @Nullable
  public static  ELEMENTTYPE getLastElement (@Nullable final SortedSet  aSortedSet)
  {
    return isEmpty (aSortedSet) ? null : aSortedSet.last ();
  }

  @Nullable
  public static  ELEMENTTYPE getLastElement (@Nullable final Collection  aCollection)
  {
    if (isEmpty (aCollection))
      return null;

    // Slow but shouldn't matter
    ELEMENTTYPE aLast = null;
    for (final ELEMENTTYPE aElement : aCollection)
      aLast = aElement;
    return aLast;
  }

  @Nullable
  public static  ELEMENTTYPE getLastElement (@Nullable final Iterable  aIterable)
  {
    if (aIterable == null)
      return null;

    // Slow but shouldn't matter
    ELEMENTTYPE aLast = null;
    for (final ELEMENTTYPE aElement : aIterable)
      aLast = aElement;
    return aLast;
  }

  /**
   * Remove the element at the specified index from the passed list. This works
   * if the list is not null and the index is ≥ 0 and <
   * list.size()
   * 
   * @param aList
   *        The list to remove an element from. May be null.
   * @param nIndex
   *        The index to be removed. May be arbitrary.
   * @return {@link EChange#CHANGED} if removal was successful
   * @see #removeAndReturnElementAtIndex(List, int)
   */
  @Nonnull
  public static EChange removeElementAtIndex (@Nullable final List  aList, final int nIndex)
  {
    if (aList == null || nIndex < 0 || nIndex >= aList.size ())
      return EChange.UNCHANGED;
    aList.remove (nIndex);
    return EChange.CHANGED;
  }

  /**
   * Remove the element at the specified index from the passed list. This works
   * if the list is not null and the index is ≥ 0 and <
   * list.size()
   * 
   * @param 
   *        element type
   * @param aList
   *        The list to remove an element from. May be null.
   * @param nIndex
   *        The index to be removed. May be arbitrary.
   * @return null if removal failed or the removed element. Note:
   *         the removed element may also be null so it may be
   *         tricky to determine if removal succeeded or not!
   * @see #removeElementAtIndex(List, int)
   */
  @Nullable
  public static  ELEMENTTYPE removeAndReturnElementAtIndex (@Nullable final List  aList,
                                                                         final int nIndex)
  {
    if (aList == null || nIndex < 0 || nIndex >= aList.size ())
      return null;
    return aList.remove (nIndex);
  }

  /**
   * Get the last key of the passed sorted map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aSortedMap
   *        The sorted map. May be null.
   * @return null if the map is null or empty, the
   *         last key otherwise.
   */
  @Nullable
  public static  KEYTYPE getLastKey (@Nullable final SortedMap  aSortedMap)
  {
    return isEmpty (aSortedMap) ? null : aSortedMap.lastKey ();
  }

  /**
   * Get the last value of the passed map.
   * 
   * @param 
   *        map key type
   * @param 
   *        map value type
   * @param aSortedMap
   *        The map. May be null.
   * @return null if the map is null or empty, the
   *         last value otherwise.
   */
  @Nullable
  public static  VALUETYPE getLastValue (@Nullable final SortedMap  aSortedMap)
  {
    final KEYTYPE aKey = getLastKey (aSortedMap);
    return aKey == null ? null : aSortedMap.get (aKey);
  }

  @Nullable
  public static  ELEMENTTYPE removeLastElement (@Nullable final List  aList)
  {
    final int nSize = getSize (aList);
    return nSize == 0 ? null : aList.remove (nSize - 1);
  }

  public static boolean isEmpty (@Nullable final Iterable  aCont)
  {
    return aCont == null || !aCont.iterator ().hasNext ();
  }

  public static boolean isEmpty (@Nullable final Iterator  aIter)
  {
    return aIter == null || !aIter.hasNext ();
  }

  public static boolean isEmpty (@Nullable final IIterableIterator  aIter)
  {
    return aIter == null || !aIter.hasNext ();
  }

  public static boolean isEmpty (@Nullable final Enumeration  aEnum)
  {
    return aEnum == null || !aEnum.hasMoreElements ();
  }

  public static boolean isEmpty (@Nullable final Collection  aCont)
  {
    return aCont == null || aCont.isEmpty ();
  }

  public static boolean isEmpty (@Nullable final Map  aCont)
  {
    return aCont == null || aCont.isEmpty ();
  }

  public static boolean isNotEmpty (@Nullable final Iterable  aCont)
  {
    return aCont != null && aCont.iterator ().hasNext ();
  }

  public static boolean isNotEmpty (@Nullable final Iterator  aIter)
  {
    return aIter != null && aIter.hasNext ();
  }

  public static boolean isNotEmpty (@Nullable final IIterableIterator  aIter)
  {
    return aIter != null && aIter.hasNext ();
  }

  public static boolean isNotEmpty (@Nullable final Enumeration  aEnum)
  {
    return aEnum != null && aEnum.hasMoreElements ();
  }

  public static boolean isNotEmpty (@Nullable final Collection  aCont)
  {
    return aCont != null && !aCont.isEmpty ();
  }

  public static boolean isNotEmpty (@Nullable final Map  aCont)
  {
    return aCont != null && !aCont.isEmpty ();
  }

  /**
   * Retrieve the size of the passed {@link Collection}. This method handles
   * null containers.
   * 
   * @param aCollection
   *        Object to check. May be null.
   * @return The size of the object or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final Collection  aCollection)
  {
    return aCollection == null ? 0 : aCollection.size ();
  }

  /**
   * Retrieve the size of the passed {@link Map}. This method handles
   * null containers.
   * 
   * @param aMap
   *        Object to check. May be null.
   * @return The size of the object or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final Map  aMap)
  {
    return aMap == null ? 0 : aMap.size ();
  }

  /**
   * Retrieve the size of the passed {@link Iterable}.
   * 
   * @param aIterable
   *        Iterator to check. May be null.
   * @return The number objects or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final Iterable  aIterable)
  {
    return aIterable == null ? 0 : getSize (aIterable.iterator ());
  }

  /**
   * Retrieve the size of the passed {@link Iterable}.
   * 
   * @param aIterator
   *        Iterable iterator to check. May be null.
   * @return The number objects or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final IIterableIterator  aIterator)
  {
    return aIterator == null ? 0 : getSize (aIterator.iterator ());
  }

  /**
   * Retrieve the size of the passed {@link Iterator}.
   * 
   * @param aIterator
   *        Iterator to check. May be null.
   * @return The number objects or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final Iterator  aIterator)
  {
    int ret = 0;
    if (aIterator != null)
      while (aIterator.hasNext ())
      {
        aIterator.next ();
        ++ret;
      }
    return ret;
  }

  /**
   * Retrieve the size of the passed {@link Enumeration}.
   * 
   * @param aEnumeration
   *        Enumeration to check. May be null.
   * @return The number objects or 0 if the passed parameter is
   *         null.
   */
  @Nonnegative
  public static int getSize (@Nullable final Enumeration  aEnumeration)
  {
    int ret = 0;
    if (aEnumeration != null)
      while (aEnumeration.hasMoreElements ())
      {
        aEnumeration.nextElement ();
        ++ret;
      }
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static  List  getConcatenatedList (@Nullable final Collection  aCollection1,
                                                                      @Nullable final Collection  aCollection2)
  {
    final int nSize1 = getSize (aCollection1);
    if (nSize1 == 0)
      return newList (aCollection2);

    final int nSize2 = getSize (aCollection2);
    if (nSize2 == 0)
      return newList (aCollection1);

    final List  ret = new ArrayList  (nSize1 + nSize2);
    ret.addAll (aCollection1);
    ret.addAll (aCollection2);
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static  List  getConcatenatedList (@Nullable final Collection  aCont1,
                                                                      @Nullable final ELEMENTTYPE... aCont2)
  {
    final int nSize1 = getSize (aCont1);
    if (nSize1 == 0)
      return newList (aCont2);

    final int nSize2 = ArrayHelper.getSize (aCont2);
    if (nSize2 == 0)
      return newList (aCont1);

    final List  ret = new ArrayList  (nSize1 + nSize2);
    ret.addAll (aCont1);
    Collections.addAll (ret, aCont2);
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static  List  getConcatenatedList (@Nullable final ELEMENTTYPE [] aCont1,
                                                                      @Nullable final Collection  aCont2)
  {
    final int nSize1 = ArrayHelper.getSize (aCont1);
    if (nSize1 == 0)
      return newList (aCont2);

    final int nSize2 = getSize (aCont2);
    if (nSize2 == 0)
      return newList (aCont1);

    final List  ret = new ArrayList  (nSize1 + nSize2);
    Collections.addAll (ret, aCont1);
    ret.addAll (aCont2);
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static  Set  getConcatenatedSet (@Nullable final Collection  aCont1,
                                                                    @Nullable final Collection  aCont2)
  {
    final int nSize1 = getSize (aCont1);
    if (nSize1 == 0)
      return newSet (aCont2);

    final int nSize2 = getSize (aCont2);
    if (nSize2 == 0)
      return newSet (aCont1);

    final Set  ret = new HashSet  (nSize1 + nSize2);
    ret.addAll (aCont1);
    ret.addAll (aCont2);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  getConcatenatedSet (@Nullable final Collection  aCont1,
                                                                    @Nullable final ELEMENTTYPE... aCont2)
  {
    final int nSize1 = getSize (aCont1);
    if (nSize1 == 0)
      return newSet (aCont2);

    final int nSize2 = ArrayHelper.getSize (aCont2);
    if (nSize2 == 0)
      return newSet (aCont1);

    final Set  ret = new HashSet  (nSize1 + nSize2);
    ret.addAll (aCont1);
    Collections.addAll (ret, aCont2);
    return ret;
  }

  @Nonnull
  @ReturnsMutableCopy
  public static  Set  getConcatenatedSet (@Nullable final ELEMENTTYPE [] aCont1,
                                                                    @Nullable final Collection  aCont2)
  {
    final int nSize1 = ArrayHelper.getSize (aCont1);
    if (nSize1 == 0)
      return newSet (aCont2);

    final int nSize2 = getSize (aCont2);
    if (nSize2 == 0)
      return newSet (aCont1);

    final Set  ret = new HashSet  (nSize1 + nSize2);
    Collections.addAll (ret, aCont1);
    ret.addAll (aCont2);
    return ret;
  }

  @Nonnull
  @ReturnsMutableObject (reason = "design")
  public static > COLLTYPE getConcatenatedInline (@Nonnull final COLLTYPE aCont,
                                                                                                                 @Nullable final ELEMENTTYPE... aElementsToAdd)
  {
    ValueEnforcer.notNull (aCont, "Container"); //$NON-NLS-1$

    if (aElementsToAdd != null)
      Collections.addAll (aCont, aElementsToAdd);
    return aCont;
  }

  @Nonnull
  @ReturnsMutableObject (reason = "design")
  public static > COLLTYPE getConcatenatedInline (@Nonnull final COLLTYPE aCont,
                                                                                                                 @Nullable final Collection  aElementsToAdd)
  {
    ValueEnforcer.notNull (aCont, "Container"); //$NON-NLS-1$

    if (aElementsToAdd != null)
      aCont.addAll (aElementsToAdd);
    return aCont;
  }

  /**
   * Create a map that contains the combination of the other 2 maps. Both maps
   * need to have the same key and value type.
   * 
   * @param 
   *        The map key type.
   * @param 
   *        The map value type.
   * @param aMap1
   *        The first map. May be null.
   * @param aMap2
   *        The second map. May be null.
   * @return Never null and always a new object. If both parameters
   *         are not null a new map is created, initially
   *         containing the entries from the first parameter, afterwards
   *         extended by the parameters of the second map potentially
   *         overwriting elements from the first map.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  Map  getCombinedMap (@Nullable final Map  aMap1,
                                                              @Nullable final Map  aMap2)
  {
    if (isEmpty (aMap1))
      return newMap (aMap2);
    if (isEmpty (aMap2))
      return newMap (aMap1);

    // create and fill result map
    final Map  ret = new HashMap  (aMap1);
    ret.putAll (aMap2);
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final boolean [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final boolean x : aArray)
      ret.add (Boolean.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final byte [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final byte x : aArray)
      ret.add (Byte.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final char [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final char x : aArray)
      ret.add (Character.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final double [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final double x : aArray)
      ret.add (Double.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final float [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final float x : aArray)
      ret.add (Float.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final int [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final int x : aArray)
      ret.add (Integer.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final long [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final long x : aArray)
      ret.add (Long.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final short [] aArray)
  {
    if (ArrayHelper.isEmpty (aArray))
      return null;

    final List  ret = new ArrayList  (aArray.length);
    for (final short x : aArray)
      ret.add (Short.valueOf (x));
    return ret;
  }

  @Nullable
  @ReturnsMutableCopy
  public static List  newObjectListFromArray (@Nullable final Object aValue, @Nonnull final Class  aComponentType)
  {
    if (aComponentType == boolean.class)
    {
      // get as List
      return newObjectListFromArray ((boolean []) aValue);
    }
    if (aComponentType == byte.class)
    {
      // get as List
      return newObjectListFromArray ((byte []) aValue);
    }
    if (aComponentType == char.class)
    {
      // get as List
      return newObjectListFromArray ((char []) aValue);
    }
    if (aComponentType == double.class)
    {
      // get as List
      return newObjectListFromArray ((double []) aValue);
    }
    if (aComponentType == float.class)
    {
      // get as List
      return newObjectListFromArray ((float []) aValue);
    }
    if (aComponentType == int.class)
    {
      // get as List
      return newObjectListFromArray ((int []) aValue);
    }
    if (aComponentType == long.class)
    {
      // get as List
      return newObjectListFromArray ((long []) aValue);
    }
    if (aComponentType == short.class)
    {
      // get as List
      return newObjectListFromArray ((short []) aValue);
    }

    // the rest
    final Object [] aArray = (Object []) aValue;
    if (ArrayHelper.isEmpty (aArray))
    {
      return null;
    }
    final List  aRet = new ArrayList  (aArray.length);
    Collections.addAll (aRet, aArray);
    return aRet;
  }

  /**
   * Gets a sublist excerpt of the passed list.
   * 
   * @param 
   *        Type of elements in list
   * @param aCont
   *        The backing list. May not be null.
   * @param nStartIndex
   *        The start index to use. Needs to be ≥ 0.
   * @param nSectionLength
   *        the length of the desired subset. If list is shorter than that,
   *        aIter will return a shorter section
   * @return The specified section of the passed list, or a shorter list if
   *         nStartIndex + nSectionLength is an invalid index. Never
   *         null.
   */
  @Nonnull
  @ReturnsMutableCopy
  public static  List  getSubList (@Nullable final List  aCont,
                                                             @Nonnegative final int nStartIndex,
                                                             @Nonnegative final int nSectionLength)
  {
    ValueEnforcer.isGE0 (nStartIndex, "StartIndex"); //$NON-NLS-1$
    ValueEnforcer.isGE0 (nSectionLength, "SectionLength"); //$NON-NLS-1$

    final int nSize = getSize (aCont);
    if (nSize == 0)
    {
      return new ArrayList  (0);
    }
    if (nStartIndex >= nSize)
    {
      return new ArrayList  (0);
    }
    int nEndIndex = nStartIndex + nSectionLength;
    if (nEndIndex > nSize)
    {
      nEndIndex = nSize;
    }
    // Create a copy of the list because "subList" only returns a view of the
    // original list!
    return newList (aCont.subList (nStartIndex, nEndIndex));
  }

  /**
   * Get a map where keys and values are exchanged.
   * 
   * @param 
   *        Original key type.
   * @param 
   *        Original value type.
   * @param aMap
   *        The input map to convert. May not be null.
   * @return The swapped hash map (unsorted!)
   */
  @Nullable
  @ReturnsMutableCopy
  public static  Map  getSwappedKeyValues (@Nullable final Map  aMap)
  {
    if (isEmpty (aMap))
      return null;

    final Map  ret = new HashMap  (aMap.size ());
    for (final Map.Entry  aEntry : aMap.entrySet ())
      ret.put (aEntry.getValue (), aEntry.getKey ());
    return ret;
  }

  /**
   * Get a map where the lookup (1K..nV) has been reversed to (1V..nK)
   * 
   * @param 
   *        Original key type
   * @param 
   *        Original value type
   * @param aMap
   *        The input map to convert. May not be null
   * @return A swapped {@link IMultiMapSetBased}
   */
  @Nullable
  @ReturnsMutableCopy
  public static  IMultiMapSetBased  getReverseLookupSet (@Nullable final IMultiMap > aMap)
  {
    if (isEmpty (aMap))
      return null;

    final IMultiMapSetBased  ret = new MultiHashMapHashSetBased  ();
    for (final Map.Entry > aEntry : aMap.entrySet ())
      for (final VALUETYPE aValue : aEntry.getValue ())
        ret.putSingle (aValue, aEntry.getKey ());
    return ret;
  }

  /**
   * Get a map where the lookup (1K..nV) has been reversed to (1V..nK)
   * 
   * @param 
   *        Original key type
   * @param 
   *        Original value type
   * @param aMap
   *        The input map to convert. May not be null
   * @return A swapped {@link HashMap}
   */
  @Nullable
  @ReturnsMutableCopy
  public static  IMultiMapSetBased  getReverseLookup (@Nullable final IMultiMapSetBased  aMap)
  {
    if (isEmpty (aMap))
      return null;

    final IMultiMapSetBased  aRet = new MultiHashMapHashSetBased  ();
    for (final Map.Entry > aEntry : aMap.entrySet ())
      for (final VALUETYPE aValue : aEntry.getValue ())
        aRet.putSingle (aValue, aEntry.getKey ());
    return aRet;
  }

  /**
   * Safe list element accessor method.
   * 
   * @param 
   *        The type of elements on the list.
   * @param aList
   *        The list to extract from. May be null.
   * @param nIndex
   *        The index to access. Should be ≥ 0.
   * @return null if the element cannot be accessed.
   */
  @Nullable
  public static  ELEMENTTYPE getSafe (@Nullable final List  aList, final int nIndex)
  {
    return getSafe (aList, nIndex, null);
  }

  /**
   * Safe list element accessor method.
   * 
   * @param 
   *        The type of elements on the list.
   * @param aList
   *        The list to extract from. May be null.
   * @param nIndex
   *        The index to access. Should be ≥ 0.
   * @param aDefault
   *        The value to be returned, if the index is out of bounds.
   * @return The default parameter if the element cannot be accessed.
   */
  @Nullable
  public static  ELEMENTTYPE getSafe (@Nullable final List  aList,
                                                   final int nIndex,
                                                   @Nullable final ELEMENTTYPE aDefault)
  {
    return aList != null && nIndex >= 0 && nIndex < aList.size () ? aList.get (nIndex) : aDefault;
  }

  /**
   * Check if the passed collection contains at least one null
   * element.
   * 
   * @param aCont
   *        The collection to check. May be null.
   * @return true only if the passed collection is neither
   *         null nor empty and if at least one null
   *         element is contained.
   */
  public static boolean containsAnyNullElement (@Nullable final Iterable  aCont)
  {
    if (aCont != null)
      for (final Object aObj : aCont)
        if (aObj == null)
          return true;
    return false;
  }

  /**
   * Check if the passed collection contains only null element.
   * 
   * @param aCont
   *        The collection to check. May be null.
   * @return true only if the passed collection is neither
   *         null nor empty and if at least one null
   *         element is contained.
   */
  public static boolean containsOnlyNullElements (@Nullable final Iterable  aCont)
  {
    if (isEmpty (aCont))
      return false;

    for (final Object aObj : aCont)
      if (aObj != null)
        return false;
    return true;
  }

  /**
   * Checks whether the passed collection contains the passed element in a
   * null-safe way
   * 
   * @param aCont
   *        The container
   * @param aElem
   *        The element to look for in the container
   * @return true if the container is non-null and contains the
   *         element, false otherwise
   */
  public static boolean contains (@Nullable final Collection  aCont, final Object aElem)
  {
    return aCont != null && aCont.contains (aElem);
  }

  /**
   * Iterates all passed objects and collect their IDs
   * 
   * @param aElements
   *        Objects for which to collect the IDs, must not be null
   * @return All IDs (no duplicates)
   */
  @Nonnull
  public static final Set  getIDs (@Nonnull final Collection > aElements)
  {
    return LockedContainerHelper.getIDs (aElements, null);
  }

  /**
   * Iterates all passed objects and collect their IDs
   * 
   * @param aElements
   *        Objects for which to collect the IDs, must not be null
   * @return All IDs in stable order (may contain duplicates)
   */
  @Nonnull
  public static final List  getIDs (@Nonnull final List > aElements)
  {
    return LockedContainerHelper.getIDs (aElements, null);
  }

  /**
   * Iterates all passed objects and collect their names
   * 
   * @param aElements
   *        Objects for which to collect the names, must not be
   *        null
   * @return All names (no duplicates)
   */
  @Nonnull
  public static final Set  getNames (@Nonnull final Collection  aElements)
  {
    return LockedContainerHelper.getNames (aElements, null);
  }

  /**
   * Iterates all passed objects and collect their names
   * 
   * @param aElements
   *        Objects for which to collect the names, must not be
   *        null
   * @return All names in stable order (may contain duplicates)
   */
  @Nonnull
  public static final List  getNames (@Nonnull final List  aElements)
  {
    return LockedContainerHelper.getNames (aElements, null);
  }
}